Bagaimana Anda mengubah lokasi output `form_set_error`?

9

Apakah ada cara di Drupal 7 untuk mengubah lokasi output form_set_error?

Saat ini, ia memanggil drupal_set_messageantrian semua kesalahan formulir ke bagian atas layar.

Yang saya inginkan adalah agar setiap pesan muncul di bawah bidang yang sesuai.

Jika ini tidak memungkinkan, dapatkah saya menandai formulir secara manual sebagai "tidak valid" dalam MODULE_form_name_validate()fungsi tanpa menggunakan form_set_error?

Chris
sumber

Jawaban:

7

The Inline Formulir Kesalahan modul memiliki fungsi yang:

IFE atau Inline Form Error memungkinkan Anda untuk menempatkan kesalahan pengiriman formulir sesuai dengan elemen formulir. Tiga opsi disediakan untuk mengatur perilaku kesalahan inline Anda. Anda bisa mengonfigurasi perilaku default atau mengganti perilaku berdasarkan basis per formulir. Anda dapat menambahkan sebanyak mungkin formulir.

Rilis Drupal 7 hanya dalam alpha tetapi saya akan mengatakan itu patut dicoba. Bahkan jika ada masalah, itu harus memberi Anda tempat yang baik untuk mulai mengimplementasikan versi Anda sendiri. Ini adalah tangkapan layar modul:

masukkan deskripsi gambar di sini

Clive
sumber
Modul ini sangat tua. Saya mengujinya tetapi sangat buruk dalam hal kustomisasi. Sayangnya tidak berguna untuk Formulir yang telah Anda buat tanpa kreasi formulir ini.
kwoxer
8

Memperluas jawaban (benar) dari Clive, saya bekerja melalui kode IFE. Saya tidak benar-benar membutuhkan seluruh modul yang didedikasikan untuk ini, jadi saya mengadopsi beberapa cuplikan di sana-sini untuk mendapatkan hasil yang saya butuhkan. Saya telah menandai jawabannya sebagai jawaban yang benar karena pada akhirnya itu adalah jawaban yang tepat.

Kode di bawah, semua kredit diberikan kepada Clive dan tim IFE - Saya hanya ingin menyajikan versi yang disederhanakan bagi siapa pun yang mencari jawaban yang sama.

// 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
sumber
Halo Chris, ketika Anda mengatakan "Paparkan larik ini bagaimanapun Anda suka dengan templat Anda, atau lewati formulir Anda dengan menambahkan #suffix ke setiap elemen dengan kesalahan", bagaimana saya bisa mengakses variabel $ reset_errors yang dikembalikan dalam fungsi validasi dalam formulir saya fungsi? Apakah tidak apa-apa untuk memberikan tampilan sampel untuk itu? Terima kasih!
Leolando Tan
@LeolandoTan mate maaf - Saya belum pernah menggunakan Drupal sejak 2013 - Saya bahkan tidak ingat menjawab pertanyaan ini!
Chris