gebeer Posted January 1, 2017 Share Posted January 1, 2017 Hello, I'm struggling to access module config values inside init() or ready(). My module extends InputfieldCheckboxes and implements Module interface. I have a custom configuration field public function ___getConfigInputfields() { $inputfields = parent::___getConfigInputfields(); $modules = $this->wire('modules'); $options = $this->getInputfieldCheckboxes(); $f = $modules->get('InputfieldSelect'); $f->attr('name', 'targetField'); $f->set('label', $this->_('Choose the target checkboxes field')); $f->set('description', $this->_('The field that has checkboxes which depend on this field\'s checkboxes')); // $f->set('notes', $this->_('Types indicated with an asterisk are for multiple field selection.')); foreach ($options as $fieldName => $prop) $f->addOption($fieldName, $prop['label']); $f->attr('value', $this->targetField); $inputfields->add($f); return $inputfields; } This is working fine and saving values. Right after getModuleInfo() I have public function __construct() { parent::__construct(); $this->set('targetField', ''); } In my render() and getConfigInputfields() methods, I can access the value for the custom config setting with $this->targetField. But in other methods, it is not available. In the API Reference for init() it says: Quote This method is called after __construct() and after any configuration data has been populated to the module. When I remove my __construct() method entirely, config values still get saved correctly. But when I access $this->targetField in init() or ready(), I get null. How can I access configuration data inside init() or ready() ? I read many posts and looked at how other modules do this. But couldn't find a solution. Thanks in advance for any pointers. Link to comment Share on other sites More sharing options...
ryan Posted January 1, 2017 Share Posted January 1, 2017 The thing you quoted from the API reference is specific to Module configuration. Configuration data for the module (that which is configured in Modules > InputfieldSomething) would be populated after __construct(), and before init(). But you are attempting to access configuration for a Field rather than a Module. The method you are using (getConfigInputfields) is what is used by Fieldtype and Inputfield modules for configuration of a Field. This is unrelated to Module configuration, because a single Fieldtype/Inputfield module can be used for multiple fields. Further, an Inputfield module can be used independently of ProcessWire's Fields system (like in other forms that aren't connected with PW fields) where a getConfigInputfields() method wouldn't even apply. For these reasons, you can't have field/instance-specific configuration data populated to Fieldtype or Inputfield modules as part of the usual Module boot process. For an Inputfield module, you would want to move whatever field-specific initialization you need into the ___render() method, or renderReady() method instead if you need it to happen before. Link to comment Share on other sites More sharing options...
ryan Posted January 1, 2017 Share Posted January 1, 2017 If you use a renderReady() method, here's what the definition looks like: https://github.com/processwire/processwire/blob/master/wire/core/Inputfield.php#L1009 Remember to end by calling the parent::renderReady() method as well: public function renderReady(Inputfield $parent = null, $renderValueMode = false) { // perform any needed initialization here return parent::renderReady($parent, $renderValueMode); } 1 Link to comment Share on other sites More sharing options...
gebeer Posted January 1, 2017 Author Share Posted January 1, 2017 @ryan thank you for the insight. Problem is, that I need my config setting values to be available to the public function addOption($value, $label = null, array $attributes = null) {...} which replaces the original method in wire/modules/InputfieldSelectMultiple.module. And that method is called before renderReady(). I'm adding custom data attributes to the checkboxes using /** * Adds an option with extended attributes * Replaces original method in wire/modules/InputfieldSelectMultiple.module * taken from https://processwire.com/talk/topic/419-extending-inputfields/?do=findComment&comment=76823 * */ 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) { /** * 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... */ $atts = array(); $targets = array(); $deps = wire('pages')->find("template=certification, instructor_types={$id}"); foreach ($deps as $d) { $targets[] = $d->id; } $atts['data-icbdtargets'] = json_encode($targets); return $atts; } And I want to build the hardcoded selector in $deps = wire('pages')->find("template=certification, instructor_types={$id}"); from values that I get from the settings fields in getConfigInputfields(). If it is not possible at all I would have to create an extra configurable module that provides the settings. I'd like to avoid that overhead. My Inputfield module provides configurable dependent checkboxes. It is working with the hardcoded selector. But I want to release this as a configurable module so that people don't need to alter code in the module. It makes sense to have the settings in the 'Input" Tab of the field settings. So I would like to avoid the need of an extra module for config settings. I'm pretty new to module development and haven't grasped all concepts yet. Link to comment Share on other sites More sharing options...
gebeer Posted January 1, 2017 Author Share Posted January 1, 2017 Kind of solved. I decided to refactor my module code and replace the original render() method instead of the addOptions() method of InputfieldCheckboxes module. This way I can access my settings values inside the render method and make use of them further down the road. Link to comment Share on other sites More sharing options...
ryan Posted January 1, 2017 Share Posted January 1, 2017 Sounds like you found a good solution. Other potential solutions are reading and re-writing the options from your render() method, or override the renderOptions() method, or just modify the protected properties inherited from InputfieldSelect (like $this->options or $this->optionAttributes). 1 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