2

我必须修改一个 Zend 表单,其中一些字段可以包含小数。目前您只能使用点输入小数:34.75)

我希望用户能够用逗号或点写他们的小数。这些字段可以包含任何一个数字,例如34.7534,75(在这种情况下,两者具有相同的值)。我不想修改服务器上的任何配置,所以我需要在代码中这样做。

现在某些字段的值是根据其他字段的函数计算的;所以当你输入一个逗号时,它会打乱计算。它是在 javascript 中完成的,我需要修复这些计算 - 但现在,我想在检索表单时在 php 代码中修复这个问题。

我试图在 Zend 网站上找到解决方案,但我没有找到任何我已经在其他地方阅读过的更多示例。正如您将在代码中看到的,我需要将过滤器或验证器添加到zend_form_element_text. 我不能使用 a str_replace,因为元素是 a zend_form_element_text

我发现了这个其他问题供参考。

这是我的结果代码:

$tabBilanFrais = array( 'txtFraisSecretariat' => array( 'nom' => 'Frais secrétariat', 'disabled' => true, "class"=>"calcul"),
                            'txtFraisRegion' => array( 'nom' => 'Frais région', 'disabled' => false),
                            'txtFraisSalle' => array( 'nom' => 'Salle', 'disabled' => false, "class"=>"calcul"),
                            'txtFraisPause' => array( 'nom' => 'Pauses', 'disabled' => false, "class"=>"calcul"),
                            'txtDivers' => array( 'nom' => 'Divers', 'disabled' => false, "class"=>"calcul"),
                            'txtTotalRegion' => array( 'nom' => 'Total région', 'disabled' => true, "class"=>"total"),
                            'txtIndemnisationAdherent' => array( 'nom' => 'Comm. ADH', 'disabled' => true, "class"=>"calcul"),
                            'txtIndemnisationPAP' => array( 'nom' => 'Comm. PAP', 'disabled' => true, "class"=>"calcul"),
                            'txtIndemnisationForNext' => array( 'nom' => 'Comm. ForNext', 'disabled' => true, "class"=>"calcul"),
                            'txtIndemnisationPROStages' => array( 'nom' => 'Comm. PROStages', 'disabled' => true, "class"=>"calcul"),
                            'txtRecettes' => array( 'nom' => 'Recettes', 'disabled' => true, "class"=>"totalMontant"),
                            'txtDepenses' => array( 'nom' => 'Dépenses', 'disabled' => true, "class"=>"totalMontant"),
                            'txtRecettesH' => array( 'nom' => 'Recettes', 'disabled' => false, "class"=>"hiddenTxt"),
                            'txtDepensesH' => array( 'nom' => 'Dépenses', 'disabled' => false, "class"=>"hiddenTxt")
                    );


$tabFormulaire = array() ;

foreach($tabBilanFrais as $id => $tabElement)
{
    if($tabElement['nom'] == 'Frais region' )
        $element = new Zend_Form_Element_Hidden($id, array("label" => $tabElement['nom'], "required" => false, 'decorators' => array("ViewHelper", "Errors", "Label"))) ;
    else{
        $element = new Zend_Form_Element_Text($id, array("label" => $tabElement['nom'], "required" => false, 'decorators' => array("ViewHelper", "Errors", "Label"))) ;
        //$element->addFilter('pregReplace', array('match' => '/,/', 'replace' => '.'));
        $element->addFilter('LocalizedToNormalized');
        $element->addValidator('float', true, array('locale' => 'fr_FR'));
        if(isset($tabElement['class']) && $tabElement['class']){
            $element->setAttrib('class', $tabElement['class']);
        }
    }

    if( $tabElement['disabled'])
        $element->setAttrib('disabled', 'disabled');



    $tabFormulaire[] = $element ;
}

pregReplace不工作。验证器是(comma becomes a .). 我收到关于数字不是浮点数的错误消息。

4

3 回答 3

2

You can always write your own validator. In case of float I faced the same problem like you:

class Yourlib_Validate_Float extends Zend_Validate_Abstract
{
    const INVALID   = 'floatInvalid';
    const NOT_FLOAT = 'notFloat';

    /**
     * @var array
     */
    protected $_messageTemplates = array(
        self::INVALID   => "Invalid type given. String, integer or float expected",
        self::NOT_FLOAT => "'%value%' does not appear to be a float",
    );

    public function isValid($value)
    {
        $this->_setValue($value);

        $value = str_replace(',', '.', $value);

        if (!is_string($value) && !is_int($value) && !is_numeric($value)) {
            $this->_error(self::INVALID);
            return false;
        }

        if (is_numeric($value)) {
            return true;
        }

        $this->_error(self::NOT_FLOAT);
        return false;
    }
}

And to add the validator:

$element->addValidator(new Yourlib_Validate_Float());

Please rename Yourlib to whatever suits you. And you need to register your "namespace" in the application.ini like this:

autoloadernamespaces.Yourlib = "Yourlib_"

Strictly speaking this validator is a numeric validator. It accepts all numeric values like ints and floats thru the check with is_numeric. Feel free to modify that.

于 2013-07-15T15:26:42.367 回答
0

好了,下面是修改后的部分代码:

foreach($tabBilanFrais as $id => $tabElement)
        {
            if($tabElement['nom'] == 'Frais region' )
                $element = new Zend_Form_Element_Hidden($id, array("label" => $tabElement['nom'], "required" => false, 'decorators' => array("ViewHelper", "Errors", "Label"))) ;
            else{
                $element = new Zend_Form_Element_Text($id, array("label" => $tabElement['nom'], "required" => false, 'decorators' => array("ViewHelper", "Errors", "Label"))) ;
                $element->addFilter('pregReplace', array('match' => '/,/', 'replace' => '.'));
                $element->addFilter('LocalizedToNormalized');
                $element->addValidator(new Anper_Validate_Float(), true, array('locale' => 'fr_FR'));
                if(isset($tabElement['class']) && $tabElement['class']){
                    $element->setAttrib('class', $tabElement['class']);
                }
            }

            if( $tabElement['disabled'])
                $element->setAttrib('disabled', 'disabled');



            $tabFormulaire[] = $element ;
        }

但是现在我需要 $element 中的字段值在将元素添加到 $tabFormulaire 之前将逗号替换为点。当前,当我验证表单并显示更新的值时,带有逗号的数字会被截断(124,5 变为 124)。pregreplace 似乎不起作用。

编辑:看来我不需要 pregReplace。我在自定义验证器的 isValid 函数中使用了两个回显:一个在 str_replace 之前,一个在之后。当我在其中一个字段中写入一个带逗号的值时,两个回显都显示带有点的数字。我认为这是过滤器 LocalizedToNormalized 的结果。我不明白的是,为什么一旦保存并显示了这些值,尽管我刚刚做出了发现,但那些带有逗号的值会被截断。

Edit2:如果我写例如 124 8,并使用 pregReplace 来做就像没有空白一样,则 8 不会保存;尽管 pregReplace 工作(尝试了我以前的回声)。

于 2013-07-16T07:05:20.687 回答
0

尽管@bitWorking 的回答是 100% OK,但从语义的角度来看,最好使用过滤器(因为它更多的是过滤而不是验证)

NumberFormat 过滤器或编写您自己的过滤器。

于 2017-07-02T07:41:02.423 回答