Como você altera a localização da saída `form_set_error`?

9

Existe uma maneira no Drupal 7 de alterar a localização da saída de form_set_error?

No momento, ele chama drupal_set_messagequais enfileiram todos os erros do formulário na parte superior da tela.

O que eu gostaria é que cada mensagem apareça abaixo do campo apropriado.

Se isso não for possível, posso sinalizar manualmente o formulário como "inválido" dentro da MODULE_form_name_validate()função sem usar form_set_error?

Chris
fonte

Respostas:

7

O módulo Erros de formulário embutido possui essa funcionalidade:

O IFE ou erros de formulário embutido permite inserir erros de envio de formulário alinhados com os elementos do formulário. São fornecidas três opções para definir seu comportamento de erro em linha. Você pode configurar o comportamento padrão ou substituí-lo por formulário. Você pode adicionar quantos formulários desejar.

O lançamento do Drupal 7 é apenas em alfa, mas eu diria que vale a pena tentar. Mesmo se houver problemas, deve ser um bom lugar para você começar a implementar sua própria versão. Esta é a captura de tela do módulo:

insira a descrição da imagem aqui

Clive
fonte
Este módulo é realmente antigo. Eu testei, mas é tão ruim em termos de personalizações. Lamentavelmente inútil para formulários que você já criou sem essas criações clicáveis ​​de formulários.
kwoxer
8

Estendendo a resposta (correta) de Clive, trabalhei com o código IFE. Eu realmente não precisava de um módulo inteiro dedicado a isso, então adotei alguns trechos aqui e ali para obter o resultado necessário. Marquei a resposta dele como correta, porque é a resposta certa.

O código está abaixo, todo o crédito é do Clive e da equipe do IFE - eu só queria apresentar a versão simplificada para quem procura uma resposta semelhante.

// 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
fonte
Olá, Chris, quando você diz "Exponha essa matriz da maneira que desejar ao seu modelo, ou faça um loop no seu formulário adicionando um #suffix a cada elemento com um erro", como posso acessar a variável $ reset_errors retornada na função validate no meu formulário função? Seria bom fornecer uma amostra de amostra para isso? Obrigado!
Leolando Tan
@LeolandoTan desculpe amigo - eu não uso o Drupal desde 2013 - eu nem me lembro de responder a essa pergunta!
26417 Chris