Я строю абстрактную форму в Zend Framework. Это делается путем создания динамических элементов формы из базы данных (таблицы со значениями ключ / значение).
Большинство из них работает нормально, за исключением функции setDefault / populate формы. Позвольте мне объяснить.
У меня есть основная форма с 3 подчиненными формами (форма в стиле мастера). 3-й шаг формы имеет 5 или более динамических элементов. (например: свойства серверной стойки).
Форма на шаге 3 может быть клонирована с помощью ajax. (Таким образом, вы сможете добавить 4 серверных стойки одновременно). При отправке формы функция preValidation () проверит все новые поля и добавит их в подчиненную форму.
Так хорошо, так хорошо. Теперь проблемы начинаются.
При добавлении полей в подчиненную форму я использую фабричный способ создания элементов формы =>
$subForm->addElement($presentation_type,'fixedField'. $key.'_'.$formStep,
array('label' => $label.':',
'required' => $is_mandatory,
'filter' => $filters,
'value' => $value,
'description' => $unit .' '. $description,
'validators' => $validators));
Это прекрасно работает при запуске новой неподтвержденной формы, но не может установить параметр-значение при отправке формы, он не заполняет параметр-значение (остальные параметры в той же функции работают нормально).
Я обновил Zend Framework до последней версии. Попытался найти мою проблему на Google и форумах, но безуспешно.
Я пришлю вам бельгийское пиво, если вы решите это :)
Искал 3 дня сейчас.
Также пытались использовать функцию setDefault и функцию заполнения.
Странная вещь, когда я делаю "echo $ subForm-> getElement ('xxxxxx') -> getValue ();" я получаю правильный вывод. Похоже, что Zend просто не будет отображать значение внутри элемента.
Код контроллера:
<code><?php
class TestController extends Zend_Controller_Action {
protected $_form;
protected $_namespace = 'TestController';
protected $_session;
/**
* Gets the add/edit form for the current object
*
* @access public
* @return object|void
* @param boolean $search_form Set to true if you want the search form object to be returned
*/
public function getForm()
{
if (null === $this->_form) {
$action = $this->getRequest()->getActionName();
$this->_form = new Application_Form_Test();
}
return $this->_form;
}
/**
* Action for the new page
*
* @access public
* @return void
*/
public function newAction (){
//Store the parent object in a session, this way we can use the var in the 3th form step
$this->getSessionNamespace();
// Either re-display the current page, or grab the "next"
// (first) sub form
if (!$form = $this->getCurrentSubForm()) {
$form = $this->getNextSubForm();
}
$this->view->form = $this->getForm()->prepareSubForm($form);
}
/**
* Action to process the multi step form
*
* @access public
* @return mixed
*/
public function processAction(){
//No form is set
if (!$form = $this->getCurrentSubForm()) {
return $this->_forward('new');
}
if (!$this->subFormIsValid($form, $this->getRequest()->getPost())) {
$this->view->form = $this->getForm()->prepareSubForm($form);
return $this->render('new');
}
if (!$this->formIsValid()) {
$form = $this->getNextSubForm();
$this->view->form = $this->getForm()->prepareSubForm($form);
return $this->render('new');
}
// Valid form!
// Let's save everything
//......
// All done, clear the sessions
Zend_Session::namespaceUnset($this->_namespace);
//$this->render('index');
$this->_forward('index');
}
/**
* Ajax action that returns the dynamic form field for step3 in the form
*/
public function newajaxformAction() {
if(!$this->getRequest()->isXmlHttpRequest()) throw new Zend_Controller_Action_Exception("This isn't a Ajax request !", 404);
$ajaxContext = $this->_helper->getHelper('AjaxContext');
$ajaxContext->addActionContext('newfield', 'html')->initContext();
//Disable view
$this->_helper->viewRenderer->setNoRender();
$this->_helper->layout()->disableLayout();
$id = $this->_getParam('id', null);
$amount = $this->_getParam('amount', null);
$fieldsKeys = $_POST['key'];
$fieldsValues = $_POST['value'];
//This one adds multiple objects on one page
$po = new Test_Partial($id,$amount,$fieldsKeys,$fieldsValues);
echo $po->__toString();
}
/**
* Get the session namespace we're using
*
* @access public
* @return Zend_Session_Namespace
*/
public function getSessionNamespace()
{
if (null === $this->_session) {
$this->_session = new Zend_Session_Namespace($this->_namespace);
}
return $this->_session;
}
/**
* Get a list of forms already stored in the session
*
* @access public
* @return array
*/
public function getStoredForms()
{
$stored = array();
foreach ($this->getSessionNamespace() as $key => $value) {
$stored[] = $key;
}
return $stored;
}
/**
* Get list of all subforms available
*
* @access public
* @return array
*/
public function getPotentialForms()
{
return array_keys($this->getForm()->getSubForms());
}
/**
* What sub form was submitted?
*
* @access public
* @return false|Zend_Form_SubForm
*/
public function getCurrentSubForm()
{
$request = $this->getRequest();
if (!$request->isPost()) {
return false;
}
foreach ($this->getPotentialForms() as $name) {
if ($data = $request->getPost($name, false)) {
if (is_array($data)) {
return $this->getForm()->getSubForm($name);
break;
}
}
}
return false;
}
/**
* Get the next sub form to display
*
* @return Zend_Form_SubForm|false
* @access public
*/
public function getNextSubForm()
{
$storedForms = $this->getStoredForms();
$potentialForms = $this->getPotentialForms();
foreach ($potentialForms as $name) {
if (!in_array($name, $storedForms)) {
return $this->getForm()->getSubForm($name);
}
}
return false;
}
/**
* Is the sub form valid?
*
* @param Zend_Form_SubForm $subForm
* @param array $data
* @return bool
*/
public function subFormIsValid(Zend_Form_SubForm $subForm,array $data)
{
$name = $subForm->getName();
echo '<br />Submitted data(Send from Controller) = <pre>';
print_r($data);
echo '
';
if ($ subForm-> isValid ($ data)) {
$ this-> getSessionNamespace () -> $ name = $ subForm-> getValues ();
вернуть истину;
}
вернуть ложь;
}
/ **
* Действительна ли полная форма?
*
* @return bool
* @ доступ общественности
* /
публичная функция formIsValid ()
{
$ data = array ();
foreach ($ this-> getSessionNamespace () как $ key => $ info) {
$ data [$ key] = $ info [$ key];
}
return (count ($ this-> getStoredForms ()) getPotentialForms ()))? false: $ this-> getForm () -> isValid ($ data);
}
}
?>
Код формы:
<? PHP
Класс Application_Form_Test extends Zend_Form {
публичная функция init () {
// Установить несколько фильтров для полей
$ This-> setElementFilters (массив ( 'StringTrim'));
// Давайте создадим несколько подформ => каждая подформа будет на другой странице
//Шаг 1
$ step1 = new Zend_Form_SubForm ();
$ step1-> addElement ('select', 'test', array ('label' => 'Save in:',
'multiOptions' => array ('choose' => 'Choose one ...', 'a' => 'a', 'b' => 'b'),
'required' => false,
'игнорировать' => правда,
'значение' => массив ('выбрать'),
'validators' => array (array ('InArray', false, array (array_keys (array ('Choose' => 'Choose one ...', 'a' => 'a', 'b' => 'b) «)))))));
// Шаг 3
$ step2 = new Zend_Form_SubForm ();
// Добавить кнопку удаления и добавления для динамических форм
$ step2-> addElement ('text', 'addFormAmount', array ('label' => '',
'required' => false,
'игнорировать' => правда,
'значение' => 1,
'description' => 'objects.',
'order' => 99992
));
$ step2-> addElement ('button', 'addForm', array ('label' => 'Add',
'order' => 99991
));
$ step2-> getElement ('addForm') -> setAttrib ('onClick', 'ajaxAddForm ();');// Добавить скрытое поле идентификатора, таким образом, мы можем использовать идентификатор в javascript для подсчета количества полей $ step2-> addElement ('hidden', 'id', array ('value' => 1));$ this-> addAbstractField ($ step2, '', 1, 'test value');// тест, давайте поместим нашу предварительную проверку в конец объекта формы $ this-> preValidation ($ step2, $ _ POST);// Наконец, присоединяем вложенные формы к главной форме $ this-> addSubForms (array ('step1' => $ step1, 'step2' => $ step2));} / ** * Создание медленной строки для форм или любой другой связанной с URI строки * * @return mixed * @access public * @param mixed $ array * / защищенная функция getSlug ($ string) {$ slug = trim ($ string);// обрезать строку $ slug = preg_replace ('/ [^ a-zA-Z0-9 -] /', '', $ slug);// принимаем только буквенно-цифровые символы, но сохраняем также пробелы и тире… $ slug = str_replace ('', '-', $ slug);// заменить пробелы тире $ slug = strtolower ($ slug);// сделать его строчным. return $ slug;} / ** * Подготовка формы для отображения * * @param string | Zend_Form_SubForm $ spec * @return Zend_Form_SubForm * / открытая функция prepareSubForm ($ spec) {if (is_string ($ spec)) {$ subForm = $ this->{$} спецификации;} elseif ($ spec instanceof Zend_Form_SubForm) {$ subForm = $ spec;} else {throw new Exception ('Недопустимый аргумент, переданный'. __FUNCTION__. '()');} $ this-> setSubFormDefaultDecorators ($ subForm) -> addSubmitButton ($ subForm) -> addSubFormActions ($ subForm);вернуть $ subForm;} / ** * Добавление декораторов формы к отдельной подформе * * @param Zend_Form_SubForm $ subForm * @return My_Form_Registration * / открытая функция setSubFormDefaultDecorators (Zend_Form_SubForm $ subForm) {$ subForm-> setDecorators (array ('FormElements', массивHtmlTag ', array (' tag '=>' dl ',' class '=>' zend_form ')),' Form ',));вернуть $ this;} / ** * Добавить кнопку отправки в отдельную суб-форму * * @param Zend_Form_SubForm $ subForm * @return My_Form_Registration * / открытая функция addSubmitButton (Zend_Form_SubForm $ subForm) {$ subForm-> addElement (новый массив Zend_Form_Element_Submit (сохранить)('label' => 'Сохранить и продолжить', 'required' => false, 'ignore' => true, 'order' => 99999)));$ subForm-> getElement ('save') -> setAttrib ('onClick', 'ajaxController (); $ ("# processing_alert"). css ("display", "block");');вернуть $ this;} / ** * Добавление действия и метода в подформу * * @param Zend_Form_SubForm $ subForm * @return My_Form_Registration * / открытая функция addSubFormActions (Zend_Form_SubForm $ subForm) {$ subForm-> setAction ('/ test / process') -> setMethod('post') -> setEnctype (Zend_Form :: ENCTYPE_MULTIPART);вернуть $ this;} / ** * После публикации, ловушка предварительной проверки * * Находит все поля, в которых name включает 'newField', и использует addNewField для добавления * их к объекту формы * * @param array $ data $ _GET или $ _POST * / public function preValidation(Zend_Form_SubForm $ subForm, массив $ data) {// функция обратного вызова array_filter findFields ($ field) {// вернуть имена полей, которые включают 'newField' if (strpos ($ field, 'newField')! == false) {return $поле;}} // Поиск $ data для динамически добавляемых полей с использованием обратного вызова findFields $ newFields = array_filter (array_keys ($ data), 'findFields');foreach ($ newFields as $ fieldName) {// убрать номер идентификатора из имени поля и использовать его для установки нового порядка $ ex1 = explode ('newField', $ fieldName);$ ex2 = взорваться ('_', $ ex1 [1]);$ key = $ ex2 [0];$ order = $ ex2 [1];$ this-> addAbstractField ($ subForm, $ key, $ order, $ data [$ fieldName]);
// echo 'order:'. $ order. "и ключ". $ key. "
"; тест хорошо
}
}
/ **
* Добавляет новые поля для динамического формирования
*
* @param string $ name
* @param string $ value
* @param int $ order
* @param object $ subForm
*
* /
публичная функция addAbstractField (Zend_Form_SubForm $ subForm, $ key, $ formStep = null, $ value) {
$ subForm-> addElement ('text', 'fixedField'. $ key .'_ '. $ formStep, array (' label '=>' Test label: ',
'required' => 'true',
'value' => $ value,
'description' => 'описание теста'));
echo '
Добавлен элемент в подчиненную форму (метод Send from Form) key = "fixedField". $ key .'_'. $ formStep. '"and value"'. $ value. '"
';
вернуть $ this;
}
}
?>
Форма Частичный код:
<? PHP
class Test_Partial {
защищенный $ id;
публичная функция __construct ($ id, $ amount = 1, $ fieldsKeys = array (), $ fieldsValues = array ())
{
$ this-> id = $ id;
$ this-> amount = is_int ((int) $ amount)? сумма в долларах: 1;
$ this-> fields = array ();
// Позволяет объединить оба массива в один
foreach ($ fieldsKeys как $ key => $ value) {
$ ex = explode ('fixedField', $ value);
$ ex2 = взорваться ('_', $ ex [1]);
$ this-> fields [$ ex2 [0]] = $ fieldsValues [$ key];
}
}
публичная функция get () {
$ result_array = array ();
$ amount_counter = 1;
while ($ amount_counter <= $ this-> amount) {
$ result_array [] = new Zend_Form_Element_Text ('newField'. $ keyvalue ['id'] .'_ '. ($ this-> id + $ amount_counter), массив (' label '=>' test: ',
'required' => true,
'value' => 'эти данные будут потеряны'));
$ tikk = new Zend_Form_Element_Button ('removeForm'. ($ this-> id + $ amount_counter), массив ('label' => 'Remove'));
$ tikk-> setAttrib ('onClick', 'ajaxRemoveForm ('. ($ this-> id + $ amount_counter). ')');
$ result_array [] = $ tikk;
++ $ amount_counter;
}
return $ result_array;
}
публичная функция __toString ()
{
return implode ('', $ this-> get ());
}
/ **
* Создать медлительную строку для форм или любую другую строку, связанную с URI
*
* @return смешанный
* @ доступ общественности
* @param mixed $ array
* /
защищенная функция getSlug ($ string) {
$ slug = trim ($ string); // обрезать строку
$ slug = preg_replace ('/ [^ a-zA-Z0-9 -] /', '', $ slug); // принимаем только буквенно-цифровые символы, но сохраняем также пробелы и тире ...
$ slug = str_replace ('', '-', $ slug); // заменить пробелы тире
$ slug = strtolower ($ slug); // сделать его строчным
вернуть $ slug;
}
}
?>
Посмотреть:
function getLastSubId () {
var maxc = 0;
// Удалить все элементы с определенным субидидом
$ ('*'). each (function () {
num = parseInt (this.id.split ("_") [1], 10);
if (num> maxc)
{
maxc = num;
}
});
возврат maxc;
}
// Получить html нового элемента из контроллера действий
function ajaxAddForm (amount) {
// Diplay обработка сообщений
$ ("# processing_alert"). css ("display", "block");
// Получить значение id - целое число, добавляемое к динамическим именам полей и идентификаторам
var id = $ ("# step2-id"). val ();
if (typeof amount == 'undefined') {
var amount = $ ("# step2-addFormAmount"). val ();
}
var fields = '';
// Собираем все ключи и значения полей и включаем их в запрос ajax.
$ ('* [id * = step2-fixedField]: visible'). each (function () {var key = $ (this) .attr ('id');
var value = $ (this) .attr ('value');
поля + = '& key [] =' + key + '& value [] =' + value;
});
$ .Ajax (
{
тип: "POST",
url: "<? php echo $ this-> url (array ('action' => 'newAjaxForm'));?>",
данные: "id =" + id + "& amount =" + amount + fields,
асинхронный: ложный,
success: function (newForm) {
// Вставляем новый элемент перед кнопкой Добавить
var counter = parseInt (id) + parseInt (amount);
$ ( "# AddForm-метка") перед (NEWFORM).
. $ ( "# Step2-ID") Вал (счетчик);
}
}
);
// Отключить обработку сообщения
$ ("# processing_alert"). css ("display", "none");
}
function ajaxRemoveForm (id) {
// Diplay обработка сообщений
$ ("# processing_alert"). css ("display", "block");
// Удалить кнопку "удалить", которую мы только что нажали + метка
$ ( "# RemoveForm" + ID + "- метка") удалить ().
$ ( "# RemoveForm" + + идентификатор "- элемент") удалить ().
// Удалить все элементы с определенным субидидом
$ ('* [id * = _' + id + '-]: visible'). each (function () {
$ (Это) .remove ();
});
// Отключить обработку сообщения
$ ("# processing_alert"). css ("display", "none");
}
<? php echo $ this-> form; ?>