diff --git a/clientside_validation.install b/clientside_validation.install new file mode 100644 index 0000000000000000000000000000000000000000..04ba76b2e178c300468d746b21b15145533a7f18 --- /dev/null +++ b/clientside_validation.install @@ -0,0 +1,38 @@ +getEditable('clientside_validation.settings'); + + // Set default values for the new schema fields. + if ($config->isNew()) { + $config->set('validation_scope', CLIENTSIDE_VALIDATION_VALIDATE_ALL_FORMS); + $config->set('selected_forms', []); + } + else { + // Check the value of enable_all_forms and set validation_scope accordingly. + if ($config->get('enable_all_forms')) { + // If enable_all_forms is checked, set validation_scope the first choice. + $config->set('validation_scope', CLIENTSIDE_VALIDATION_VALIDATE_ALL_FORMS); + } + else { + $config->set('validation_scope', CLIENTSIDE_VALIDATION_VALIDATE_SELECTED_FORMS); + } + + // Set the enabled_forms to selected_forms. + if ($config->get('enabled_forms')) { + $config->set('selected_forms', $config->get('enabled_forms')); + } + } + + // Save the updated configuration. + $config->save(); +} diff --git a/clientside_validation.links.menu.yml b/clientside_validation.links.menu.yml new file mode 100644 index 0000000000000000000000000000000000000000..0803f80165dab49b5d93a0ace129aba621d4e9e3 --- /dev/null +++ b/clientside_validation.links.menu.yml @@ -0,0 +1,5 @@ +clientside_validation.settings_form: + title: 'Clientside Validation Settings' + description: 'Configure clientside validation settings.' + route_name: clientside_validation.settings_form + parent: system.admin_config_ui diff --git a/clientside_validation.module b/clientside_validation.module index 50fa8b3e85a750e70e3bed66b2b8432df89905b6..6871e14d096096283ae8f8dbbf0a808cbb4d3545 100644 --- a/clientside_validation.module +++ b/clientside_validation.module @@ -5,14 +5,59 @@ * Hook implementations for the Clientside Validation module. */ +use Drupal\Core\Cache\Cache; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Render\Element; +/** + * Selections for the types of validation scopes. + */ +const CLIENTSIDE_VALIDATION_VALIDATE_ALL_FORMS = '0'; +const CLIENTSIDE_VALIDATION_VALIDATE_SELECTED_FORMS = '1'; +const CLIENTSIDE_VALIDATION_VALIDATE_EXCEPT_SELECTED_FORMS = '2'; + /** * Implements hook_form_alter(). */ function clientside_validation_form_alter(&$form, FormStateInterface &$form_state, $form_id) { - $form['#after_build'][] = 'clientside_validation_form_after_build'; + $config = \Drupal::config('clientside_validation.settings'); + + // Add cache tags for the config. + if (!empty($form['#cache']['tags'])) { + $form['#cache']['tags'] = Cache::mergeTags($form['#cache']['tags'], $config->getCacheTags()); + } + else { + $form['#cache']['tags'] = $config->getCacheTags(); + } + + // If enabled for all forms, add the after build function. + $validation_scope = $config->get('validation_scope'); + if ($validation_scope === CLIENTSIDE_VALIDATION_VALIDATE_ALL_FORMS) { + $form['#after_build'][] = 'clientside_validation_form_after_build'; + } + // Else, add it only if the form ID was added in configuration. + elseif ($validation_scope === CLIENTSIDE_VALIDATION_VALIDATE_SELECTED_FORMS) { + $selected_forms = $config->get('selected_forms'); + if (!empty($selected_forms) && in_array($form_id, $selected_forms)) { + $form['#after_build'][] = 'clientside_validation_form_after_build'; + } + } + elseif ($validation_scope === CLIENTSIDE_VALIDATION_VALIDATE_EXCEPT_SELECTED_FORMS) { + $selected_forms = $config->get('selected_forms'); + if (!empty($selected_forms) && !in_array($form_id, $selected_forms)) { + $form['#after_build'][] = 'clientside_validation_form_after_build'; + } + } + + // Remove the clientside validation if the novalidate attribute was set. + if ( + isset($form['#attributes']['novalidate']) && + isset($form['#after_build']) && + in_array('clientside_validation_form_after_build', $form['#after_build']) + ) { + $validation_key = array_search('clientside_validation_form_after_build', $form['#after_build']); + unset($form['#after_build'][$validation_key]); + } } /** diff --git a/clientside_validation.permissions.yml b/clientside_validation.permissions.yml new file mode 100644 index 0000000000000000000000000000000000000000..579ecaab512f3f2d28655a2122d78dc4643591ac --- /dev/null +++ b/clientside_validation.permissions.yml @@ -0,0 +1,4 @@ +administer clientside validation: + description: 'Grants access to the clientside validation configuration form.' + title: 'Administer clientside validation' + restrict access: TRUE diff --git a/clientside_validation.routing.yml b/clientside_validation.routing.yml new file mode 100644 index 0000000000000000000000000000000000000000..9cf0f16a5754e254d777a758f9f628c30746b8b5 --- /dev/null +++ b/clientside_validation.routing.yml @@ -0,0 +1,7 @@ +clientside_validation.settings_form: + path: '/admin/config/user-interface/clientside-validation' + defaults: + _form: '\Drupal\clientside_validation\Form\ClientsideValidationSettingsForm' + _title: 'Clientside Validation Settings' + requirements: + _permission: 'administer clientside validation' diff --git a/config/install/clientside_validation.settings.yml b/config/install/clientside_validation.settings.yml new file mode 100644 index 0000000000000000000000000000000000000000..92fdcdeda3de1ae234cdd5e9690f6f9d971de91e --- /dev/null +++ b/config/install/clientside_validation.settings.yml @@ -0,0 +1,2 @@ +validation_scope: '0' +selected_forms: { } diff --git a/config/schema/clientside_validation.schema.yml b/config/schema/clientside_validation.schema.yml new file mode 100644 index 0000000000000000000000000000000000000000..724545e144f55225e786fa41554939a199102f66 --- /dev/null +++ b/config/schema/clientside_validation.schema.yml @@ -0,0 +1,12 @@ +clientside_validation.settings: + type: config_object + mapping: + validation_scope: + type: string + label: 'Setting for the validation scheme' + selected_forms: + type: sequence + label: 'A list of forms, based on the validation scheme' + sequence: + type: string + label: 'The form ID' diff --git a/src/Form/ClientsideValidationSettingsForm.php b/src/Form/ClientsideValidationSettingsForm.php new file mode 100644 index 0000000000000000000000000000000000000000..bfad9b9e882f2ad0412ce118f629dfd1a78a6ec5 --- /dev/null +++ b/src/Form/ClientsideValidationSettingsForm.php @@ -0,0 +1,103 @@ +config('clientside_validation.settings'); + + // Add a note in regards to the overrides with the novalidate attribute. + $form['novalidate_note'] = [ + '#markup' => $this->t('Forms with the "novalidate" attribute will not have clientside validation enabled, regardless of these settings.'), + ]; + + // Set the scope of the validation. + $form['validation_scope'] = [ + '#type' => 'radios', + '#title' => $this->t('Select the forms to validate'), + '#default_value' => $config->get('validation_scope') ?: CLIENTSIDE_VALIDATION_VALIDATE_ALL_FORMS, + '#options' => [ + CLIENTSIDE_VALIDATION_VALIDATE_ALL_FORMS => $this->t('Validate all forms.'), + CLIENTSIDE_VALIDATION_VALIDATE_SELECTED_FORMS => $this->t('Only validate forms listed below.'), + CLIENTSIDE_VALIDATION_VALIDATE_EXCEPT_SELECTED_FORMS => $this->t('Validate all forms except those listed below.'), + ], + ]; + + // Selected forms. + $selected_forms = (!empty($config->get('selected_forms'))) ? $config->get('selected_forms') : []; + $form['selected_forms'] = [ + '#type' => 'textarea', + '#title' => $this->t('Enter form IDs below, separated by a new line.'), + '#default_value' => implode(PHP_EOL, $selected_forms), + '#states' => [ + 'visible' => [ + // Only show this when validating less than all. + [':input[name="validation_scope"]' => ['value' => CLIENTSIDE_VALIDATION_VALIDATE_SELECTED_FORMS]], + 'or', + [':input[name="validation_scope"]' => ['value' => CLIENTSIDE_VALIDATION_VALIDATE_EXCEPT_SELECTED_FORMS]], + ], + ], + ]; + + return $form; + } + + /** + * {@inheritdoc} + */ + public function submitForm(array &$form, FormStateInterface $form_state) { + parent::submitForm($form, $form_state); + $config = $this->config('clientside_validation.settings'); + $values = $form_state->getValues(); + + $config->set('validation_scope', $values['validation_scope']); + $selected_forms = preg_split("[\n|\r]", $values['selected_forms']); + $selected_forms = array_filter($selected_forms); + $config->set('selected_forms', $selected_forms); + $config->save(); + } + +}