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.
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) –
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' –