zend form float and integer validation - zend-framework

I am using zend form. I want to validate a field and want to allow only flat and integer values in the field. It means user can either enter any floating value like 2.0 or 3.56, etc OR 4 or 7, etc. But I dont want to receive alpha numeric or alphabet input.
I have used digit validator but it only allows digits not floating number.
Can any body tell me how to put both validations together?
My code is as follows
$parent_affiliate_commission = new Zend_Form_Element_Text('parent_affiliate_commission');
$parent_affiliate_commission->setRequired(true)
->addFilter('StringTrim')
->addFilter('StripTags')
->addValidator('Digits')
->setAttrib('class', 'small')
->addValidator('StringLength', false, array(2, 100))
->setDecorators(array('ViewHelper', 'errors'))

It would be really easy to create and use a custom validator. You could validate simply by using PHP is_int and is_float functions and still do in the 'Zend way'.

By using the callback method I have validated the value in numeric.Because it will not allow the characters.
$inputFilter->add(
$factory->createInput(
array(
'name' => 'proximity',
'required' => true,
'validators' => array(
array(
'name' => 'Callback',
'options' => array(
'messages' => array(
\Zend\Validator\Callback::INVALID_VALUE => 'The proximity value should be numbers'
),
'callback' => function (
$value,
$context = array())
{
$isValid = is_numeric(
$value);
return $isValid;
}
)
)
)
)));

Related

How to set a default values to input field type in Prestashop backoffice in renderform

In renderform I have one input field and its type is "text". How to set a value to that input field, so at every time when the form is loaded the value should be displayed. I am using Prestashop 1.7.
Sample code:
array(
'type' => 'text',
'label' => $this->l('VENDOR_SERVER_IP'),
'name' => 'serverip',
'size' => 50,
'class' => 'fixed-width-xxl',
'required' => true,
'desc' => $this->l('Please enter your server ip.')
),
You need to use the fields_value property
$helper = new HelperForm();
//...
$helper->fields_value = array(
'serverip' => 'x:x:x:x'
);
You have no option to pass default value of input field in the form array. To provide default value, you have to use fields_value property of form helper.
$hlper = new HelperForm();
$value = 'Your already saved value if any';
if (empty($value)) {
$value = 'your default value';
}
$hlper->field_values = array('YOUR_FORM_INPUT_NAME' => $value);
echo $hlper->generate($your_form_array);

zf2 Form Validator DateTime dateInvalidDate

Trying to use a DateTime Form element in ZF2 and cannot valid the form.
$inputFilter->add(array(
'name' => 'event_datetime',
'required' => true,
'filters' => array(
array('name' => 'StringTrim'),
),
'validators' => array(
array(
'name' => 'StringLength',
'options' => array(
'encoding' => 'UTF-8',
'min' => 0,
'max' => 20,
),
),
),
));
Using this on the .phtml file.
<?php $formElement = $form->get('event_datetime');?>
<dt><?php echo $this->formLabel($formElement);?></dt>
<dd><?php echo $this->formDateTimeLocal($formElement);?>
<?php echo $this->formElementErrors($formElement);?>
NOTE: using formDateTimeLocal instead of formDateTime as the latter does not show the HTML5 elements.
Using Chrome the HTML5 DateTimeLocal field appears with a calendar and Time section.
When running $form->isValid() I receive: (var_dump($form->getMessages()))
array (size=1) 'event_datetime' => array (size=1) 'dateInvalidDate' => string 'The input does not appear to be a valid date' (length=44)
The getRequest->getPost() = public 'event_datetime' => string '2015-08-10T03:00' (length=16)
I've tried to split this field into 2: a Date and a Time field as separate variables. This works correctly for the Date BUT not for the Time element.
Reading around I've noticed this: ZF2 validating date and time format PT_BR always The input does not appear to be a valid date which does not help as I need the time component. (obviously I have looked at more than just 1 link but my rep on SO allows only 1 url in post.)
I've also read that Chrome and Opera cut off the 'seconds' part of the time field....
How to I validate either a \Zend\Form\Element\DateTime field or just the \Zend\Form\Element\Time for field...
I've tried to manually glue these together, add the :00 seconds part of the string to Time but to no effect.
If I set the input filter to 'required' => false I still receive the dateInvalidDate validator for for attempts: DateTime and Time...
So, the question is:
How do I validate a DateTime or Time field using Zf2 form elements and inputFilters. Following the Docs and example don't seem to work for me and manually creating the Time string also has the same issue.
Try this:
$inputFilter->add(array(
'type' => 'Zend\Form\Element\DateTimeLocal',
'name' => 'event_datetime',
'required' => true,
'options' => array(
'label' => 'Appointment Date',
'format' => 'Y-m-d\TH:i'
),
'filters' => array(
array('name' => 'StringTrim'),
),
'validators' => array(
array(
'name' => 'StringLength',
'options' => array(
'encoding' => 'UTF-8',
'min' => 0,
'max' => 20,
),
),
),
));
You get the error, because the datetime string/format you pass is different than the expected datetime format by default. Try playing with 'format' => 'Y-m-d\TH:i' to get the result.
Taken directly from Zend documentation. It's all the same, but with a different element.
use Zend\Form\Element;
use Zend\Form\Form;
$time = new Element\Time('time');
$time
->setLabel('Time')
->setAttributes(array(
'min' => '00:00:00',
'max' => '23:59:59',
'step' => '60', // seconds; default step interval is 60 seconds
))
->setOptions(array(
'format' => 'H:i:s'
));
$form = new Form('my-form');
$form->add($time);
My original issue was validation. The suggestion by Stanimir did help and the dateTimeLocal format has great in pointing me in the right direction.
The whole issue was with the 'format' value.
My main problem was that when populating the \Zend\Form\Element\Time field the format was H:i:s but the HTML5 form only submitted H:i. (also due to my 'format' setting which is OK)
So, when populating the form the DB field returned H:i:s which populated the form correctly BUT on submission failed IF I didn't edit the Time field.
THEREFORE: the answer to this questions is basically make sure the format submitted [and $form->bind($object), $form->setData($post) etc] is EXACTLY the same as the form element definition [H:i != H:i:s] and when pulling from database format to correspond to your required setting.
var_dump($form->get('valid_to_time')->getFormat());
var_dump($form->get('valid_to_time')->getValue());
Once this is the same all will be well and you can split DateTime fields into individual Date and Time (or use DateTime as above).
Sounds simple but this was a headache to get right.

zf2 doctrine form int required not working

$inputFilter->add(array(
'name' => 'seatingCapacity',
'required' => TRUE,
'filters' => array(
array('name' => 'Int'),
),
));
In my Doctrine Entity, I have a getInputFilter method which I use for form validation. The above is code snippet for one of the input elements. My problem is the required => true is not working even if I submit an empty form.
After researching I found out, that the Int filter converts the empty input to 0 and submits it and that is why the required validator is not working. I just need reasons why it may not be working.
For reference where I searched
Zend Framework 2 - Integer Form Validation
where he suggests to use Between validator
$inputFilter->add($factory->createInput(array(
'name' => 'zip',
'required' => true,
'filters' => array(
array('name' => 'Int'),
),
'validators' => array(
array(
'name' => 'Between',
'options' => array(
'min' => 1,
'max' => 1000,
)
)
)
)
));
I want to know why I should use Between and why required is failing.
You should only use the Between validator to validate if the given value is Between a min and max value. It has nothing to do with solving your empty value to 0 issue.
You should ask yourself 2 questions:
Is 0 a valid value?
Do I want to automatically cast null empty string ('') and other empty values to this 0 or not?
If you actually want to prevent that the Int filter sets an empty value to 0, maybe then you should not use this filter at all then?
You can instead add an IsInt validator to check if the given value is an integer. Your required => true setting will work as expected and validation will fail on any other (not integer) input so also on null, empty strings etc.
Thank you for your time, energy & effort.
Actually I solved the problem.
I had copy-pasted the code, which I should have been careful while doing so.
What I found out is there is no such filter named 'Int' and actually it's 'Digits'
$inputFilter->add(array(
'name' => 'seatingCapacity',
'required' => TRUE,
'filters' => array(
array('name' => 'Int'),
),
));
shows me error because the filter name should have been 'Digits'.
Only doing so solved my problem and works as per my requirement.
$inputFilter->add(array(
'name' => 'seatingCapacity',
'required' => TRUE,
'filters' => array(
array('name' => 'Digits'),
),
));
This is the right way to do and I would advice you to be careful while referring code from your sources because it's an illogical mistake I did.
Happy coding

Zend: Form validation: value was not found in the haystack error

I have a form with 2 selects. Based on the value of the first select, it updates the values of the second select using AJAX. Doing this makes the form not being valid. So, I made the next change:
$form=$this->getAddTaskForm(); //the form
if(!$form->isValid($_POST)) {
$values=$form->getValues();
//get the options and put them in $options
$assignMilestone=$form->getElement('assignedMilestone');
$assignMilestone->addMultiOptions($options);
}
if($form->isValid($_POST)) {
//save in the database
}else {
//redisplay the form
}
Basically, I check if it is valid and it isn't if the user changed the value of the first select. I get the options that populated the second select and populate the form with them. Then I try to validate it again. However this doesn't work. Anybody can explain why? The same "value was not found in the haystack" is present.
You could try to deactivate the validator:
in your Form.php
$field = $this->createElement('select', 'fieldname');
$field->setLabel('Second SELECT');
$field->setRegisterInArrayValidator(false);
$this->addElement($field);
The third line will deactivate the validator and it should work.
You can also disable the InArray validator using 'disable_inarray_validator' => true:
For example:
$this->add( array(
'name' => 'progressStatus',
'type' => 'DoctrineModule\Form\Element\ObjectSelect',
'options' => array(
'disable_inarray_validator' => true,
),
));
Additionaly you should add you own InArray Validator in order to protect your db etc.
In Zend Framework 1 it looks like this:
$this->addElement('select', $name, array(
'required' => true,
'label' => 'Choose sth:',
'filters' => array('StringTrim', 'StripTags'),
'multiOptions' => $nestedArrayOptions,
'validators' => array(
array(
'InArray', true, array(
'haystack' => $flatArrayOptionsKeys,
'messages' => array(
Zend_Validate_InArray::NOT_IN_ARRAY => "Value not found"
)
)
)
)
));
Where $nestedArrayOptions is you multiOptions and $flatArrayOptionsKeys contains you all keys.
You may also add options to select element before checking for the form validation. This way you are insured the select value is in range.

drupal questions - how to print a form from another module?

I'm trying to include a module form in a panel and I've tried using drupal_get_form(), but not sure I'm using it correctly.
In the organic groups module, there's a function to render an og_broadcast_form. It's called within a page_callback in og.module:
// Broadcast tab on group node.
$items['node/%node/broadcast'] = array(
'title' => 'Broadcast',
'page callback' => 'drupal_get_form',
'page arguments' => array('og_broadcast_form', 1),
'access callback' => 'og_broadcast_access',
'access arguments' => array(1),
'type' => MENU_LOCAL_TASK,
'file' => 'og.pages.inc',
'weight' => 7
);
And in og.pages.inc, the function is:
function og_broadcast_form($form_state, $node) {
drupal_set_title(t('Send message to %group', array('%group' => $node->title)));
if (!empty($form_state['post'])) {
drupal_set_message(t('Your message will be sent to all members of this group.'));
}
$form['subject'] = array(
'#type' => 'textfield',
'#title' => t('Subject'),
'#size' => 70,
'#maxlength' => 250,
'#description' => t('Enter a subject for your message.'),
'#required' => TRUE,
);
$form['body'] = array(
'#type' => 'textarea',
'#title' => t('Body'),
'#rows' => 5,
'#cols' => 90,
'#description' => t('Enter a body for your message.'),
'#required' => TRUE
);
$form['send'] = array('#type' => 'submit', '#value' => t('Send message'));
$form['gid'] = array('#type' => 'value', '#value' => $node->nid);
return $form;
}
I've tried a number of variations of drupal_get_form:
print drupal_get_form('og_broadcast_form', NULL, arg(1)); //where arg 1 is the node id from the url
print drupal_get_form('og_broadcast_form');
print drupal_get_form('og_broadcast_form', &$form_state, arg(1));
print drupal_get_form('og_broadcast_form', $n); //where $n is node_load(arg(1));
print drupal_get_form('og_broadcast_form', &$form_state, $n);
etc., etc... Is there a way to accomplish what I'm trying to do here?
FYI.. your problem is that you're attempting to load a form located in another modules include file.
The function is located in og.pages.inc and you'll need to make a call to:
module_load_include('inc', 'og', 'og.pages');
This must be done before you can grab the form.
If drupal_get_form is given the name of a function as it's first argument, that will be both the form_id and a function to be called to generate the $form array.
On line 3 of the function code, we have $args = func_get_args();, this is used by drupal_get_form to collect any or all additional arguments you may want to pass to your form-building function.
You should be using drupal_get_form('og_broadcast_form', node_load(arg(1)));.
Are you sure you should be using print and not return? I have recently learned they do very different things in the theming system. I have used drupal_get_form in this way to populate the contents of a block successfully, but at no point did I print to the screen myself.
EDIT: The full node object and not the nid because %node in a menu path uses a wildcard loader to pass the node_load(arg(1)) on to whatever function is being called.
drupal_get_form gets the form for you. have you tried print drupal_render(drupal_get_form('whatever'))) ?
drupal_get_form() only accepts one argument, the $form_id.
http://api.drupal.org/api/function/drupal_get_form/6
Run a hook_form_alter() and var_dump($form_id). That will give you the $form_id, and when you pass that to drupal_get_form(), it should return the rendered form.