Как вы меняете расположение вывода `form_set_error`?

9

Есть ли способ в Drupal 7 изменить расположение вывода form_set_error?

На данный момент он вызывает, drupal_set_messageкоторый ставит все ошибки формы в верхнюю часть экрана.

Вместо этого я хотел бы, чтобы каждое сообщение отображалось под соответствующим полем.

Если это невозможно, могу ли я вручную пометить форму как «недействительную» в MODULE_form_name_validate()функции без использования form_set_error?

Крис
источник

Ответы:

7

Модуль Inline Form Errors имеет такую ​​функциональность:

IFE или Inline Form Errors позволяет помещать ошибку отправки формы в линию с элементами формы. Предусмотрено три варианта настройки поведения встроенной ошибки. Вы можете настроить поведение по умолчанию или переопределить поведение для каждой формы. Вы можете добавить столько форм, сколько захотите.

Релиз Drupal 7 только в альфа-версии, но я бы сказал, что стоит попробовать. Даже если есть проблемы, это должно дать вам хорошее место для начала реализации своей собственной версии. Это скриншот модуля:

введите описание изображения здесь

Клайв
источник
Этот модуль действительно старый. Я проверил это, но это так плохо с точки зрения настроек. К сожалению, бесполезно для форм, которые вы уже создали без этих щелчковых созданий форм.
Kwoxer
8

Расширяя (правильный) ответ от Клайва, я работал через код IFE. Мне не нужен был целый модуль, посвященный этому, поэтому я применил несколько фрагментов здесь и там, чтобы получить нужный мне результат. Я пометил его ответ как правильный, потому что в конечном итоге это правильный ответ.

Код ниже, все заслуги перед Клайвом и командой IFE - я просто хотел представить упрощенную версию для тех, кто ищет подобный ответ.

// 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!");
}
Крис
источник
Привет, Крис, когда ты говоришь: «Экспонируйте этот массив так, как вам нравится в вашем шаблоне, или перебирайте форму, добавляя #suffix к каждому элементу с ошибкой», как я могу получить доступ к переменной $ reset_errors, возвращенной в функции validate в моей форме функция? Было бы хорошо предоставить образец дисплея для этого? Спасибо!
Леоландо Тан
@ LeolandoTan Извините, приятель - я не использовал Drupal с 2013 года - я даже не помню, как отвечал на этот вопрос!
Крис