Juergen Posted June 26, 2020 Share Posted June 26, 2020 Hello @ all, On a custom inputfield I want to use a multiple checkbox field (InputfieldCheckboxes) in the inputfield configuration. The user can select which fields of this inputfield are required. I have created these checkboxes as followed: As you can see, I am not using "InputfieldCheckbox" but "InputfieldCheckboxes" (the multi-checkbox version) $f = $this->modules->get('InputfieldCheckboxes'); $f->label = _x('Required fields', 'simpleaddress'); $options = [ 'street' => _x('Street', 'simpleaddress'), 'number' => _x('Number', 'simpleaddress'), 'postalcode' => _x('Postalcode', 'simpleaddress'), 'city' => _x('City', 'simpleaddress'), 'state' => _x('State', 'simpleaddress'), 'country' => _x('Country', 'simpleaddress'), ]; foreach($options as $value => $label) { $f->attr('name', 'input_required[]'); $checked = ($this->input_required == '1') ? 'checked' : '';//How to check if a checkbox was checked??????? $f->addOption($value, $label, ['checked' => $checked]); } $inputfields->append($f); Problem: I am struggeling to find out how to determine if a checkbox was checked or not . On a single checkbox field I can use something like this to set the checked attribute. $f->attr('checked', $this->myInputfield == '1' ? 'checked' : ''); How can I achive the same for a multiple checkbox field? I haven´t found a working example. Thanks in advance! Link to comment Share on other sites More sharing options...
Robin S Posted June 26, 2020 Share Posted June 26, 2020 /** @var InputfieldCheckboxes $f */ $f = $modules->get('InputfieldCheckboxes'); $f->name = 'foo'; $f->label = 'Foo'; $f->addOptions([ 'red' => 'Red', 'green' => 'Green', 'blue' => 'Blue', ]); // The value will be an array e.g. ['red', 'blue'] $f->value = $this->foo; $inputfields->add($f); 4 Link to comment Share on other sites More sharing options...
Juergen Posted June 27, 2020 Author Share Posted June 27, 2020 Thanks for your help @Robin S Your code: 11 hours ago, Robin S said: /** @var InputfieldCheckboxes $f */ $f = $modules->get('InputfieldCheckboxes'); $f->name = 'foo'; $f->label = 'Foo'; $f->addOptions([ 'red' => 'Red', 'green' => 'Green', 'blue' => 'Blue', ]); // The value will be an array e.g. ['red', 'blue'] $f->value = $this->foo; $inputfields->add($f); Unfortunately $this->foo is always empty after form submission (independent if a checkbox was marked or not). Array ( [0] => ) By taking a look at the $this object you can see that you cannot reach the foo property via $this->foo, because foo is part of the field object. ProcessWire\InputfieldSimpleAddress Object ( [data] => Array ( [input_street] => [input_number] => [input_postalcode] => [input_city] => [input_state] => [input_country] => test [label] => Address [description] => [icon] => [notes] => [detail] => [head] => [required] => 0 [requiredIf] => [collapsed] => 0 [showIf] => [columnWidth] => [skipLabel] => [wrapClass] => [headerClass] => [contentClass] => [textFormat] => 4 [renderValueFlags] => 0 [prependMarkup] => [appendMarkup] => [hasFieldtype] => ProcessWire\FieldtypeSimpleAddress Object ( ) [hasField] => ProcessWire\Field Object ( [id] => 116 [name] => address [label] => Address [flags] => [type] => ProcessWire\FieldtypeSimpleAddress Object ( ) [data] => Array ( [label1021] => Adresse [collapsed] => 0 [foo] => Array ( [0] => red [1] => green [2] => blue ) ) ) [hasPage] => ProcessWire\Page Object ( [id] => 1 [name] => home [parent] => [status] => systemID [template] => home [numChildren] => 3 [title] => Home [data] => Array ( [title] => Home ) ) ) ) I have checked all 3 checkboxes and you get the values (red, green and blue) in the object as part of the data property (see code below): [data] => Array ( [label1021] => Adresse [collapsed] => 0 [foo] => Array ( [0] => red [1] => green [2] => blue ) ) Therefore you can get the values (array) only by using $this->hasField->data['foo'] instead of $this->foo My goal: I want to make multiple checkboxes stay checked after form submission if they were marked by an user. I havent found a way to achive this at the moment and this was the reason for this post. Link to comment Share on other sites More sharing options...
Juergen Posted June 27, 2020 Author Share Posted June 27, 2020 I found a solution to keep multiple checkboxes checked after form submission. Here is the complete code of this multiple checkbox list field: // checkbox field to make specific fields required $f = $this->modules->get('InputfieldCheckboxes'); $f->label = _x('Required fields', 'simpleaddress'); $f->attr('name', 'input_required'); $options = [ 'street' => _x('Street', 'simpleaddress'), 'number' => _x('Number', 'simpleaddress'), 'postalcode' => _x('Postalcode', 'simpleaddress'), 'city' => _x('City', 'simpleaddress'), 'state' => _x('State', 'simpleaddress'), 'country' => _x('Country', 'simpleaddress'), ]; $values = (isset($this->hasField->data['input_required'])) ? $this->hasField->data['input_required'] : []; foreach($options as $value => $label) { $checked = (in_array($value,$values)) ? 'checked' : ''; $f->addOption($value, $label, ['checked' => $checked]); } $f->description = _x('If checked the input is required.', 'simpleaddress'); $inputfields->append($f); Lets take a closer look: $values = (isset($this->hasField->data['input_required'])) ? $this->hasField->data['input_required'] : []; This is how we get all checked checkboxes after form submission. "input_required" is the name attribute of my multiple checkbox field. If one or more checkboxes were checked, we get the values in an array, otherwise we will get an empty array. So $values could be an empty array or an array with values like ['street, postalcode']. To make the checkboxes checked after form submission we include a simple check inside the foreach loop. $checked = (in_array($value,$values)) ? 'checked' : ''; We check if the value from the foreach loop is in the array too. If yes, then add the checked attribute as third parameter to this checkbox input. $f->addOption($value, $label, ['checked' => $checked]); Thats all! Maybe someone has a nicer solution, please post it here. Best regards Link to comment Share on other sites More sharing options...
Robin S Posted June 28, 2020 Share Posted June 28, 2020 14 hours ago, Juergen said: Therefore you can get the values (array) only by using $this->hasField->data['foo'] instead of $this->foo Well, this depends on if the stored value for the inputfield has been set as a property of the class. There are multiple different places you might use an inputfield and it's up to you to get the value you want to set to it. How you get it doesn't have anything to with InputfieldCheckboxes per se - you just need to make sure you are setting an array as the value. If the inputfield is used in the getModuleConfigInputfields() method of a module then the value stored in the module config is automatically set as a property of the module class. Alternatively, if you have a config field for an Inputfield module (in the getConfigInputfields() method) that is used with a PW field then this config data is stored on the field, because only the field has a record in the database. In other words there is a "fields" table but no "inputfields" table. So you can get the stored value from the $field object as you are doing, but arguably it's better to make use of the features that PW has built in to automatically populate Inputfield properties from the corresponding Field. The Field class has this code in the getInputfield() method: // custom field settings foreach($this->data as $key => $value) { if($inputfield instanceof InputfieldWrapper) { $has = $inputfield->hasSetting($key) || $inputfield->hasAttribute($key); } else { $has = $inputfield->has($key); } if($has) { if(is_array($this->trackGets)) $this->trackGets($key); $inputfield->set($key, $value); } } What this boils down to is: "For every data property set on this Field object, check to see if a property of that name exists on the Inputfield object used by this field. If it does, set the value stored on this Field object as a property of the Inputfield object". So to make use of this you just need to set a property name in your Inputfield module's init() method, so that the property can be seen to exist when Field::getInputfield() is called. And typically you would set a default value for this property when appropriate. You can see how this is done in InputfieldRadios for example: public function init() { $this->set('optionColumns', 0); parent::init(); } By doing this: 1. A default value of 0 is set for optionColumns 2. Any value for optionColumns that is stored on a corresponding Field object automatically becomes available in the InputfieldRadios class as $this->optionColumns. 3 Link to comment Share on other sites More sharing options...
Juergen Posted June 28, 2020 Author Share Posted June 28, 2020 Wow, thanks for this detailed explanation!! Things are getting clearer now for me!!! 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