darrenc Posted February 16, 2017 Share Posted February 16, 2017 Is it possible to make a page field, that outputs options based on what a user has selected in a previous page field? Template data setup house (template) title (text) body (textarea) neighborhood (page field) neighborhood (template) title (text) Obviously it's set up with lots of neighborhood pages, and if you create a house you get a dropdown of those neighborhoods which you can select. What I want to do featured_neighborhood (template) title (text) body (textarea) neighborhood (page field) homes_in_neighborhood (page field) The goal would be for the user to create a new featured neighborhood, choose the neighborhood reference, and then homes_in_neighborhood would be a selection dynamically created from whatever neighborhood that is. Is this possible in PW? Thanks in advance! Link to comment Share on other sites More sharing options...
adrian Posted February 16, 2017 Share Posted February 16, 2017 or 1 Link to comment Share on other sites More sharing options...
Robin S Posted February 16, 2017 Share Posted February 16, 2017 You can do this with the undocumented dependent selects feature, which AJAX loads the selectable pages in a Page Reference field based on the value of another Page Reference field in the same page being edited. Your "homes_in_neighborhood" field would use this as the "Selector string" setting: neighborhood=page.neighborhood, neighborhood!='' You can limit by template, parent, etc too if you want. Based on my previous experience: Both Page Reference fields must use a Select, Select Multiple or AsmSelect inputfield. Dependent selects do not work inside Repeater fields. When changing the "source" Page Reference field you sometimes randomly get an option preselected in the "target" Page Reference field. Not a major problem but just something to keep an eye on to avoid accidentally saving an unintended value. If these limitations are a problem and you don't mind having to save the page after changing the "neighborhood" field then you can use the "Custom PHP code" option for selectable pages instead. 6 1 Link to comment Share on other sites More sharing options...
Zeka Posted February 19, 2018 Share Posted February 19, 2018 On 16.02.2017 at 10:38 PM, Robin S said: Dependent selects do not work inside Repeater fields. @Robin S Do you mean inside a repeater field or if items inside 'parent' Page reference field is repeater items? It seems like it doesn't work in both cases. Link to comment Share on other sites More sharing options...
Robin S Posted February 20, 2018 Share Posted February 20, 2018 6 hours ago, Zeka said: Do you mean inside a repeater field or if items inside 'parent' Page reference field is repeater items? I mean inside a repeater field. Technically it will work there, but not in a useful way. The issue being that the names of inputfields inside a repeater item have a suffix according to the ID of the repeater page. So you would have to include the suffix in the selector for the dependent Page Reference field and therefore it would only ever work inside a single repeater item. Should be no problem if the pages that make up the selectable options in a Page Reference field happen to be repeater pages. They are treated the same as any other page inside the field. Link to comment Share on other sites More sharing options...
Kiwi Chris Posted November 29, 2019 Share Posted November 29, 2019 It's a while since this thread has been updated, so I thought I'd check whether there's been any update on anyone finding a way to make dependent selects work dynamically inside repeaters. I've got dependent selects inside repeaters working ok IF I save each time I make a selection, but that's a bit clunky for an end user. I realise there are issues with the way repeaters generate ids that might make ajax based updates impossible but it would be handy. I originally rejected using pagetables as there are only every going to be a handful of repeater items for each page, and the modal edit method with pagetable fields, rather than inline editing, along with the need to publish each item is not as intuitive as repeaters. A repeater field would be my preference, although I guess I could go back to using pagetables/pagetable extended, but they're not as convenient for end users as a repeater, apart from the issue around dynamic selects. Link to comment Share on other sites More sharing options...
Robin S Posted November 30, 2019 Share Posted November 30, 2019 (edited) On 11/29/2019 at 8:43 PM, Kiwi Chris said: It's a while since this thread has been updated, so I thought I'd check whether there's been any update on anyone finding a way to make dependent selects work dynamically inside repeaters. I had a play around and this hook seems to do the job: Edit: the hook doesn't work because the selected pages are lost on page save. Maybe related to the discussion in this issue. $wire->addHookBefore('InputfieldPage::render', function(HookEvent $event) { /* @var InputfieldPage $inputfield */ $inputfield = $event->object; $page = $inputfield->hasPage; $field = $inputfield->hasField; // Return early if inputfield is not in a Repeater page if(!$page instanceof RepeaterPage) return; $selector = $inputfield->findPagesSelector; // Return early if no selector or selector doesn't include a dependency if(!$selector || strpos($selector, '=page.') === false) return; // Get suffix added to inputfields in this Repeater page $suffix = str_replace($field->name, '', $inputfield->name); // Add the suffix to dependency inputfield names $selector = preg_replace('/(=page.[_a-zA-Z0-9]+)/', "$1{$suffix}", $selector); // Replace the original findPagesSelector $inputfield->findPagesSelector = $selector; }); Demo... Page tree: Selector string for Subcategory field: Page Edit: Edited December 2, 2019 by Robin S Hook doesn't work. 5 Link to comment Share on other sites More sharing options...
Kiwi Chris Posted December 1, 2019 Share Posted December 1, 2019 @Robin S That seems to partially work, but it seems to have issues if a custom selector returned by a hook in ready.php, rather than a selector configured in the field properties. I'm not sure if there's a way around that? Link to comment Share on other sites More sharing options...
Robin S Posted December 1, 2019 Share Posted December 1, 2019 1 hour ago, Kiwi Chris said: That seems to partially work, but it seems to have issues if a custom selector returned by a hook in ready.php, rather than a selector configured in the field properties. I'm not sure if there's a way around that? The dependent selects feature has only ever worked with the selector string option as far as I know. Link to comment Share on other sites More sharing options...
OLSA Posted December 2, 2019 Share Posted December 2, 2019 Hi, thanks @Robin S for your hook example, but also (in my case) I had a problem to save values inside repeaters. I use 3 fields per/row and out of repeaters everything works fine (PW 3.0.146.). The images below shows my page tree and two different situations (after save). --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Here is another hook example ("cascade" case like on images) but before test, please read setup notes: 1) For the first column field (continents / categories) set parent page inside field setup. 2) For subfields (country and city) set template (eg. "blank") inside field setup. 3) Write selector strings for subfields inside hook configuration (ready.php). PHP (ready.php) <?php namespace ProcessWire; /** * Configuration: * Field names and selectors * * For subfields and after save problem * need to write string selectors here, and leave empty * that part inside field setup. */ $config->names = array( 'continent' => '', 'country' => 'parent=page.continent', 'city' => 'parent=page.country', ); $wire->addHookAfter('InputfieldPage::getSelectablePages', function ($event) { $inputfield = $event->object; $field = $inputfield->hasField; $names = $this->config->names; if (isset($names["$field->name"])) { $selector = $names["$field->name"]; if (trim($selector) !== "") { if (strpos($inputfield->name, '_repeater') !== false) { $id = str_replace($field->name . "_repeater", "", $inputfield->name); foreach ($names as $n => $s) { if (strpos($selector, $n) !== false) { $repeater_name = $n . '_repeater' . $id; $selector = str_replace($n, $repeater_name, $selector); } } } $inputfield->findPagesSelector($selector); } } } ); Here is screen record: Regards. 3 Link to comment Share on other sites More sharing options...
Kiwi Chris Posted December 2, 2019 Share Posted December 2, 2019 22 hours ago, Robin S said: The dependent selects feature has only ever worked with the selector string option as far as I know. Sorry, I checked a case outside of a repeater, and you're right. I have dependent selects working, but only after a save. What I had was several page fields outside a repeater that used custom code in ready.php, and a dependent page field inside a repeater, but the containing page was always saved first, so of course the dependent page fields in the repeater worked. Thanks to your help in another thread: I can also get dependent selects working inside a repeater if I save after each field is updated. There doesn't seem to be an option to refresh an individual page field either inside or outside a repeater via an ajax call other than by the selector string option you've mentioned. Link to comment Share on other sites More sharing options...
Robin S Posted December 2, 2019 Share Posted December 2, 2019 7 hours ago, OLSA said: thanks @Robin S for your hook example, but also (in my case) I had a problem to save values inside repeaters. You're right - it doesn't work because the selected pages are lost after save. I remember now that there was an issue with how InputfieldPage and FieldtypePage interpret "page.some_field" when it is used to refer to another Page Reference field: https://github.com/processwire/processwire-issues/issues/479 The thing is that PW has to make some consistent evaluation of what "page" is in this circumstance and it can't really know whether you want page to refer to the edited page or the repeater page. I don't have much time right now but I might come back and explore this more later. Link to comment Share on other sites More sharing options...
OLSA Posted December 3, 2019 Share Posted December 3, 2019 3 hours ago, Robin S said: You're right - it doesn't work because the selected pages are lost after save. I remember now that there was an issue with how InputfieldPage and FieldtypePage interpret "page.some_field" when it is used to refer to another Page Reference field: https://github.com/processwire/processwire-issues/issues/479 Yes, but in my hook example selected pages are not lost and to get that I need to remove selector string settings to hook. You can see how that's works in my previous post (just added screnshot). Link to comment Share on other sites More sharing options...
entschleunigung Posted December 20, 2019 Share Posted December 20, 2019 hello, i have a strange behaviour in this matter. on one page there are two page reference fields which are dependent on each other. the selector string for this is template=foo, refClients=page.refClients, sort=title if i save the page in admin, the selection works, but not via ajax if i stay on the page in admin. as soon as i change source page reference field, it looks like the selector is not working anymore and everything is displayed in target page reference field. maybe someone has an idea what i can do better. thanks a lot Link to comment Share on other sites More sharing options...
MarkE Posted February 12, 2022 Share Posted February 12, 2022 Just came across this thread - very useful: On 2/16/2017 at 8:38 PM, Robin S said: the undocumented dependent selects feature Not sure why it is not documented, unless there are risks using it. It really should be documented IMHO. @OLSA's solution for repeaters was particularly helpful and was (almost) what I needed for my use case. My case was complicated by the successive pages not being children of the previous selection - the last page reference was a repeater matrix item, not a child. In my case, however, the 'blendFrom' page reference is a repeater stage in the Cider/Juice page, not a child of it, so parent=page.cider{suffix} does not work. My solution was to add (via a before save hook) a field 'parent_page_id' to the repeater matrix item, which is the id of its getForPage, and use the selector "template=repeater_stage, parent_page_id=page.cider" where 'cider' is the field in the previous page selector. Ideally, I would have liked to have used 'parent.name$=page.cider', as that would avoid the use of an extra field, but although that seems to work fine normally (in Tracy console, for example), it does not seem to work in this context. Link to comment Share on other sites More sharing options...
GhostRider Posted April 13, 2022 Share Posted April 13, 2022 Thanks to @MarkE for the recommendation to this forum thread and to @OLSA for the post. Very close to what I was trying to solve. One thing to add to @OLSA's example, is the subfield template may need to be set to the template you require. 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