同时使用逗号和点分隔符

时间:2013-07-15 14:57:02

标签: php zend-framework

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

我希望用户能够用逗号或点来写小数。这些字段可以包含34.7534,75之类的数字(在这种情况下,两者都具有相同的值)。我不想修改服务器上的任何配置,所以我需要在代码中执行此操作。

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

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

I have found this other question for reference.

这是我的结果代码:

$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 .)。我收到一条关于数字不是浮点数的错误消息。

3 个答案:

答案 0 :(得分:2)

您始终可以编写自己的验证程序。在浮动的情况下,我遇到了和你一样的问题:

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;
    }
}

并添加验证器:

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

请将Yourlib重命名为适合您的任何内容。你需要在application.ini中注册你的“命名空间”,如下所示:

autoloadernamespaces.Yourlib = "Yourlib_"

严格来说,此验证程序是numeric验证程序。它通过is_numeric的检查接受所有数值,如整数和浮点数。随意修改它。

答案 1 :(得分: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函数中使用了两个echo:一个在str_replace之前,另一个在after之后。当我在其中一个字段中用逗号写入一个值时,echo都会显示带有一个点的数字。我假设它是过滤器LocalizedToNormalized的结果。 我不明白的是,为什么一旦值保存并显示那些带有逗号的内容会被截断,尽管我刚刚做出了调查结果。

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

答案 2 :(得分:0)

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

NumberFormat filter或自己编写。