【问题标题】:CakePHP - Ajax form - submit on blurCakePHP - Ajax 表单 - 提交模糊
【发布时间】:2014-09-24 14:35:50
【问题描述】:

我是 CakePHP 和 Ajax 的新手,在特定情况下使用 Ajax 验证时遇到了一些麻烦。

正如标题中所说,我在 jQuery blur() 事件上提交表单。每次完成 ajax 请求时,成功时我们会显示一个包含一条小消息的 success.ctp。

这里是我的 index.ctp

<h2>Edition - Id client : <?php echo h($id); ?></h2>
<hr>
<div id="success"></div>
<div>
    <?php
    echo $this->Form->create('Client', array(
        "id" => "ajax-form"
        ));
        ?>
    <fieldset>
        <?php
        //echo $this->Form->input('nom', array('onchange'=>"this.form.submit()"));
        echo $this->Form->input('nom', array(
            "id" =>  "nom",
            ));
        echo $this->Form->input('prenom', array(
            "id" =>  "prenom",
            ));
        echo $this->Form->input('email', array(
            "id" =>  "email",
            ));
        echo $this->Form->input('adresse', array(
            "id" =>  "adresse",
            ));
        echo $this->Form->input('ville', array(
            "id" =>  "ville",
            ));
        echo $this->Form->input('code_postal', array(
            "id" =>  "code_postal",
            ));
        echo $this->Form->input('pays', array(
            "id" =>  "pays",
            ));
        echo $this->Form->input('num_fixe', array(
            "id" =>  "num_fixe",
            ));
        echo $this->Form->input('num_portable', array(
            "id" =>  "num_portable",
            ));
        echo $this->Form->input('genre', array(
            "id" =>  "genre",
            "type" => "select",
            //"before" => '<p>Genre</p>',
            //"after" => '--après--',
            //"between" => '--entre---',
            "separator" => '<br>',
            "options" => array('' => '', 'Homme' => 'homme', 'Femme' => 'femme')
            ));
        echo $this->Form->input('date_naissance', array(
            "type" => "text",
            "id" =>  "date_naissance",
            "label" => "Date de naissance",
            "class"=>'datepicker',
            'empty' => true));
        ?>

        <script type="text/javascript">
            $(function () {
                $('.datepicker').datepicker(
                    {
                        format: 'yyyy-mm-dd',
                        language:'fr',
                        startView:'decade',
                        showToday: false,
                        startDate:'-80y',
                        endDate:'-18y'
                    }
                );
            });
        </script>
        </div>
    </fieldset>
    <?php echo $this->Form->submit(
         'Sauvegarder les modifications', 
        array(  'class'     => 'btn btn-primary',
                'title'     => 'Savegarder'
        )) ?>    


<?php echo $this->Form->end(); ?>
</div>
<div class="spacer"></div>
<hr>
<p>
    <?php echo $this->Html->link(
        '<span class="glyphicon glyphicon-list"></span> Retour',
        array('controller' => 'Clients', 'action' => 'index'),
        array('class' => 'btn btn-default', 'escape' => FALSE)
    ); ?>
</p>

<div style="display:none;" id="sending">Sending...</div>
<?php echo $errors; ?>

<script type="text/javascript">

       $(document).ready(function () {

            $("#ajax-form input").blur(function () {


                $.ajax({beforeSend:function (XMLHttpRequest) {
                    $("#sending").fadeIn();}, 
                    data:$("#ajax-form").closest("form").serialize(), 
                    dataType:"html", 
                    success:function (data, textStatus) {
                        $("#sending").fadeOut();
                        if(data.length < 50)
                            $("#success").html(data);
                    }, 
                    type:"post", 
                    url:"\/clients\/index\/<?php echo h($id); ?>"
                });
                return false;
            });


        });
</script>

我的索引函数

public function index($id = null) {

        if (!$id) {
            throw new NotFoundException(__('Invalid post'));
        }

        $user = $this->Client->findById($id);
        if (!$user) {
            throw new NotFoundException(__('Invalid post'));
        }

        if ($this->request->is(array('post', 'put'))) {
            $this->Client->id = $id;
            $this->request->data['Client']['modified_at']   =   date('Y-m-d H:i:s');
            if ($this->Client->save($this->request->data)) {
                if($this->RequestHandler->isAjax()){

                    $this->render('success', 'ajax');
                }
                else{
                    $this->Session->setFlash(__('L\'utilisateur a été mis à jour.'));
                    return $this->redirect(array('action' => 'recap', $id));
                }
            }
            $this->Session->setFlash(
                __('Unable to update.')
                );
        }

        $user =  $this->Client->findById($id);
        $this->set('id',$id);
        $this->set('user',$user);
        if (!$this->request->data) {
            $this->request->data = $user;
        }

    }

还有模特

public $validate = array(
        'nom' => array(
            'required' => array(
                'rule' => array('notEmpty'),
                'message' => 'Nom incorrect'
            )
        ),
        'prenom' => array(
            'required' => array(
                'rule' => array('notEmpty'),
                'message' => 'Prenom incorrect'
            )
        ),
        'email' => array(
            'required' => array(
            'rule' => array('email'),
            'message' => 'Email incorrect'
            )
        )
    );

当数据有效时,代码可以完美运行。当他们不是时,我必须使用修复来不显示success.ctp:

$("#success").html(data);

这就是'if'所做的。否则我在success.ctp中得到一个重复的index.ctp。

有没有其他方法可以在这个 blur() 事件上使用 Ajax 验证,就像提交按钮一样。

【问题讨论】:

  • 另外,当表单出现错误时,blur上的数据库中无法记录其他数据

标签: ajax forms cakephp submit


【解决方案1】:

现在,当我用错误值填充字段时,会显示错误响应。我认为最好只更新最后一个更改的字段,而不是记录所有表单。

我应该使用类似的东西

$this->someModel->save( $data, false, array('someField') );

【讨论】:

    【解决方案2】:

    如果您的表单无法保存,您可以将 HTTP Header 设置为 500,这样 ajax 将触发失败,并使用验证错误做出响应。像这样:

            if ($this->Client->save($this->request->data)) {
                if($this->RequestHandler->isAjax()){
    
                    $this->render('success', 'ajax');
                }
                else{
                    $this->Session->setFlash(__('L\'utilisateur a été mis à jour.'));
                    return $this->redirect(array('action' => 'recap', $id));
                }
            } else if($this->RequestHandler->isAjax()){
               $this->header('HTTP/1.1 500 Internal Server Error');
               $this->set('data', implode(', ', $this->Client->validationErrors));
               //render a view that only echoes data var
               return $this->render('ajaxResponse');
            }
    

    然后是ajax:

                $.ajax({beforeSend:function (XMLHttpRequest) {
                    $("#sending").fadeIn();}, 
                    data:$("#ajax-form").closest("form").serialize(), 
                    dataType:"html", 
                    type:"post", 
                    url:"\/clients\/index\/<?php echo h($id); ?>"
                }).done(function(data){
                        $("#sending").fadeOut();
                        if(data.length < 50)
                            $("#success").html(response);
                }).fail(function(response){
                //alert with errors
                    alert(response.responseText);
                });
    

    【讨论】:

    • 您好,感谢您的评论。但是我使用的成功是一个回调函数,而不是弃用的方法。 done() 方法不起作用。在 Ajax 的文档中,建议使用成功/错误/完成回调
    • 我看到它们在回调中没有被弃用... done 对我来说非常有效... 验证错误触发失败了吗?
    • 由于一些模糊的原因,我在使用这种方法记录文本区域输入时遇到了问题,其他输入效果很好。使用您的方法,它可以完美地适用于所有领域。
    【解决方案3】:

    我对表单的工作方式进行了一些改进。 以前,表格错误会导致无法记录任何其他新的有效数据。

    所以我将脚本更改为

    $.ajax({beforeSend:function (XMLHttpRequest) {
                            $("#sending").fadeIn();}, 
                            data:$("#ajax-form").closest("form").serialize(), 
                            dataType:"html", 
    
                            type:"post", 
                            url:"\/clients\/index\/<?php echo h($id); ?>?param="+key
                            //url:"\/clients\/ajax_form_field\/<?php echo h($id); ?>\/"+key
                        }).done(function(data){
                            $("#sending").fadeOut();
                            if(data.length>50){
                                $("#page").html(data);
                                if($("#nom-notEmpty").length == 0)
                                    $('#ajax-form').before('<div id="nom-notEmpty" class="error-message">Merci de corriger les erreurs de saisie avant de valider le formulaire</div>');
                            }
                            if(data.length<50){
                                $("#success").html('message_sent');
                                $(".help-inline").remove();
                                if($(".help-inline").length == 0){
                                    $("#nom-notEmpty").remove();
                                }
                            }
    
                        }).fail(function(data){
                        //alert with errors
                           alert(response.responseText);
                        });
                        return false;
    

    现在我在 Ajax 请求中添加一个参数来获取被更改的字段的名称。

    然后我用开关在我的控制器中验证它

    if ($this->request->is(array('post', 'put'))) {
            $this->Client->id = $id;
            $this->request->data['Client']['modified_at']   =   date('Y-m-d H:i:s');            
    
            if($this->RequestHandler->isAjax()){
                $data =$this->request->data['Client'];
    
                switch($this->request->query['param']){
                    case "nom" :
                        if($this->Client->save( $data, true, array($this->request->query['param']) )){
                            $this->render('success', 'ajax');
                        }   
                    break;
                    case "prenom" :
                        if($this->Client->save( $data, true, array($this->request->query['param']) )){
                            $this->render('success', 'ajax');
                        }
                    break;
                    case "email" :
                        if($this->Client->save( $data, true, array($this->request->query['param']) )){
                            $this->render('success', 'ajax');
                        }
                    break;
                    case "adresse" :
                        if($this->Client->save( $data, true, array($this->request->query['param']) )){
                            $this->render('success', 'ajax');
                        }
                    break;
                    case "ville" :
                        if($this->Client->save( $data, true, array($this->request->query['param']) )){
                            $this->render('success', 'ajax');
                        }
                    break;
                    case "pays" :
                        if($this->Client->save( $data, true, array($this->request->query['param']) )){
                            $this->render('success', 'ajax');
                        }
                    break;
                    case "code_postal" :
                        if($this->Client->save( $data, true, array($this->request->query['param']) )){
                            $this->render('success', 'ajax');
                        }
                    break;
                    case "num_fixe" :
                        if($this->Client->save( $data, true, array($this->request->query['param']) )){
                            $this->render('success', 'ajax');
                        }
                    break;
                    case "num_portable" :
                        if($this->Client->save( $data, true, array($this->request->query['param']) )){
                            $this->render('success', 'ajax');
                        }
                    break;
                    case "genre" :
                        if($this->Client->save( $data, true, array($this->request->query['param']) )){
                            $this->render('success', 'ajax');
                        }
                    break;
                    case "date_naissance" :
                        if($this->Client->save( $data, true, array($this->request->query['param']) )){
                            $this->render('success', 'ajax');
                        }
                    break;
                }
            }
            else{
    
                $this->Session->setFlash(__('L\'utilisateur a été mis à jour.'));
                return $this->redirect(array('action' => 'recap', $id));
            }
    

    它有效。但我认为有一种更好的方法可以用更少的代码、更优化的方式来完成。

    此外,当字段的值错误时,会在字段下方显示错误消息。但在彼此验证时,消息由 ajax 请求清除。我仍在努力。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-19
      • 1970-01-01
      相关资源
      最近更新 更多