2015-04-12 38 views
13

添加一些字段的形式yii2我有一個Yii2 form用ajax

<?php $form = ActiveForm::begin(['id' => 'que']); ?> 
    <?php echo $form->field($model, 'type') 
      ->dropDownList($questionTypes, [ 
       'class' => 'form-control ng-pristine ng-valid ng-touched', 
       'prompt' => 'Select question type', 
       'ng-model' => 'que.type', 
       'ng-change' => 'addAnswerOptions(que);', 
     ]); 
    ?> 
<?php ActiveForm::end(); ?> 

上選擇下拉值的基礎上,我有一些更多的字段添加到相同型號的相同的形式。什麼字段將被添加,完全取決於下拉值。

我該怎麼做?

+0

我絕對可以幫忙,但需要更多的信息。你是否事先知道你想在每個場景中顯示哪些字段?或者,在這種情況下,用戶可以通過單擊按鈕來添加額外的字段(因此,我們不知道每個案例中會有多少字段) –

+0

是的,我知道每個字段需要提前添加場景。它就像'type == 1'我必須添加2個字段(這也是模型的一部分)命名爲'option1','option2','type == 2'我必須添加4個字段'option1 ,option2,option3,option4' –

回答

5

從你給出的信息是我會建議。

1)動態 - 沒有AJAX

建立你的形式與你所需要的,只包含每個「方案」在一個單獨的div喜歡的所有字段如下:

<?php $form = ActiveForm::begin(['id' => 'que']); ?> 
    <?php echo $form->field($model, 'type') 
      ->dropDownList($questionTypes, [ 
       'class' => 'form-control ng-pristine ng-valid ng-touched', 
       'prompt' => 'Select question type', 
       'ng-model' => 'que.type', 
       'ng-change' => 'addAnswerOptions(que);', 
     ]); 
    ?> 
    <div class="form-option" data-type="class" style="display:none;"> 
     <?php 
      // ... fields here for case type == class 
     ?> 
    </div> 
    <div class="form-option" data-type="prompt" style="display:none;"> 
     <?php 
      // ... fields here for case type == prompt 
     ?> 
    </div> 
    <div class="form-option" data-type="ng-model" style="display:none;"> 
     <?php 
      // ... fields here for case type == ng-model 
     ?> 
    </div> 
    <div class="form-option" data-type="ng-change" style="display:none;"> 
     <?php 
      // ... fields here for case type == ng-change 
     ?> 
    </div> 
<?php ActiveForm::end(); ?> 

那麼你將要根據選擇的下拉選項,註冊Javascript代碼以顯示正確的區塊。 貝婁是使用JQuery一個例子:

$(document).ready(function(){ 
    $('select.form-control').change(function(){ 
     $('.form-option').hide(); // hide all options if an option is showing 
     var index = $('select.form-control').index(); 
     $('div[data-type="'+index+'"]').show(); //show the correct fields 
    }); 
}); 

如果你打算走這條路,我建議你使用AJAX validation爲表單。它將避免你在頁面重新加載時處理頭痛。

表單提交後,您將不得不處理控制器中的每個案例。您可以使用一組簡單的if()語句來檢查下拉值。或者您可以根據下拉值設置您的型號validation scenario

這樣做的好處是它會更快,您將能夠利用ActiveForm。缺點是你需要知道你想要爲每個選項顯示哪些字段,並且它不允許你累積n字段數,當你不知道多少n是。

2)使用Ajax

在要使用AJAX調用加載額外的表單字段,你將不得不作出一個controller/action組合將返回取決於您通過類型的字段事件在GET

這個動作會產生你想要顯示的字段的html。這裏有一個例子:

public function actionAjaxFields($type) 
{ 
    $html = ''; 
    if($type == "class") 
    { 
     $html .= Html::textInput('Field1'); 
    } 
    elseif($type == "prompt") 
    { 
     $html .= Html::textInput('Field2'); 
    } 
    else 
    { 
     // etc... 
    } 
    return $html; 
} 

請注意,您也可以通過用戶ID,以這種方法,讓您生成一個模型,並用Html::activeTextInput(),然而,你將不能夠採取的ActiveForm功能。

一旦做到這一點,你應該在功能綁定到下拉的變化情況和使用的東西線沿線的:

var responsePromise = $http.get("controller/ajax-fields", {params: {type: <type-from-dropdown>}}); 

不幸的是,我不知道很多關於angularjs所以這是的程度我可以在JavaScript方面給予的幫助。我確信有足夠多的關於綁定事件的google/stackoverflow的信息,並且在angularjs中將數據附加到DOM以讓您運行。

讓我知道我是否可以在Yii2方面獲得任何額外幫助。

+0

我不希望它用'jquery'來做,我想用ajax實時加載它們。 –

+0

好,所以你想要實時加載這個。但是,您是否使用jQuery的JavaScript庫來進行Ajax調用,或者根本沒有?另外,如果使用Ajax,您將無法利用$ form。你應該意識到這一點。 –

+0

實際上,我使用'angularjs'來創建'ajax'請求並加載字段。 –