¿Cómo agrego un controlador de validación personalizado a un formulario existente (o campo de formulario) en Drupal 8?
Tengo un formulario que no he creado. Quiero agregar mis propias reglas de validación en algunos campos cuando se envíe el formulario.
Para Drupal 7, ¿ Validación personalizada para un formulario? explica implementar hook_form_alter()
y luego agregar su controlador de validación] [1] a la $form['#validate']
matriz, pero en Drupal 8 los formularios son clases. La validación se realiza a través del validateForm()
método y no sé cómo conectar mi código a eso.
Respuestas:
La
#validate
propiedad todavía se usa en Drupal 8. (Con la solución de Adi, anulará el validador existente)Si desea agregar su validador personalizado además del predeterminado, deberá agregar algo como esto en hook_form_FORM_ID_alter (o similar):
fuente
#validate
(su enlace), no debe usarlo$form_state
como una matriz (la forma D7), sino como un objeto de implementaciónFormStateInterface
(la forma D8). En otras palabras, el código en su validador personalizado debe ser análogo al código que encontraría en unvalidateForm()
método original .Berdir dio la respuesta correcta, que una restricción es la forma correcta de agregar validación a un campo en Drupal 8. Aquí hay un ejemplo.
En el siguiente ejemplo, trabajaré con un nodo de tipo
podcast
, que tiene el campo de valor únicofield_podcast_duration
. El valor de este campo debe formatearse como HH: MM: SS (horas, minutos y segundos).Para crear una restricción, se deben agregar dos clases. El primero es la definición de restricción, y el segundo es el validador de restricción. Ambos son complementos, en el espacio de nombres de
Drupal\[MODULENAME]\Plugin\Validation\Constraint
.Primero, la definición de restricción. Tenga en cuenta que la ID del complemento se proporciona como 'PodcastDuration', en la anotación (comentario) de la clase. Esto se usará más abajo.
A continuación, debemos proporcionar el validador de restricciones. Este nombre de esta clase será el nombre de la clase de arriba, junto
Validator
con él:Finalmente, necesitamos decirle a Drupal que use nuestra restricción
field_podcast_duration
en elpodcast
tipo de nodo. Hacemos esto enhook_entity_bundle_field_info_alter()
:fuente
$item = $items->first();
y devolver NULL si no hay nada o de lo contrario obtendrá un error fatal al editar el campo: TypeError: Argument 2 pasado a Drupal \ Component \ Utility \ NestedArray :: getValue () debe ser del tipo array, nulo dado, llamado en /data/app/core/lib/Drupal/Core/Field/WidgetBase.php en la línea 407 en Drupal \ Component \ Utility \ NestedArray :: getValue () (línea 69 de core / lib / Drupal / Component /Utility/NestedArray.php).La forma correcta de hacer esto para una entidad de contenido como nodo es registrarlo como una restricción.
Ver
forum_entity_bundle_field_info_alter()
y el correspondiente?ForumLeaf
restricción de validación (tenga en cuenta que se necesitan dos clases).Eso es un poco más complicado al principio, pero la ventaja es que está integrado en la API de validación, por lo que su validación no se limita al sistema de formularios sino que, por ejemplo, también puede funcionar con nodos enviados a través de la API REST.
fuente
hook_entity_bundle_field_info_alter()
(como se describe aquí ) pero nunca funcionó ... Parece que hay un problema documentado con este enlace : drupal.org/node/2346347 .Quiero agregar algo más de luz sobre este asunto. La adición de la validación es exactamente la misma que antes: en hook_form_alter:
Sin embargo, el uso del objeto de valores dentro de $ form_state en la función de validación es un poco diferente. p.ej:
Entonces, no con un acceso directo al objeto de variables privadas, sino con una función getter.
Para obtener más información, puede ver un ejemplo completo en mi github: https://github.com/flesheater/drupal8_modules_experiments/blob/master/webham_formvalidation/webham_formvalidation.module
¡aclamaciones!
fuente
Es muy parecido a D7. Un ejemplo completo:
mymodule.module :
fuente
hook_form_FORM_ID_alter
necesita la identificación del formulario. Puede hacer que la función de validación personalizada sea la que desee. Además, siga la guía API aquí para conocer los parámetros adecuados.En complemento de estas buenas respuestas, agregaría:
Es cómo llamar a un método de clase distante para una validación de formulario. Creo que es mejor llamar a una función anterior en el archivo del módulo como en el ejemplo dado.
fuente
puede usar el módulo de Validación del lado del cliente . Algunos detalles más al respecto (de su página de proyecto):
fuente