Thomas Diroll Posted August 9, 2018 Posted August 9, 2018 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!
elabx Posted August 9, 2018 Posted August 9, 2018 Sounds to me like a good option is the RuntimeMarkup module, so you can basically render whatever you want in the inputfield, and add the necessary javascript to do the whole copy-paste to clipboard. 2
Thomas Diroll Posted August 9, 2018 Author Posted August 9, 2018 @elabx Thanks for the fast reply! This actually looks like a nice way to implement own code! I will take a look at it. Thanks!
szabesz Posted August 9, 2018 Posted August 9, 2018 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 7
kixe Posted August 9, 2018 Posted August 9, 2018 Once I made a nice Fieldtype for this. Please try out http://modules.processwire.com/modules/fieldtype-button/ 1
Thomas Diroll Posted August 9, 2018 Author Posted August 9, 2018 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! 7
kongondo Posted September 9, 2018 Posted September 9, 2018 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');
adrian Posted September 9, 2018 Posted September 9, 2018 We also have: $files->render() these days. 2
kongondo Posted September 10, 2018 Posted September 10, 2018 12 hours ago, adrian said: $files->render() Of course. Silly me ?. Thanks @adrian 1
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now