Я читал руководство много раз, я просмотрел сообщения, предлагаемые Google по этому вопросу, я даже купил пару книг, посвященных ZF. Теперь, почему я все еще запутался?
Я могу, используя Zend_Form, создать форму, которая проверяет и функционирует нормально. То, что я не могу сделать, делает форму, которая выглядит так, как будто я хочу, чтобы она выглядела с сообщениями об ошибках, которые я хочу иметь. Мне нужны пользовательские кнопки, мне нужны фанковые макеты, я хочу вставлять текст в середине формы и т. Д.
У кого-нибудь есть простой способ достичь такого рода вещей? Что-то, что заставляет меня чувствовать, что структура меня спасает, а не стоит? Я мог бы отказаться от формы Zend … создать свою собственную форму, заставить ее действие попасть на страницу, чтобы проверить и обработать опубликованные данные, и я мог бы сделать это так же быстро, как я могу напечатать, но я действительно хочу «получить» это и уметь использовать его так, как он был, по-видимому, предназначен.
Любой совет? Любые простые «способы» для пользовательских кнопок, фанковые макеты и базовые (или, скорее, продвинутые, поскольку есть тонны базовых обучающих программ, которые пропускают более сложные проблемы), «что-то делается» с формой zend?
Совет Барретта Конрада – это то, что я бы предложил. Кроме того, имейте в виду, что вам не нужно использовать объект формы для визуализации вашей формы.
Одна вещь, которую вы можете сделать, это создать форму в сценарии просмотра, которая имеет элементы с тем же именем, что и класс формы.
Ваша форма HTML:
<form action="/login/" method="post"> <fieldset> <label for="username">Username:</label> <input type="text" size="10" name="username" /> <label for="password">Password:</label> <input type="password" size="10" name="password" /> <input type="submit" /> </fieldset> </form>
Твой класс:
class LoginForm extends Zend_Form { public function init() { $username = $this->createElement('text','username'); $username->setRequired(true); $this->addElement($username); $password = $this->createElement('password','password'); $password->setRequired(true); $this->addElement($password); } }
Ваш класс формы отражает вашу HTML-форму, каждый элемент вашего класса имеет свои собственные валидаторы и требования. В своем действии вы можете создать экземпляр своего класса формы и проверить свой пост / получить vars против этой формы:
$form = new LoginForm(); if ($this->_request->isPost()) { if ($form->isValid($this->_request->getParams())) { // do whatever you need to do } else { $this->view->errors = $form->getMessages(); } }
Вы можете отобразить сообщения об ошибках в верхней части формы в одной группе, используя этот метод.
Это основной пример, но он позволяет вам полностью контролировать представление вашей формы, не тратя время на изучение декораторов. На мой взгляд, значительная часть Zend_Form находится в его свойствах проверки и фильтрации. Это дает вам силу. Главное обратное к решению вроде этого состоит в том, что ваша HTML-форма сценария представления может стать несинхронизированной с вашим классом формы.
Отметьте каждый элемент индивидуально в своем представлении – например
<!-- view script here --> <form method="POST"> Name: <?php echo $this->myForm->getElement('name')->render(); ?> some other text between the fields Birthdate: <?php echo $this->myForm->getElement('birthdate')->render(); ?> <input type="submit" /> </form>
Это поддерживает возможность использования помощников вида Zend_Form (т. Е. Отображать сообщения об ошибках и поддерживать значения полей формы при неудачной проверке валидации), но дает вам полную возможность настройки.
Если вы хотите пойти дальше, затем отключите декораторы по умолчанию для отдельных элементов формы, а затем либо приложите свои собственные для дальнейшей настройки, какие именно теги используются (то есть для сообщений об ошибках и меток), либо вообще не используют декораторы (другие чем отображать сам элемент формы), а затем писать весь окружающий HTML вручную. Полная возможность настройки, не теряя при этом преимуществ Zend_Form, как на уровне формы, так и на уровне представления.
Мэтью Вейер O'Phinney начал серию сообщений в блогах о декораторах Zend_Form:
В настоящее время у нас есть новая и блестящая Zend\Form
которая еще сложнее старого компонента, но также гораздо более управляемая, инкапсулированная и мощная. Итак, то, что я сказал ниже, не применяется. Новый компонент IMHO – огромное улучшение, потому что он …
Я действительно не могу помочь, потому что у меня точно такая же проблема. Я думаю, что декораторы Zend_Form являются мощными, но, безусловно, наименее программным и неинтуитивным элементом ZF, который я видел до сих пор, и я использовал большую часть ZF в различных проектах.
Тем не менее, я могу дать лишь несколько советов по моему опыту:
Из связанных с этим вопросов к этому с правой стороны очевидно, что отсутствует полная документация для Zend_Form, особенно учитывая ее неинтуитивный характер. Мне бы очень хотелось, чтобы парни ZF делали что-то в этом отношении, насколько мне нравится Zend Framework.
Таким образом, этот ответ, вероятно, просто позволит вам узнать, что вы не единственный, у кого есть эта проблема.
или, альтернативно, вы могли бы использовать трюки умения джедая, конечно!
Чтобы добавить к сказанному:
Не бойтесь декораторов, вы будете использовать их много, если решите придерживаться Zend_Form. Это довольно просто, как только вы его получите », к сожалению, документы слабы, и играть с ним – это почти единственный способ добраться туда.
Декораторы ViewScript и ViewHelper дают вам много энергии.
Не бойтесь прорываться через источник для разных декораторов, которые существуют, и посмотреть, как они делают вещи (я получил достаточное количество проницательности, сравнивая оригинальные декораторы с додзе).
Я думаю, что Шон предлагал, что вам не нужно вызывать form-> render, вы можете использовать что-то вроде этого в вашем viewcript.
<someHtmlThingy name="blah" value="<?php echo $this->formInstance->getElement('whatever')->getValue(); ?>" />
Я работал над одним проектом (pre Zend_Form), где мы построили наборы валидаторов и использовали стандартные просмотровые сценарии на всем протяжении. Это была небольшая работа (сантехника для сообщений об ошибках и т. П.), Но не чрезмерная по сравнению с созданием элементов с Zend_Form.
Если вы просто хотите добавить произвольную разметку до или после элементов формы без использования декоратора ViewScript, вы можете использовать мой декоратор AnyMarkup: http://www.zfsnippets.com/snippets/view/id/62
Например, вот как вы добавили бы поле ввода с изображением внутри тега обертки (для этого нужно указать пути для автоматической загрузки):
$ form-> addElement ('text', 'my_field', array ( 'label' => 'Введите информацию:', 'decorators' => array ( 'ViewHelper', массив («AnyMarkup», массив ( 'markup' => '<span class = "imgwrapper">'. '<img src = "info.png" alt = "информационный значок" /> </ span>'), 'placement' => 'preend' ), 'HtmlTag', 'Метка' ) );
Пропускание на декораторах формы (IE – печать отдельных элементов формы, а не просто использование стандартного помощника View Form для обработки всего) – это один из способов получить кучу контроля.
Другой вариант – просто обработать код вручную и использовать ZF только для проверки и фильтрации.
К сожалению, более сложные проблемы пропущены, потому что без реальной конкретной цели или цели очень сложно написать пример или инструкции. Я потратил некоторое время на помощь другому разработчику здесь, на SO, который хотел изменить способ отображения скрытых элементов , но его случай был очень специфичным, поэтому было легче разобраться в деталях.
Большинство более сложных задач действительно сводятся к расширению хелпера по умолчанию для определенного типа поля. Например, у меня был проект, в котором я хотел применить класс «ошибка» ко всем полям, которые не прошли проверку после того, как форма была отправлена вместо того, чтобы вывести текст ошибки проверки:
<label for="field">Label:</label> <input type="text" name="field" id="field" class="error">
Это был довольно сложный процесс, потому что фактический элемент формы недоступен для помощника вида по умолчанию, поэтому помощник не может проверить, имеет ли элемент ошибку проверки. Поэтому я пошел по следующему процессу:
formXXX()
метод formXXX()
и добавил проверку, чтобы увидеть, произошел ли элемент с ошибкой. Кроме того, я добавил метод setElement()
который декоратор мог вызвать, чтобы установить экземпляр элемента, чтобы мой помощник мог проверить наличие ошибок. Zend_Form_Decorator_ViewHelper
. В нем я обратился к представлению и создавал экземпляр хелпера для типа элемента формы и проверял наличие метода setElement()
который я создал в моем помощнике вида, установив его, если он существует. Делая это, я мог бы расширить некоторые типы элементов формы, а не другие, не разбивая весь сценарий. addElementPrefixPath('My_Form_Decorator'), 'path/to/decorator')
), который указывал на мой новый декоратор формы. addHelperPath('/path/to/helpers', 'My_View_Helper');
Вы можете понять, почему для написания сложных учебников действительно нужны проблемы реального мира. Большую роль в создании таких помощников или сложных декораторских схем состоит в том, что все это раздражает прежде всего, это позволяет вам очень легко создавать множество форм, которые придерживаются одной и той же схемы проектирования и очень быстро изменяют их выход, если изменения должны быть сделаны. Но если, с другой стороны, вы чувствуете, что тратите много времени на выяснение того, как делать то, что должно быть простой задачей на благо одной формы, я бы сказал, пропустите ее!
Однако, если вы хотели бы помочь в чем-то более конкретном, я был бы более чем счастлив помочь. Просто задайте другой вопрос (или обновите этот), и я сделаю все возможное, чтобы помочь.
whycantitbemorethan25c упомянул их выше, но ViewScripts дают вам чрезвычайно тонкий контроль для рендеринга форм. Zend_Form должен быть быстрым, и поэтому он принимает множество значений по умолчанию, таких как стандартные декораторы, и упорядочивает элемент так, как он был добавлен в объект формы. С помощью ViewScript вы можете пропустить большую часть этого и поместить все свои элементы, но вы хотите в нормальном HTML.
Однако не пропустите концепцию Decorators. Они стилируют отдельные элементы, даже если они используются позже в представлении ViewScript. Например, вы можете использовать их для сообщений об ошибках, как это предлагали другие.
Если у вас очень сложная форма с несколькими точками данных с аналогичными действиями (подумайте о списке пользователей с активными / неактивными кнопками и кнопке удаления для каждого), вы должны рассмотреть Zend_Form_SubForm . Субформы могут использовать ViewScripts точно так же, как и обычные формы, и если вы каскадируете форму с помощью ViewScript с субформами со своими собственными ViewScripts, вы получите красивую логику и презентацию, которая намного мощнее, чем просто форма.
Я написал некоторые подклассы Zend_Form и декораторам, чтобы сделать его макетом формы в <table>. У него даже были некоторые специальные трюки, чтобы делать такие вещи, как сделать несколько кнопок отправки в одной строке.
Получил полный день взлома, чтобы заставить его работать. Он был написан против Zend 1.5.1, поэтому не знаю, будет ли он работать с текущей версией, но если вы заинтересованы, я мог бы, возможно, загрузить источник где-нибудь.
Это, кажется, очень распространенная жалоба с Zend Forms.
(Я знаю, что пуристы CSS будут использовать poo-poo, используя таблицы для форм макета, и, хотя я согласен с тем, что CSS лучше для большинства вещей, мне еще предстоит увидеть хороший макет формы, используя CSS, который не выглядит как прикладом-уродливым клочем. С таблицами формы «просто работают» в основном в каждом браузере, в котором они мне нужны.)
EDIT: Хорошо, говоря о прикладом-уродливых кломах, я поместил свой код для создания табличных форм zend в github. Иди сюда, чтобы посмотреть. (Потому что gaoshan88 попросил об этом.)
ОТВЕЧАЙ ЗДЕСЬ. НАДЕЖДА, это поможет вам. Я просмотрел огромное количество информации, пока не нашел ее.
<table> <tr> <td>Page name: *</td> <td><?php echo $this->pageForm->header_title;?></td> </tr> <tr> <td>H1 tag: *</td> <td><?php echo $this->pageForm->h1_tag;?></td> </tr> <tr> <td>Page URL: *</td> <td><?php echo $this->pageForm->url;?></td> </tr> <tr> <td>Meta Description: </td> <td><?php echo $this->pageForm->meta_description;?></td> </tr> <tr> <td>Meta Keywords: </td> <td><?php echo $this->pageForm->meta_keywords;?></td> </tr> <tr> <td>Short Description: *</td> <td><?php echo $this->pageForm->short_description;?></td> </tr> <tr> <td colspan="2"><a href="<?php echo $this->websiteUrl;?>backend_template/list?placeValuesBeforeTB_=savedValues&TB_iframe=true&height=200&width=300&modal=true" title="add a caption to title attribute / or leave blank" class="thickbox">Open iFrame Modal</a></td> <td> <a href="<?php echo $this->websiteUrl;?>backend_template/list?placeValuesBeforeTB_=savedValues&TB_iframe=true&height=200&width=300&modal=true" onclick="javascript:getDataFromAddPage()" title="Select Template For Page" class="thickbox" > TEST FORM </a> </td> </tr> <tr> <td>Featured: </td> <td><?php echo $this->pageForm->featured;?></td> </tr> <tr> <td>Mark as 404: </td> <td><?php echo $this->pageForm->is_404page;?></td> </tr> <tr> <td>Show in Navigation Menu: </td> <td><?php echo $this->pageForm->in_navmain;?></td> </tr> <tr> <td>Show in Static Menu:</td> <td><?php echo $this->pageForm->in_navstatic;?></td> </tr> <tr> <td><?php echo $this->pageForm->submit;?></td> <td><?php echo $this->pageForm->button_close;?></td> </tr> </table>
Вероятно, вы решили это сделать, но я занимался какой-то работой и нуждался в аналогичном решении.
форма-> getSubform ( 'подчиненная'); foreach ($ subform as $ key => $ value) { // какая-то разметка и пользовательский код здесь print $ value; // какая-то разметка и пользовательский код здесь } ?>
в цикле foreach вы можете добавить разметку таблицы. Если вы правильно назвали свои ключи для строк таблицы, они должны совпадать с ключами формы. Вы даже можете использовать цикл, который захватывает соответствующую подформацию по ключу или даже элемент ключом. вы можете пропустить цикл foreach, если знаете ключи, и просто скажите print $ subform ['somekey']; если вы задаете основную форму, указав $ form-> setIsArray (true); (не уверен, что эта последняя часть строго необходима, но для сложных форм она должна быть установлена так же.
Я удалил декораторы по умолчанию, чтобы я мог полностью контролировать печать внутри каждого элемента. Zend_Form должен иметь встроенный метод для захвата отдельных элементов немного легче .. но я думаю, что это работает очень хорошо.
Надеюсь, это полезно кому-то!
Первый совет Шона Максомти – это способ пойти за мной. Я всегда думал, что сделать <?php echo $this->form ?>
Для визуализации формы слишком волшебным. Я сделаю еще один шаг и сделаю индивидуальные декораторы, а не отдельные элементы с помощью магических методов $element->renderDecorator()
. Таким образом, вам не придется беспокоиться о порядке, в котором вы определили своих декораторов. Вам просто нужно, чтобы они были там, и вам не придется добавлять этих надоедливых, неинтуитивных декораторов HtmlTag
. Я сделал сообщение в блоге об этом .
Я не уверен, что у Zend уже есть эта функция, но быстрым решением было бы расширить класс, заставить его принять шаблон html.
Например:
<?php $form = new zend_form_whatever($field_list + $validators + $template); echo $form; ?>
шаблон:
<form id="my_custom_form"> <label>{label.email}</label> {input.email} <span class="red">{error.email}</span> <div> {label.password} {error.password} {input.password} </div> <div class="purple">{input.submit}<div> </form>