DomDocument, рисовалка форм + покритикуйте

Духовность™

Продвинутый новичок
DomDocument, рисовалка форм + покритикуйте

Когда я начал писать приложения, использующие большое количество полей, мне очень не нравилось работать с HTML формами "вручную". Т.е. что бы в шаблоне после неудачного POST запроса отобразить данные приходилось писать что то вроде:

PHP:
<select name="sort">
<option value="audio"<?=@$_GET["sort"] == "audio" 	?	" selected"	: ""?>>Аудиозапись
<option value="video"<?=@$_GET["sort"] == "video" 	?	" selected"	: ""?>>Видеозапись
<option value="dvd"<?=@$_GET["sort"] == "dvd" 		?	" selected"	: ""?>>DVD-видеозапись
<option value="book"<?=@$_GET["sort"] == "book" 	?	" selected"	: ""?>>Книги
<option value="data"<?=@$_GET["sort"] == "data" 	?	" selected"	: ""?>>Data-диск
<option value=""<?=empty($_GET["sort"]) 			?	" selected"	: ""?>>все
</select>
(образец 2004 года)

PHP:
<input type="text" value="<?=htmlspecialchars($var)?>" name="field">
ну и т.д. Я думаю, идея ясна.

Для контроля и автоматизации написания HTML форм я на удивление очень быстро написал библиотеку для построения форм на базе DomDocument. Это позволило

- не заботиться о различных опечатках
- не заботиться о преобразовании "плохих" символов в мнемоники HTML
- создать ОО-интерфейс и попытаться реализовать наработку в стиле JavaScript DOM

Библиотека состояла из 2 частей - сам код рисовалок форм и хэлпер. Хелпер нужен был для того, что бы спрятать код инициализации и присвоения элементам форм аттрибутов, создать специфические методы. Наглядный пример:

Реализация метода хелпера создания текстового поля:

PHP:
/**
* Возвращает объект Html_Element_Input типа text.
* 
* @param string $name имя элемента
* @param string|int $value значение
* @param array дополнительные необязательные параметры
* @return object
*/
public function inputText($name, $value, $params=array())
{
    $object = new Html_Element_Input('text');
    $object->name = $name;
    $object->value = $value;
    $object->setData($params);

    return $object;
}
в шаблоне это выглядело бы так:

PHP:
...<td>
<?=$helper->inputText('user[user_login]', 
                      $user_login, 
                      array('maxlength'=>255, 'class'=>'textSmall')
                     )->getHtml()?></td>...
Реализация метода хелпера создания Select-списка:

PHP:
/**
* Возвращает объект Html_Element_Select.
* 
* @param string $name имя элемента
* @param string|int $checked_value значение сравнения - если $value и $checked_value равны, 
  то checkbox is checked.
* @param array дополнительные необязательные параметры
* @return object
*/
public function inputSelect($name, $checked_value=null, $params=array())
{
    $object = new Html_Element_Select();
    $object->name = $name;
    $object->setCheckedValue($checked_value);
    $object->setData($params);

    return $object;
}
и создания тега option:

PHP:
/**
* Возвращает объект Html_Element_Option.
* 
* @param string $value значение value тега option
* @param string $text текстовой узел-значение тега option
* @param array дополнительные необязательные параметры
* @return object
*/
public function inputOption($value, $text=null, $params=array())
{
    $object = new Html_Element_Option();
    $object->value = $value;
    $object->setText($text);
    $object->setData($params);

    return $object;
}
в шаблоне это выглядит так:

PHP:
...        <td><?
            $select = $helper->inputSelect('user[user_group]', $user_group);
            $select->addOption( $helper->inputOption(0, 'выберите значение') );
            foreach ($groups as $group):
                $select->addOption( $helper->inputOption($group['id'], $group['group_name']) );
            endforeach;
            echo $select->getHtml();
            ?>...

На данный момент меня беспокоит быстродействия - стоит ли использовать для этого DomDocument? Мне как-то сказали, что в контексте этой задачи он лишний и тяжелый. У меня домашнем пк данный пример генерится 0.02 сек, а на сервере 0.007. В принципе, реализацию без изменения абстракции можно сделать, но как-то пока не хочется.

Вот. Что скажите. Развивать или нет эту библиотеку?

Код сырой библиотеки с примером: скачать
Работающий пример кода по ссылке выше: смотреть
 

флоппик

promotor fidei
Команда форума
Партнер клуба
1. Тоже считаю, что домДокумент тут не нужен. Зачем использовать огромный сложный обьект парсера, когда нужно сгенерить пару текстовых строк?
2. Возможно если ты расширишь функционал так, что бы можно было совместить генерацию форм с ее валидацией, то польза от этого класса возрастет значительно. Думаю, лучший вариант будет генерировать форму по заданным ограничениям, с возможностью проверки результата при сабмите, и возможно, клиентской валидации для дружелюбности интерфейса.
 

Духовность™

Продвинутый новичок
генерацию форм с ее валидацией
я вот всегда не понимал, что вы имеете под этим в виду. Мне кажется, что генерация формы - это удел шаблонизатороподобных приложений, а валидация - либо модели, либо контроллера, либо отдельный слой. ?????

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

HraKK

Мудак
Команда форума
к этому приходит каждый и каждый в итоге понимает что это фигня. А не фигня - покажу что чуть позже
 

Farsh

~ on ~ high ~ wave ~
Автор оригинала: triumvirat
я вот всегда не понимал, что вы имеете под этим в виду. Мне кажется, что генерация формы - это удел шаблонизатороподобных приложений, а валидация - либо модели, либо контроллера, либо отдельный слой. ?????
Под валидацией тут имеется ввиду вывод той же самой формы, только с заметками пользователю о том, если он что-то сделал не так. То есть, допустим, имеется куча инпутов, в 2 из которых он ввел что-то не то - нужно вывести эту же форму и над этими инпутами выдать сообщение.
 

Духовность™

Продвинутый новичок
То есть, допустим, имеется куча инпутов, в 2 из которых он ввел что-то не то - нужно вывести эту же форму и над этими инпутами выдать сообщение.
у меня эта валидация идет в контроллере. вы предлагаете её вынести в вид? а как прикажете валидировать поле email на предмет наличия такого уже вбазе? тоже во view?

HraKK
ты как всегда красноречив )
 

флоппик

promotor fidei
Команда форума
Партнер клуба
а валидация - либо модели, либо контроллера, либо отдельный слой. ?????
а чем твоя форма сама по себе не модель? данные у нее есть, методы свои есть, отобразить ее можно, почему она не может сделать валидацию?

алсо, эти самые ограничения можно получать из самой БД, ибо почти всегда поле формы == поле в таблице, форма == записи в строке
 

Духовность™

Продвинутый новичок
если мне не изменяет память, он её грозился показать ещё году так в 2008. до апреля дожить ещё надо. пусть тогда теорию расскажет.
 

флоппик

promotor fidei
Команда форума
Партнер клуба
triumvirat, ну так он и обещал в апреле 2008 показать ))
 

Farsh

~ on ~ high ~ wave ~
Вот, например, то, как идет работа с формами в симфони
PHP:
    $this->form = new ContactForm();
 
    if ($request->isMethod('post'))
    {
      $this->form->bind($request->getParameter('contact'));
      if ($this->form->isValid())
      {
          $this->redirect('contact/thankyou?'.http_build_query($this->form->getValues()));
      }
    }
Имеется класс для постройки форм, который содержит объекты классов каких-то элементов форм. На эти объекты навешиваются валидаторы ( и там же хоть проверка email на уникальность ). После запроса данные биндятся к форме, и при вызове ->isValid() ( конечно же, в контроллере ) начинают срабатывать те самые валидаторы. Тем самым мы в контроллере и получаем всю ошибки, а при постройке этой же формы спокойно выводим их над соответствующими полями.
 

Sigorma

Новичок
если библиотека занимается отрисовкой формы странно что не имеется функций для отрисовки тега <form> и различных сабмитов.
если я хочу добавить в инпут событие, например onclick как мне его втулить?
 

Beavis

Banned
triumvirat
ну если будешь развивать, получится в итоге тормозная, но удобная штука, типа как в ZF =)
 

Fortop

Новичок
Автор оригинала: Sigorma
если библиотека занимается отрисовкой формы странно что не имеется функций для отрисовки тега <form> и различных сабмитов.
если я хочу добавить в инпут событие, например onclick как мне его втулить?
Если я правильно понял автора, то при помощи этого массива
PHP:
array('maxlength'=>255, 'class'=>'textSmall')
Например
PHP:
array('maxlength'=>255, 'class'=>'textSmall', 'onclick' => 'alert("меня ткнули");return false;') ;
 

C_TIGER

Новичок
генераторы форм зло
http://dklab.ru/lib/HTML_FormPersister/
http://pyha.ru/forum/topic/3203.0
 

HraKK

Мудак
Команда форума
флоппик
Я не о цмс сейчас.

C_TIGER
+1

triumvirat
Генераторы это фигня, ты сейчас дошел до состояния эйфории от достигнутого дао ООП и поэтому пытаешься совать его куда не попади. Ради бога, оставь хтмл в покое. Все равно, все это вместе с валидацией тебе должны присылать верстальщики, а ты лишь подставлять в нужные места управляющие структуру. Так нет, же. Теперь я должен лезть в контролер, ради того чтоб нарисовать хтмл который у меня уже есть. Не в том направлении думаешь, лучше думай над автоматизацией - упрощением жизни, чтоб наоборот не приходилось в контроллер лезть.
 

LeoKee

Новичок
Формы - вещь настолько изменчивая, что общих имхо решений нет... все равно приходится делать все ручками, если код на клиенте сложен
 

AmdY

Пью пиво
Команда форума
triumvirat
у тебя не форма, а рисовалка html.
PHP:
<?=$helper->inputText('user[user_login]',  
                      $user_login,  
                      array('maxlength'=>255, 'class'=>'textSmall') 
                     )->getHtml()?></td>...
на человеческом языке это значит:
берём зелёный фломастер ($helper) рисуем им фигурку человека, называем его Нео ('user[user_login]'), даём синию таблетку ( $user_login), объясняем что он на стороне добра и должен бороться с матрицей ( array('maxlength'=>255, 'class'=>'textSmall')) и пинаем на толпу агентов Смит (getHtml())

А должно быть проще: Нео - фас.
$form->neo->getHtml(); - во вью выводим
$form->neo->validate(); - в контроллере проверяем значение
$form->neo->getValue(); - узнать значения поля
$form->save(); - сохранить модель(модели) каторые описывает форма.
$form->getHtml(); разом вывести всех гномов, людей, энтов ... и парочку хоббитов на битву за средиземье.
 
Сверху