2015-04-12 12 views
13

Tôi có một Yii2 form:Thêm một số lĩnh vực nhiều mẫu tại yii2 sử dụng 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(); ?> 

Trên cơ sở giá trị thả xuống chọn, tôi có thêm một số lĩnh vực hơn với hình thức tương tự của cùng một mô hình. Trường nào sẽ được thêm vào, hoàn toàn phụ thuộc vào giá trị thả xuống.

Tôi làm cách nào để thực hiện việc này?

+0

Tôi chắc chắn có thể trợ giúp với điều này nhưng sẽ cần thêm một chút thông tin. Bạn có biết trước các trường nào bạn muốn hiển thị trên mỗi trường hợp không? Hoặc đây là trường hợp người dùng có thể thêm các trường bổ sung bằng cách nhấp vào nút (nghĩa là chúng tôi không biết chính xác có bao nhiêu trường trong mỗi trường hợp) –

+0

Vâng. Tôi biết các trường cần được thêm trước cho mỗi trường kịch bản. Nó giống như nếu 'type == 1' tôi phải thêm 2 trường (cũng là phần của mô hình) có tên là' option1', 'option2', cho' type == 2' tôi phải thêm 4 trường 'option1 , option2, option3, option4' –

Trả lời

5

Từ thông tin bạn đưa ra ở đây là những gì tôi sẽ đề xuất.

1) Năng động - không AJAX

Xây dựng hình thức của bạn với tất cả các lĩnh vực bạn cần, chỉ chứa mỗi "kịch bản" trong một riêng biệt div thích sau:

<?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(); ?> 

Sau đó, bạn sẽ muốn để đăng ký mã Javascript để hiển thị các khối chính xác tùy thuộc vào tùy chọn thả xuống nào đã được chọn. Bellow là một ví dụ sử dụng 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 
    }); 
}); 

Nếu bạn đang đi để đi theo con đường này, tôi đề nghị bạn sử dụng AJAX validation cho mẫu của bạn. Nó sẽ tránh bạn phải đối phó với một nhức đầu trên trang tải lại.

Khi biểu mẫu của bạn được gửi, bạn sẽ phải xử lý từng trường hợp trong bộ điều khiển của mình. Bạn có thể sử dụng một tập hợp đơn giản gồm các câu lệnh if() kiểm tra giá trị thả xuống. Hoặc bạn có thể đặt mô hình validation scenario theo giá trị thả xuống.

Lợi thế của việc này là nó sẽ nhanh hơn và bạn sẽ có thể tận dụng lợi thế của ActiveForm. khuyết điểm là bạn cần phải biết trường nào bạn muốn hiển thị cho từng tùy chọn và không cho phép bạn tích lũy số lượng trường n khi bạn không biết số lượng n là bao nhiêu.

2) Sử dụng Ajax

Trong trường hợp bạn muốn sử dụng ajax gọi để nạp các trường mẫu có thêm bạn sẽ phải thực hiện một sự kết hợp controller/action rằng sẽ trở lại với lĩnh vực tùy thuộc vào loại mà bạn vượt qua trong số GET

Tác vụ này sẽ tạo ra html của các trường bạn muốn hiển thị. Dưới đây là một ví dụ:

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

Lưu ý rằng bạn cũng có thể vượt qua một id người dùng phương pháp này sẽ cho phép bạn để tạo ra một mô hình và sử dụng Html::activeTextInput(), tuy nhiên bạn sẽ không thể tận dụng lợi thế của các tính năng ActiveForm.

Một khi điều này được thực hiện, bạn nên gắn một chức năng để sự kiện thay đổi của danh sách thả xuống và sử dụng một cái gì đó dọc theo dòng:

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

Đáng tiếc là tôi không biết nhiều về angularjs vì vậy đây là mức độ sự giúp đỡ tôi có thể đưa ra bên javascript của mọi thứ. Tôi chắc rằng có đủ thông tin trên google/stackoverflow về các sự kiện ràng buộc và thêm dữ liệu vào DOM trong angularjs để giúp bạn chạy.

Hãy cho tôi biết nếu tôi có thể trợ giúp thêm về phía Yii2.

+0

Tôi không muốn nó làm với 'jquery', tôi muốn tải chúng vào thời gian thực bằng ajax. –

+0

Ok vì vậy bạn muốn tải nội dung này theo thời gian thực. Nhưng bạn đang sử dụng một thư viện JavaScript như jquery cho các cuộc gọi Ajax của bạn hay không? Ngoài ra, nếu sử dụng Ajax, bạn sẽ không thể tận dụng lợi thế của biểu mẫu $. Bạn nên được nhận thức về điều này. –

+0

thực sự, tôi đang sử dụng 'angularjs' để tạo một trường yêu cầu và tải' ajax'. –

Các vấn đề liên quan