Jump to content

Hook in Select Dropdown modifies option attributes


kixe
 Share

Recommended Posts

In a project I had to add the attribute 'disable' to some options of a select field (page reference) to show them but make them unselectable. Since I could not find an integrated solution, I wrote a tiny module and a hook. This could also be a POC to similar needs.

  1. Install module
  2. Add the Module to InputfieldPage in the module settings to make it selectable as Inputfield for page reference fields
  3. Create a hook in ready.php to manipulate attributes of the <option> tag for specified items


Module

<?php namespace ProcessWire;

/**
 * POC Inputfield Select Hook Add Option -- Replacement for InputfieldSelect
 *
 * Selection of a single value from a select pulldown. Same like InputfieldSelect
 * except this version provides hookable addOption() function which allows to modify
 * attributes of the <option> tag (i. e. 'disabled' to show items but disallow to select them
 *
 * @author Christoph Thelen aka @kixe
 *
 */

class InputfieldSelectHookAddOption extends InputfieldSelect {

	/**
	 * Return information about this module
	 *
	 */
	public static function getModuleInfo() {
		return array(
			'title' => __('Select Hookable Add Option', __FILE__), // Module Title
			'summary' => __('Selection of a single value from a select pulldown. Same like InputfieldSelect. except this version provides hookable addOption() function which allows to modify attributes of the <option> tag (e.g. \'disabled\' to show items in dropdown but disallow to select', __FILE__), // Module Summary
			'version' => 100,
			);
	}

	/**
	 * Hook in here to modify attributes
	 */
	public function ___addOptionAttributes($value, $label) {
		return array();
	}

	/**
	 * @see InputfieldSelect::addOption()
	 *
	 */
	public function addOption($value, $label = null, array $attributes = null) {
		if (!is_array($attributes)) $attributes = array();
		$attributes = array_merge($attributes, $this->addOptionAttributes($value, $label));
		return parent::addOption($value, $label, $attributes);
	}
}


Hook

/**
 * This example hook modifies the attributes of the selectable options of a Pagereference field named 'test'.
 * The selectable pages have the template 'test' assigned which includes a checkbox 'disallow'.
 * The attribute 'disabled' will be added to the selectable page if the user does not have the role 'user-extended' and 'disallow' is set.
 *
 */
$wire->addHookAfter('InputfieldSelectHookAddOption::addOptionAttributes', function($e) {
    // quick exit
    if ($e->object->name != 'test') return;
    if ($this->wire('user')->isSuperuser()|| $this->wire('user')->hasRole('user-extended')) return;
    // disable items (pages) in select
    $restrictedPageIDs = $this->wire('pages')->find('template=test,disallow=1')->each('id');
    if (in_array($e->arguments[0], $restrictedPageIDs)) $e->return = array('disabled' => 'disabled');
});    

 

  • Like 4
Link to comment
Share on other sites

  • 1 month later...
31 minutes ago, zimali said:

That is where I was stuck. It is not populating the default value into the dropdown. The value remains unchanged. I checked the value of $form['egender'] using dpm() and the default_value still showing integer 1. But the dropdown value remains unchanged rather than showing "Female" What am I missing?

ShowBoxKodiLucky Patcher

@zimali. Consider this your final warning. You have been posting Drupal stuff in the ProcessWire forums. You have, presumably,  ignored my request for clarification. This has trolling written all over it. 

  • Like 1
Link to comment
Share on other sites

  • 2 months later...

We have a lot of selects that are fairly similar so I'd like to have a wrapper for select that encompasses this commonality with data to change the behavior, changing the properties of an object is easier than adding/removing/manipulating html.

Link to comment
Share on other sites

  • 3 months later...

Since PW >= 3.0.105 you can easily use the following hook.

    $wire->addHookBefore('InputfieldSelect::render', function($e) {
        if ($e->object->name != 'myfield') return; // quick exit if fieldname doesn't match
        $restrictedIDs = array(); // array of option values to be modified, page IDs in case of pagefield
        $optionAttributes = array_fill_keys($restrictedIDs, array('disabled' => 'disabled'));
        $e->object->addOptionAttributes($optionAttributes);
    });

Related commit:
https://github.com/processwire/processwire/commit/07ab8ef9fcefff6a97c688599fb08fb0d462332e#diff-79808b1661a74c0668ee6157537ae478R390

  • Like 2
Link to comment
Share on other sites

  • 5 months later...
On 10/18/2018 at 11:26 AM, kixe said:

Since PW >= 3.0.105 you can easily use the following hook.


    $wire->addHookBefore('InputfieldSelect::render', function($e) {
        if ($e->object->name != 'myfield') return; // quick exit if fieldname doesn't match
        $restrictedIDs = array(); // array of option values to be modified, page IDs in case of pagefield
        $optionAttributes = array_fill_keys($restrictedIDs, array('disabled' => 'disabled'));
        $e->object->addOptionAttributes($optionAttributes);
    });

Related commit:
https://github.com/processwire/processwire/commit/07ab8ef9fcefff6a97c688599fb08fb0d462332e#diff-79808b1661a74c0668ee6157537ae478R390tv

 

Thank you for the share this commit. 🙂

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...