2015-04-12 13 views
13

Ho un Yii2 form:L'aggiunta di alcuni altri campi al modulo in yii2 utilizzando 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(); ?> 

Sulla base del valore di discesa selezionato, devo aggiungere più campi alla stessa forma dello stesso modello. Quali campi verranno aggiunti, dipende totalmente dal valore dell'elenco a discesa.

Come posso fare questo?

+0

Posso sicuramente aiutare con questo, ma avrebbe bisogno di un po 'più di informazioni. Sai in anticipo quali campi vuoi visualizzare su ogni scenario? Oppure è un caso in cui l'utente può aggiungere campi aggiuntivi facendo clic su un pulsante (quindi non sappiamo esattamente quanti campi ci saranno in ogni caso) –

+0

Sì, conosco i campi che devono essere aggiunti in anticipo per ogni scenario. È come se 'type == 1' Devo aggiungere 2 campi (che sono anche la parte del modello) nominati come' option1', 'option2', per' type == 2' Devo aggiungere altri 4 campi 'option1 , option2, option3, option4' –

risposta

5

Dalle informazioni fornite qui è quello che vorrei suggerire.

1) dinamica - non AJAX

Costruisci il modulo con tutti i campi necessari, basta contiene ogni "scenario" in un separato div come segue:

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

poi si vuole per registrare il codice Javascript per visualizzare i blocchi corretti a seconda dell'opzione a discesa selezionata. Bellow è un esempio utilizzando 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 
    }); 
}); 

Se avete intenzione di andare in questo modo vi consiglio di usare AJAX validation per il modulo. Eviterà di dover affrontare un mal di testa nella pagina di ricarica.

Una volta inviato il modulo, dovrai gestire ogni caso nel controller. Puoi utilizzare una semplice serie di istruzioni if() che controllano il valore dell'elenco a discesa. Oppure puoi impostare il tuo modello validation scenario in base al valore di discesa.

Il vantaggio di questo è che sarà più veloce e sarete in grado di sfruttare ActiveForm. i contro sono che è necessario sapere quali campi si desidera visualizzare per ciascuna opzione e non consente di accumulare il numero di campi n quando non si conosce quanto sia n.

2) Utilizzo di Ajax

Nel caso in cui si desidera utilizzare chiamate AJAX per caricare i campi del modulo in più si dovrà fare una combinazione controller/action che restituirà i campi a seconda del tipo che si passa nel GET

Questa azione genererà l'html dei campi che si desidera visualizzare. Ecco un esempio:

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

Nota che si può anche passare un ID utente a questo metodo che vi permetterà di generare un modello e utilizzare Html::activeTextInput(), tuttavia non sarà in grado di approfittare delle ActiveForm funzionalità.

Una volta fatto questo, si dovrebbe associare una funzione per l'evento di modifica della discesa e usare qualcosa sulla falsariga di:

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

Purtroppo non so molto di angularjs quindi questo è l'estensione della l'aiuto che posso dare sul lato javascript delle cose. Sono sicuro che ci sono più che sufficienti informazioni su google/stackoverflow sugli eventi di associazione e sull'aggiunta di dati al DOM in angularjs per farti funzionare.

Fammi sapere se posso essere di ulteriore aiuto sul lato Yii2.

+0

Non voglio farlo con 'jquery', voglio caricarli in tempo reale usando ajax. –

+0

Ok, quindi vuoi caricarlo in tempo reale. Ma stai usando una libreria JavaScript come jquery per le tue chiamate Ajax o per niente? Inoltre, se si utilizza Ajax non si sarà in grado di sfruttare $ form. Dovresti essere reso consapevole di questo. –

+0

effettivamente, sto usando 'angularjs' per fare una richiesta' ajax' e caricare i campi. –

Problemi correlati