Динамическое добавление полей в форму, сохранение в связанной модели. yii 1.1
Доброго дня, знатоки. Я недавно начал изучать php и yii 1.1, но уже взялся за создание веб-приложения для оптимизации процессов своего бизнеса. Само собой, сталкиваюсь со сложными для меня моментами. Следующий завел меня в тупик.
Есть две таблицы. "Клиенты" и "Номера клиентов". Сделано это для того и потому, что у клиентов может быть как один, так и множество контактных номеров. В таблице номера "Номера клиентов" есть два поля "phone" - PK и "clientId" - FK.
Модели генерировал при помощи gii. Есть такие связи:
В модели "Клиенты":
'clientPhones' => array(self::HAS_MANY, 'ClientPhone', 'clientId')
В модели "Номера клиентов":
'client' => array(self::BELONGS_TO, 'Client', 'clientId')
Задача:
В форме добавления клиента должно отображаться одно поле для ввода телефона, а также кнопка, при нажатии на которую будут добавляться новые поля для дополнительных номеров. Также нужна кнопка для удаления добавленного поля. Все это дело нужно сохранять в БД.
В случае редактирования клиента необходимо отобразить поля для каждого из имеющихся номеров телефонов для этого клиента с возможностью редактирования, добавления и удаления отдельных записей номеров телефонов.
Заранее спасибо за помощь!
UPD: Нашел все-таки решение моей задачи, правда собрав много кусочков информации из сети. Получилась такая солянка.
Контролер ClientController.php:
public function actionCreate()
{
$model=new Client;
$modelPhone = new ClientPhone;
if(isset($_POST['Client']))
{
$model->attributes=$_POST['Client'];
if($model->save())
$this->redirect(array('view','id'=>$model->id));
}
$this->render('create',array(
'model'=>$model,
'modelPhone'=>$modelPhone,
));
}
...
public function actionUpdate($id)
{
$model=$this->loadModel($id);
$modelPhone=$this->loadModelsPhone($id);
if(isset($_POST['Client']))
{
if(isset($_POST['ClientPhone']))
{
$this->savePhones($modelPhone);
}
$model->attributes=$_POST['Client'];
if($model->save())
$this->redirect(array('view','id'=>$model->id));
}
$this->render('update',array(
'model'=>$model,
'modelPhone'=>$modelPhone,
));
}
...
public function actionDeletePhone($id,$modelId)
{
if($this->loadModelPhoneToDelete($id)->delete())
$this->redirect(array('update','id'=>$modelId));
}
...
public function loadModel($id)
{
$model=Client::model()->findByPk($id);
if($model===null)
throw new CHttpException(404,'The requested page does not exist.');
return $model;
}
public function loadModelsPhone($id)
{
return $model=ClientPhone::model()->findAllByAttributes(array('clientId'=>$id));
}
public function loadModelPhoneToDelete($id)
{
return $model=ClientPhone::model()->findByPk($id);
}
public function savePhones($modelPhone)
{
if(isset($_POST['ClientPhone']))
{
foreach($modelPhone as $i=>$phone)
{
if(isset($_POST['ClientPhone']))
$phone->phone = $_POST['ClientPhone'][$i]['phone'];
$phone->save(false);
}
return true;
}}
Файл формы _form.php:
<?php if ($model->isNewRecord): ?>
<div class="row">
<?php echo $form->labelEx($modelPhone,'phone'); ?>
<?php echo $form->textField($modelPhone,'phone[0]'); ?>
<script>
var count = 0;
function addField()
{
$("#container").append('<div id="ttt' + (++count) + '"><input id="ClientPhone_phone" type="text" maxlength="20" name="ClientPhone[phone][' + count + ']"><input type="button" value="Удалить" /><div>');
}
function delField(counter)
{
$("#ttt" + counter).remove();
}
</script>
<div id="container"></div>
<?php echo CHtml::Button('Добавить еще номер', array('onclick'=>'addField(); return false;')); ?>
<?php echo $form->error($modelPhone,'phone'); ?>
</div>
<?php endif; ?>
<?php if (!$model->isNewRecord): ?>
<div class="row">
<?php foreach($modelPhone as $i=>$phone): ?>
<?php echo $form->labelEx($phone,"[$i]phone"); ?>
<?php echo $form->textField($phone,"[$i]phone")
.CHtml::Button('X',array(
'submit'=>array('deletePhone','id'=>$phone->id,'modelId'=>$model->id),
'confirm'=>"Точно удалить номер телефона? Уверен?",
)); ?>
<?php echo $form->error($phone,"[$i]phone"); ?>
<?php endforeach; ?>
<script>
var count = 0;
function addField()
{
$("#container").append('<div id="ttt' + (++count) + '"><input id="ClientPhone_phone" type="text" maxlength="20" name="ClientPhone[phone][' + count + ']"><input type="button" value="Удалить" /><div>');
}
function delField(counter)
{
$("#ttt" + counter).remove();
}
</script>
<div id="container"></div>
<?php echo CHtml::Button('Добавить еще номер', array('onclick'=>'addField(); return false;')); ?>
</div>
<?php endif; ?>
Модель Client.php:
public function afterSave()
{
if(isset($_POST['ClientPhone']['phone']))
{
$id = $this->id;
$phones = $_POST['ClientPhone']['phone'];
foreach($phones as $i=>$phone)
{
$modelPhone = new ClientPhone;
$modelPhone->phone = $_POST['ClientPhone']['phone'][$i];
$modelPhone->clientId = $id;
$modelPhone->save();
}}
return parent::afterSave();
}