From 707d977cfcf42dff5287ebd93cbf7aa5f027dc2b Mon Sep 17 00:00:00 2001 From: Johannes Meyer Date: Thu, 5 Feb 2015 13:14:29 +0100 Subject: [PATCH 1/4] WCAG/3.3.3: Add example for required form elements refs #8349 --- doc/accessibility/required-form-elements.html | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 doc/accessibility/required-form-elements.html diff --git a/doc/accessibility/required-form-elements.html b/doc/accessibility/required-form-elements.html new file mode 100644 index 000000000..86fc9374e --- /dev/null +++ b/doc/accessibility/required-form-elements.html @@ -0,0 +1,19 @@ + + + + + + Accessibility: Required form elements + + + + +
+ + +
+ + \ No newline at end of file From c5b6d7ee41cb0edf272847a5d63d55e6c3452116 Mon Sep 17 00:00:00 2001 From: Johannes Meyer Date: Thu, 5 Feb 2015 13:15:18 +0100 Subject: [PATCH 2/4] Ensure that all required form elements are marked as such in HTML markup refs #8349 --- library/Icinga/Web/Form.php | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/library/Icinga/Web/Form.php b/library/Icinga/Web/Form.php index 1a75cb852..606a74f98 100644 --- a/library/Icinga/Web/Form.php +++ b/library/Icinga/Web/Form.php @@ -6,6 +6,7 @@ namespace Icinga\Web; use LogicException; use Zend_Config; use Zend_Form; +use Zend_Form_Element; use Zend_View_Interface; use Icinga\Application\Icinga; use Icinga\Authentication\Manager; @@ -550,7 +551,24 @@ class Form extends Zend_Form unset($el->autosubmit); } - return $el; + return $this->ensureElementAccessibility($el); + } + + /** + * Add accessibility related attributes + * + * @param Zend_Form_Element $element + * + * @return Zend_Form_Element + */ + public function ensureElementAccessibility(Zend_Form_Element $element) + { + if ($element->isRequired() && strpos(strtolower($element->getType()), 'checkbox') === false) { + $element->setAttrib('aria-required', 'true'); // ARIA + $element->setAttrib('required', ''); // HTML5 + } + + return $element; } /** From 437050430f8f3f806516b7e8cfa349dadb821f71 Mon Sep 17 00:00:00 2001 From: Johannes Meyer Date: Thu, 5 Feb 2015 13:18:21 +0100 Subject: [PATCH 3/4] Make sure that the admin wizard-step provides the required-HTML markup refs #8349 --- .../application/forms/AdminAccountPage.php | 44 ++++++++++++++++++- .../scripts/form/setup-admin-account.phtml | 6 +-- 2 files changed, 46 insertions(+), 4 deletions(-) diff --git a/modules/setup/application/forms/AdminAccountPage.php b/modules/setup/application/forms/AdminAccountPage.php index e9334c650..de8650439 100644 --- a/modules/setup/application/forms/AdminAccountPage.php +++ b/modules/setup/application/forms/AdminAccountPage.php @@ -78,7 +78,7 @@ class AdminAccountPage extends Form 'text', 'by_name', array( - 'required' => isset($formData['user_type']) && $formData['user_type'] === 'by_name', + 'required' => !isset($formData['user_type']) || $formData['user_type'] === 'by_name', 'value' => $this->getUsername(), 'label' => $this->translate('Username'), 'description' => $this->translate( @@ -87,6 +87,12 @@ class AdminAccountPage extends Form ) ) ); + if (! $this->request->isXmlHttpRequest()) { + // In case JS is disabled we must not provide client side validation as + // the user is required to input data even he has changed his mind + $this->getElement('by_name')->setAttrib('required', null); + $this->getElement('by_name')->setAttrib('aria-required', null); + } } if ($this->backendConfig['backend'] === 'db' || $this->backendConfig['backend'] === 'ldap') { @@ -111,6 +117,12 @@ class AdminAccountPage extends Form 'multiOptions' => array_combine($users, $users) ) ); + if (! $this->request->isXmlHttpRequest()) { + // In case JS is disabled we must not provide client side validation as + // the user is required to input data even he has changed his mind + $this->getElement('existing_user')->setAttrib('required', null); + $this->getElement('existing_user')->setAttrib('aria-required', null); + } } } @@ -149,6 +161,14 @@ class AdminAccountPage extends Form ) ) ); + if (! $this->request->isXmlHttpRequest()) { + // In case JS is disabled we must not provide client side validation as + // the user is required to input data even he has changed his mind + foreach (array('new_user', 'new_user_password', 'new_user_2ndpass') as $elementName) { + $this->getElement($elementName)->setAttrib('aria-required', null); + $this->getElement($elementName)->setAttrib('required', null); + } + } } if (count($choices) > 1) { @@ -157,6 +177,8 @@ class AdminAccountPage extends Form 'user_type', array( 'required' => true, + 'autosubmit' => true, + 'value' => key($choices), 'multiOptions' => $choices ) ); @@ -218,6 +240,26 @@ class AdminAccountPage extends Form return true; } + /** + * Return whether the given values (possibly incomplete) are valid + * + * Unsets all empty text-inputs so that they are not being validated when auto-submitting the form. + * + * @param array $formData + * + * @return type + */ + public function isValidPartial(array $formData) + { + foreach (array('by_name', 'new_user', 'new_user_password', 'new_user_2ndpass') as $elementName) { + if (isset($formData[$elementName]) && $formData[$elementName] === '') { + unset($formData[$elementName]); + } + } + + return parent::isValidPartial($formData); + } + /** * Return the name of the externally authenticated user * diff --git a/modules/setup/application/views/scripts/form/setup-admin-account.phtml b/modules/setup/application/views/scripts/form/setup-admin-account.phtml index ac060526a..b069bb371 100644 --- a/modules/setup/application/views/scripts/form/setup-admin-account.phtml +++ b/modules/setup/application/views/scripts/form/setup-admin-account.phtml @@ -17,7 +17,7 @@ $showRadioBoxes = strpos(strtolower(get_class($radioElem)), 'radio') !== false;
@@ -32,7 +32,7 @@ $showRadioBoxes = strpos(strtolower(get_class($radioElem)), 'radio') !== false;
@@ -49,7 +49,7 @@ $showRadioBoxes = strpos(strtolower(get_class($radioElem)), 'radio') !== false;
From 423025b3fe2776df7c6d314c567ad8544b50d987 Mon Sep 17 00:00:00 2001 From: Johannes Meyer Date: Thu, 5 Feb 2015 13:21:03 +0100 Subject: [PATCH 4/4] javascript: Do not bind the button click event Catching form submit events is sufficient as catching the button click event is not an option due to circumventing the browser's native form validation logic otherwise. refs #8349 --- public/js/icinga/events.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/public/js/icinga/events.js b/public/js/icinga/events.js index 7bcbc8e3b..16b6fb0f5 100644 --- a/public/js/icinga/events.js +++ b/public/js/icinga/events.js @@ -118,8 +118,6 @@ // Select a table row $(document).on('click', 'table.multiselect tr[href]', { self: this }, this.rowSelected); - $(document).on('click', 'button', { self: this }, this.submitForm); - // We catch all form submit events $(document).on('submit', 'form', { self: this }, this.submitForm);