我必须修改Zend表单,其中某些字段可以包含小数。目前,您只能使用一个点输入您的小数:34.75)
我希望用户能够用逗号或点来写小数。这些字段可以包含34.75
和34,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 .)
。我收到一条关于数字不是浮点数的错误消息。
答案 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或自己编写。