Jump to content

How to create a copy URL Fieldype?


Recommended Posts

Hi guys I'm relatively new to PW and just finished developing a page for a client. I was able to include all necessary functionality using the core fieldtypes but now I it seems that I need to extend them with a custom one. What I need is a simple button, that copies the absolute url (frontend not PW-backend) of the page which is currently edited to the clipboard. As this feature is only needed inside a specific template, I tend to use a custom fieldtype which provides this feature. I've been looking inside the core modules code (eg. FieldtypeCheckbox.module) but I don't really get the structure of it and how its rendered to the admin page. I also didn't find a lot of tutorials covering custom fieldtypes.

Maybe some of you could give me some tips on how to write a basic custom fieldtype that renders a button which copies the value of

page->httpUrl()

to the clipboard using JS. Thanks!

Link to comment
Share on other sites

13 hours ago, Thomas Diroll said:

I need is a simple button, that copies the absolute url (frontend not PW-backend) of the page which is currently edited to the clipboard.

Hello,

I have something similar I hope you can adapt it to your needs. Mine is for user templates:

<?php 
//adds a button to the end of the user edit page:
$this->addHook('ProcessPageEdit::buildForm', function (HookEvent $event) {
    $current_page = $event->object->getPage();

    if ($current_page->template->name != 'user') return; // this button is for the user edit page only
    if (empty($current_page->user_family_name)) return; // custom field is not yet filled in, which means the new User has not been saved but still being edited in the admin

    $id = (int) $current_page->id;
    if ($id != 0) {
        if ($current_page->hasRole('mycustomrole')) {

            $href = createLink($current_page); // this is a custom function to be implemented, it must generate and return the required URL 
            $field = $this->modules->get('InputfieldButton');
            $field->attr('class', $field->class . " my-custom-css-class-if-needed"); // this is just opitional, I left it here as an example
            $field->attr('value', 'Copy URL to clipboard...');
            $field->attr('data-clipboard-text', $href); // data-clipboard-text is needed by https://clipboardjs.com/
            $field->attr('href', ''); // $href

            $event->return = $event->return->append($field);
        }
    }
});

The copy to clipboard action is performed by https://clipboardjs.com/ which can be loaded by the admin using various techniques or free modules (such as AdminOnSteroids or Admin Custom Files) or one can simply put this line into config.php: $config->scripts->add($config->urls->templates . "clipboard.min.js"); where clipboard.min.js is in the templates directory, for example.

EDIT: I forgot to note that the hook goes into init.php

  • Like 7
Link to comment
Share on other sites

Thanks for all your answers!!! This was really fast and seems like a very active community! I'm sure the code snippet by @szabesz and the fieldtype by @kixe will work as well and are definitely more lightweight. I went with the RuntimeMarkup fieldtype suggested by @elabx as it was the fastest and easiest one to apply. Here is my php snippet for the runtime field:

return "
<a id='custom-action-button' href='#' onclick='copyUrlToClipboard(event);'>Copy URL to clipboard</a>
<input type='text' value='" . $page->httpUrl() . "' id='target-page-url'>
<p id='action-executed-hint'>Successfully copied URL to clipboard!</p>

<style>
#custom-action-button {
color: #FFF;
background: #93BF0D;
font-weight: bold;
padding: 0.6em 1.1em;
font-size: 1em !important;
border-radius: 5px;
}
#custom-action-button:hover {
color: #FFF;
background-color: #DB1174;
}
#custom-action-button:active {
color: #FFF;
background-color: #860A47;
}
#custom-action-button:visited {
color: #FFF;
}
#target-page-url {
position: absolute;
left: -9999px;
top: -9999px;
opacity: 0;
pointer-events: none;
}
#action-executed-hint {
display: none;
}
#action-executed-hint.show {
display: inline;
}
</style>

<script>
function copyUrlToClipboard(event) {
event.preventDefault();
var urlText = document.getElementById('target-page-url');
urlText.select();
document.execCommand('copy');
var hint = document.getElementById('action-executed-hint');
hint.className += ' show';
}
</script>
";

It creates an a-tag which is styled like a backend button. Hope its useful for someone else!

  • Like 7
Link to comment
Share on other sites

  • 1 month later...
On 8/9/2018 at 7:13 PM, Thomas Diroll said:

Here is my php snippet for the runtime field:

Just seen this. Welcome to the forums @Thomas Diroll. It's better (readability, maintenance, etc) to throw the code in a file and call it using the wireRenderFile() method. 

If using ProcessWire 3.x, you will need to use namespace as follows:

return ProcessWire\wireRenderFile('name-of-file');
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...