diff --git a/config/vufind/FeedbackForms.yaml b/config/vufind/FeedbackForms.yaml index 2223642fdadc69a7c24db06ab1807111b2496058..43f9b0767a2f321841103b5d386f2c1e295d8ee4 100644 --- a/config/vufind/FeedbackForms.yaml +++ b/config/vufind/FeedbackForms.yaml @@ -47,16 +47,18 @@ # # fields (array) List of form elements with the following options: # -# name (string) Element name -# label (string) Element label (translation key) -# required (boolean) Is the element required? -# settings (array) HTML attributes as key-value pairs, for example: +# name (string) Element name +# label (string) Element label (translation key) +# required (boolean) Is the element required? (for checkbox elements this means that +# all options have to be selected.) +# requireOne (boolean) Require at least one checkbox option to be selected. +# settings (array) HTML attributes as key-value pairs, for example: # - [class, "custom-css-class another-class"] -# type (string) Element type (text|textarea|email|url|select|radio|checkbox|hidden) +# type (string) Element type (text|textarea|email|url|select|radio|checkbox|hidden) # -# help (string) Element help text (translation key) that is displayed before the element. -# To include HTML formatting, use a translation key ending -# in '_html' here, and define markup in the language files. +# help (string) Element help text (translation key) that is displayed before the element. +# To include HTML formatting, use a translation key ending +# in '_html' here, and define markup in the language files. # # or # diff --git a/module/VuFind/src/VuFind/Form/Form.php b/module/VuFind/src/VuFind/Form/Form.php index 4f313ace62ab76a531d328385b3b3bbca86178e7..dd4b43ec9883e050d9660d5ce5295bf71f0a14b0 100644 --- a/module/VuFind/src/VuFind/Form/Form.php +++ b/module/VuFind/src/VuFind/Form/Form.php @@ -397,7 +397,8 @@ class Form extends \Laminas\Form\Form implements protected function getFormElementSettingFields() { return [ - 'required', 'help', 'value', 'inputType', 'group', 'placeholder' + 'required', 'requireOne', 'help', 'value', 'inputType', 'group', + 'placeholder' ]; } @@ -758,7 +759,10 @@ class Form extends \Laminas\Form\Form implements ]; foreach ($this->getElements() as $el) { - $required = ($el['required'] ?? false) === true; + $required = $el['type'] === 'checkbox' + ? $el['required'] ?? $el['requireOne'] ?? false + : $el['required'] ?? false; + $fieldValidators = []; if ($required) { $fieldValidators[] = $validators['notEmpty']; diff --git a/themes/bootstrap3/less/components/form.less b/themes/bootstrap3/less/components/form.less index a6ef56c3b99c29838aac1556a9e3b295e64aa655..bce828c5d4d1038e0048876238e16a747ec8b675 100644 --- a/themes/bootstrap3/less/components/form.less +++ b/themes/bootstrap3/less/components/form.less @@ -17,6 +17,7 @@ form { } .form-group label.required::before, .form-group .radio-label.required::before, + .form-group .radio-label.require-one::before { content: '* '; } diff --git a/themes/bootstrap3/scss/components/form.scss b/themes/bootstrap3/scss/components/form.scss index a6ef56c3b99c29838aac1556a9e3b295e64aa655..bce828c5d4d1038e0048876238e16a747ec8b675 100644 --- a/themes/bootstrap3/scss/components/form.scss +++ b/themes/bootstrap3/scss/components/form.scss @@ -17,6 +17,7 @@ form { } .form-group label.required::before, .form-group .radio-label.required::before, + .form-group .radio-label.require-one::before { content: '* '; } diff --git a/themes/bootstrap3/templates/feedback/form.phtml b/themes/bootstrap3/templates/feedback/form.phtml index 5f449abd71a31701a1d66d064af79a7be13a6282..68eb14eb22c3b89eb5ce59535718472beac64f84 100644 --- a/themes/bootstrap3/templates/feedback/form.phtml +++ b/themes/bootstrap3/templates/feedback/form.phtml @@ -83,10 +83,14 @@ <?php endif ?> <?php if ($el['type'] !== 'submit'): ?> <?php if ($el['label']): ?> + <?php + $required = $el['required'] ?? false; + $requireOne = !$required && ($el['requireOne'] ?? false); + ?> <?php if (in_array($el['type'], ['checkbox', 'radio'])): ?> - <p id="<?=$this->escapeHtmlAttr($el['name'])?>" class="control-label radio-label<?=!empty($el['required']) ? ' required' : ''?>"><?=$this->transEsc($el['label'])?>:</p> + <p id="<?=$this->escapeHtmlAttr($el['name'])?>" class="control-label radio-label<?=$required ? ' required' : ''?><?=$requireOne ? ' require-one' : ''?>"><?=$this->transEsc($el['label'])?>:</p> <?php else: ?> - <label for="<?=$this->escapeHtmlAttr($el['name'])?>" class="control-label<?=!empty($el['required']) ? ' required' : ''?>"><?=$this->transEsc($el['label'])?>:</label> + <label for="<?=$this->escapeHtmlAttr($el['name'])?>" class="control-label<?=$required ? ' required' : ''?>"><?=$this->transEsc($el['label'])?>:</label> <?php endif ?> <?php endif ?> <?php else: ?>