【问题标题】:Keep old value of a select field in a form - Zend Framework 2在表单中保留选择字段的旧值 - Zend Framework 2
【发布时间】:2020-12-06 09:21:04
【问题描述】:

我正在使用 ZF 2.8 开发一个应用程序,并且我正在尝试在用户输入错误的情况下维护表单的值。

如果有用户输入错误,其他字段(类型<input>)的旧数据“仍然存在”,但对于不起作用的<select>,我不明白为什么......?!

这是控制器的代码:

public function addAction() {
        $form = new InscriptionForm();  
        $form->get('submit')->setValue('Add');

        $request = $this->getRequest();
        if ($request->isPost()) {
            $inscription = new Inscription();
            $form->setInputFilter($inscription->getInputFilter());
            $form->setData($request->getPost());
            if ($form->isValid() && ($request->getPost('ACTIVITE1') != 0 || $request->getPost('ACTIVITE2') != 0 || $request->getPost('ACTIVITE3') != 0)) {
                $data = $form->getData();
                $inscription->exchangeArray($data);
                $lastId = $this->getInscriptionTable()->saveInscription($inscription);
                $sm = $this->getServiceLocator();
                $adapter = $sm->get('Zend\Db\Adapter\Adapter');
// code - requests
 } else {
                $sm = $this->getServiceLocator();
                $adapter = $sm->get('Zend\Db\Adapter\Adapter');
                $statement = $adapter->query(
                    "
                    SELECT *
                    FROM session
                    "
                );
                $results = $statement->execute();
                if ($request->getPost('ACTIVITE1') == 0 && $request->getPost('ACTIVITE2') == 0 && $request->getPost('ACTIVITE3') == 0) {
                    return new ViewModel(array(
                        'errors' => 'Le formulaire contient une ou plusieurs erreurs : Au moins une activité doit être renseignée.',
                        'form' => $form,
                        'sessions' => $results
                    ));
                } else {
                    return new ViewModel(array(
                        'errors' => 'Le formulaire contient une ou plusieurs erreurs.',
                        'form' => $form,
                        'sessions' => $results
                    ));
                }
            }
        }
        $sm = $this->getServiceLocator();
        $adapter = $sm->get('Zend\Db\Adapter\Adapter');
        $statement = $adapter->query(
            "
            SELECT *
            FROM session
            "
        );
        $results = $statement->execute();
            
        return new ViewModel(array(
            'form' => $form,
            'sessions' => $results
        ));
    }

模型铭文:

<?php

namespace Inscription\Model;

use Zend\InputFilter\InputFilter;
use Zend\InputFilter\InputFilterAwareInterface;
use Zend\InputFilter\InputFilterInterface;
use Zend\Validator\StringLength;
use Zend\Validator\NotEmpty;
use Zend\Validator\Date;
use Zend\Validator\Regex;

class Inscription implements InputFilterAwareInterface {

    public $id_inscription;
    public $dt_inscription;
    // i delete some attributes because the post was too long
    // from insc_sess
    public $activite1;
    public $activite2;
    public $activite3;

    protected $inputFilter;

    public function getArrayCopy() {
        return get_object_vars($this);
    }

    public function exchangeArray($data) {
        $this->id_inscription     = (!empty($data['ID_INSCRIPTION'])) ? $data['ID_INSCRIPTION'] : null;
        $this->dt_inscription = (!empty($data['DT_INSCRIPTION'])) ? $data['DT_INSCRIPTION'] : null;

        $this->nom_enfant  = (!empty($data['NOM_ENFANT'])) ? $data['NOM_ENFANT'] : null;
        $this->prenom_enfant     = (!empty($data['PRENOM_ENFANT'])) ? $data['PRENOM_ENFANT'] : null;
        $this->sexe_enfant = (!empty($data['SEXE_ENFANT'])) ? $data['SEXE_ENFANT'] : null;
        $this->dtNaissance_enfant  = (!empty($data['DTNAISSANCE_ENFANT'])) ? $data['DTNAISSANCE_ENFANT'] : null;
        $this->nom_ecole    = (!empty($data['NOM_ECOLE'])) ? $data['NOM_ECOLE'] : null;

        $this->resp1 = (!empty($data['RESP1'])) ? $data['RESP1'] : null;
        $this->adresse_resp1  = (!empty($data['ADRESSE_RESP1'])) ? $data['ADRESSE_RESP1'] : null;
        $this->tel_Resp1     = (!empty($data['TEL_RESP1'])) ? $data['TEL_RESP1'] : null;
        $this->mail_Resp1 = (!empty($data['MAIL_RESP1'])) ? $data['MAIL_RESP1'] : null;

        $this->resp2  = (!empty($data['RESP2'])) ? $data['RESP2'] : null;
        $this->adresse_resp2  = (!empty($data['ADRESSE_RESP2'])) ? $data['ADRESSE_RESP2'] : null;
        $this->tel_Resp2  = (!empty($data['TEL_RESP2'])) ? $data['TEL_RESP2'] : null;
        $this->mail_Resp2 = (!empty($data['MAIL_RESP2'])) ? $data['MAIL_RESP2'] : null;

        $this->activite1 = (!empty($data['ACTIVITE1'])) ? $data['ACTIVITE1'] : null;
        $this->activite2 = (!empty($data['ACTIVITE2'])) ? $data['ACTIVITE2'] : null;
        $this->activite3 = (!empty($data['ACTIVITE3'])) ? $data['ACTIVITE3'] : null;

        $this->autorise1  = (!empty($data['AUTORISE1'])) ? $data['AUTORISE1'] : null;
        $this->autorise2     = (!empty($data['AUTORISE2'])) ? $data['AUTORISE2'] : null;
        $this->saitNager = (!empty($data['SAITNAGER'])) ? $data['SAITNAGER'] : null;
        $this->traitement  = (!empty($data['TRAITEMENT'])) ? $data['TRAITEMENT'] : null;
        $this->ouiTraitement     = (!empty($data['OUITRAITEMENT'])) ? $data['OUITRAITEMENT'] : null;
        $this->allergies = (!empty($data['ALLERGIES'])) ? $data['ALLERGIES'] : null;
        $this->autresAllergies  = (!empty($data['AUTRESALLERGIES'])) ? $data['AUTRESALLERGIES'] : null;
        $this->autreSante     = (!empty($data['AUTRESSANTE'])) ? $data['AUTRESSANTE'] : null;

        $this->coche = (!empty($data['COCHE'])) ? $data['COCHE'] : null;
        $this->dateNew  = (!empty($data['DTNEW'])) ? $data['DTNEW'] : null;
        $this->utilNew     = (!empty($data['UTILNEW'])) ? $data['UTILNEW'] : null;
        $this->dateMAJ = (!empty($data['DTMAJ'])) ? $data['DTMAJ'] : null;
        $this->utilMAJ  = (!empty($data['UTILMAJ'])) ? $data['UTILMAJ'] : null;
    }

    public function setInputFilter(InputFilterInterface $inputFilter) {
        throw new \Exception("Not used");
    }

    public function getInputFilter()
    {
        if (!$this->inputFilter) {
            $inputFilter = new InputFilter();

            $inputFilter->add(array(
                'name'     => 'DTNAISSANCE_ENFANT',
                'required' => true,
                'filters'  => array(
                    array('name' => 'StripTags'),
                    array('name' => 'StringTrim'),
                ),
                'validators' => array(
                    array(
                        'name' => 'NotEmpty',
                        'options' => array(
                            'messages' => array(
                                NotEmpty::IS_EMPTY => "Champ obligatoire"
                            )
                        )
                    ),
                ),
            ));

            $inputFilter->add(array(
                'name'     => 'SAITNAGER',
                'required' => true,
                'filters'  => array(
                    array('name' => 'StripTags'),
                    array('name' => 'StringTrim'),
                ),
                'validators' => array(
                    array(
                        'name' => 'NotEmpty',
                        'options' => array(
                            'messages' => array(
                                NotEmpty::IS_EMPTY => "Champ obligatoire"
                            )
                        )
                    ),
                ),
            ));

            $inputFilter->add(array(
                'name'     => 'TRAITEMENT',
                'required' => true,
                'filters'  => array(
                    array('name' => 'StripTags'),
                    array('name' => 'StringTrim'),
                ),
                'validators' => array(
                    array(
                        'name' => 'NotEmpty',
                        'options' => array(
                            'messages' => array(
                                NotEmpty::IS_EMPTY => "Champ obligatoire"
                            )
                        )
                    ),
                ),
            ));

            $inputFilter->add(array(
                'name'     => 'COCHE',
                'required' => true,
                'filters'  => array(
                    array('name' => 'StripTags'),
                    array('name' => 'StringTrim'),
                ),
                'validators' => array(
                    array(
                        'name' => 'NotEmpty',
                        'options' => array(
                            'messages' => array(
                                NotEmpty::IS_EMPTY => "Champ obligatoire"
                            )
                        )
                    ),
                ),
            ));
            
            $this->inputFilter = $inputFilter;
        }
        return $this->inputFilter;
    }
}

InscriptionForm 类:

<?php

namespace Inscription\Form;

use Zend\Form\Form;
use Zend\Form\Element;
use Zend\Form\Element\Date;

class InscriptionForm extends Form {

    public function __construct($name = null) {
        parent::__construct('inscription');

        $this->add(array(
            'name' => 'ID_INSCRIPTION',
            'type' => 'hidden',
            'required' => 'required'
        ));

        $this->add(array(
            'name' => 'NOM_ENFANT',
            'type' => 'Text',
            'required' => 'required',
            'options' => array(
                'label' => ' * Nom :',
            ),
            'attributes' => array(
                'class' => 'form-control',
                'style' => 'text-transform : uppercase'
            )
        ));

        $this->add(array(
            'name' => 'PRENOM_ENFANT',
            'type' => 'Text',
            'required' => 'required',
            'options' => array(
                'label' => '* Prénom :',
            ),
            'attributes' => array(
                'class' => 'form-control',
                                'style' => 'text-transform : uppercase'
            )
        ));

        $this->add(array(
            'name' => 'SEXE_ENFANT',
            'type' => 'Zend\Form\Element\Radio',
            'required' => 'required',
            'options' => array(
                'label' => '* Sexe :',
                'value_options' => array(
                    'F' => 'Fille',
                    'G' => 'Garçon',
                ),
            ),
            'attributes' => array(
               
            )
        ));

        $this->add(array(
            'name' => 'DTNAISSANCE_ENFANT',
            'type' => 'Text',
            'required' => 'required',
            'options' => array(
                'label' => '* Date de naissance :',
            ),
            'attributes' => array(
                'class' => 'form-control date-field',
                'id' => 'input-dtNaissance',
                'placeholder' => 'jj/mm/AAAA',
                'pattern' => '^([0-2][0-9]|(3)[0-1])(\/)(((0)[0-9])|((1)[0-2]))(\/)\d{4}$'
            )
        ));

        $this->add(array(
            'name' => 'NOM_ECOLE',
            'type' => 'Text',
            'required' => 'required',
            'options' => array(
                'label' => '* Nom de l\'école :',
            ),
            'attributes' => array(
                'class' => 'form-control',
                'style' => 'text-transform : uppercase'
            )
        ));

        $this->add(array(
            'name' => 'ACTIVITE1',
            'type' => 'Zend\Form\Element\Select',
            'options' => array(
                'value_options' => array(
                    'Choisir l\'activité'
                ),
                'disable_inarray_validator' => true,
            ),
            'attributes' => array(
                'class' => 'form-control',
                'id' => 'select-session1'
            )
        ));

        $this->add(array(
            'name' => 'ACTIVITE2',
            'type' => 'Zend\Form\Element\Select',
            'options' => array(
                'value_options' => array(
                    'Choisir l\'activité'
                ),
                'disable_inarray_validator' => true,
            ),
            'attributes' => array(
                'class' => 'form-control',
                'id' => 'select-session2'
            )
        ));

        $this->add(array(
            'name' => 'ACTIVITE3',
            'type' => 'Zend\Form\Element\Select',
            'options' => array(
                'value_options' => array(
                    'Choisir l\'activité'
                ),
                'disable_inarray_validator' => true,
            ),
            'attributes' => array(
                'class' => 'form-control',
                'id' => 'select-session3'
            )
        ));

        $this->add(array(
            'name' => 'RESP1',
            'type' => 'Text',
            'required' => 'required',
            'options' => array(
                'label' => '* Nom, prénom Responsable 1:',
            ),
            'attributes' => array(
                'class' => 'form-control',
                'style' => 'text-transform : uppercase'
            )
        ));

        $this->add(array(
            'name' => 'ADRESSE_RESP1',
            'type' => 'Text',
            'required' => 'required',
            'options' => array(
                'label' => '* Adresse Responsable 1:',
            ),
            'attributes' => array(
                'class' => 'form-control',
                'style' => 'text-transform : uppercase'
            )
        ));

        $this->add(array(
            'name' => 'TEL_RESP1',
            'type' => 'Text',
            'options' => array(
                'label' => '* Téléphone Responsable 1:',
            ),
            'attributes' => array(
            'pattern' => '^0[1-78]([-. ]?[0-9]{2}){4}$',
                'class' => 'form-control',
                 'style' => 'text-transform : uppercase'
            )
        ));

        $this->add(array(
            'name' => 'MAIL_RESP1',
            'type' => 'Zend\Form\Element\Email',
            'options' => array(
                'label' => '* Mail Responsable 1:',
            ),
            'attributes' => array(
                'class' => 'form-control'
            )
        ));

        $this->add(array(
            'name' => 'RESP2',
            'type' => 'Text',
            'options' => array(
                'label' => 'Nom, Prénom Responsable 2 :',
            ),
            'attributes' => array(
                'class' => 'form-control',
                'style' => 'text-transform : uppercase'
            )
        ));

        $this->add(array(
            'name' => 'ADRESSE_RESP2',
            'type' => 'Text',
            'options' => array(
                'label' => 'Adresse Responsable 2 :',
                'style' => 'text-transform : uppercase'
            ),
            'attributes' => array(
                'class' => 'form-control'
            )
        )); 

        $this->add(array(
            'name' => 'TEL_RESP2',
            'type' => 'Text',
            'options' => array(
                'label' => 'Téléphone Responsable 2 :',
            ),
            'attributes' => array(
                'pattern' => '^0[1-78]([-. ]?[0-9]{2}){4}$',
                'class' => 'form-control',
                'style' => 'text-transform : uppercase'
            )
        )); 

        $this->add(array(
            'name' => 'MAIL_RESP2',
            //'type' => 'Zend\Form\Element\Email',
            'type' => 'Text',
            'options' => array(
                'label' => 'Mail Responsable 2 :',
            ),
            'attributes' => array(
                'class' => 'form-control',
            )
        ));

        $this->add(array(
            'name' => 'AUTORISE1',
            'type' => 'Text',
            'options' => array(
                'label' => 'Nom, prénom :',
            ),
            'attributes' => array(
                'class' => 'form-control',
                    'style' => 'text-transform : uppercase'
            )
        ));

        $this->add(array(
            'name' => 'AUTORISE2',
            'type' => 'Text',
            'required' => 'required',
            'options' => array(
                'label' => 'Nom, prénom :',
            ),
            'attributes' => array(
                'class' => 'form-control',
                    'style' => 'text-transform : uppercase'
            )
        ));

        $this->add(array(
            'name' => 'SAITNAGER',
            'type' => 'Zend\Form\Element\Checkbox',
            'options' => array(
                'label' => 'Sait Nager :',
                'use_hidden_element' => true,
                'checked_value' => 'O',
                'unchecked_value' => 'N'
            ),
            'attributes' => array(
                'id' => 'input-SaitNager'
            )
        ));

        $this->add(array(
            'name' => 'TRAITEMENT',
            'type' => 'Zend\Form\Element\Checkbox',
            'options' => array(
                'label' => 'Traitement :',
                'use_hidden_element' => true,
                'checked_value' => 'O',
                'unchecked_value' => 'N'
            ),
            'attributes' => array(
                'id' => 'input-Traitement'
            )
        ));

        $this->add(array(
            'name' => 'OUITRAITEMENT',
            'type' => 'Text',
            'options' => array(
                'label' => 'Si oui lequel :',
            ),
            'attributes' => array(
                'class' => 'form-control',
                    'style' => 'text-transform : uppercase'
            )
        ));

        $this->add(array(
            'name' => 'ALLERGIES',
            'type' => 'Zend\Form\Element\Radio',
            'options' => array(
                'disable_inarray_validator' => true,
                'label' => '* Allergies : ',
                'value_options' => array(
                    'Aucune' => 'Aucune',
                    'Asthmatiques' => 'Asthmatiques',
                    'Médicamenteuses' => 'Médicamenteuses',
                    'Alimentaires' => 'Alimentaires',
                    'Autres' => 'Autres',
                ),
            ),
            'attributes' => array(
                'id' => 'input-allegies'
            )
        ));

        $this->add(array(
            'name' => 'AUTRESALLERGIES',
            'type' => 'Text',
            'options' => array(
                'label' => 'Si autres, précisez :',
            ),
            'attributes' => array(
                'id' => 'input-autresallergies',
                'class' => 'form-control',
                    'style' => 'text-transform : uppercase'
            )
        ));

        $this->add(array(
            'name' => 'AUTRESSANTE',
            'type' => 'Zend\Form\Element\Textarea',
            'options' => array(
                'label' => 'Autres difficultés de santé :',
            ),
            'attributes' => array(
                'id' => 'input-autresante',
                'class' => 'form-control',
                'rows' => "5",
                    'style' => 'text-transform : uppercase'
            )
        ));

        $this->add(array(
            'name' => 'COCHE',
            'type' => 'Zend\Form\Element\Checkbox',
            'options' => array(
                'label' => '* Je certifie que ces informations sont correctes :',
                'use_hidden_element' => true,
                'checked_value' => 'O',
                'unchecked_value' => ''
            ),
            'attributes' => array(
                'id' => 'checkbox-coche'
            )
        ));

        $this->add(array(
            'name' => 'submit',
            'type' => 'submit',
            'options' => array(
                'value' => 'Valider',
            ),
            'attributes' => array(
                'id' => 'validation-form-inscription',
                'class' => 'button-default'
            )
        ));
    }
}

与我的问题有关的选择被命名为ACTIVITE1/ACTIVITE2/ACTIVITE3... 这些选择的选项是使用 json 加载的,其想法是根据表格中告知的出生日期提出活动。

这里是加载 select 选项的 jQuery 代码:

        $().ready(function() {
            var dateNaissance = $("#input-dtNaissance").val();
            if (dateNaissance != "") {
                var year = $("#input-dtNaissance").val().substring(6,10);
                if (year == "") {
                    year = 1;
                }
                // si date supprimée/réinitialisée 
                if (year == 1) {
                // on supprime les activités proposées du select
                $(".activites-options").remove();
                } else {
                    $.getJSON("<?php echo $this->basePath() ?>/activite/listActivitySession1/" + year, function(data) {
                        data.forEach(function(element) {
                            var option = "<option value='" + element.ID_ACTIVITES + "' class='activites-options'>" +element.activite[0] + element.activite.substring(1).toLowerCase() + " avec " + element.INTERVENANT + " - " + element.HORAIREDEB + "/" + element.HORAIREFIN + " (" + element.site[0] + element.site.substring(1).toLowerCase() + ")" + "</option>";
                            $("#select-session1").append(option);
                        });
                    });
                    $.getJSON("<?php echo $this->basePath() ?>/activite/listActivitySession2/" + year, function(data) {
                        data.forEach(function(element) {
                            var option = "<option value='" + element.ID_ACTIVITES + "'class='activites-options'>" + element.activite[0] + element.activite.substring(1).toLowerCase() + " avec " + element.INTERVENANT + " - " + element.HORAIREDEB + "/" + element.HORAIREFIN + " (" + element.site[0] + element.site.substring(1).toLowerCase() + ")" + "</option>";
                            $("#select-session2").append(option);
                        });
                    });
                    $.getJSON("<?php echo $this->basePath() ?>/activite/listActivitySession3/" + year, function(data) {
                        data.forEach(function(element) {
                            var option = "<option value='" + element.ID_ACTIVITES + "' class='activites-options'>" + element.activite[0] + element.activite.substring(1).toLowerCase() + " avec " + element.INTERVENANT + " - " + element.HORAIREDEB + "/" + element.HORAIREFIN + " (" + element.site[0] + element.site.substring(1).toLowerCase() + ")" + "</option>";
                            $("#select-session3").append(option);
                        });
                    });
                }
            }
        })

如果有人提出想法,我将不胜感激,因为我现在有点卡住了!提前谢谢...

【问题讨论】:

  • 可以发布“铭文”类吗?
  • 是的,我已经编辑了我的帖子:)
  • 我唯一能想到的就是验证。这三个选择的选项是什么?您传递的不是选择验证器不接受的值吗?
  • select的选项来自数据库,我将它们序列化为json并加载到视图中。
  • 因此您只使用前端代码呈现您的选择选项。这意味着您的后端完全不知道这些值(所有选择都是空的),因此不可能将“selected”设置为未注册的值。

标签: php zend-framework zend-form


【解决方案1】:

正如我在评论中所说,问题在于您的选择元素没有任何选项。

这意味着,在验证时,表单会尝试绑定和验证一个不在选项中的值他知道

实际情况如下:

  • 您创建了一个没有选项的Select 元素
  • 您将此选择添加到表单中
  • 您在控制器中创建表单并将其传递给视图
  • 在视图中,您打印以下选项(值、标签):
    • 1、足球
    • 2、单车
    • 3,篮子
    • 4,法式滚球

这些值只存在于视图中。对于表单,所有这些值都不存在。这意味着:

  • 你点击“提交按钮”,发送 POST 请求
  • 您将数据设置为表单
  • 表单将尝试将值“4”绑定到元素activite1
  • 表单将无法绑定此值,因为它不是您选择中的有效选项(因为您将其创建为空)
  • activity1 将结果为空,并将其传递给视图

这就是为什么当表单出现错误时这些 select 的值会被刷新。

要解决此问题,您必须(最佳解决方案):

  • 创建一个自定义元素类,例如ActivitySelect,您将在其中创建一个包含所有这些选项的选择
  • 不要在表单中使用Select,而是使用ActivitySelect
  • 您将创建所有需要的工厂
  • 您将通过 FormElementManager 检索表单。

一个类似的、更简单但更糟糕的解决方案是为表单创建一个工厂,您将在其中传递所有必要的对象来为表单创建选项。这将避免创建自定义元素类,但我发现这个解决方案对于可维护性来说不是那么干净

由于这个问题已经回答了几次,我将避免在这里重写所有内容并链接一个:

【讨论】:

    猜你喜欢
    • 2017-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多