Tzvibe
Tzvibe

Reputation: 369

Yii2 Dependent Drop down list not working

I have a Customer fiels that is dependent on a Project field.
In my form, I have a dropdown for project, and I need my second dropdown of customers to change dynamically according to the project.
I find the solution in a few places on the web, but the array doesn't change.
Can anyone help with this?

My form:

$dataProject=ArrayHelper::map(Project::find()->asArray()->all(), 'id', 'name');
  echo $form->field($model, 'project_id')->dropDownList($dataProject,
       ['prompt'=>'-Choose a Project-',
       'onchange'=>'
            $.post( "'.Yii::$app->urlManager->createUrl('customer/lists?id=').'"+$(this).val(), function( data ) {
            $( "select#title" ).html( data );
       });
  ']);
  $dataPost=ArrayHelper::map(Customer::find()->asArray()->all(), 'id', 'first_name');
  echo $form->field($model, 'customer_id')
       ->dropDownList(
            $dataPost,
            ['id'=>'title']
       );

Code in the Customer controller:

public function actionLists($id) {
 $countPosts = Customer::find()
      ->where(['project_id' => $id])
      ->count();
 $posts = Customer::find()
      ->where(['project_id' => $id])
      ->orderBy('id DESC')
      ->all();
 if($countPosts>0) {
      foreach($posts as $post){
           echo "<option value='".$post->id."'>".$post->first_name."</option>";
      }
 }
 else{
      echo "<option>-</option>";
 }
}

Upvotes: 1

Views: 929

Answers (1)

Muhammad Omer Aslam
Muhammad Omer Aslam

Reputation: 23738

So far the best way to add the dropdown options to the select when you have the access to jquery is to use .each() but you need to provide the options from the controller/action as json rather than creating the html and then adding the html to the dropdown.

Then you are using $.post and adding query string with the url for the id whereas you can use the data option to send the id.

Change your onchange function to the following

'onchange'=>'
     $.post( "'.Yii::$app->urlManager->createUrl('/customer/lists').'", {id:$(this).val()},function( data ) {

         //this will clear the dropdown of the previous options

         $("#title").children("option").remove();

         //optionally you can use the following if you have a placeholder in the dropdown so that the first option is not removed
         //$("#title").children("option:not(:first)").remove();

         $.each(data, function(key, value) {

         $("#title")
             .append($("<option></option>")
             .attr("value",key)
             .text(value)); 
         });
});

Then you are querying 2 times to the Customer table once for count all records and one for all the lists of customers

$countPosts = Customer::find()
      ->where(['project_id' => $id])
      ->count();
$posts = Customer::find()
      ->where(['project_id' => $id])
      ->orderBy('id DESC')
      ->all();

you can simply query for the customers and use php:count() function on the result set $posts to count the total number of records.

  $posts = Customer::find()
          ->where(['project_id' => $id])
          ->orderBy('id DESC')
          ->all();
  $countPosts = count($post);

But we are not going to need the count anyway this was just for information, change your action actionLists() to below and remove the parameter $id now as we are sending the id with post.

public function actionLists() {
    //set the response format to JSON
    Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;

    //get the id 
    $id = Yii::$app->request->post ( 'id' );

    $posts = Customer::find ()
            ->where ( [ 'project_id' => $id ] )
            ->orderBy ( 'id DESC' )
            ->all ();

    return ArrayHelper::map ( $posts , 'id' , 'first_name' );
}

Apart from doing all the above you should get used to of using available resources in form of extensions or plugins that are widely available one of them is Kartik/DepDropdown which does the same thing with a lot of less pain of writing the javascript and just providing data from server-side.

Upvotes: 2

Related Questions