2013-04-23 33 views
5

我有一個從另一個模型(團隊has_many team_members)調用渲染部分的Yii窗體。我想通過ajax調用一個局部視圖來添加team/_form中的成員。除ajax驗證(服務器和客戶端)之外的所有作品(調用,顯示,保存)。如果我提交表單,成員的模型不驗證,即使在客戶端,它不驗證必填字段。Yii ClientSide驗證渲染局部不工作

任何線索?

// _形式

<?php $form=$this->beginWidget('CActiveForm', array(
    'id'=>'team-form', 
     'enableAjaxValidation'=>true, 
     'enableClientValidation'=>true, 
     'clientOptions'=>array(
      'validateOnSubmit'=>true, 
      'validateOnChange'=>true 

     ), 
     'htmlOptions' => array('enctype' => 'multipart/form-data'), 
)); ?> 

//控制器

public function actionMember($index) 
{ 
    $model = new TeamMember(); 
     $this->renderPartial('_member',array(
      'model'=> $model, 'index'=> $index 
     ) 
       ,false,true 
       ); 
} 

public function actionCreate() 
{ 
     $model=new Team; 
     $members = array(); 
     if(isset($_POST['Team'])) 
     { 
       $model->attributes=$_POST['Team']; 

       if(!empty($_POST['TeamMember'])){ 
       foreach($_POST['TeamMember'] as $team_member) 
          { 
           $mem = new TeamMember(); 
           $mem->setAttribute($team_member); 
           if($mem->validate(array('name'))) $members[]=$mem; 
          } 
       } 
         $this->redirect(array('team/create','id'=>$model->id,'#'=>'submit-message')); 

     } 

     $members[]=new TeamMember; 
     $this->performAjaxMemberValidation($members); 
     $this->render('create',array(
       'model'=>$model,'members'=>$members 
     )); 

} 

// _構件

<div class="row-member<?php echo $index; ?>"> 
    <h3>Member <?php echo $index+1; ?></h3> 
    <div class="row"> 
    <?php echo CHtml::activeLabel($model, "[$index]name",array('class'=>'member')); ?> 
    <?php echo CHtml::activeTextField($model, "[$index]name",array('class'=>'member')); ?> 
    <?php echo CHtml::error($model, "[$index]name");?>  
    </div> 
</div> 

ProcessOutput被設置爲true。沒有骰子。 開關renderPartial()render()。沒有骰子。

+0

MEM,coppettim:你是同一個人嗎?如果沒有,爲什麼你編輯這個問題並添加最後一行,你怎麼知道這個? – soju 2013-04-23 17:42:18

+0

@soju:我們不是同一個人。但我們都在研究這個問題。 - 我們都沒能找到答案。 – MEM 2013-04-23 18:00:34

+0

你的規則是什麼()? – JorgeeFG 2013-04-23 18:46:37

回答

6

如果你會看CActiveForm::run

$cs->registerCoreScript('yiiactiveform'); 
//... 
$cs->registerScript(__CLASS__.'#'.$id,"jQuery('#$id').yiiactiveform($options);"); 

然後你會明白,你驗證將無法工作,因爲你渲染部分,而不是整個頁面。這些腳本顯示在頁面的底部。所以你應該通過執行這些腳本解決這個問題。

你局部渲染後,試圖獲得其應存放在scipts陣列的ActiveForm腳本:

$this->renderPartial('_member',array('model'=> $model, 'index'=> $index)); 
$script = Yii::app()->clientScript->scripts[CClientScript::POS_READY]['CActiveForm#team-form']; 

後,與呈現的HTML發送到頁面:

echo "<script type='text/javascript'>$script</script>" 

還記得在頁面上添加收到的html之前,您應該包括jquery.yiiactiveform.js,如果您尚未(通過渲染其他表單或registerCoreScript('yiiactiveform'))在頁面上調用ajax請求。否則,JavaScript錯誤會引發。

希望這會有所幫助。

編輯: 對不起,我不明白你是渲染的一部分,而不是整體。但是你的驗證不會完全適用於同一個問題。因爲jQuery('#$id').yiiactiveform($options);腳本未爲該字段創建。

+0

對不起,不知道在哪裏把「$ script = Yii :: app() - > clientScript-> scripts [CClientScript :: POS_READY] ['CActiveForm#team-form'];」..我在控制器中調用我的renderPartial,所以$ script在_member視圖中將不可見。 – coppettim 2013-04-24 09:36:28

0

那麼,在renderPartial設置processOutput爲true(爲了使客戶端驗證工作在新添加的字段)在這種情況下,不會幫助,因爲它只會爲CActiveForm形式的工作,你沒有任何形式的_member查看(只有輸入字段)。

一個簡單處理這類問題的方法可以是使用只有AJAX驗證,並在你的控制器使用CActiveForm::validateTabular()來驗證你的團隊成員。

+0

我做到了,並且_member加載了已驗證的字段。但是,當我在輸入內輸入數據時,他們不會改變他們的狀態,一直說「這個字段是強制性的」等等。 – coppettim 2013-04-24 09:37:40

+0

您是否將'enableAjaxValidation'設置爲true並且'enableClientValidation'設置爲false? – soju 2013-04-24 09:41:31

+0

是的,ajax true和客戶端爲false。同樣的問題... – coppettim 2013-04-24 09:47:09

1

實際的問題是,ActiveForm將其屬性保存在「設置」數據屬性中進行驗證。我發現你已經在使用索引,所以你需要添加新的元素到這個設置對象,以便驗證工作。 Ajax響應後,這是必須要做的:

//Get the settings object from the form 
var settings = $("#form").data('settings'); 
//Get all the newly inserted elements via jquery 
$("[name^='YourModel']", data).each(function(k, v) { 
    //base attribute skeleton 
    var base = { 
     model : 'YourModel', 
     enableAjaxValidation : true, 
     errorCssClass : 'error', 
     status : 1, 
     hideErrorMessage : false, 
    }; 

    var newRow = $.extend({ 
     id : $(v).attr('id'), 
     inputID : $(v).attr('id'), 
     errorID : $(v).attr('id') + '_em_', 
     name : $(v).attr('name'), 
    }, base); 
    //push it to the settings.attribute object 
    settings.attributes.push(newRow); 
}); 
//update the form 
$("#form").data('settings', settings); 

```

這種方式的ActiveForm會意識到新的領域,而且將支持他們。

+0

不錯的工作!這有助於解決問題。嘗試一整天來解決這個問題。使用您的解決方案,解決方案在幾分鐘內完成感謝分享 – funktioneer 2014-04-14 14:59:31