Frank Vèssia Posted September 8, 2011 Share Posted September 8, 2011 It's possible to extend an inputfield without replacing the entire module? I want to add some functionalities to all the inputfields but i don't want to recreate all, i just want to create a single module that add this function to the existing fields. Link to comment Share on other sites More sharing options...
ryan Posted September 8, 2011 Share Posted September 8, 2011 It sounds like you want to add a hook. Can you provide more context? I think once I know what you are trying to do, I should be able to tell you how to do it. Link to comment Share on other sites More sharing options...
Frank Vèssia Posted September 8, 2011 Author Share Posted September 8, 2011 I'm building a form builder based on the original inputfileds of PW. Now i'm at the point in which i have the same form in the admin and in the frontend, changing a field in the admin my form change in the same way, same for the post action. Now i want to add the automatic validation for every field and for making this i need to add a select near every inputfield in the admin for choose the right validator. Link to comment Share on other sites More sharing options...
ryan Posted September 8, 2011 Share Posted September 8, 2011 I think I understand. I should say though that PW's fields and inputs are designed for administrative use rather than front end use. If I'm building something for the front end, I might still use PW pages to store the data, but I'm handling the input on my own and populating fields into page objects. That's what I recommend because you'll be able to do whatever you want without limitation and use PW's API in the manner it was built for. But if the Inputfields are suiting your need, then here's what you'd do to extend all of them. In the example, we add a hook to the field rendering (to add a select box with each one) and another hook to the input processing. This example module should be pasted into a file called /site/modules/InputfieldHookTest.module <?php class InputfieldHookTest extends WireData implements Module { public static function getModuleInfo() { return array( 'title' => 'Inputfield Hook Test', 'version' => 100, 'summary' => 'Just a test.', 'singular' => true, 'autoload' => true, ); } public function init() { $this->addHookAfter('Inputfield::render', $this, 'render'); $this->addHookAfter('Inputfield::processInput', $this, 'processInput'); } public function render(HookEvent $event) { $inputfield = $event->object; // optional, but better to limit to those you want if(!$inputfield instanceof InputfieldText && !$inputfield instanceof InputfieldTextarea) return; $name = $inputfield->name; $event->return .= "<p><select name='test_$name'><option></option><option>test</option><option>test2</option></select></p>"; } public function processInput(HookEvent $event) { $inputfield = $event->object; $name = $inputfield->name; $post = $event->arguments[0]; $value = $post["test_$name"]; if($value) $this->message("You selected '$value' for '$name'"); } } 2 Link to comment Share on other sites More sharing options...
Soma Posted September 8, 2011 Share Posted September 8, 2011 that kinda was what I was asking for here http://processwire.com/talk/index.php/topic,465.0.html I already was this far to have the right hook on inputfields and all but missed the obvious, that playing with str_replace I replaced itself each recursion... was late night. Thanks for the example that helped and made some things clearer. Link to comment Share on other sites More sharing options...
Frank Vèssia Posted September 8, 2011 Author Share Posted September 8, 2011 Thanks so much Link to comment Share on other sites More sharing options...
Macrura Posted October 14, 2014 Share Posted October 14, 2014 I'm trying to create a slightly enhanced page select, whereby the only difference to the output would be adding a data-description to each option, which would be populated by looking up the value of a data-description field on that selectable page; I know where (renderOptions function) to make the change, but not sure how to hook in there and replace that function, or should i make a new inputfield for this? I did try copying the InputfieldSelect and making some changes (calling it InputfieldSelectEnhanced), and but i'm not clear how to get this new inputfield to show up in the list of options for the Fieldtype Page... ultimately the goal would be to use javascript to replace the description area below the page select with the data for that particular select; for a simple example, say I have a select on a page that specifies actions that will take place on save (like importing files, or deleting files from the page etc..), i would like to have a more descriptive paragraph about what exactly my save action will do.. this would be sort of useful just about anytime you needed to show the user more information about what they have selected, beyond just the title, and where that info is going to be a little verbose (and wouldn't work as the option label).. thanks! Link to comment Share on other sites More sharing options...
netcarver Posted October 14, 2014 Share Posted October 14, 2014 Hi Macrura, I've just done something similar to this for my current project. I needed to add data-start-time attributes to every option in a select dropdown so I decided to extend the InputfieldSelectMultiple class to provide a replacement addOption() implementation that added the required data attribute as part of the internal attributes array for each option. Here's what I did... public function addOption($value, $label = null, array $attributes = null) { if ( is_null($value) || (is_string($value) && !strlen($value)) ) { return $this; } if (null === $attributes) { $attributes = array(); } $extra_atts = $this->extendAttributes($value, $label); $attributes = array_merge($attributes, $extra_atts); return parent::addOption($value, $label, $attributes); } public function ___extendAttributes($id, $value) { $atts = array(); /** * Either hook this method to do what you want or implement things directly if this * is the only use of this Inputfield. * For your example you'd grab the fields you want from your page and put into data * attributes... */ //$page = wire()->pages->get($id); //$atts['data-description'] = $page->description; return $atts; } I've updated the example above to output data-description. Hope that helps you with some ideas! 8 Link to comment Share on other sites More sharing options...
Macrura Posted October 14, 2014 Share Posted October 14, 2014 w.o.w. ! netcarver - thanks -this is going to be amazing, and i don't think i could have figured this out, at least not for a while.. so (this being the first time i'm doing this more advanced sort of module), could you possibly explain a tiny bit more about how to extend the class (say for InputfieldSelect) - where or what sort of module would i create to place that code? TIA Link to comment Share on other sites More sharing options...
netcarver Posted October 15, 2014 Share Posted October 15, 2014 Hi Macrura, Here's a version for select multiple... <?php class InputfieldSelectMultipleExtended extends InputfieldSelectMultiple { public static function getModuleInfo() { return array( 'title' => __('Select Multiple Extended', __FILE__), 'version' => 1, 'summary' => __('Multiple selection with extended attributes. An enhancement to select multiple', __FILE__), 'permanent' => false, ); } /** * Adds an option with extended attributes */ public function addOption($value, $label = null, array $attributes = null) { if ( is_null($value) || (is_string($value) && !strlen($value)) ) { return $this; } if (null === $attributes) { $attributes = array(); } $extra_atts = $this->extendAttributes($value, $label); $attributes = array_merge($attributes, $extra_atts); return parent::addOption($value, $label, $attributes); } /** * Hook this and return an array with whatever extended attributes you need. * */ public function ___extendAttributes($id, $value) { $atts = array(); /** * Either hook this method to do what you want or implement things directly if this * is the only use of this Inputfield. * For your example you'd grab the fields you want from your page and put into data * attributes... */ $page = wire()->pages->get($id); $atts['data-description'] = $page->description; return $atts; } } Here's how to use it... Save this module as InputfieldSelectMultipleExtended.module in your site/modules directory of a development install of PW. Install it in PW. Edit InputfieldPage's module configuration and add InputfieldSelectMultipleExtended to the inputfields that can represent pages. Create a new Page field and select InputfieldSelectMultipleExtended on the input tab and setup the parent and other fields as required. Add the new page reference field to a template. Add some pages that use this template. Check the HTML of any of the pages using the template and you should see the options for the select have data-description attribute for every page referenced that has a non-empty description field. Hope that helps! 8 Link to comment Share on other sites More sharing options...
Macrura Posted October 15, 2014 Share Posted October 15, 2014 @netcarver - can't thank you enough -this completely works!! I added a js file to populate my description field above the select, and changed the module name to be select, not multiple.. will have to do a screenshot/screencast; this module should be made available in some form on the directory, as i think it has some great use cases for data- attributes on selects... maybe both versions, select and select multiple 2 Link to comment Share on other sites More sharing options...
Soma Posted October 15, 2014 Share Posted October 15, 2014 I would ask Ryan to make the method hookah Le. So no need for extendingm I think it can be useful in cases like this. 3 Link to comment Share on other sites More sharing options...
horst Posted October 15, 2014 Share Posted October 15, 2014 +1 for hookable compared against extending! Link to comment Share on other sites More sharing options...
netcarver Posted October 15, 2014 Share Posted October 15, 2014 I'll add a pull request to the PW repo for this feature. Edited to add: Done. 4 Link to comment Share on other sites More sharing options...
Macrura Posted October 15, 2014 Share Posted October 15, 2014 Here's an example of how I used the module that netcarver posted: before something is selected: after selection: i also had an idea for extending AsmSelect to make the selected items clickable and brings up a modal editor for that selected page; has anyone done something like that yet? For example with this site I'm working on, you can add composers to a track, but it would be cool if after you add new items to the page you could click on them to make some edits (bio, website for ex), without having to go and find that page in the tree.. 2 Link to comment Share on other sites More sharing options...
netcarver Posted October 19, 2014 Share Posted October 19, 2014 @Macrura Glad this worked out for you. Actually, the PW admin interface does what you are after already (if I understand you correctly.) If you edit a template and look at the AsmSelect list of fields in the template - each one of them is clickable and brings up a modal edit for that field's properties when used in that particular template. This would suggest that everything you need is already built right into AsmSelect so I'd suggest you have a look through the source code and see what's commented in there and how Ryan uses it. 3 Link to comment Share on other sites More sharing options...
Macrura Posted October 19, 2014 Share Posted October 19, 2014 @netcarver - yes, that's what I was thinking, and have been sort of studying that now for a few hrs; i came up with a quick solution using jquery for now.. ( https://processwire.com/talk/topic/8005-page-select-edit-links/?p=77312 ) but it would be nice if there could be a simple toggle on every page select field, like "title links to edit" .. Link to comment Share on other sites More sharing options...
netcarver Posted October 2, 2016 Share Posted October 2, 2016 @Macrura @horst I've added this feature request to the new repo - please emoti-vote for it if you still want this as a core feature. As a side note, here are some screenshots of a module that I ended up developing in the absence of this feature. Take a standard ASM Select... ...add some extended data attributes to the options... ...and a little javascript to use the data-group attribute of the selected options to disable other, currently unselected options with a matching data-group value (all while keeping things in the right sort order.) You then get a list that prevents your gymnasts from being booked in to the Trampoline group at the same time they are already booked in the Gymnastics group... 4 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