float numbers validation in form - php

I am trying to have a form with float number validation.
when validation works it won't let me click the submit button and will show the proper error message.
I am using zend framework 2 and in my Form I want to retrieve alcohol volume.
I'm trying to use the following code:
$this->add($factory->createElement(array(
'name' => 'alcohol_vol',
'attributes' => array(
'label' => 'alcohol vol%:',
'filters' => array('Float'),
'type' => 'text',
'required' => true,
),
)));
this doesn't do anything actually. it will pass validation if i enter regular text.
I also tried changing the type to 'Number' from 'text' but then it won't allow me to use floating number. it will allow only none-float numbers :)

There is no "Float" filter in ZF2, I guess may you want is "Float" Validator, Float Validator could be add into ZF2 form like this:
$this->add($factory->createElement(array(
'name' => 'alcohol_vol',
'attributes' => array(
'label' => 'alcohol vol%:',
'type' => 'text',
),
)));
$factory = new Zend\InputFilter\Factory();
$this->setInputFilter($factory->createInputFilter(array(
'alcohol_vol' => array(
'name' => 'alcohol_vol',
'required' => true,
'validators' => array(
array(
'name' => 'Float',
),
),
),
)));
Then you should validate form in controller, above validators should still set into form. If input not float, the input element will have invalidate messages:
$form->setData($userInputData);
if (!$form->isValid()) {
$inputFilter = $form->getInputFilter();
$invalids = $inputFilter->getInvalidInput();
var_dump($invalids);
// output: 'abc' does not appear to be a float
}

I think you can use this filter
new Zend\I18n\Filter\NumberFormat("en_US", NumberFormatter::TYPE_DOUBLE);

I recommend the Zend\I18n\Validator\Float class. Example usage:
$floatInput = new Input('myFloatField');
$floatInput->getValidatorChain()
->attach(new \Zend\I18n\Validator\Float());
See:
http://framework.zend.com/manual/2.3/en/modules/zend.input-filter.intro.html
http://framework.zend.com/manual/2.0/en/modules/zend.validator.set.html#validating-digits

Related

Nested Parameters/Values in POST Requests

I have been thinking about a good way to handle nested/complex values in POST requests to a apigility resource.
For example, an order might contain a collection of order items in a single POST requested that is used to create an order. Both, order and order-item do exist as a resource. However, I would very much like to have only one request that would create order and order item entities. Handling that in the resource is not a problem, but I wonder how you would configure that resource (let´s call it order-place) using the apigiliy UI - or, if at all impossible, using the configuration. Applying validators and filters is one of the key features of apigility, and i´d like to keep using that, even for complex request data.
And before you ask, using an underscore to separate the values scopes, for example order_comment and order_item_comment should not be an option.
Any ideas?:)
Addition: A sample json request payload could look like this:
{
"created_at": "2000-01-01",
"amount" : "5000.00",
"address" : {
"name": "some name",
"street": "some street"
...
},
"items" : [
{"productId":99,"qty":1}
...
]
}
Starting from Wilt's answer, I've found that the following code works as well:
# file path: /module/MyApi/config/module.config.php
// some other stuff
'MyApi\\V1\\Rest\\MyRestService\\Validator' => array(
'address' => array(
0 => array(
'name' => 'name',
'required' => true,
'filters' => array(),
'validators' => array(),
),
1 => array(
'name' => 'street',
'required' => true,
'filters' => array(),
'validators' => array(),
),
'type' => 'Zend\InputFilter\InputFilter'
),
'amount' => array(
'name' => 'amount',
'required' => true,
'filters' => array(),
'validators' => array()
)
The only problem I get is when address is passed as a field (string or numeric) rather then an array or object. In this case Apigility throws an exception:
Zend\InputFilter\Exception\InvalidArgumentException: Zend\InputFilter\BaseInputFilter::setData expects an array or Traversable argument; received string in /var/www/api/vendor/zendframework/zendframework/library/Zend/InputFilter/BaseInputFilter.php on line 175
Adding address as a further simple (required) field avoids the exception, but then Apigility doesn't see any difference whether we pass address as an array of name and street or a dummy string.
If you are using the ContentValidation module then you can configure an input filter for the nested resources by assigning it to a variable. Then you have to add a type key (essential otherwise reusing the filter won't work). Now you are able to use this variable in your input_filter_specs and you can reuse the whole filter inside another filter. So something like this in your config.php:
<?php
namespace Application;
// Your address config as if it was used independently
$addressInputFilter => array(
'name' => array(
'name' => 'name',
'required' => true,
'filters' => array(
//...
)
'validators' => array(
//...
)
),
'street' => array(
'name' => 'street',
'required' => true,
'filters' => array(
//...
)
'validators' => array(
//...
)
),
// 'type' key necessary for reusing this input filter in other configs
'type' => 'Zend\InputFilter\InputFilter'
),
'input_filter_specs' => array(
// The key for your address if you also want to be able to use it independently
'Application\InputFilter\Address'=> $addressInputFilter,
// The key and config for your other resource containing a nested address
'Application\InputFilter\ItemContainingAddress'=> array(
'address' => $addressInputFilter,
'amount' => array(
'name' => 'amount',
'required' => true,
'filters' => array(
//...
),
'validators' => array(
//...
)
)
//... your other fields
)
)

Zendframework 2 Checkox

im pretty new to ZF2 and i have a pretty strange problem. I´ve created a simple checkbox using arrays,
and set checked value to good and unchecked value to bad. But when i submit my form, the URL shows that when the checkbox is checked, it sends .....checkbox=bad&checkbox=good... I don´t know why.
class SearchForm extends Form {
public function __construct($name = null){
parent:: __construct('Search');
$this->setAttribute('method', 'get');
$this->setAttribute ( 'enctype', 'multipart/formdata' );
$this->add(array(
'type' => 'Zend\Form\Element\Checkbox',
'name' => 'checkbox',
'options' => array(
'label' => 'A checkbox',
'checked_value' => 'good',
'unchecked_value' => 'bad',
),
));
Because by default Zend\Form\Element\Checkbox has use_hidden_element is true.
If set to true (which is default), the view helper will generate a
hidden element that contains the unchecked value. Therefore, when
using custom unchecked value, this option have to be set to true.
You use GET method. Of couse, you see two values in query string: for checkbox and for hidden elements.
See more carefully ZF2#Checkbox.
Not 100% sure this is the answer to the issue and not in a position to test right now but it is likely to do with the hidden element that the checkbox uses try:
$form->add(array(
'type' => 'Zend\Form\Element\Checkbox',
'name' => 'checkbox',
'options' => array(
'label' => 'A checkbox',
'use_hidden_element' => false,
'checked_value' => 'good',
'unchecked_value' => 'bad'
),
));

Zend Form Validate URL

I am currently validating a URL using the Regex Pattern and it appears to be working correctly. However, if I leave the URL field blank, it should not check the Regex Validation or perhaps just return a message like "No URL given".
Here is an example of my current code I'm working with:
array(
'name' => 'programurl1',
'attributes' => array(
'type' => 'text',
'error_msg' => 'Enter Valid Program URL 1',
'label_msg' => 'Program URL 1 *'
),
'validation' => array(
'required' => true,
'filters' => array(
array(
'name' => 'StripTags'
),
array(
'name' => 'StringTrim'
)
),
'validators' => array(
array(
'name' => 'Regex',
'options' => array(
'pattern' => '/^(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$/'
)
)
)
)
)
I'm not certain how to accomplish what I am looking for when the URL field is blank.
Instead of a type text, you can use the url type. That is specifically meant to enter url values:
$this->add(array(
'name' => 'programurl',
'type' => 'Zend\Form\Element\Url',
'options' => array(
'label' => 'Program URL 1'
),
'attributes' => array(
'required' => 'required'
)
));
The url element is a special HTML5 element, see also the docs.
Zend\Form\Element\Url is meant to be paired with the Zend\Form\View\Helper\FormUrl for HTML5 inputs with type url. This element adds filters and a Zend\Validator\Uri validator to it’s input filter specification for validating HTML5 URL input values on the server.
Afaik if the browser cannot render the url input element, it just shows the text input as a fallback.

How do I use ZF2 regex validators within the factory pattern

Is anyone familiar with the use of ZF2 regex validators within the factory pattern?
I have taken this code from various blogs and other stackoverflow questions, but it does not seem to work.
The addition of the regex validator blocks all changes to my form from updating the database - so the validator must be failing even when I insert a number.
However, when I check
$form -> getMessages();
I get an empty array. Any insight would be appreciated.
To illustrate I use a very simple regex that, as I understand it, would block any entry character that is not a number.
$inputFilter->add($factory->createInput(array(
'name' => 'Number',
'required' => true,
'filters' => array(
array('name' => 'StripTags'),
array('name' => 'StringTrim'),
),
'validators' => array(
array(
'name' => 'StringLength',
'options' => array(
'encoding' => 'UTF-8',
'max' => 20,
),
),
),
array(
'name' => 'Regex',
'options' => array(
'pattern' => '/^[0-9]+$',
'messages' => array(
'Invalid input, only 0-9 characters allowed'
),
),
),
)));
At a glance, Regex validator should sit inside "validators" array...

How to give validator for floating point number in zend form?

Following is the piece of code which has been taken from form,
$debit_amount = new Zend_Form_Element_Text('debit_amount', array(
'label' => 'Debit_amount',
'value' => '',
'class' => 'text-size text',
'required' => true,
'tabindex' => '13',
'validators' => array(
array('Digits', false, array(
'messages' => array(
'notDigits' => "Invalid entry, ex. 10.00",
'digitsStringEmpty' => "",
))),
array('notEmpty', true, array(
'messages' => array(
'isEmpty' => 'Debit_amount can\'t be empty'
)
)),
),
'filters' => array('StringTrim'),
//'decorators' => $this->requiredElementDecorators,
//'description' => '<img src="' . $baseurl . '/images/star.png" alt="required" />',
));
$this->addElement($debit_amount);
When i try submit the form using floating number , it throws my error "Invalid Enter....". It does not validate floating point number. Kindly advice.
Use Zend_Validate_Float:
'validators' => array(
array('Float', ...
You are getting the error message because the Digits validator only validates digits. There is a comment about it in the Zend_Validate documentation:
Note: Validating numbers
When you want to validate numbers or numeric values, be aware that this validator only
validates digits. This means that any other sign like a thousand separator or a comma
will not pass this validator. In this case you should use Zend_Validate_Int or
Zend_Validate_Float.
As #Zyava says, using Zend_Validate_Float is the way to go.

Categories