0
votes

I'm trying to make a dependend dropDownList in Yii2. I'm trying to use DepDrop Widget, but I can't understand how to edit the code according to my situation. I have 1 model and inside of it I need to make category dropdown list and according to the category_id, the next dropDownList should be Item. (F.e If I select category 1, the Item should be Item1 and so on).

I guess that extension only can do dropdowns of the same model? I'm new to Yii2, so.

My view file:

<div class="site-create">

<?php $form = ActiveForm::begin(); ?>

    <?= $form->field($model, 'code') ?>
    <?= $form->field($category, 'id')->dropDownList($category, ['id'=>'category-id']); ?>
    <?= $form->field($item, 'subcat')->widget(DepDrop::Item(), [
         'options'=>['id'=>'item-id'],
        'pluginOptions'=>[
         'depends'=>['category-id'],
        'placeholder'=>'Select...',
        'url'=>Url::to(['/site/subcat'])
        ]
   ]); ?>

My $model is different model from $category and $item. I set those variables to use a different model in the action

Here is my action:

    public function actionSubcat() {
    $category = new Category();
    $item = new Item();
    $out = [];
    if (isset($_POST['depdrop_parents'])) {
        $parents = $_POST['depdrop_parents'];
        if ($parents != null) {
            $cat_id = $parents[0];
            $out = self::getSubCatList($cat_id); 
            echo Json::encode(['output'=>$out, 'selected'=>'']);

        return $this->render('create', [
                'category' => $category,
                'item' => $item,
            ]);
        }
    }
    echo Json::encode(['output'=>'', 'selected'=>'']);
}
}

Now I'm getting the error message that the $category variable is undefined. Could someone explain me what I'm doing wrong?

2

2 Answers

0
votes

i suggest using knockoutjs for doing this. i answered a similar question here knockout example is here (category > product)

html:

<select data-bind="options: data, value: selected, optionsText: 'title', optionsCaption: '---'"></select>
<select data-bind="options: dependent"></select>

javascript:

<script>
    function viewmodel() {
        var self = this;

        this.data = [
            { title: 'title a', items: ['a1', 'a2', 'a3'] },
            { title: 'title b', items: ['b1', 'b2', 'b3'] },
            { title: 'title c', items: ['c1', 'c2', 'c3'] }
        ];

        this.selected  = ko.observable();
        this.dependent = ko.computed(function() {
            return ((self.selected() || {}).items || []);
        });

    }

    $(document).ready(function() {
        ko.applyBindings(new viewmodel());
    });
</script>

you can still use $form->field, just add 'data-bind' attribute as inputOption. if you want to use the field's default values, Json::encode those key-value-pairs and create the viewmodel like this:

ko.applyBindings(new viewmodel(<?= Json::encode($data) ?>));

using those parameters is javascript manual labour

0
votes

Actually you dont need any Widgets or Plugins. In yii2 you can easily do Dependent Dropdown list here is example:

echo $form->field($search,'category')->dropDownList(
    ArrayHelper::map(
        \app\models\Category::find()->all(),
        'id','name'
    ),
    [
        'prompt' => Yii::t('app','choose_city'),
        'onchange'=>'
        $.get( "'.Yii::$app->urlManager->createUrl('site/dropdown?id=').'"+$(this).val(), function( data ) {
        $( "select#subcat" ).html( data );
        })'
    ]
);
echo $form->field($search, 'sub_category', ['inputOptions'=>['id'=>'subcat',]])->dropDownList([]);

after that you need to create action for returning action. Example:

 public function actionDropdown($id)
{
    $countPosts = \app\models\SubCategory::find()
        ->where(['category_id' => $id])
        ->count();

    $posts =  \app\models\SubCategory::find()
        ->where(['category_id' => $id])
        ->orderBy('name ASC')
        ->all();
    echo "<option value=''>-</option>";
    if($countPosts>0){
        foreach($posts as $post){
            echo "<option value='".$post->id."'>".Yii::t('app',$post->name)."</option>";
        }
    }

}

thats all.