Jak zmienić lokalizację wyjścia `form_set_error`?

9

Czy w Drupal 7 jest sposób na zmianę położenia wyjścia form_set_error?

W tej chwili wywołuje drupal_set_messagekolejkę wszystkich błędów formularza na górze ekranu.

Zamiast tego chciałbym, aby każda wiadomość pojawiła się poniżej odpowiedniego pola.

Jeśli nie jest to możliwe, czy mogę ręcznie oflagować formularz jako „nieprawidłowy” w MODULE_form_name_validate()funkcji bez użycia form_set_error?

Chris
źródło

Odpowiedzi:

7

Moduł Inline Form Errors ma tę funkcję:

IFE lub Inline Form Errors pozwala umieścić błąd przesyłania formularza w linii z elementami formularza. Dostępne są trzy opcje ustawiania zachowania błędu podczas wstawiania. Możesz skonfigurować domyślne zachowanie lub zastąpić zachowanie dla poszczególnych formularzy. Możesz dodać dowolną liczbę formularzy.

Wydanie Drupal 7 jest tylko w wersji alfa, ale powiedziałbym, że warto spróbować. Nawet jeśli występują problemy, powinno to dać ci dobre miejsce do rozpoczęcia wdrażania własnej wersji. Oto zrzut ekranu modułu:

wprowadź opis zdjęcia tutaj

Clive
źródło
Ten moduł jest naprawdę stary. Przetestowałem to, ale jest tak źle pod względem dostosowań. Niestety nieużyteczne dla formularzy, które już utworzyłeś bez tych klikalnych kreacji formularzy.
kwoxer
8

Rozszerzając (poprawną) odpowiedź od Clive, pracowałem przez kod IFE. Tak naprawdę nie potrzebowałem całego modułu poświęconego temu, więc zaadaptowałem kilka fragmentów tu i tam, aby uzyskać oczekiwany rezultat. Oznacziłem jego odpowiedź jako poprawną, ponieważ jest to ostatecznie właściwa odpowiedź.

Kod jest poniżej, wszystkie podziękowania należą się Clive i zespołowi IFE - chciałem tylko przedstawić uproszczoną wersję każdemu, kto szuka podobnej odpowiedzi.

// 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
źródło
Cześć Chris, kiedy mówisz „Odsłoń tę tablicę, jak chcesz, do szablonu lub zapisz pętlę, dodając # suffix do każdego elementu z błędem”, jak mogę uzyskać dostęp do zmiennej $ reset_errors zwróconej w funkcji sprawdzania poprawności w moim formularzu funkcjonować? Czy byłoby w porządku podać do tego przykładowy wyświetlacz? Dzięki!
Leolando Tan,
@LeolandoTan przepraszam kolego - nie korzystam z Drupala od 2013 roku - nie pamiętam nawet odpowiedzi na to pytanie!
Chris