вторник, 16 сентября 2008 г.

Symfony: Создаем форму обратной связи 2/3

Приступим к генерации формы.

Начиная с версии 1.1 в Symfony для генерации форм используется система виджетов. Это означает что Вам надо будет в основном заниматься описанием полей и их свойств, и не заботиться о пользовательском вводе и проверке.

Теперь к практике.
В прошлой статье мы сгенерировали базовые классы форм командой >symfony propel:build-forms
Небольшое объяснение, Symfony генерирует базовые классы, в каталоге например
/lib/forms/base/BaseFeedbackLogForm.class.php
мы их не трогаем, мы в них будем "подглядывать", т.к. в следующий раз при выполнении
>symfony propel:build-forms
все классы в каталоге /lib/forms/base/ будут регенерированы заново, в соответствии в моделью, описанной в schema.yml, и все изменения внесенные в них будут уничтожены.

Для всех опытов и модернизаций нам предоставлены классы в каталоге /lib/forms/
Открываем класс /lib/forms/FeedbackLogForm.class.php, видим пустой класс, отложим его на время.

Открываем actions.class.php, и меняем метод executeIndex

public function executeIndex($request){
$this->form = new FeedbackLogForm(FeedbackLogPeer::retrieveByPk($request->getParameter('id')));
}

Запускаем http://minisite/frontend_dev.php/feedback
ops, error

Class "FeedbackUsers" must implement a "__toString" method to be rendered in a "sfWidgetFormPropelSelect" widget

Что произошло?
Symfony попыталась создать листбокс со списком получателей, для него используется "магический метод" __toString, но он не определен в модели, исправим это.

class FeedbackUsers extends BaseFeedbackUsers
{
public function __toString(){
return $this->getName();
}
}


Пробуем еще, и получаем такой экран:


Для начала неплохо, немного наведем красоту, открываем файл /lib/form/FeedbackLogForm.class.php и вносим следующие изменения:

class FeedbackLogForm extends BaseFeedbackLogForm
{
public function configure()
{
$this->setWidgets(array(
'id' => new sfWidgetFormInputHidden(),
'feedback_user_id' => new sfWidgetFormPropelSelect(array('model' => 'FeedbackUsers', 'add_empty' => true)),
'name' => new sfWidgetFormInput(),
'email' => new sfWidgetFormInput(),
'subject' => new sfWidgetFormInput(),
'content' => new sfWidgetFormTextarea(),
'get_answer' => new sfWidgetFormInputCheckbox(),
));

$this->widgetSchema->setLabels(array(
'feedback_user_id' => 'Кому',
'name' => 'Ваше Ф.И.О.',
'content' => 'Вопрос',
'email' => 'Ваш Email',
'subject' => 'Заголовок письма',
'get_answer' => 'Получить ответ на Email',
));
}//configure
}//class

Обратите внимание на $this->widgetSchema->setLabels тут мы меняем подписи к полям.

Что бы листбокс не пустовал, добавим пару записей.
ПО большому счету сайт начинается с админки.
Но мы пока не будем ей уделять много времени.
symfony propel:init-admin backend feedback_users FeedbackUsers
symfony propel:init-admin backend feedback_log FeedbackLog
Открываем http://minisite/backend_dev.php/feedback_users и вносим пару получателей.

Обновляем страницу http://minisite/frontend_dev.php/feedback и видим



Форма обрела более понятый вид, но нас не устраивает вид подписей к полям, мы хотим их выровнять по левому краю, также мы хотим поля снабдить коментариями, для обязательных полей поставим "*", и рядом с флажком напишем "да"
Для этого мы напишем воспользуемся директивой $this->widgetSchema->setHelps

$this->widgetSchema->setHelps(array(
'feedback_user_id' => ' * ',
'name' => ' * ',
'content' => ' * ',
'email' => ' * ',
'subject' => ' * ',
'get_answer' => ' да ',
));
$myDecorator = new sfFeedbackFormDecorator($this->getWidgetSchema());
$this->getWidgetSchema()->addFormFormatter('custom', $myDecorator);
$this->widgetSchema->setFormFormatterName('custom');

и напишем свой декоратор для строчек формы.

/*
* CUSTOM DECORATOR
*/
class sfFeedbackFormDecorator extends sfWidgetFormSchemaFormatter {
protected
$rowFormat = "
%hidden_fields%

%label%
%field% %help%
\n",
$helpFormat = '%help%',
$errorRowFormat = "
\n%errors%
\n",
$errorListFormatInARow = " \n%errors% \n",
$errorRowFormatInARow = " %error%\n",
$namedErrorRowFormatInARow = "
  • %name%: %error%
  • \n",
    $decoratorFormat = "";
    }// decorator class


    Обновляем страницу и видим:


    На сегодня хватит.
    Что мы пока имеем? Никаких очевидных преимуществ ;)
    Такую формочку с использованием классического HTML мы бы сделали гораздо быстрее, но не будем торопиться, завтра попробуем проверять введенные данные и сохранять их в БД.

    Комментариев нет: