CakePHP - Ajax表单 - 提交模糊

时间:2014-09-24 14:35:51

标签: ajax forms cakephp submit

我是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'
            )
        )
    );

当数据有效时,代码可以正常工作。如果不是,我必须使用修复程序才能显示成功.ctp:

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

这就是'如果'做的。否则我在success.ctp中找到了index.ctp的重复。

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

3 个答案:

答案 0 :(得分:0)

您可以制作,否则如果您的表单无法保存,请将HTTP标头设置为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);
            });

答案 1 :(得分:0)

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

我应该使用像

这样的东西吗?
$this->someModel->save( $data, false, array('someField') );

答案 2 :(得分:0)

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

所以我将脚本更改为

$.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请求清除。我还在努力。