Предметная область: Сервисные центры по обслуживанию по республике.
Каждый сервисный центр имеет адрес: area_id, city_id, street_id.
Пытаюсь сделать чтобы при изменении записи, в dropdownlist от activeForm устанавливались значения.
Всё бы ничего, но загрузка данных в dropdownlist идёт из API с другого сервера. Для реализации подобного на странице просмотра всех существующих сервисных центров, я писал js-ку, которая при загрузке страницы, загружала списки областей, городов и улиц в поиск сверху, а дальше, после загрузки, брала значение из GET массива и подставляла его в списки. Делал так:
для страницы service-center/index:
Код: Выделить всё
'use strict';
let city = $('select[name="ServiceCenterSearch[city_id]"]'); //для более короткого имени
let area = $('select[name="ServiceCenterSearch[area_id]"]');
let street = $('select[name="ServiceCenterSearch[street_id]"]');
$_GET['area_id'] = $_GET['ServiceCenterSearch[area_id]']; //для более короткого имени
$_GET['city_id'] = $_GET['ServiceCenterSearch[city_id]'];
$_GET['street_id'] = $_GET['ServiceCenterSearch[street_id]'];
area.change(function () {
city.html('');
city.val('');
loadCities(area.val(), city, undefined, { 'prompt': true });
});
city.change(function () {
street.html('');
street.val('');
loadStreets(city.val(), street, undefined, { 'prompt': true });
});
getAreas();
if (typeof $_GET['area_id'] !== 'undefined' && $_GET['area_id']!=='' && $_GET['area_id']!=='0') {
getCities();
}
if (typeof $_GET['city_id'] !== 'undefined' && $_GET['city_id']!=='' && $_GET['city_id']!=='0') {
getStreets();
}
function getAreas() {
loadAreas(area, $_GET['area_id'], { 'prompt': true });
}
function getCities() {
loadCities($_GET['area_id'], city, $_GET['city_id'], { 'prompt': true });
}
function getStreets() {
loadStreets($_GET['city_id'], street, $_GET['street_id'], { 'prompt': true });
}
в переменной $_GET находятся распарсеные в ассоциативный массив параметры из URL. несмотря на именование, это Javascript. Просто сделал так.
Сами функции loadAreas, loadCities, loadStreets - это функции, которые возвращают промисы с данными.
Вот пример такой функции: (другие сделаны аналогично)
Код: Выделить всё
function loadCities(area = 3, targetElement, defValue, settings = []) {
let fetchCities = fetch(MICRON_ADDR + '/belarus/areas/' + area + '/cities', {
method: 'GET'
});
return fetchCities
.then(response => response.json())
.then(cities => {
console.log(cities);
if (cities) {
let options = [];
if (settings['prompt']) {
options.push(document.createElement('OPTION'));
}
for (let i=0; i<cities.length; ++i) {
let option = document.createElement('OPTION');
option.value = cities[i].cityId;
option.text = cities[i].cityName + ' ' + cities[i].cityTypeName+ ' (' + cities[i].district + ')';
options.push(option);
}
targetElement.html(options);
console.log("Загрузили список городов");
if (typeof defValue !== 'undefined') {
targetElement.val(defValue);
}
}
return cities;
})
.catch(err => {
console.error(err);
});
}
Теперь я начал делать страницу редактирования подобного сервисного центра. У меня всё также есть эти списки, но я не совсем понимаю откуда мне взять данные по модели и как и где их установить для списков как значения по умолчанию. При опять же учёте того, что данные по областям, городам и улицам, грузятся из REST API с другого сервера. Ведь теперь все данные передаются через POST, и модель я нахожу только по переданному в $_GET id сервисного центра по адресу /service-center/update?id=1
Меня сразу смутил и поставил в ступор тот вариант, что я не хочу в GET передавать ещё id области, города, улицы. ведь всё что надо по модели я получаю по id.
мой экшен апдейт:
Код: Выделить всё
public function actionUpdate($id)
{
$modelServiceCenter = $this->findModel($id);
$modelAddress = Address::findOne(['object_id' => $modelServiceCenter->object_id, 'object_type_id' => $modelServiceCenter->object_type_id]);
if ($modelServiceCenter->load(Yii::$app->request->post()) && $modelServiceCenter->save() && $modelAddress->load(Yii::$app->request->post()) && $modelAddress->save()) {
return $this->redirect(['view', 'id' => $modelServiceCenter->object_id]);
}
return $this->render('update', [
'modelServiceCenter' => $modelServiceCenter,
'modelAddress' => $modelAddress
]);
}
Код: Выделить всё
use yii\helpers\Html;
use yii\widgets\ActiveForm;
/* @var $this yii\web\View */
/* @var $modelAddress app\models\Address */
/* @var $form ActiveForm */
?>
<div class="includes-_address">
<div class="row">
<div class="col-md-4">
<?= $form->field($modelAddress, 'area_id')->dropDownList([], [
'class' => 'form-control',
''
]) ?>
</div>
<div class="col-md-4">
<?= $form->field($modelAddress, 'city_id')->dropDownList([], [
'class' => 'form-control',
]) ?>
</div>
<div class="col-md-4">
<?= $form->field($modelAddress, 'street_id')->dropDownList([], [
'class' => 'form-control',
]) ?>
</div>
</div>
<div class="row">
<div class="col-md-2">
<?= $form->field($modelAddress, 'house_number')->input('number') ?>
</div>
<div class="col-md-2">
<?= $form->field($modelAddress, 'house_letter')->dropDownList([], [
'class' => 'form-control',
]) ?>
</div>
<div class="col-md-2">
<?= $form->field($modelAddress, 'housing_number')->input('number') ?>
</div>
<div class="col-md-2">
<?= $form->field($modelAddress, 'housing_letter')->dropDownList([], [
'class' => 'form-control',
]) ?>
</div>
<div class="col-md-2">
<?= $form->field($modelAddress, 'flat_number')->input('number') ?>
</div>
<div class="col-md-2">
<?= $form->field($modelAddress, 'flat_letter')->dropDownList([], [
'class' => 'form-control',
]) ?>
</div>
</div>
<?= $form->field($modelAddress, 'house') ?>
<?= $form->field($modelAddress, 'housing') ?>
<?= $form->field($modelAddress, 'flat') ?>
<?= $form->field($modelAddress, 'post_code')->input('number') ?>
<?= $form->field($modelAddress, 'comment')->textarea([
'class' => 'form-control v-resize',
'rows' => 5,
'cols' => 100,
]) ?>
</div><!-- includes-_address -->
Код: Выделить всё
use yii\helpers\Html;
use yii\bootstrap\ActiveForm;
use app\models\Catalog;
/* @var $this yii\web\View */
/* @var $modelServiceCenter app\models\ServiceCenter */
/* @var $modelAddress app\models\Address */
/* @var $form yii\bootstrap\ActiveForm */
?>
<div class="service-center-form container">
<?php $form = ActiveForm::begin(); ?>
<div class="row">
<div class="col-md-3">
<?= $form->field($modelServiceCenter, 'object_type_id')->dropDownList(Catalog::getServiceCenterTypes()) ?>
</div>
<div class="col-md-4">
<?= $form->field($modelServiceCenter, 'object_name')->textInput(['maxlength' => true]) ?>
</div>
<div class="col-md-4">
<?php
if ($modelServiceCenter->isNewRecord) {
$modelServiceCenter->disable = 0;
} else {
echo $form->field($modelServiceCenter, 'disable')->radioList([
0 => "Нет",
1 => "Да"
], [
'class' => 'ml-2',
'item' => function($index, $label, $name, $checked, $value) {
return Html::radio($name,
$checked,
[
'label' => $label,
'value' => $value,
'name' => $name,
'class' => 'mr-2',
'labelOptions' => ['class' => 'mr-4'],
]);
}
]);
}
?>
</div>
</div>
<?php
if (!$modelServiceCenter->isNewRecord) {
?>
<?= $this->render('..\includes\_address', [
'modelAddress' => $modelAddress,
'form' => $form,
]) ?>
<?php
}
?>
<div class="form-group">
<?= Html::submitButton(($modelServiceCenter->isNewRecord ? 'Создать' : 'Сохранить'), ['class' => ($modelServiceCenter->isNewRecord ? 'btn btn-success' : 'btn btn-primary')]) ?>
</div>
<?php ActiveForm::end(); ?>
</div>
в принципе он нормально включает этот файл, и загружает некоторые данные по адресу - проблем тут нет. но как мне установить значения для выпадающих списков которые должны ещё загрузится, и только потом из модели подставить данные я не знаю и прошу вашей помощи. Спасибо!