We'll cover 4 different methods to solve this, each with increasing levels of abstraction and flexibility.
| 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 |
SiteController.php)public function actionGetStates($country_id)
{
$states = State::find()
->where(['country_id' => $country_id])
->asArray()
->all();
return \yii\helpers\Json::encode($states);
}<?= $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'
]) ?>$('#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);
});
});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'
);
}<?= $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'
]) ?>$.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);
});DepDrop Widgetcomposer require kartik-v/yii2-widget-depdrop "@dev"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' => ''];
}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'])
]
]); ?>onchange (Returns Raw HTML)<?= $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']
); ?>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>";
}
}Sign in to join the discussion and post comments.
Sign in