ryan Posted May 10 Share Posted May 10 I've been continuing to work on the PageEditChildren module that I wrote about here last week. This week a "Clone" feature was added. You can click the Clone action and it'll create a copy of the page below the one you cloned, and then make it immediately editable before you even have to save. This Clone action is an example of an Inputfield header action, and it accompanies the Move, Pub/Unpub and Trash actions for each page in PageEditChildren. I thought this ability to add Inputfield actions seemed useful beyond just this module, so the ability has been added directly into ProcessWire's core Inputfields JS API. If you grab the current dev branch of ProcessWire, you can test it out if you'd like. You can paste these examples in your web browser's Javascript console. But in actual web development, you'd likely put these in a separate JS file that is added to your page editor with a hook. Open the page editor to any page, then open your Javascript console in your web browser, and then paste this in: Inputfields.addHeaderAction('title', { icon: 'fa-hand-stop-o', callback: function() { ProcessWire.alert('Hello World!'); } }); That should add a hand icon to your "Title" field header, and if you click it, it'll pop-up a dialog box that says "Hello World". Let's say you wanted it to show a different icon when you hover it, and also to show tooltip text via a title attribute. You can add the 'overIcon' to specify what icon to show on mouseover, and 'tooltip' to specify the tooltip text: Inputfields.addHeaderAction('title', { icon: 'fa-hand-stop-o', overIcon: 'fa-hand-peace-o', tooltip: 'Hello world', callback: function() { ProcessWire.alert('Hello World!'); } }); Above are examples of 'click' actions. We also support toggle or "on/off" actions: Inputfields.addHeaderAction('title', { onIcon: 'fa-toggle-on', onTooltip: 'Click to toggle off', onCallback: function() { ProcessWire.alert('You toggled on'); }, offIcon: 'fa-toggle-off', offTooltip: 'Click to toggle on', offCallback: function() { ProcessWire.alert('You toggled off'); } }); Toggle actions like this are primarily what is used by the PageEditChildren module to handle the Published vs Unpublished state, and Trash on/off state. Whereas "Clone" is an example of a Click action. Our callback functions in the examples above are very simple alerts, but of course you could make it do anything you want in those callbacks. Also added this week to the Inputfield JS API was an update to the Inputfields.label() function that now allows you to set the label for an Inputfield (previously it could only get the label). This is a bit of a contrived example, but since we were talking about header actions above, let's demonstrate the label() function within a header action. This example adds an action that lets you edit the Inputfield label: Inputfields.addHeaderAction('title', { icon: 'smile-o', callback: function($f) { ProcessWire.prompt('Enter new label', 'Label', function(val) { if(val) Inputfields.label($f, val); }); } }); By the way, there's a lot more to the Inputfields JS API, and it's all documented directly in ProcessWire's inputfields.js file. I'll be bumping the core dev version next week to hopefully accompany the first version of the PageEditChildren module. Thanks for reading and have a great weekend! 14 4 Link to comment Share on other sites More sharing options...
Robin S Posted May 10 Share Posted May 10 The header action feature is cool, thanks @ryan! Is there a way that a header action can be added through the PHP API rather than through the Inputfield JS API? A couple of reasons this could be useful: 1. I can imagine a module that would add some header action feature to every inputfield (or every inputfield of a particular type) and it would be simpler to do this via a hook before Inputfield::render(). 2. Sometimes the inputfield you want to target doesn't exist in the DOM when the page loads (e.g. Repeater subfields or other Ajax-loaded scenarios) and so the JS code to add the header action would also need to watch for other events like "reloaded" or "ajaxComplete", and again it would be easier to add the action in a before render hook. I was thinking that if the PHP API supported header actions then JS actions could be handled via an "event" property. So something like this... $action->event = 'myAction'; ...which means that clicking the icon would trigger a "myAction" event, and the developer would use JS like... $(document).on('myAction', '.Inputfield', function(event) { const $inputfield = $(event.target); // Do something involving the inputfield... }); And in case the action doesn't need JS but should instead be PHP-based or just link to some URL there could also be an "href" property which would make the icon into a link, perhaps to be used with URL hooks... $action->href = "/my-action/$page->id/$field->name"; ...and... $wire->addHook('/my-action/{page_id}/{field_name}', function($event) { // Do something with $event->page_id and $event->field_name here... }); What do you think? 6 Link to comment Share on other sites More sharing options...
ryan Posted May 12 Author Share Posted May 12 @Robin S I was thinking that since a JS callback is necessary to make it do anything, it was simplest just to keep it all JS, contained to one definition. At least for the case that prompted adding this feature (PageEditChildren module). But for cases like what you are describing, what you say makes a lot of sense. I will add an $inputfield->addHeaderAction([ ... ]); that does the same thing, maybe like these examples? // click action $inputfield->addHeaderAction([ 'icon' => 'hand-stop-o', 'overIcon' => 'hand-peace-o', 'tooltip' => 'Hello world', 'event' => 'myEvent' ]); // toggle action $inputfield->addHeaderAction([ 'onIcon' => 'toggle-on', 'onEvent' => 'MyOnEvent', 'onTooltip' => 'Click to toggle off', 'offIcon' => 'toggle-off', 'offEvent' => 'MyOffEvent', 'offTooltip' => 'Click to toggle on', ]); // link action $inputfield->addHeaderAction([ 'icon' => 'fa-link', 'href' => 'https://processwire.com/api/ref/', 'tooltip' => 'API reference', 'target' => '_blank', // or 'modal' or omit for '_self' ]); 8 Link to comment Share on other sites More sharing options...
Robin S Posted May 12 Share Posted May 12 @ryan, that sounds great, thanks! Link to comment Share on other sites More sharing options...
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