Конструктор форм в Yii

в 13:43, , рубрики: yii

Привет читатели!

В большинстве проектов на Yii которые я видел, работа с формами была организована самым простым способом, где рендеринг формы определялся в файле вида через виджет ActiveForm. Да, это безусловно оправдано для сложных форм, которые сложно уместить в какой либо шаблон. Но сегодня я хочу поговорить о конструкторе форм и показать как это применяем мы.

Все просто. Работа с формами у нас построена по принципу «не смешивать модели формы и модели таблиц». А идея состоит в том, что бы в модель формы добавить функциональность конструктора форм.

Для этого создадим класс от которого будут наследоваться наши формы. Т.е. сделаем так, что бы модель формы сама определяла рендеринг исходя из конфигурации формы.

/**
 * FormModel.
 *
 * @author     Andrey Nilov <nilov@glavweb.ru>
 * @copyright  Copyright (c) 2007-2012 Glavweb.Soft, Russia. (http://glavweb.ru)
 */
class FormModel extends CFormModel
{
    /**
     * Config of the form
     * @var array
     */
    protected $_formConfig = array();

    /**
     * Config of the form by default
     * @var array
     */
    private $_defaultFormConfig = array(
        'method' => 'post'
    );
       
    /**
     * Class name of form
     * @var string
     */
    protected $_formClass = 'CForm';

    /**
     * Object of Form
     * @var Form
     */
    private $_form = null;    
    
    
    /**
     * Constructor
     * 
     * @param string $scenario Name of the scenario that this model is used in
     * @return void
     */
    public function __construct($scenario = '') 
    {
        parent::__construct($scenario);
        $this->_setFormConfig();
    }

    /**
     * Sets config of the form
     * 
     * @return void
     */
    private function _setFormConfig() 
    {
        $this->_formConfig = array_replace_recursive(
            $this->_defaultFormConfig, 
            $this->_formConfig()
        );
    }

    /**
     * Returns config of the form
     * 
     * @return array
     */
    protected function _formConfig() 
    {
        return $this->_formConfig;
    }
    
    /**
     * Returns the attribute labels
     *
     * @return array Attribute labels (name=>label)
     */
    public function attributeLabels()
    {
        return $this->getLabels();
    }    
    
    /**
     * Returns the config of the form
     * 
     * @return array
     */
    public function getFromConfig() 
    {
        return $this->_formConfig;
    }
    
    /**
     * Sets the config of the form
     * 
     * @param array $config
     * @return void
     */
    public function setFromConfig(array $config) 
    {
        $this->_formConfig = $config;
    }
    
    /**
     * Returns labels
     * 
     * @return array
     */
    public function getLabels() 
    {
        $labels = array();
        if (!empty($this->_formConfig['elements'])) {
            foreach ($this->_formConfig['elements'] as $name => $data) {
                if (isset($data['label'])) {
                    $labels[$name] = $data['label'];
                }
            }
        }
        
        return $labels;
    }
    
    /**
     * Returns object of Form
     * 
     * @return Form
     */
    public function getForm() 
    {
        if ($this->_form === null) {
            $this->_form = new $this->_formClass($this->_formConfig, $this);
        }
        
        return $this->_form;
    }    
}

Пройдемся по классу более подробно. Массив "$_formConfig" позволяет задать конфигурацию формы. Например:

/**
 * Config of the form
 * @var array
 */
protected $_formConfig = array(
    'activeForm' => array(
        'class'                  => 'CActiveForm',
        'id'                     => 'registration_form',
        'enableClientValidation' => true,
        'clientOptions' => array(
            'validateOnSubmit' => true
        )
    ),

    'elements' => array(
        ....
        'name' => array(
            'type' => 'text',
            'label' => 'ФИО'
        ),
        'organization' => array(
            'type' => 'text',
            'label' => 'Организация'
        ),
       ....
    ),

    'buttons' => array(
        'register' => array(
            'type'  => 'submit',
            'label' => 'Регистрация'
        )
    )
);

Так же для конфигурации формы можно переопределить метод "_formConfig()". Это удобно когда нужно во время конфигурации реализовать какую-то логику.

Свойство "$_formClass" позволяет изменить класс который используется для отображения формы (CForm или его потомок).

Заметьте, что теперь вам не обязательно указывать атрибуты формы. Для этого мы переопределили метод «attributeLabels()» и теперь атрибуты равны лейблам из конфигурации формы.

Получить объект формы (CForm) можно методом «getForm()».

Использование.

Рендеринг формы:

$formModel = new RegistrationForm();
$form = $formModel->getForm();
echo $form;

Использование совместно с моделью таблицы.

$user = new User();
$user->setAttributes($formModel->getAttributes());
$result = $user->save();

На этом сегодня всё, спасибо всем кто дочитал до конца. Объективная критика приветствуется.

Автор: Nilov_A


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js