¿Cómo se cambia la ubicación de la salida `form_set_error`?

9

¿Hay alguna manera en Drupal 7 para cambiar la ubicación de la salida de form_set_error?

Por el momento, llama a drupal_set_messageque pone en cola todos los errores del formulario en la parte superior de la pantalla.

Lo que me gustaría es que cada mensaje aparezca debajo del campo apropiado.

Si esto no es posible, ¿puedo marcar manualmente el formulario como "no válido" dentro de la MODULE_form_name_validate()función sin usar form_set_error?

Chris
fuente

Respuestas:

7

El módulo de errores de formulario en línea tiene esa funcionalidad:

Los errores de formulario IFE o en línea le permiten colocar el error de envío del formulario en línea con los elementos del formulario. Se proporcionan tres opciones para configurar su comportamiento de error en línea. Puede configurar el comportamiento predeterminado o anular el comportamiento por formulario. Puede agregar tantos formularios como desee.

La versión de Drupal 7 solo está en alfa, pero diría que vale la pena intentarlo. Incluso si hay problemas, debería darle un buen lugar para comenzar a implementar su propia versión. Esta es la captura de pantalla del módulo:

ingrese la descripción de la imagen aquí

Clive
fuente
Este módulo es realmente viejo. Lo probé pero es tan malo en términos de personalizaciones. Tristemente inútil para los formularios que ya ha creado sin estas creaciones de formularios.
kwoxer
8

Extendiendo la respuesta (correcta) de Clive, trabajé a través del código IFE. Realmente no necesitaba un módulo completo dedicado a esto, así que adopté algunos fragmentos aquí y allá para obtener el resultado que necesitaba. He marcado su respuesta como correcta porque, en última instancia, es la respuesta correcta.

El código está debajo, todo el crédito va para Clive y el equipo de IFE: solo quería presentar la versión simplificada para cualquiera que busque una respuesta similar.

// Standard gear - do some custom validation and set the errors
// as you go..
// 
// Once all the validation has been done, call MODULE_errors_reset
// which will return an array of all errors against their ID. 
// Expose this array however you like to your template, or loop
// over your form adding a #suffix to each element with an error
//
function MODULE_form_name_validate($form, &$form_state) {
    drupal_set_message("validating...");

    form_set_error("description", "There is an error here!!!!");
    form_set_error("tags", "Yep, and here too!!!");

    $reset_errors = MODULE_errors_reset( $form );

    drupal_set_message( "<pre>" . print_r( $reset_errors, true ) . "</pre>" );
}

// This part is adopted from IFE. It's changed in two ways, it returns
// an array (which also merges with its recursive self). 
// And it also skips all the 'display' stuff present in the original
// Essentially it extracts out the error messages from the session and unsets 
// them. I am assuming that Drupal 7 marks the success of a validation based not
// whether the SESSION variable contains anything, the SESSION seems to be only
// for the message at the top of the screen.
//
function MODULE_errors_reset( $element ) {
    if( ! isset( $_SESSION[ 'messages' ] ) ) {
        return;
    }

    $reset_errors = array();

    // Recurse through all children.
    foreach( element_children( $element ) as $key ) {
        if( isset( $element[ $key ] ) && $element[ $key ] ) {
            $reset_errors += MODULE_errors_reset( $element[ $key ] );
        }
    }

    // Check for errors and settings
    $errors = form_get_errors();
    $element_id = implode( '][', $element[ '#parents' ] );

    if ( !empty( $errors[ $element_id ] )) {
        $error_message = $errors[ $element_id ];

        // Get error id
        $error_id = array_search( $error_message, $_SESSION[ 'messages' ][ 'error' ] );

        if( $error_id !== FALSE ) {
            unset( $_SESSION[ 'messages' ][ 'error' ][ $error_id ] );
            $_SESSION[ 'messages' ][ 'error' ] = array_values( $_SESSION[ 'messages' ][ 'error' ]  );

            if( count( $_SESSION[ 'messages' ][ 'error' ] ) <= 0 ) {
                unset( $_SESSION[ 'messages' ][ 'error' ] );
            }

            $reset_errors[ $element[ '#id' ] ] = $error_message;
        }
    }

    return $reset_errors;
}

// If there are no form errors, we still hit here, even after the 'reset', this is
// a good thing. 
function MODULE_form_name_submit( $form, &$form_submit ) {
    drupal_set_message("submited!");
}
Chris
fuente
Hola Chris, cuando dices "Expone esta matriz como quieras a tu plantilla, o repite tu formulario agregando un #suffix a cada elemento con un error", ¿cómo puedo acceder a la variable $ reset_errors devuelta en la función de validación en mi formulario? ¿función? ¿Estaría bien proporcionar una muestra de muestra para eso? ¡Gracias!
Leolando Tan
@LeolandoTan lo siento amigo - No he usado Drupal desde 2013 - ¡Ni siquiera recuerdo haber respondido esta pregunta!
Chris