如何在模块中使用ExpressionEngine表单验证类来重新填充模板中的表单?

发布于 2024-10-22 06:35:36 字数 1055 浏览 1 评论 0原文

是否可以在硬编码到模板中的表单上显示错误并重新填充字段?到目前为止,我只弄清楚如何在模块的视图中显示错误,而不是模板。

基于 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(); 

有人可以帮忙吗?

Is it possible to display errors and repopulate fields on a form that is hard coded into a template? So far I’ve only figured out how to display the errors in a module’s view, but not a template.

Based on the logic of ExpressionEngine, I’m guessing I need to somehow make the validation errors visible through a tag in my module, or even generate the whole form from the module, but I’m not sure how to best approach this.

Here is what I have right now.

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
    }
} 

And for testing, the view simply contains:

echo validation_errors(); 

Can anyone help?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

留蓝 2024-10-29 06:35:37

很好的问题,我花了很长时间才找到解决问题的最佳方法。

CodeIgniter 表单验证库很棒,但只能与适当的视图和控制器一起使用,所以它不当您开发前端标签时,开箱即用。

通常,提交前端表单的首选方法是在 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}

注意我们随表单一起提交的隐藏字段,这使我们能够确保我们只处理 this 的提交表单,而不是页面上的任何其他表单,例如登录表单或其他表单。如果页面上有多个表单实例(例如在频道条目循环或其他内容内),则需要实施一些技巧以确保仅处理已提交的表单实例,例如通过一起提交Entry_id 也是一个隐藏字段。

很高兴将所有内容记录下来,希望这对其他 EE 开发人员也有用!

Great question, and one which took me a long time to figure out the best way to solve.

The CodeIgniter Form Validation library is great, but can only be used with proper views and controllers, so it doesn't work out of the box when you are developing a front end tag.

Normally, the preferred way of submitting a front-end form is to register an 'Action' in your upd.addon.php file (I'm guessing you have done this for your submit_form() function). This is then assigned a number, which you can post with the url /index.php?ACT=37 or something similar. This is a good system, because it means we know the form submission came from our module. However, with input forms, this is a hindrance, because it means we can't repopulate input fields. You therefore need to configure the input form to post back to the current URL, and wait until the template engine tries to render your tag before handling the form submission.

The easiest, and visually ugliest way to achieve this, is to use $this->EE->output->show_user_error(FALSE, array_of_errors). You can actually use this from either an action, or within your module code. It displays the standard grey EE message page we have all grown to know and hate.

With that sort of intro, you probably knew the solution wasn't going to be quite that simple, right? Here's a skeleton of a tag function which implements inline error checking:

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>';
}

This way, the designer can specify error_handling="inline" in the tag if they want inline errors, otherwise they will just be redirected to the standard error form. If they do request inline error handling, they will simply need to make sure their inputs look like this:

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

Note the hidden field we submit along with the form, this allows us to ensure we only handle submission of this form, and not any other forms on the page, such as a login form or something. If you have more than one instance of your form on a page (say inside a channel entries loop or something), you will need to implement some trickery to make sure that you only handle the form instance which was submitted, for example by submitting along entry_id as a hidden field too.

Glad to get that all documented, hopefully this will be useful to other EE developers too!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文