Datamapper validation with form validation - Codeigniter - php

I'm using this datamapper http://datamapper.wanwizard.eu
problem is datamapper have validation methods similar with codeigniter form validation.but not as same.
An example, a model admins model validation array:
public $validation = array(
'username' => array(
'rules' => array('unique', 'required', 'trim', 'max_length' => 60, 'min_length' => 3),
'label' => 'User'
),
'password' => array(
'rules' => array('required', 'trim', 'encrypt', 'min_length' => 6),
'label' => 'Password'
)
);
but form validation array must be like that:
public $form_validation = array(
array(
'field' => 'username',
'label' => 'User',
'rules' => 'unique|required|trim|max_length[60]|min_length[3]'
),
array(
'field' => 'password',
'label' => 'Password',
'rules' => 'required|trim|encrypt|min_length[6]'
)
);
I don't want to make two manual validation for new admin adding (first form validation, after datamapper validation). I think there is a way to make this with just one manual validation.
sorry my bad English, I hope you understand. Thanks in advance.

Using the Datamapper's validation alone should be enough, without the CI's form library.
When you try to save the model, the save() method will return a true or false depending on if the save was successful. If it isn't the model's error property should be filled with the error messages generated for the validation that failed. The messages can be loaded from language files with keys named appropriately, also the codeigniter's form validation library's form_validaton_lang.php is loaded too.
In your controller you could make use of them like this:
Class TheController extends CI_Controller {
function save() {
// get the model object somehow
// ...
// update attributes
$model->prop0 = $this->input->post('prop0');
$model->prop1 = $this->input->post('prop1');
// try to save it
if ($model->save()) {
// save successful
redirect(...);
} else {
// save failed load form again, with the model
$this->load->view('path/to/the/form', array('model' => $model));
}
}
}
The view could work like this:
<form method="post" action="...">
<label>prop0</label>
<input type="text" name="prop0" value="<?php print $model->prop0?> ">
<?php if (!empty($model->error->prop0)):?>
<div class="error"><?php print $model->error->prop1; ?></div>
<?php endif; ?>
<label>prop1</label>
<input type="text" name="prop1" value="<?php print $model->prop1?> ">
<?php if (!empty($model->error->prop0)):?>
<div class="error"><?php print $model->error->prop1; ?></div>
<?php endif; ?>
<buton type="submit">go</button>
</form>
The same form can be used when no previous model exists in the database, just create an empty instance of the model you need, and pass it to the form.

Related

Validation is not working in codeigniter

Validation is not working. All the form fields are coming dynamically. It depends on the user how many fields he chooses.If he chooses 2 and it will display 2 fields in the view. If select 3 then it will display 3 fields and so on.I have more than 30 fields
I set 3 arrays(for testing purpose I set only 3. It will be total no of fields ) in my form validation page. If I remove the last array than validation is working because I am getting only 2 fields in the view. I am not able to use the more than 2 array in my form validation page.
Is it mandatory to require the number of fields in view is equal to a number of sets of rules array in form validation?
View
This is my dynamic view page
<?php
echo form_open('formbuilder_control/enxample_from_view');
foreach ($data as $key) {// I am getting output
$exp_fields_name=$key->fields_name;
$exp_fields_type=$key->fields_type;
$exp_form_elements=$key->form_elements;
$abc=explode(',',$exp_form_elements);
foreach ($abc as $value) {
if ($exp_fields_name == $value) {?>
<div class="form-group row label-capitals">
<label class="col-sm-5 col-form-label"><?php echo $exp_fields_name;?></label>
<div class="col-sm-7">
<input type="<?php echo $exp_fields_type;?>" name="<?php echo $exp_fields_name;?>" placeholder="<?php echo $value;?>" class="form-control" />
<?php echo form_error($exp_fields_name); ?>
</div>
</div>
<?php
}}}?>
<div class="form-buttons-w btn_strip">
<input type="submit" name="submit" value="Save" class="btn btn-primary margin-10">
</div>
<?php echo form_close(); ?>
Form_validation.php
$config = array(
'test'=>array(
array('field' =>'firstname',
'label' => 'First Name',
'rules' => 'required'
),
array('field' => 'lastname',
'label' => 'lastname',
'rules' => 'required'
),
array('field' => 'middlename',
'label' => 'middlename',
'rules' => 'required'
)
),
);
Controller
public function test()
{
if($this->form_validation->run('test') == TRUE)
{
echo "working";
}
$this->load->view('test1');
}
Of course it will fail. Your validation rules define a 'middlename' field as required, and that field doesn't even exist in the form.
A missing field cannot satisfy a required rule.
It is possible to have flexible sets of rules with a minimum of code. Consider this form_validation.php example
<?php
$first_last = array(
array('field' => 'firstname',
'label' => 'First Name',
'rules' => 'required'
),
array('field' => 'lastname',
'label' => 'lastname',
'rules' => 'required'
),
);
$middle_name = array(
array('field' => 'middlename',
'label' => 'middlename',
'rules' => 'required'
)
);
$config = array(
'fullname' => array_merge($first_last, $middle_name), //first, middle and last name fields
'shortname' => $first_last, //only first and last name fields
);
This provides two different sets of fields for use with form_validation->run().
For example: On a form using first, middle and last name fields
if($this->form_validation->run('fullname'))
{
...
Or, when the form contains only the first and last name fields
if($this->form_validation->run('shortname'))
{
...
As others have mentioned, you are requiring a field that does not exist. You either need to:
Add a field in your view with the name middlename
Remove the validation rule that requires a field middlename to exist
Not contributing to your issue, but in a usability aspect, you likely want to change the label in your lastname and middlename rules to make them more user friendly.
$config = array('test'=>array(
array('field' =>'firstname',
'label' => 'First Name',
'rules' => 'required'
),
array('field' => 'lastname',
'label' => 'lastname',
'rules' => 'required'
),
array('field' => 'middlename',
'label' => 'middlename',
'rules' => 'required'
)
),
);
Also, the documentation has other helpful tips for different custom rules if you're not trying to require the middlename but want to sanitize or validate its format prior to insertion into a database.
https://www.codeigniter.com/userguide3/libraries/form_validation.html#form-validation-tutorial
Well, as you want to have one set of validation rules and you have two different forms to validate, you can do it using very nice option with Codeigniter's validation callback function.
I am going to post a simple example here:
Your view file:
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<?php echo form_open('formbuilder_control/test');?>
<input type="text" name="firstname">
<input type="hidden" name="which_form" value="first_form">
<?php echo form_error('firstname'); ?>
<input type="text" name="lastname">
<?php echo form_error('lastname'); ?>
<input type="submit" name="submit" value="submit">
<?php echo form_close(); ?>
<?php echo form_open('formbuilder_control/test');?>
<input type="text" name="firstname">
<input type="hidden" name="which_form" value="second_form">
<?php echo form_error('firstname'); ?>
<input type="text" name="lastname">
<?php echo form_error('lastname'); ?>
<input type="text" name="middlename">
<?php echo form_error('middlename'); ?>
<input type="submit" name="submit" value="submit">
<?php echo form_close(); ?>
</body>
</html>
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class YourController extends CI_Controller {
public function save()
{
//.... Your controller method called on submit
$this->load->library('form_validation');
// Build validation rules array
$validation_rules = array(
array(
'field' => 'A',
'label' => 'Field A',
'rules' => 'trim|xss_clean'
),
array(
'field' => 'B',
'label' => 'Field B',
'rules' => 'trim|xss_clean'
),
array(
'field' => 'C',
'label' => 'Field C',
'rules' => 'trim|xss_clean|callback_required_inputs'
)
);
$this->form_validation->set_rules($validation_rules);
$valid = $this->form_validation->run();
// Handle $valid success (true) or failure (false)
}
public function required_inputs()
{
if( $this->input->post('which_form') == "second_form" && !$this->input->post('middlename'))
{
$this->form_validation->set_message('middlename', 'Middle name is required!');
return FALSE;
}
return TRUE;
}
}
From above example you can see required_inputs function is just like a normal function, where you can write any php code.
So what I would advice is, have one hidden field in both of the forms, jus to check which form got submitted, and then set callback function for middlename validation rule and in that function, check which form is submitted by user, and based on it, return TRUE or FALSE.
I hope this will get you the whole idea what you can do.
You just need to add a hidden field with different value in each the forms and check the value in callback function to decide whether you should apply the third validation rule or not.

codeigniter form validation on array not form submit

i want validate my form input field or you want to say i have an array and i want to validate that array using codeigniter
Example :
i have array like :
$array['obj_type']='sample';
$array['obj_id']='44';
$array['user_id']='34566';
and my form validation config as like :
'validatedata' => array(
array(
'field' => 'obj_type',
'label' => 'No Type Define here',
'rules' => 'required'
),
array(
'field' => 'obj_id',
'label' => 'No any item selected here',
'rules' => 'required|is_natural_no_zero'
),
array(
'field' => 'user_id',
'label' => 'No user logged in',
'rules' => 'required|is_natural_no_zero'
),
),
and when i use form validate its not validate array
if ($this->form_validation->run('validatedata')) {
} else {
echo validation_errors();
}
its print all error which define on on validatedata config array;
i just use
$this->form_validation->set_data($array);
then i validate form
if ($this->form_validation->run('validatedata')) {
echo "sucess";
} else {
echo validation_errors();
}
now its works fine and good.
You have to load form validation library in your controller..
$this->load->library(array('form_validation'));
You have to provide the data to the form_validation library:
$this->form_validation->set_data($array);
and then you can use
$this->form_validation->run('validatedata')
as intended.
If you want to validate multiple arrays, you'll have to call reset_validation() after validating each array.
Check system/libraries/Form_validation.php (around line 255, depending on your version of CI) for more information.

ZF2 Form: Customizing order of elements

I'm creating a form for a logged-in user to change their password, so I created a subclass of an existing password-reset form I have available. The forms will be identical except with an additional field for existing password. It's worked so far, except I can't figure out a way to manually set the order the new field; the only place I've gotten it to appear is at the end of the form. It seems that ZF2 requires you to add() form elements in the order that you want them rendered. I would do so, except the subclass form's constructor must the parent form's constructor before it can add new fields, by which point the parent form has already added its fields.
I have already tried setting the property order of my new field, but it did not work; I've tried several different combinations (I can't find the documentation for this feature anywhere, after lots of searching).
Subclass constructor snippet:
class ChangePassword extends ResetPassword implements InputFilterProviderInterface {
public function __construct() {
parent::__construct();
$this->add(array(
'type' => 'Zend\Form\Element\Password',
'name' => 'existingPassword',
'order' => 0,
'options' => array(
'label' => 'Existing Password',
'order' => 0,
),
'attributes' => array(
'required' => 'required',
'order' => 0,
)
));
}
Parent constructor snippet:
class ResetPassword extends Form implements InputFilterProviderInterface {
public function __construct() {
parent::__construct('reset-password');
$this->add(array(
'type' => 'Zend\Form\Element\Password',
'name' => 'password',
...
The key you're looking for which affects element order is named priority.
The form add() method accepts a second array containing $flags, and it's in this array that you must add the priority key/value pair.
Your constructor should end up looking something like this ...
class ChangePassword extends ResetPassword implements InputFilterProviderInterface {
public function __construct() {
parent::__construct();
$this->add(array(
'type' => 'Zend\Form\Element\Password',
'name' => 'existingPassword',
'options' => array(
'label' => 'Existing Password',
),
'attributes' => array(
'required' => 'required',
)
), // add flags array containing priority key/value
array(
'priority' => 1000, // Increase value to move to top of form
));
}
}
I have encouter this issue today, Crisp's answer helped but I think it would be nice to precise this :
In the view we have a lot of options to show our form :
<?= $this->form($form)?>
<?= $form->get('{element}') ?>
loop over $form->getIterator()
loop over $form->getElements()
etc...
I have to say i used a lot this structure in all of my projects :
<?php foreach ($form->get('fieldset')->getElements() as $elementName => $element): ?>
<?= $this->partial('partial/formElement', ['element' => $element])?>
<?php endforeach ?>
The problem is : getElements does not use priority, so its just give the element in order of when it was instanciated.
In the view we have to use the iteration method ($form->getIterator()) to get back this flag priority.

Add class attribute to Form Errors

I´m developing an application using Zend Framework 2 and I use FormRow helper to render a label, the input and errors (if present) in a Form.
//within the view
echo $this->formRow($form->get('Name'));
When a user submits the form without filling the required input text field FormRow render´s it with the following error message:
<label>
<span>Name: </span>
<input class="input-error" type="text" value="" placeholder="Insert Name Here" name="Name">
</label>
<ul>
<li>Value is required and can't be empty</li>
</ul>
How can I set a class for the li tag to style it afterwards?
I know that I can echo the formElementErrors with the desired class attribute via..
<?php echo $this->formElementErrors($form->get("Name"), array('class' => "valuerequired", 'message' => "errortestmessage")); ?>
..but FormRow will still render the error message without the class.
Just for reference I´m setting the entity this way:
public function getInputFilter()
{
if (!$this->inputFilter) {
$inputFilter = new InputFilter();
$factory = new InputFactory();
$inputFilter->add($factory->createInput(array(
'name' => 'Name',
'required' => true,
'filters' => array(
array('name' => 'StripTags'),
array('name' => 'StringTrim'),
),
'validators' => array(
array(
'name' => 'StringLength',
'options' => array(
'encoding' => 'UTF-8',
'min' => 1,
'max' => 100,
),
),
),
)));
$this->inputFilter = $inputFilter;
}
return $this->inputFilter;
}
See the code of formElementErrors
Basically you could do something like:
$this->formElementErrors($elem)
->setMessageOpenFormat('<ul%s><li class="some-class">')
->setMessageSeparatorString('</li><li class="some-class">');
But that is quite unhandy...
The better solution would be to extend the Zend\Form\View\Helper\FormElementErrors by your own class and then register the view-helper formElementErrors to your class. So basically you'd have something like this:
namespace Mymodule\Form\View\Helper;
use Zend\Form\View\Helper\FormElementErrors as OriginalFormElementErrors;
class FormElementErrors extends OriginalFormElementErrors
{
protected $messageCloseString = '</li></ul>';
protected $messageOpenFormat = '<ul%s><li class="some-class">';
protected $messageSeparatorString = '</li><li class="some-class">';
}
Last thing then would be to register the view helper with this new Class. For this you provide the following code inside your Modules Module.php
public function getViewHelperConfig()
{
return array(
'invokables' => array(
'formelementerrors' => 'Mymodule\Form\View\Helper\FormElementErrors'
),
);
}
displaimer: This code isn't tested, let me know if there are some errors, but i think this should work out quite well.
Ok, the solution to my own problem was right in front of me, instead of using:
//within the view
echo $this->formRow($form->get('Name'));
I called each element of the form individually:
//within the view
echo $this->formLabel($form->get('Name'));
echo $this->formInput($form->get('Name'));
echo $this->formElementErrors($form->get("Name"), array('class' => "some_class", 'message' => "errormessage"));
Don´t know if it´s the most efficient way of doing it, plz drop a line if you think otherwise.
FormRow check if "form_element_errors" plugin registered. And if so use it as default to display error messages.
So Sam's example work. You should redefine standard plugin and inform mvc about it.
I'v done it in module.config.php
'view_helpers' => array(
'invokables' => array(
'formElementErrors'=> 'MyModule\View\Helper\FormElementErrors',
and FormRow start display errors as I wish :)
As your problem, please try
Change
//within the view
echo $this->formRow($form->get('Name'));
to
//within the view
echo $this->formRow($form->get('Name'),null,false);
// Note: add more 2 last parameters, false- for $renderErrors => will NOT render Errors Message.
//Look original function in helper/formrow.php: function __invoke(ElementInterface $element = null, $labelPosition = null, $renderErrors = null, $partial = null)
Render Errors Message as your funciton
echo $this->formElementErrors($form->get('name'), array('class' => 'your-class-here'));
From the documentation of ZF2. Here's the link: http://framework.zend.com/manual/2.0/en/modules/zend.form.view.helpers.html#formelementerrors
echo $this->formElementErrors($element, array('class' => 'help-inline'));
// <ul class="help-inline"><li>Value is required and can't be empty</li></ul>
I use echo $this->formElementErrors($form, array('class' => "error-messages")); to show all error messages in one place:
echo $this->formElementErrors($form, array('class' => "error-messages"));// Print all error messagess
echo $this->formLabel($form->get('Name'));
echo $this->formInput($form->get('Name'));
echo $this->formLabel($form->get('Name2'));
echo $this->formInput($form->get('Name2'));

Zend framework - form not rendering

I'm just starting to use Zend Framework and was following the quick start documentation for the latest version (1.11.10). Everything was going just fine, but when I placed the form code and ran the application, the form did not render. My code is exactly like http://framework.zend.com/manual/en/learning.quickstart.create-form.html
On the view, I can dump the form just fine with var_dump($this->form);
I've tried echo $this->form(), echo $this->form->render(), but nothing appeared... What could it be?
This problem can occur when Zend can't find the template file for an element. Look at following code:
$element->setDecorators(array(
array('ViewScript',
array(
'viewScript' => 'directory/_input.phtml'
)
)
));
The file _input.phtml must be in the right folder for this Controller. Otherwise Zend can't find the template for input and can't successfully render your element and will not show anything.
Make sure you pass the form to the view from the controller.
In your action handler:
$this->view->form = $my_form;
In your view:
echo $this->form;
I suspected that this was the cause of your problem because Zend Framework doesn't complain if you try to echo a parameter that doesn't exist. (i.e. echo $this->some_fake_parameter won't do anything)
Ok so i tried your code, and it worked for me no problem.
Here is everything:
Controller
<?php
class IndexController extends Zend_Controller_Action
{
public function myTestAction()
{
$form = new Form_Guestbook();
// ... processing logics
if($this->getRequest()->isPost())
{
if($form->isValid($this->getRequest()->getPost()))
{
var_dump($form->getValues());
}
}
$this->view->assign('form', $form);
}
}
Form
<?php
class Form_Guestbook extends Zend_Form
{
public function init()
{
// Set the method for the display form to POST
$this->setMethod('post');
// Add an email element
$this->createElement('text', 'email', array(
'label' => 'Your email address:',
'required' => true,
'filters' => array('StringTrim'),
'validators' => array(
'EmailAddress',
)
));
// Add the comment element
$this->addElement('textarea', 'comment', array(
'label' => 'Please Comment:',
'required' => true,
'validators' => array(
array('validator' => 'StringLength', 'options' => array(0, 20))
)
));
// Add a captcha
$this->addElement('captcha', 'captcha', array(
'label' => 'Please enter the 5 letters displayed below:',
'required' => true,
'captcha' => array(
'captcha' => 'Figlet',
'wordLen' => 5,
'timeout' => 300
)
));
// Add the submit button
$this->addElement('submit', 'submit', array(
'ignore' => true,
'label' => 'Sign Guestbook',
));
// And finally add some CSRF protection
$this->addElement('hash', 'csrf', array(
'ignore' => true,
));
}
}
?>
View
<?php echo $this->form->render(); ?>
can be seen on: http://yaconiello.com/index/my-test
If this isnt working for you, you may be having a configuration error.
I had a problem like that (exact same form, since it is eclipse example)
My problem was due to misunderstanding. Since I thought that I have to directly access to the view script. I entered in the browser something like: hostname/application/view/script/something.php
But in zend all accesses should be through public folder. You have to access to the view like this: hostname/app_name/public/guestbook
hope that would help you

Categories