Jump to content

Disable selected/used options (Page references) in Admin


Recommended Posts

I have a couple of pages that has a specific template. In the template i have a page reference field (Activator). What im trying to achive is when i select an option in the dropdown (Activator) in admin and save, then the specific option is disabled (greyed out) in all of the other pages that has the page reference field (Activator). So basically you can only select one specific option once. But when i unselect the same one i want it to be reset and can be selected again in other pages.

Please help!

Link to comment
Share on other sites

  • Flashmaster82 changed the title to Disable selected/used options (Page references) in Admin

This would be easier to explain in your context if you had included all the relevant field and template names in your post. So here is an example that you can adapt to your scenario...

I have a Page Reference field named "select_colour" and generally the selectable pages are those that have the template "colour". I add this field to the template "animal", so that on animal pages I have a field to choose the colour of the animal. But in the select_colour field I only want to show colours that have not been selected on any other animal page. So in the settings for field select_colour I only use the "Custom PHP code" option for "Selectable pages" and add the following code to /site/ready.php:

$wire->addHookAfter('InputfieldPage::getSelectablePages', function($event) {
	$page = $event->arguments(0);
	// Define selectable pages for the select_colour field
	if($event->object->hasField == 'select_colour') {
		/** @var Pages $pages */
		$pages = $event->wire()->pages;
		// Find colours that are already selected on another animal page using "owner" selector
		// https://processwire.com/blog/posts/processwire-3.0.95-core-updates/
		$already_selected_on_another_page = $pages->find("template=colour, select_colour.owner.template=animal, select_colour.owner.id!=$page->id");
		// Return colour pages that aren't already selected on another page
		$event->return = $event->pages->find("template=colour, id!=$already_selected_on_another_page");
	}
});

Another possible approach is to loop over all the colour pages and remove those that are referenced on another page, but this is less specific because it will remove colours that have been referenced in any field, not just the select_colour field.

$wire->addHookAfter('InputfieldPage::getSelectablePages', function($event) {
	$page = $event->arguments(0);
	// Define selectable pages for the select_colour field
	if($event->object->hasField == 'select_colour') {
		/** @var Pages $pages */
		$pages = $event->wire()->pages;
		// All colours
		$colours = $pages->find("template=colour");
		foreach($colours as $colour) {
			// Remove colour if any other pages are referencing it
			if($colour->numReferences) $colours->remove($colour);
		}
		// Return the filtered colours
		$event->return = $colours;
	}
});

 

  • Like 1
  • Thanks 1
Link to comment
Share on other sites

Thank you so much for the solution it worked!

This is my current code.

 $wire->addHookAfter('InputfieldPage::getSelectablePages', function($event) {
        $page = $event->arguments(0);
            if($event->object->hasField == 'booking_searchactivator_option') {
                $pages = $event->wire()->pages;
                $already_selected_on_another_page = $pages->find("template=searchactivator, booking_searchactivator_option.owner.template=booking, booking_searchactivator_option.owner.id!=$page->id");
    $event->return = $event->pages->find("template=searchactivator, id!=$already_selected_on_another_page");
	}
    });

Page reference field: booking_searchactivator_option
Template that is referred to in the reference field: searchactivator
Template that "booking_searchactivator_option" is used on: booking

Selector string in the settings: parent=/sokaktivatorer/, template=searchactivator, sort=name

I don´t know what the "owner" does though? If i remove it then it will break?

/Thanks

Link to comment
Share on other sites

6 hours ago, Flashmaster82 said:

I don´t know what the "owner" does though? If i remove it then it will break?

Yes, it will break. I gave the link to the blog post introducing "owner" selectors in the code, but here it is again: https://processwire.com/blog/posts/processwire-3.0.95-core-updates/

Quote

They let you match aspects of whatever Page reverse references another (whether from a Page field, Repeater field or PageTable field), and make it part of the find() criteria.

So this selector...

template=colour, select_colour.owner.template=animal, select_colour.owner.id!=$page->id

...is saying...

Match pages where:

  • the page template is "colour"
  • and the page is selected in a field named "select_colour" and the page containing the select_colour field is using the template "animal"
  • and the page containing the select_colour field is not the page represented by the $page variable (i.e. the page that is currently open in Page Edit)
  • Like 3
  • Thanks 1
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...