зависимый раскрывающийся список yii2. Как сделать?

могу ли я создать зависимый выпадающий список в yii2?

У меня есть две таблицы:

'id','name_country"
'id','name_city','country_id'

и иметь два метода в моей модели:

public function getCountryList()
{
$models = NetCountry::find()->asArray()->all();
return ArrayHelper::map($models, 'id', 'country_name');
} 

а также

public function getCityList($parent_id) { 
$models = \common\models\City::find()->where(['parent_id' => $country_id])->asArray()->all();
return ArrayHelper::map($models, 'id', 'name_city','country_id');
}

У меня есть первое поле:

 <?= $form->field($model, 'country')->dropDownList($model->countryList),['id'=>'parent_id'];

и второй

<?= $form->field($model, 'city')->dropDownList($model->cityList);

Мне нужно «передать» parent_id контроллеру и вернуть city_list с помощью AJAX (с JSON).

Как я могу это сделать? Я видел пример в Yii1, но как насчет Yii2?


person Slip    schedule 30.05.2014    source источник


Ответы (4)


используйте расширение krajee для зависимого раскрывающегося списка

Подробности здесь раскрывающийся список Krejee для yii2

или следуйте следующим инструкциям:

Установите расширение через композитор:

 $ php composer.phar require kartik-v/dependent-dropdown "dev-master"

На ваш взгляд:

  use kartik\widgets\DepDrop;

// Normal parent select
echo $form->field($model, 'cat')->dropDownList($catList, ['id' => 'cat-id']);

// Dependent Dropdown
echo $form->field($model, 'subcat')->widget(DepDrop::classname(), [
    'options' => ['id' => 'subcat-id'],
    'pluginOptions' => [
        'depends' => ['cat-id'],
        'placeholder' => 'Select...',
        'url' => Url::to(['/site/subcat'])
    ]
]);

// КОНТРОЛЛЕР

public function actionSubcat() {
$out = [];
if (isset($_POST['depdrop_parents'])) {
$parents = $_POST['depdrop_parents'];
if ($parents != null) {
$cat_id = $parents[0];
$out = self::getSubCatList($cat_id);
// the getSubCatList function will query the database based on the
// cat_id and return an array like below:
// [
// ['id'=>'<sub-cat-id-1>', 'name'=>'<sub-cat-name1>'],
// ['id'=>'<sub-cat_id_2>', 'name'=>'<sub-cat-name2>']
// ]
echo Json::encode(['output'=>$out, 'selected'=>'']);
return;
}
}
echo Json::encode(['output'=>'', 'selected'=>'']);
}
person Neophile    schedule 03.06.2014
comment
как написать эту функцию getSubCatList(), если у меня есть извлечение данных из базы данных - person john sunam; 16.01.2016
comment
убедитесь, что вы используете use yii\helpers\Json; в контроллере и в вашей модели вы можете использовать $data = Contact::find()-›where(['parent_id'=›$id])-›select(['id','name'])-›asArray ()->все(); $значение = (количество($данные) == 0) ? ['' =› ''] : $данные; вернуть $значение; - person open-ecommerce.org; 21.04.2017

создание зависимого раскрывающегося списка в yii2 без использования каких-либо сторонних библиотек так же просто, как и в yii1. вам нужно попробовать следующий код, написанный ниже, в соответствии с вашими требованиями. используйте gii для создания моделей, представлений, контроллера для соответствующих таблиц.

предположим, что есть две таблицы, такие как страна, город, как вы написали. затем напишите следующий код в файл представлений для одного контроллера (например, страны):

         <?php
                    use yii\helpers\ArrayHelper;
                    use yii\widgets\ActiveForm;
                    ?>
               <div>
            <?php
     $dataCountry=ArrayHelper::map(\app\models\Country::find()->
     asArray()->all(),'id', 'name');    
                  $form = ActiveForm::begin();
                echo $form->field($model, 'id')->dropDownList($dataCountry, 
                                     ['prompt'=>'-Choose a Name-',
                                         'class'=>'adjust',
                          'onchange'=>'
             $.post("'.Yii::$app->urlManager->createUrl('city/lists?id=').
           '"+$(this).val(),function( data ) 
                   {
                              $( "select#city" ).html( data );
                            });
                        ']); 

                $dataPost=ArrayHelper::map(\app\models\City::find()->
                 asArray()->all(), 'id', 'city');
              echo $form->field($model, 'id')
                    ->dropDownList(
                        $dataPost,   
                         ['id'=>'city',
                             'class'=>'adjust'
                             ]
                    );
                 ActiveForm::end(); 
               ?>
            </div>

и после этого в другом контроллере для города напишите следующий код:

 <?php

namespace app\controllers;

class CityController extends \yii\web\Controller
{
        public function actionLists($id)
      {
         //echo "<pre>";print_r($id);die;
         $countPosts = \app\models\City::find()
         ->where(['country_id' => $id])
         ->count();

         $posts = \app\models\City::find()
         ->where(['country_id' => $id])
         ->orderBy('id DESC')
         ->all();

         if($countPosts>0){
         foreach($posts as $post){

         echo "<option value='".$post->id."'>".$post->city."</option>";
         }
         }
         else{
         echo "<option>-</option>";
         }

 }
}

затем запустите URL-адрес, он работает!

редактировать: фиксированная конструкция URL. HTTP-запросы теперь будут работать.

person sprytechies    schedule 23.08.2014

Вы можете сделать это без какого-либо виджета вручную:

сделайте свою активную форму следующим образом:

<?=  $form->field($model, 'nameofyourmodel')->dropDownList(
    ArrayHelper::map(\app\models\nameofyourmodel::find()->all(), 'id', 'name'),
    [
        'prompt'=>'smth',
        'onchange' => '
            $.post(
                "' . Url::toRoute('getoperations') . '", 
                {id: $(this).val()}, 
                function(res){
                    $("#requester").html(res);
                }
            );
        ',

    ]
); ?>

а вот вторая форма, которая получает идентификатор от первой модели:

 <?= $form->field($model,'nameofyourmodel')->dropDownList(
    [],
    [
        'prompt' => 'smth',
        'id' => 'requester'
    ]
); ?>

и последнее действие - сделать функциональность в контроллере для сопоставления двух идентификаторов и отправить их в вашу модель:

public function actionGetoperations()
{
    if ($id = Yii::$app->request->post('id')) {
        $operationPosts = \app\models\firstmodel::find()
            ->where(['id' => $id])
            ->count();

        if ($operationPosts > 0) {
            $operations = \app\models\secondmodel::find()
                ->where(['firstmodelid' => $id])
                ->all();
            foreach ($operations as $operation)
                echo "<option value='" . $operation->firstmodelid. "'>" . $operation->name . "</option>";
        } else
            echo "<option>-</option>";

    }
}
person G'ulomjon Sulaymonov    schedule 04.10.2018
comment
Спасибо ! именно то, что я хотел. не забудьте включить это в свое представление use yii\helpers\Url; - person Shuhad zaman; 07.09.2019

Приведенный выше код работает неправильно. В строке есть ошибка

$.post("'.Yii::$app->urlManager->createUrl('city/lists&id=').'"+$(this).val(),function( data ) 

консоль показывает ошибку: Not Found (# 404): невозможно разрешить запрос: subcategory/lists&id=54

есть ли какое-либо решение для этого, мой контроллер выглядит следующим образом

public function actionLists($id)
      {
         $posts = SubCategory::find()
         ->where(['category_id' => $id])
         ->orderBy('id DESC')
         ->all();

         if($posts){
         foreach($posts as $post){

         echo "<option value='".$post->id."'>".$post->name."</option>";
         }
         }
         else{
         echo "<option>-</option>";
         }

    }

когда я удаляю идентификатор из URL-адреса и жестко запрограммирую его в контроллере, он работает правильно.

Я нашел решение для этого, пожалуйста, измените свое мнение следующим образом

 <?= $form->field($model, 'category_id')->dropDownList($data,['prompt'=>'-Choose a Category-',

                                                            'onchange'=>'
             $.get( "'.Url::toRoute('product/catlists').'", { id: $(this).val() } )
                            .done(function( data )
                   {
                              $( "select#product-sub_categoryid" ).html( data );
                            });
                        ']); ?> 

и такой контроллер

public function actionCatlists($id)
    {
        $mymodel = new Product ();
        $size = $mymodel->modelGetCategory ( 'product_sub_category',$id );
        if($size){
            echo '<option value="">Choose Sub category</option>';
            foreach($size as $post){
                echo "<option value='".$post['id']."'>".$post['name']."</option>";
            }
        }
        else{
            echo '<option value="0">Not Specified</option>';
        }

    }

не забудьте включить это в свой вид

use yii\helpers\Url;
person Premjith    schedule 20.01.2015