Cakephp 2.3.9 custom message in model validation not working - cakephp

I am doing model validation in my admin panel login so there is only two fields username and password. Validation is working but custom message which I have written in my model is not shown.
Model
public $validate = array(
'username' => array(
'required' => array(
'rule' => array('notEmpty'),
'message' => 'Please Enter Your Username'
)
),
'password' => array(
'required' => array(
'rule' => array ('notEmpty'),
'message' => 'Please Enter Your Password'
)
)
);
Controller
function login(){
$this->layout = 'admin_login';
if ($this->request->is('post')) {
if ($this->Auth->login()) {
return $this->redirect($this->Auth->redirect());
}
$this->Session->setFlash(__('Invalid username or password, try again'));
}
}
View
echo $this->Form->create('Admin',array('autocomplete'=>"off"));
echo '<div style="width:294px;float:left;position:relative;">';
echo $this->Form->input('username' , array('label' => '', 'placeholder' =>'Enter your username','div' => false));
echo $this->Form->input('password' , array('label' => '', 'value' =>'', 'div' => false,'placeholder'=>'Enter Your Password'));
echo '</div>';
echo '<div style="padding-left:0px;">';
echo $this->Form->end(__('Login' ,true));
I have already tried a few things like which is mentioned in this link, but it's not working for me.
CakePHP : Validation message not displaying

That looks like a message from the browser and not CakePHP.
CakePHP now adds a required attribute which modern browsers can use to trigger an error.
You can do one of three things here:
One: Set up your form to leave validation to the server:
$this->Form->create(array('novalidate'=>true));
Two: Set a custom validation message in the browser: http://www.whatwg.org/specs/web-apps/current-work/multipage/association-of-controls-and-forms.html#dom-cva-setcustomvalidity
Three: tolerate it

You get that message because the "username" field is flagged as "required". Maybe you've not defined it in the Form->input() function, but the "required" flag has been automatically added from the Model (due to your validation rules). As timstermatic said, it's a browser validation message caused by the required attribute.
To solve this issue (and show the CakePHP validation message) you've to force for avoiding the addition of the "required" flag on your field:
$this->Form->input('username', array('required' => FALSE));
This will override the Model automatic additions. Happy coding ;)
*Edited => It's important to clarify that the inline override removes only the required flag on the field: you'll take advantage of the Model validation anyway (just because if an empty field is sent to the server, it will not pass the validation rule you entered.

keep this code it will bypass the html5 validation and add your custom validations
view
echo $this->form->create('Post',array('action'=>'add'));
echo $this->form->input('title');
echo $this->form->input('body');
echo $this->form->submit('Save Post',array('formnovalidate'=>true));
echo $this->form->end();//Creates ending form tag
Model
var $validate=array(
'title'=>array(
'title_must_not_be_empty'=>array('rule'=>'notEmpty','message'=>'Please enter a title),
'title_must_be_unique'=>array('rule'=>'isUnique','message'=>'Title name already exists')
),
'body'=>array(
'body_must_not_be_empty'=>array(
'rule'=>'notEmpty',
'message'=>'Please enter body'
)
)
);
This will work just the way you want

Related

Validating non-model select box CakePHP

In the following from a have a select box which is not related to any database fields:
echo $this->Form->create('Event');
echo $this->Form->input('customer_id', array('label' => __('Customer')));
echo $this->Form->input('service_id', array('label'=>__('Service')));
echo $this->Form->select('user_id', $users, array('multiple'=>true));
echo $this->Form->end(__('Save'));
In the Event model I have a validation rule which is as follows:
var $validate = array(
'user_id'=>array(
'notempty'=> array(
'rule'=>'notEmpty',
'message'=> 'Vælg en medarbejder'
)
))
THe problem is that this validation rule is never called. What may the problem be?
Here is the dump of data after from submition:
array(
'customer_id' => '107',
'service_id' => '195',
'user_id' => '',
...
)
The rule has just been tested on edit and it works perfectly, together with the remaining rules. The problem is that none of the rules are fired on create.
You need to validates manually. Try this in your Controller.
$this->Event->set($this->request->data);
if ($this->Event->validates()) {
//Save your data by calling $this->Event->save($this->request->data);
} else {
// didn’t validate logic
$errors = $this->ModelName->validationErrors;
}
Validation doesn't apply on select(), hidden(), radio() etc. You should always go through Form::input() like:
$this->Form->input(
'user_id',
array(
'type'=>'select',
'options'=>$users,
'multiple'=>true, ....));
Then the validation will be called as expected ;)

Multiple form with same model name on single page cakephp

I have two form on a single page: login form and register form. When I submit the register form, it validates both: form fields that are in login and registeration. How can I handle it if both form have the same model (user model)
Register form
<?php echo $this->Form->create('User', array('url' => array('controller' => 'users', 'action' => 'add'))); ?>
<?php echo $this->Form->input('username', array('label' => false, 'div' => false, 'class' => 'reg_input'));?>
<?php echo $this->Form->input('email', array('label' => false, 'div' => false, 'class' => 'reg_input'));?>
<?php echo $this->Form->input('password', array('label' => false, 'div' => false, 'class' => 'reg_input'));?>
<?php echo $this->Form->input('confirm_password', array('type' => 'password', 'label' => false, 'div' => false, 'class' => 'reg_input'));?>
<?php echo $this->Form->submit(__('Submit', true), array ('class' => 'reg_button', 'div' => false));
echo $this->Form->end();?>
and Login form is below
<?php echo $this->Form->create('User', array('controller' => 'users', 'action' => 'login'))?>
<?php echo $this->Form->input('User.username',array('label'=>false,'div'=>false, 'class' => 'reg_input'));?>
<?php echo $this->Form->input('User.password',array('label'=>false,'div'=>false, 'class' => 'reg_input'));?>
<?php echo $this->Form->submit(__('Log in', true), array ('class' => 'reg_button', 'div' => false)); ?>
<?php echo $this->Form->end();?>
When I submit registration form it validates both forms, I want to validate only the registration form.
How can I handle that?
I've come up with a "solution" (I find the approach dirty, but it works) for a different question (very similar to this). That other question worked with elements and views, though. I'll post the entire solution here to see if it helps someone (though I rather someone else comes with a different approach).
So, first: change the creation names for the two forms.
//for the registration
<?php echo $this->Form->create('Registration',
array('url' => array('controller' => 'users', 'action' => 'add'))); ?>
//for the login
<?php echo $this->Form->create('Login',
array('controller' => 'users', 'action' => 'login'))?>
The forms should work, look and post to the same actions, so no harm done.
Second step: I don't have your action code, so I'm going to explain what needs to be done in general
public function login() {
if ($this->request->is('post')) {
//we need to change the request->data indexes to make everything work
if (isset($this->request->data['Login'] /*that's the name we gave to the form*/)) {
$this->request->data['User'] = $this->request->data['Login'];
unset($this->request->data['Login']); //clean everything up so all work as it is working now
$this->set('formName', 'Login'); //we need to pass a reference to the view for validation display
} //if there's no 'Login' index, we can assume the request came the normal way
//your code that should work normally
}
}
Same thing for the registration (only need to change 'Login' to 'Registration').
Now, the actions should behave normally, since it has no idea we changed the form names on the view (we made sure of that changing the indexes in the action). But, if there are validation errors, the view will check for them in
$this->validationErrors['Model_with_errors']
And that 'Model_with_errors' (in this case 'User') won't be displayed in the respective forms because we've changed the names. So we need to also tweak the view. Oh! I'm assuming these both forms are in a view called index.ctp, for example, but if they are on separate files (if you're using an element or similar) I recommend add the lines of code for all the files
//preferably in the first line of the view/element (index.ctp in this example)
if (!empty($this->validationErrors['User']) && isset($formName)) {
$this->validationErrors[$formName] = $this->validationErrors['User'];
}
With that, we copy the model validation of the User to the fake-named form, and only that one. Note that if you have a third form in that view for the same model, and you use the typical $this->form->create('User'), then the validation errors will show for that one too unless you change the form name for that third one.
Doing that should work and only validate the form with the correct name.
I find this a messy approach because it involves controller-view changes. I think everything should be done by the controller, and the view shouldn't even blink about validation issues... The problem with that is that the render function of Controller.php needs to be replaced... It can be done in the AppController, but for every updgrade of Cakephp, you'll have to be careful of copying the new render function of Controller.php to the one replacing it in AppController. The advantage of that approach, though, is that the "feature" would be available for every form without having to worry about changing the views.
Well, it's just not that maintainable anyway, so better to leave it alone if it's just for this one case... If anyone is interested on how to handle this just in the controller side, though, comment and I'll post it.
You can duplicate your model and change his name and define $useTable as the same table name.
Example :
class Registration extends AppModel {
public $useTable = 'users';
You define the action in form->create like Nunser for your login form
<?php
echo $this->Form->create('User',array(
'url' => array(
'controller' => 'Users',
'action' => 'login',
'user' => true
),
'inputDefaults' => array(
'div' => false,
'label' => false
),
'novalidate'=>true,
));
?>
and your registration form
<?php
echo $this->Form->create('Registration',array(
'url' => array(
'controller' => 'Users',
'action' => 'validation_registration',
'user' => false
),
'inputDefaults' => array(
'div' => false,
'label' => false
),
'novalidate'=>true,
));
?>
In your controller define a method for registration validation and the most important define the render
public function validation_registration(){
$this->loadModel('Registration');
if($this->request->is('post')){
if($this->Registration->save($this->request->data)){
--- code ---
}else{
--- code ---
}
}
$this->render('user_login');
}
Sorry for my english ! Have a nice day ! :D
The create method on your login form is missing the 'url' key for creating the action attribute. I tried to re-create this once I fixed this and could not. Maybe that will fix it?

Validation problems with multiple checkboxes (HABTM) on CakePHP form

Short version
I have some HABTM checkboxes on a form. Validation is working correctly (at least one checkbox needs to be checked for validation to pass) but the CakePHP error message divs aren't being generated as they should be.
Long Version
I have a from which allows users to fill in their name and email address and then choose from a list of brochures (checkboxes) they'd like to receive.
The form looks like this:
<?php
echo $this->Form->create('Request',array('action' => 'index'));
echo $this->Form->input('id');
echo $this->Form->input('name');
echo $this->Form->input('email');
echo $this->Form->input('Brochure',array(
'label' => __('Information Required:',true),
'type' => 'select',
'multiple' => 'checkbox',
'options' => $list,
'selected' => $this->Html->value('Brochure.Brochure'),
));
echo $this->Form->submit('Submit');
echo $this->Form->end();
?>
In my controller, $list is set as like this:
$this->Request->Brochure->find('list',array('fields'=>array('id','name')));
After reading the 2nd answer (posted by user448164) in HABTM form validation in CakePHP on Stack Overflow, I set my Request model up like this:
<?php
class Request extends AppModel {
var $name = 'Request';
function beforeValidate() {
foreach($this->hasAndBelongsToMany as $k=>$v) {
if(isset($this->data[$k][$k]))
{
$this->data[$this->alias][$k] = $this->data[$k][$k];
}
}
}
var $validate = array(
'name' => array(
'rule' => 'notEmpty',
'message' => 'Please enter your full name'
),
'email' => array(
'rule' => 'email',
'message' => 'Please enter a valid email address'
),
'Brochure' => array(
'rule' => array('multiple', array('min' => 1)),
'message' => 'Please select 1'
),
);
?>
This actually works 99% well. If none of the checkboxes are checked, validation fails as it should do. However, the only problem is that Cake isn't setting the "error" class on the <div>, nor is it creating the <div class="error-message">Please select 1</div> as it should.
For name and email, there is no problem - the error divs are being created properly.
So, to clarify, validation is working for my HABTM checkboxes. The only problem is that the error divs aren't being generated.
I'm posting this here as this is actually a much better question than the related question you found.
I was banging my head against a wall trying to handle the same problem of getting the validation error to show up in the page. I'm using CakePHP v1.2 and I hit a similar problem although I have actually split out the HABTM into the individual tables i.e. Request->BrochuesRequest->Brochure. This is because I can't have it deleting and re-adding the joining table rows at will.
Firstly I think the accepted answer from your linked question assumes that you are doing a save / saveAll when the beforeValidate call is triggered, however I was doing it through a validates call. The difference is that you need to call the Request->set method first. It was an article by Jonathan Snook on Multiple Validation Sets pointed me to that issue.
The second issue is actually getting the error message to appear was down to the $field value you use when calling invalidate. For ages I was including the model as well as the field assuming that this was how it matched the invalidate call to the input, i.e. you have $form->input('BrochuresRequest.brochures_id') so you need $this->BrochuresRequest->invalidate('BrochuresRequest.brochures_id').
However that is wrong you just want $this->BrochuresRequest->invalidate('brochures_id').
<?php
// requests/add view
echo $form->input('BrochuresRequest.brochures_id', array('multiple' => true));
// requests_controller
function add() {
if (!empty($this->data)) {
$this->Request->create();
// critical set to have $this->data
// for beforeValidate when calling validates
$this->Request->set($this->data);
if ($this->Request->validates()) {
$this->Request->saveAll($this->data);
}
}
}
// request model
function beforeValidate() {
if (count($this->data['BrochuresRequest']['brochures_id']) < 1) {
$this->invalidate('non_existent_field'); // fake validation error on Project
// must be brochures_id and not BrochuresRequest.brochures_id
$this->BrochuresRequest->invalidate('brochures_id', 'Please select 1');
return false;
}
return true;
}
?>
A few of the other things that I picked up on the way through:
You don't need a separate $form->error in the view
I couldn't for the life of me get the 'multiple' validation rule to work in the model
The accepted answer checks for an isset but I believe that this isn't required and masked the problem of there being no $this->data being passed through.
The beforeValidate should return false if you want it to prevent any save action.

Validating made up fields in CakePHP?

Here's my scenario:
I'm creating a password change page.
the real field that holds the password is User.password
On the password create page, I used 3 made up fields:
$form->input('User.old_passwd');
$form->input('User.new_passwd');
$form->input('User.confirm_new_passwd');
How do I validate them with the rules:
old password must match User.password
new_passwd and confirmnew_passwd must
be equal
Are there better solutions for this? I'm open for suggestions. Thanks!
The built-in authentication component doesn't offer that functionality. I would specify the validation rules for your "made up" fields in the validate property of the model and write my own validation methods, for example: correctPassword() to ensure that the users enter their old password and matchingPasswords() to ensure that the new password was re-typed correctly.
var $validate = array(
// your existing validation rules
'old_passwd' => array(
'rule' => 'correctPassword',
'message' => 'invalid password'
),
'new_passwd' => array(
'rule' => array('minLength', 8),
'message' => '8 characters minimum';
),
'confirm_new_passwd' => array(
'rule' => 'matchingPasswords',
'message' => 'passwords do not match'
)
);
function correctPassword($check) { }
function matchingPasswords($check) { }
See the Cookbook for more information about custom validation rules.

CakePHP - radio button not showing error message

I'm unable to get the error message to show up when creating a radio form using the CakePHP form helper.
This is what I have now.
$options=array('active'=>'Active','inactive'=>'Inactive');
echo $form->input('Status', array(
'type' => 'radio',
'id' => 'EntryStatus',
'name' => 'data[Entry][status]',
'options' => $options
));
What am I missing?
I'm using CakePHP 1.2.7 and this is what I have in the validation
'status' => array(
'notempty' => array(
'rule' => 'notempty',
'required' => true,
'message' => 'yo'
)
)
Tried the answer from Form helper for creating Radio button in Cakephp and it's giving me a select option form instead.
Thanks,
Tee
had same problem, and i fount this, and it works:
http://book.cakephp.org/view/204/Form-Element-Specific-Methods
you need
if ($form->isFieldError('gender')){
echo $form->error('gender');
}
... in your code. this works in case that your field is named as gender.
I had the same issue and I added:
<?php echo $form->error('currentStatus');?>
below the radio button and it worked fine.
Try taking a look at $form->input('Status' ... (capital 'Status') versus the DB column name (which might or might not be capitalized versus 'name' => 'data[Entry][status]' (not capital 'status').
Cake's form helper is picky about inserting error messages when it can't figure out what things go to what.
Have you tried using the explicit $form->radio() method instead of the general input() method?
You need to manually add in an error form helper.
echo $form->error('status');
You need to add error condition in case of radio button
<?php
$options=array('active'=>'Active','inactive'=>'Inactive');
echo $form->input('Status', array(
'type' => 'radio',
'id' => 'EntryStatus',
'options' => $options
)
);
if ($form->isFieldError('Status')){
echo $form->error('Status');
}
?>

Resources