matjazp Posted June 1, 2018 Share Posted June 1, 2018 I would like to set html required attribute on Datetime field. We have this option on text fields, but not on Datetime (or Integer or...). Is this possible? Like hooking to InputfieldDatetime::getConfigInputfields and adding checkbox? But then, where do I hook to add this required attribute? Link to comment Share on other sites More sharing options...
Autofahrn Posted June 1, 2018 Share Posted June 1, 2018 In which situation do you not have the required checkbox on a datetime field? On all field types I'm aware of the Required checkbox is located on Input tab. Or do I miss something? Link to comment Share on other sites More sharing options...
matjazp Posted June 1, 2018 Author Share Posted June 1, 2018 You miss something ? I'm talking about "Also use HTML5 required attribute". This option is on the Input tab, right to the "Required?" field. 1 Link to comment Share on other sites More sharing options...
Autofahrn Posted June 1, 2018 Share Posted June 1, 2018 ok, got it... ? Link to comment Share on other sites More sharing options...
BitPoet Posted June 1, 2018 Share Posted June 1, 2018 4 hours ago, matjazp said: Like hooking to InputfieldDatetime::getConfigInputfields and adding checkbox? But then, where do I hook to add this required attribute? Yes, you can use the code from InputfieldText::getConfigInputfields almost verbatim in a site/ready.php hook, but since that configuration property isn't initialized in InputfieldDatetime and not set in the field's attributes, you have to add that logic too in another hook. A possible place to do that is in Field::getInputfield: <?php namespace ProcessWire; // Add the configuration field: $wire->addHookAfter("InputfieldDatetime::getConfigInputfields", function(HookEvent $event) { $inputfields = $event->return; $required = $inputfields->getChildByName('required'); if($required) { $required->set('columnWidth', 50); /** @var InputfieldCheckbox $field */ $field = wire('modules')->get('InputfieldCheckbox'); $field->attr('name', 'requiredAttr'); $field->label = $event->object->_('Also use HTML5 “required” attribute?'); $field->showIf = "required=1, showIf='', requiredIf=''"; $field->description = $event->object->_('Use only on fields *always* visible to the user.'); $field->icon = 'html5'; $field->columnWidth = 50; if($event->object->requiredAttr) $field->attr('checked', 'checked'); $required->getParent()->insertAfter($field, $required); } }); // This populates the requiredAttr property and sets the HTML attribute // on the InputfieldDatetime instance: $wire->addHookAfter("Field::getInputfield", function(HookEvent $event) { $input = $event->return; if(! $input instanceof InputfieldDatetime) return; $field = $event->object; // Configuration value retrieved from the field's settings in the database: $requiredAttr = $field->requiredAttr; // Probably not necessary but there for consistiency: if($requiredAttr) $input->requiredAttr = $requiredAttr; // This sets the HTML attribute if($input->required && $requiredAttr && !$input->getSetting('showIf') && !$input->getSetting('requiredIf')) { $input->setAttribute('required', 'required'); } }); 3 Link to comment Share on other sites More sharing options...
matjazp Posted June 1, 2018 Author Share Posted June 1, 2018 Thank you @BitPoet In the meantime I found the place to hook - InputfieldDatetime::render. And since I need this for only 2 specific dates, I'm applying the required attribute to the InputfieldDatetime based on the field name (hasField). This way I don't have to save attributes to the field - who knows someday this HTML required attribute might even get it's way to the core (and I'm surprised that it's not there already). Link to comment Share on other sites More sharing options...
Robin S Posted June 1, 2018 Share Posted June 1, 2018 The HTML required attribute seems like it would be a handy thing to use on all inputfields that play nicely with it, whenever that inputfield is required. Might as well give the user a notice before the form is submitted rather than after. The hook below does this, but as per the core option for InputfieldText it does not cover "required if" conditions: $wire->addHookBefore('Inputfield::render', function(HookEvent $event) { $inputfield = $event->object; $type = substr($inputfield->className, 10); // Only for inputfield types that play nicely with the HTML required attribute if(!in_array($type, ['Text', 'Email', 'Datetime', 'Textarea', 'Integer', 'Checkbox'])) return; // Only if the field is required and has no requiredIf condition if($inputfield->required && !$inputfield->requiredIf) $inputfield->attr('required', true); }); 1 Link to comment Share on other sites More sharing options...
matjazp Posted June 2, 2018 Author Share Posted June 2, 2018 @Robin S, thank you for your contribution. Your version is handy if you want to target more inputfield types, not just date. Maybe we should not target specific className but rather the class that it extends? In your example, Integer is covered, but Float and Decimal are not. Also, Url is not covered, but since InputfieldUrl extends InputfieldText, required attribute is already available in core. Maybe we should check on what types are specifically not supported, rather than supported? Link to comment Share on other sites More sharing options...
Robin S Posted June 2, 2018 Share Posted June 2, 2018 16 hours ago, matjazp said: Maybe we should not target specific className but rather the class that it extends? You could approach it that way, but I think I would be inclined to keep adding inputfield types to the array that are known to be compatible rather than risk affecting an inputfield that is not compatible. Because the consequences of excluding a inputfield that does work are minimal (user sees a notice after the form is submitted rather than before) but the consequences of including an inputfield that doesn't work are more severe (user cannot submit the form and does not see any notice explaining why). The HTML required attribute will not work for any inputfield that hides the actual input that holds the value, e.g. CKEditor, AsmSelect, File, Image, PageListSelect, etc. If you take the "extends" option then you need to start excluding inputfields as well as including them - e.g. you might include Textarea and Select because those inputfields will work with HTML required, but you would have to exclude some inputfields that extend those types such as CKEditor or AsmSelect. 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