Размещение виджета в Yctive’s CActiveForm теряет функциональность CActiveForm

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

Вот как я создаю выпадающий список напрямую. $activeModel относится к модели (CActiveRecord) использован CActiveForm, $allItems это CActiveRecord массив, используемый для заполнения выпадающего списка. Этот код работает отлично.

<div class="row">
<?php echo $form->labelEx($activeModel, 'keyId'); ?>:
<?php
$data = array();
foreach ($allItems as $Item) {
$data[$Item->keyId] = CHtml::encode($Item->keyName);
}
$options = array(
'prompt' => 'Select an item',
'options' => array($activeModel->keyId => array('selected' => true)),
);
echo $form->dropDownList($activeModel, 'keyId', $data, $options);
?>
<?php echo $form->error($activeModel, 'keyId'); ?>
</div>

Теоретически, вот как виджет будет включен в CActiveForm:

<div class="row">
<?php echo $form->labelEx($activeModel, 'keyId'); ?>
<?php $this->widget('path.to.CustomDropdown', array(
'form' => $form,
'items' => $allItems,
'model' => $activeModel,
'prompt' => 'Select an item',
'selected' => true,
)); ?>
<?php echo $form->error($activeModel, 'keyId'); ?>
</div>

Сам виджет выглядит так:

<?php
/**
* Echoes a populated <select> element
*/
class CustomDropdown extends CWidget {
public $form;
public $items = array();
public $model;
public $prompt;
public $selected = false;

/**
* @var CActiveForm $form
* @var CActiveRecord[] $items
* @var CActiveRecord $model
* @var string $prompt
* @var bool $selected (optional)
*/
public function run() {
$data = array();
foreach ($this->items as $Item) {
$data[$Item->{$Item->tableSchema->primaryKey}] = CHtml::encode($Item->getName());
}

$options = array(
'prompt' => CHtml::encode($this->prompt),
'options' => (
$this->selected ? array($this->model->{$Item->tableSchema->primaryKey} => array('selected' => true)) : array()
),
);

echo $this->form->dropDownList($this->model, $this->model->tableSchema->primaryKey, $data, $options);
}
}
?>

Все это работает, но CActiveForm теряет функциональность проверки в раскрывающемся списке. В частности, виджет $form не сопоставляется с массивом проверки CActiveForm, поэтому ошибка отправки никогда не отображается пользователю.

Как мне полностью интегрировать этот виджет с CActiveForm так что функциональность не потеряна? Спасибо за помощь.

0

Решение

Судя по вашему примеру, вызов виджета вызывает написание большего количества кода, чем в $form->dropDownList() вызов. Я рекомендую упростить некоторые части вашего кода и продолжать использовать решение без виджетов.

Зачем вам этот код?

$data = array();
foreach ($allItems as $Item) {
$data[$Item->keyId] = CHtml::encode($Item->keyName);
}
$options = array(
'prompt' => 'Select an item',
'options' => array($activeModel->keyId => array('selected' => true)),
);

Вы просто повторяете то, что CHtml::listData() делает. Вы можете просто создать раскрывающийся список следующим образом:

echo $form->dropDownList(
$activeModel,
'keyId',
CHtml::listData( MyActiveRecordForDropDown::model()->findAll(), 'valueField', 'textField' ),
array( 'prompt' => 'Select an item' )
);

и выбранный элемент будет выбран автоматически по значению атрибута модели.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]