2014-09-24 304 views
0

我是CakePHP和Ajax的新手,我在使用特定情况下使用Ajax验证时遇到了一些麻烦。CakePHP - 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); 

这是什么“如果”做。否则,我在success.ctp中得到了index.ctp的重复。

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

+0

此外,当表格中有错误时,其他数据无法在数据库中记录模糊 – Gnarok 2014-09-24 14:45:47

回答

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({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); 
      }); 
+0

您好,感谢您的评论。但我使用的成功是一个回调函数,而不是弃用的方法。 done()方法不起作用。在Ajax的文档建议使用成功/错误/完整回调 – Gnarok 2014-09-25 08:23:40

+0

但您的方法似乎更好地 – Gnarok 2014-09-25 08:28:34

+0

我看到他们不被弃用回调...做完美的作品...是失败触发在验证错误? – SkarXa 2014-09-25 10:09:09

0

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

我应该使用像

$this->someModel->save($data, false, array('someField')); 
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请求清除。我仍在为此努力。