Как использовать класс проверки формы ExpressionEngine в модуле для повторного заполнения формы в шаблоне? - PullRequest
5 голосов
/ 15 марта 2011

Можно ли отображать ошибки и заполнять поля в форме, которая жестко запрограммирована в шаблоне?До сих пор я только выяснил, как отображать ошибки в представлении модуля , но не в шаблоне.

Основываясь на логике ExpressionEngine, я предполагаю, что мне нужно как-тосделать ошибки проверки видимыми через тег в моем модуле, или даже сгенерировать целую форму из модуля, но я не уверен, как лучше всего подойти к этому.

Вот то, что у меня есть сейчас.

function submit_form()
{        
    $this->EE->load->helper('form');
    $this->EE->load->library('form_validation');

    $this->EE->form_validation->set_rules('first_name', 'First Name', 'required');
    $this->EE->form_validation->set_rules('last_name', 'Last Name', 'required');
    $this->EE->form_validation->set_rules('address', 'Address', 'required');
    $this->EE->form_validation->set_rules('city', 'City', 'required');
    $this->EE->form_validation->set_rules('province', 'Province', 'required');

    if ($this->EE->form_validation->run() == FALSE)
    {
        return $this->EE->load->view('form_errors');
    }
    else
    {
        // success
    }
} 

А для тестирования представление просто содержит:

echo validation_errors(); 

Может кто-нибудь помочь?

1 Ответ

10 голосов
/ 16 марта 2011

Отличный вопрос, и мне потребовалось много времени, чтобы найти лучший способ его решения.

Библиотека CodeIgniter Form Validation великолепна, но может использоваться только с соответствующими представлениями и контроллерами, поэтому она не работает сразу после разработки тега переднего плана.

Обычно предпочтительным способом отправки формы интерфейса является регистрация действия в вашем файле upd.addon.php (полагаю, вы сделали это для своей функции submit_form()). Затем ему присваивается номер, который вы можете опубликовать с помощью URL /index.php?ACT=37 или чего-то подобного. Это хорошая система, потому что это означает, что мы знаем, что отправка формы пришла из нашего модуля. Однако, с формами ввода, это является помехой, потому что это означает, что мы не можем заполнять поля ввода. Поэтому вам необходимо настроить форму ввода для отправки обратно на текущий URL-адрес и дождаться, пока механизм шаблонов попытается отобразить ваш тег, прежде чем обрабатывать отправку формы.

Самый простой и визуально уродливый способ добиться этого - использовать $this->EE->output->show_user_error(FALSE, array_of_errors). Вы можете использовать это либо из действия, либо из кода вашего модуля. Он отображает стандартную серую страницу сообщений EE, которую мы все привыкли знать и ненавидеть.

С таким вступлением вы, вероятно, знали, что решение не будет таким простым, верно? Вот скелет функции тега, которая реализует встроенную проверку ошибок:

function my_form()
{
    // load default tag variables
    $tag_vars = array();
    $tag_vars[0] = array(
        'first_name' => '',
        'error:first_name' => '',
        'last_name' => '',
        'error:last_name' => ''
    );

    // handle a form submission
    if ($this->EE->input->post('my_form_hidden') == '1'))
    {
        // load POST data into tag
        $tag_vars[0]['first_name'] = $this->EE->input->post('first_name', TRUE);
        $tag_vars[0]['last_name'] = $this->EE->input->post('last_name', TRUE);

        // use CI validation library to check submission
        $this->EE->load->helper('form');
        $this->EE->load->library('form_validation');
        $this->EE->form_validation->set_rules('first_name', 'lang:first_name', 'required');
        $this->EE->form_validation->set_rules('last_name', 'lang:first_name', 'required');

        $valid_form = $this->EE->form_validation->run();
        if ($valid_form)
        {
            // probably save something to database, then redirect
        }
        else
        {
            $form_errors = array();
            foreach (array('first_name', 'last_name') as $field_name)
            {
                $field_error = form_error($field_name);
                if ($field_error)
                {
                    $form_errors[] = $field_error;
                    $tag_vars[0]['error:'.$field_name] = $field_error;
                }
            }

            if ($this->EE->TMPL->fetch_param('error_handling') != 'inline')
            {
                // show default EE error page
                return $this->EE->output->show_user_error(FALSE, $form_errors);
            }
        }
    }

    // parse and output tagdata
    $out = $this->EE->functions->form_declaration(array(
        'action' => $this->EE->functions->fetch_current_uri(),
        'hidden_fields' => array('my_form_hidden')));
    $out .= $this->EE->TMPL->parse_variables($tagdata, $tag_vars);
    return $out.'</form>';
}

Таким образом, разработчик может указать error_handling="inline" в теге, если он хочет встроенных ошибок, в противном случае они будут просто перенаправлены на стандартную форму ошибки. Если они запрашивают встроенную обработку ошибок, им просто нужно убедиться, что их входные данные выглядят так:

<input type="text" name="first_name" value="{first_name}" />
{error:first_name}

Обратите внимание на скрытое поле, которое мы отправляем вместе с формой, это позволяет нам гарантировать, что мы обрабатываем только отправку этой формы, а не любые другие формы на странице, такие как форма для входа или что-то еще. Если у вас есть более одного экземпляра вашей формы на странице (скажем, внутри цикла записей канала или чего-то еще), вам нужно будет реализовать некоторые хитрости, чтобы убедиться, что вы обрабатываете только тот экземпляр формы, который был отправлен, например, отправляя вместе entry_id как скрытое поле тоже.

Рад, что все задокументировано, надеюсь, это будет полезно и другим разработчикам EE!

...