How to Create a Dependent Dropdown in Yii2?
Add to BookmarkProblem Statement
- Create a form with dependent dropdowns:
- Select Country, then it should update States
- Select State, then it should update Cities
Solution Overview
We'll cover 4 different methods to solve this, each with increasing levels of abstraction and flexibility.
Methods Covered
Method # | Approach | Uses JS | Uses Widget | Return Format | Suitable For |
---|---|---|---|---|---|
1 | jQuery Ajax + JSON string | Yes | No | JSON string | Beginners, learning |
2 | Yii2-style JSON response | Yes | No | JSON object | Clean apps |
3 | Kartik DepDrop | Minimal | Yes | JSON object | Production use |
4 | Inline onchange + HTML echo | Yes | No | Raw HTML | Fast dev/search forms |
Method 1: Basic jQuery Ajax + JSON String
Controller (SiteController.php
)
public function actionGetStates($country_id)
{
$states = State::find()
->where(['country_id' => $country_id])
->asArray()
->all();
return \yii\helpers\Json::encode($states);
}
View
<?= $form->field($model, 'country_id')->dropDownList(
ArrayHelper::map(Country::find()->all(), 'id', 'name'),
['prompt' => 'Select Country', 'id' => 'country-id']
) ?>
<?= $form->field($model, 'state_id')->dropDownList([], [
'prompt' => 'Select State',
'id' => 'state-id'
]) ?>
JavaScript
$('#country-id').on('change', function () {
$.get('/site/get-states?country_id=' + $(this).val(), function (data) {
let options = '<option value="">Select State</option>';
$.each(JSON.parse(data), function (i, item) {
options += '<option value="' + item.id + '">' + item.name + '</option>';
});
$('#state-id').html(options);
});
});
Method 2: Yii2 Native JSON Response
Controller
public function actionGetStates($country_id)
{
Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
return ArrayHelper::map(
State::find()->where(['country_id' => $country_id])->all(),
'id',
'name'
);
}
View
<?= $form->field($model, 'country_id')->dropDownList(
ArrayHelper::map(Country::find()->all(), 'id', 'name'),
['prompt' => 'Select Country', 'id' => 'country-id']
) ?>
<?= $form->field($model, 'state_id')->dropDownList([], [
'prompt' => 'Select State',
'id' => 'state-id'
]) ?>
JavaScript
$.get('/site/get-states?country_id=' + $(this).val(), function (data) {
let options = '<option value="">Select State</option>';
$.each(data, function (id, name) {
options += `<option value="${id}">${name}</option>`;
});
$('#state-id').html(options);
});
Method 3: Using Kartik DepDrop
Widget
Install Kartik DepDrop
composer require kartik-v/yii2-widget-depdrop "@dev"
Controller
public function actionSubcat()
{
Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
$out = [];
if (isset($_POST['depdrop_parents'])) {
$parents = $_POST['depdrop_parents'];
if ($parents !== null) {
$country_id = $parents[0];
$out = State::find()
->where(['country_id' => $country_id])
->select(['id AS id', 'name AS name'])
->asArray()
->all();
return ['output' => $out, 'selected' => ''];
}
}
return ['output' => '', 'selected' => ''];
}
View
use kartik\depdrop\DepDrop;
use yii\helpers\Url;
<?= $form->field($model, 'country_id')->dropDownList(
ArrayHelper::map(Country::find()->all(), 'id', 'name'),
['id' => 'country-id']
); ?>
<?= $form->field($model, 'state_id')->widget(DepDrop::classname(), [
'options' => ['id' => 'state-id'],
'pluginOptions' => [
'depends' => ['country-id'],
'placeholder' => 'Select State...',
'url' => Url::to(['/site/subcat'])
]
]); ?>
Method 4: Inline Ajax in DropDown onchange
(Returns Raw HTML)
View
<?= $form->field($model, 'state_id')->dropDownList(\yii\helpers\ArrayHelper::map(MasterState::find()->all(), 'id', 'state_name'),
[
'prompt' => 'Select State',
'onchange' => '
$.get("/site/citylist?state_id=" + $(this).val(), function(data) {
$("select#city_id").html(data);
});
'
]
); ?>
<?= $form->field($model, 'city_id')->dropDownList(
\yii\helpers\ArrayHelper::map(MasterCity::find()->where(['state_id' => $model->state_id])->all(), 'city_id', 'city_name'),
['prompt' => 'Select City','id'=>'city_id']
); ?>
Controller
public function actionCitylist($state_id)
{
$cities = MasterCity::find()
->where(['state_id' => $state_id])
->all();
echo "<option value=''>Select City</option>";
foreach ($cities as $city) {
echo "<option value='" . $city->id . "'>" . $city->city_name . "</option>";
}
}
Conclusion
- Use Method 1 or 2 for learning and control.
- Use Method 3 (DepDrop) for cleaner, production-ready forms.
- Use Method 4 when building quick filters or search tools.
Prepare for Interview
- SQL Interview Questions for 2–5 Years Experience
- SQL Interview Questions for 1–2 Years Experience
- SQL Interview Questions for 0–1 Year Experience
- SQL Interview Questions for Freshers
- Design Patterns in Python
- Dynamic Programming and Recursion in Python
- Trees and Graphs in Python
- Linked Lists, Stacks, and Queues in Python
- Sorting and Searching in Python
- Debugging in Python
- Unit Testing in Python
- Asynchronous Programming in PYthon
- Multithreading and Multiprocessing in Python
- Context Managers in Python
- Decorators in Python
Random Blogs
- Best Platform to Learn Digital Marketing in Free
- 15 Amazing Keyword Research Tools You Should Explore
- Grow your business with Facebook Marketing
- Important Mistakes to Avoid While Advertising on Facebook
- Downlaod Youtube Video in Any Format Using Python Pytube Library
- Transforming Logistics: The Power of AI in Supply Chain Management
- The Ultimate Guide to Artificial Intelligence (AI) for Beginners
- Types of Numbers in Python
- Python Challenging Programming Exercises Part 2
- Python Challenging Programming Exercises Part 1
- AI & Space Exploration – AI’s Role in Deep Space Missions and Planetary Research
- AI in Marketing & Advertising: The Future of AI-Driven Strategies
- Loan Default Prediction Project Using Machine Learning
- Top 10 Blogs of Digital Marketing you Must Follow
- Government Datasets from 50 Countries for Machine Learning Training
Datasets for Machine Learning
- Amazon Product Reviews Dataset
- Ozone Level Detection Dataset
- Bank Transaction Fraud Detection
- YouTube Trending Video Dataset (updated daily)
- Covid-19 Case Surveillance Public Use Dataset
- US Election 2020
- Forest Fires Dataset
- Mobile Robots Dataset
- Safety Helmet Detection
- All Space Missions from 1957
- OSIC Pulmonary Fibrosis Progression Dataset
- Wine Quality Dataset
- Google Audio Dataset
- Iris flower dataset
- Artificial Characters Dataset