Only first validation rule working - validation

I have a set of validation rules I am imposing on my model in Cakephp 2.0 and since they are all for fields that deal with web addresses, they are exactly the same. Cut and pasted exact. However, when I modify my db in my edit form, only the first rule works; all the others validate and update my record. Here is my model code:
public $validate=array(
'unit_website'=>array(
'rule'=>'url',
'message'=>'You must enter a valid website address.'
),
'rates'=>array(
'rule'=>'url',
'message'=>'You must enter a valid website address.'
),
'book'=>array(
'rule'=>'url',
'message'=>'You must enter a valid website address.'
),
'contact'=>array(
'rule'=>'url',
'message'=>'You must enter a valid website address.'
)
);
UPDATE* Here is my form:
<?php
echo $this->Form->create('Unit', array(
'action' => 'edit',
'inputDefaults' => array(
'label' => false,
'div' => false
)
)
);
echo $this->Form->hidden('id');
echo $this->Form->hidden('location_id');
echo $this->Form->hidden('Location.id');
echo $this->Form->hidden('Location.lat');
echo $this->Form->hidden('Location.lon');
echo $this->Form->input('Location.prop_name', array('label'=>'Property name where your unit is located', 'div'=>true));
if($this->data['Unit']['type']=='condo' || $this->data['Unit']['type']=='house') {
echo $this->Form->input('Unit.unitnum', array('label' => 'Unit\'s Name/Number'));
}
echo $this->Form->input('type', array('label'=>'Type of Property', 'onChange'=>'toggle()', 'options'=>array('condo'=>'Condo', 'house'=>'House', 'hotel'=>'Hotel or Motel', 'rentalco'=>'This is a rental company')));
echo $this->Form->input('Location.address', array('onChange'=>'getLatLong(address)', 'size'=>'50', 'div'=>true));
echo $this->Form->input('Location.city', array('onChange'=>'getLatLong(address)'));
echo $this->Form->input('Location.state', array('onChange'=>'getLatLong(address)', 'size'=>'2'));
echo $this->Form->input('Location.zip', array('size'=>'5'));
echo '<br />';
echo $this->Form->input('Location.area_code', array('size'=>'3'));
echo $this->Form->input('Location.exchange', array('size'=>'3'));
echo $this->Form->input('Location.sln', array('size'=>'4'));
echo '<br />';
echo $this->Form->input('unit_website', array('size'=>'65', 'label'=>'Your unit\'s website', 'error' => array('class' => 'error')));
echo '<br />';
echo $this->Form->input('specials', array('label' => 'Your website\'s Specials page', 'size'=>'65', 'error' => array('class' => 'error')));
echo '<br />';
echo $this->Form->input('rates', array('size'=>'65', 'error' => array('class' => 'error'), 'label'=>'Your unit\'s rates page'));
echo '<br />';
echo $this->Form->input('book', array('size'=>'65', 'error' => array('class' => 'error'), 'label'=>'Your unit\'s booking page or calendar'));
echo '<br />';
echo $this->Form->input('contact', array('size'=>'65', 'error' => array('class' => 'error'), 'label'=>'Your unit\'s contact or email page'));
echo '<br />';
if($this->data['Unit']['type']=='condo' || $this->data['Unit']['type']=='house') {
echo '<br /><div id="unit_info">';
echo $this->Form->input('sq_ft', array('label'=>'Square feet', 'min'=>'1000', 'max'=>'10000', 'step'=>'50'));
echo $this->Form->input('bedrooms', array('label'=>'Bedrooms', 'min'=>'1', 'max'=>'15', 'step'=>'1'));
echo $this->Form->input('baths', array('label'=>'Bathrooms', 'min'=>'1', 'max'=>'10', 'step'=>'.5'));
echo $this->Form->input('sleeps', array('label'=>'How many people does your unit sleep?', 'min'=>'1', 'max'=>'45', 'step'=>'1'));
echo '</div><br />';
echo $this->Form->input('unit_desc', array('div'=>true, 'cols'=>'150', 'rows'=>'4', 'label'=>'Describe your unit <span style="font-size:14px; font-style:italic">(Remember to include the sizes of beds in each bedroom, whether you have a sleeper sofa, deluxe kitchens and baths, balconies and their views, access to amenities, and any other items that distinguish your property.)</span>'));
}
else {
echo '<br />';
echo $this->Form->input('unit_desc', array('div'=>true, 'cols'=>'150', 'rows'=>'4', 'label'=>'Describe your hotel or rental company'));
}
echo '<br /> ';
echo $this->Form->end('Update Property');?>
<?php echo $this->Session->flash(); ?>
Does Cake have some sort of "you can only make this rule once" rule? Or do my model field names have to actually have the word website in them or something? Or have I just made some dumb syntax error?
UPDATE Here is my controller code:
function edit($id) {
$this->set('title', 'Edit your property');
$this->Unit->id = $id;
if (empty($this->data)) {
$this->data = $this->Unit->read();
} else {
if ($this->Unit->saveAll($this->data)) {
$this->Session->setFlash('Your property has been updated.', 'success');
}
}
}

What is the URL you are validating and what are you expecting? The url validation will not check for protocol unless you specify it. If you want to make sure http is in the url, you should specify your rule like this:
'rule' => array('url', true)
Please show sample URLs that are passing validation but are not valid.
UPDATE
$this->data should be changed to $this->request->data. This may not change the validation process. But $this->data is deprecated.
Try adding a beforeValidate callback in the Unit model and echo $this->data to see what is coming through.

Related

Form_submit won't perform action

Been working on this form for a while and I had it working properly. But I then re-did the form using the form helper in CodeIgniter and now when I click the submit button does nothing. Not even a refresh. I've tested my controller so I'm stuck for what it could be.
<?php
echo form_open('site/inputWorker');
echo form_label('Forename:', 'Forename');
echo form_input('Forename');
echo "<br>";
echo form_label('Surname:', 'Surname');
echo form_input('Surname');
echo "<br>";
echo form_label('Skill1:', 'Skill1');
echo form_dropdown('Skill1', $skills, 'None');
echo "<br>";
echo form_label('Skill2:', 'Skill2');
echo form_dropdown('Skill2', $skills, 'None');
echo "<br>";
echo form_label('Skill3:', 'Skill3');
echo form_dropdown('Skill3', $skills, 'None');
echo "<br>";
echo form_label('Availability:', 'Availability');
echo form_dropdown('Availability', $availability, 'None');
echo "<br>";
echo form_submit('Add Worker', 'Add Worker');
echo form_close();
?>
//Add a New Worker
public function inputWorker(){
$Forename=$this->input->post('Forename');
$Surname=$this->input->post('Surname');
$Skill1=$this->input->post('Skill1');
$Skill2=$this->input->post('Skill2');
$Skill3=$this->input->post('Skill3');
$Availability=$this->input->post('Availability');
$this->load->model("model_worker");
if($this->model_worker->insert_worker($Forename, $Surname, $Skill1, $Skill2, $Skill3, $Availability)){
$data['msg']="Sucessfully added the worker";
}
else{
$data['msg']="Something went wrong";
}
$this->load->view("view_confirmation", $data);
}
$forname = array(
'name' => 'forname',
'id' => 'forname',
'value' => '',
);
echo form_input('Forename');

update 2 elements by ajax in yii

I have a ajax link in yii when user click it do something and update a element html (content of td) without refresh page how can change 2 element html?
I explain more:
in view i have a table by some td for show information a td for send information (there are a image ajaxlink) and a td by message of content (example: "not send")
When user click image link call a function and valid information (...) and change message of td ('validation is success').("not send" change to "validation is success")
I did what I was told but i want to remove ajaxlink and replace it by a simple image how
can I do it?
i add:
CHtml::image(Yii::app()->theme->baseUrl . "/img/gridview/email-send.png", '', array('title' => 'sended success'))
view.php:
<td id="send_<?php echo CHtml::encode($profileInformationServices->id); ?>"><?php echo "not send"; ?></td>
<td id="sended_<?php echo CHtml::encode($profileInformationServices->id); ?>">
<?php
echo $profileInformationServices->send ? CHtml::image(Yii::app()->theme->baseUrl . "/img/gridview/email-send.png", '', array( 'title' => 'sended success')):
CHtml::ajaxLink(CHtml::image(Yii::app()->theme->baseUrl . "/img/gridview/send.png", '', array(
'title' => 'Send for valid')), Yii::app()->createUrl('/profileInformationService/send'),
array( // ajaxOptions
'type' => 'POST',
'data' => array( 'id' => $profileInformationServices->id ),
'update' => '#send_'.$profileInformationServices->id,
)
);
?>
</td>
controller:
public function actionSend() {
if (Yii::app()->request->isPostRequest) {
$model = $this->loadModel($_POST["id"]);
$model->send = 1;
$model->save();
echo "sended success";
}
}
Use ajaxLink callback to change the text in td.
<?php
//I am keeping your ternary code in if-else condition for readability
if($profileInformationServices->send)
{
echo CHtml::image(Yii::app()->theme->baseUrl . "/img/gridview/email-send.png", '', array('title' => 'sended success'));
}
else
{
echo CHtml::ajaxLink
(
CHtml::image(Yii::app()->theme->baseUrl . "/img/gridview/send.png", '', array('title' => 'Send for valid')),
Yii::app()->createUrl('/profileInformationService/send'),
array
(
'type' => 'POST',
'data' => array('id' => $profileInformationServices->id),
'success'=>'function(data)
{
if(data=="sended success")
{
$("#send_'.$profileInformationServices->id.'").html("validation is success");
}
}',
)
);
}
?>

Issue with validation when model has three belongsTo associations with another model

Some validation messages are missing on my form, though they are correct in the result of invalidMessages(). If I enter the last name for the ATCSTudent.lastName, then I don't get a validation message for lastName on ATCGradChair1. I tried fix for 3828 but it doesn't work.
I have a model with this belongs to:
public $belongsTo = array(
'ATCStudent' => array('className' => 'Person', 'foreignKey' => 'studentId'),
'ATCProgram' => array('className' => 'Program', 'foreignKey' => 'programId'),
'ATCGradChair1' => array('type' => 'inner', 'className' => 'Person', 'foreignKey' => 'gradChair1Id'),
'ATCGradChair2' => array('className' => 'Person', 'foreignKey' => 'gradChair2Id'),
);
My view looks like this:
echo $this->Form->create('ATCForm', array('novalidate' => true));
echo $this->Form->input('id');
//echo $this->Form->input('ATCStudent.id');
echo $this->Form->input('ATCStudent.lastName');
echo $this->Form->input('ATCStudent.firstName');
echo $this->Form->input('ATCStudent.emplId');
echo $this->Form->input('ATCStudent.campusId');
echo $this->Form->input('ATCStudent.email');
echo $this->Form->input('progCode', array('type'=>'select','options'=>$programs));
echo $this->Form->input('termCode', array('type'=>'select','options'=>$terms));
echo $this->Form->input('prelimDate');
echo "<p>Enter below only cross-listed courses and/or courses taken at another institution.
";
echo $this->Form->input('cognate');
//echo $this->Form->input('ATCGradChair1.id');
echo $this->Form->inputs(array('legend'=> 'Graduate Chair 1', 'ATCGradChair1.firstName', 'ATCGradChair1.lastName', 'ATCGradChair1.campusId'));
//echo $this->Form->input('ATCGradChair2.id');
echo $this->Form->inputs(array('legend'=> 'Graduate Chair 2', 'ATCGradChair2.firstName', 'ATCGradChair2.lastName', 'ATCGradChair2.campusId'));
echo $this->Form->end('Submit');
Most fields are required. I'm using saveAll with deep option to save and validate. It appears that the call to _introspectModel in tagIsInvalid does not return the correct array of validation messages when it's checking the fields on ATCGradChair1.
Is my view incorrect or is this a bug?

CakePHP validation messages position

Normally, the CakePHP's validation messages from models like:
class User extends AppModel {
public $name = 'User';
public $validate = array(
'username' => array(
'required' => array(
'rule' => array('notEmpty'),
'message' => 'A username is required'
),
'regexp' => array(
'rule' => '/^[a-z0-9]{3,10}$/i',
'message' => 'Only letters and integers, min 3, max. 10 characters'
)
)
)
}
Are printed below the inputs, I mean that messages: 'message' => 'A username is required'
So it looks like:
|INPUT|
[Message]
How do I can change that so the messages gonna be added to the array:
$errors[] = 'Message';
And then, I would like to use foreach to print them in one place.
Is that possible?
CakePHP has all of the validation errors available to the view in $this->validationErrors. So I loop through them thusly:
<?php if ( !empty($this->validationErrors['Model']) ) { ?>
<div id="errorlist">
<h3>You have errors in your submission. <?php echo $warnimage; ?></h3>
<div>
<ul>
<?php foreach( $this->validationErrors['Model'] as $val ){ ?>
<li><?php echo $val; ?></li>
<?php } ?>
</ul>
</div>
</div>
<?php } ?>
EDIT
Where to place this code?
Place the code in the view where you would like it displayed.
How to disable displaying those errors below inputs?
I don't disable that display but suppose if you wished you could just unset $this->validationErrors['Model']. (untested)
Another solution is to use elements as shown in this article by Miles Johnson.

CodeIgniter flashdata delay

I'm tring to validate a login form and sending error messages using flashdata. Flashdata seems to have a delay, it's only affected a second submit (no error message is shown after first submit, ok after second), whereas userdata works correctly.
View>
<?php if ($this->session->flashdata('error_messages')): ?>
<?php echo $this->session->flashdata('error_messages'); ?>
<?php endif; ?>
<?php echo form_open('user/login', array('name' => 'login_form', 'id' => 'login_form')); ?>
<fieldset>
<p>
<?php echo form_label('Username: ', 'username'); ?>
<?php echo form_input('username', set_value('username', ''), array('id' => 'username', 'placeholder' => 'username')); ?>
</p>
<p>
<?php echo form_label('Password: ', 'password'); ?>
<?php echo form_password('password', set_value('password', ''), array('id' => 'password', 'placeholder' => '********')); ?>
</p>
<p>
<?php echo form_submit('login', 'Login', array('id' => 'login')); ?>
</p>
Controller action>
public function login() {
//user is not logged in, carry on
if (!user_is_logged_in()) {
//check if form was already submitted, if yes validate
if ($this->input->post('login')) {
$this->load->library('chronos_user');
//gather data from form
$username = $this->input->post('username');
$password = $this->input->post('password');
//validate form, show error messages if not valid
if (
!($this->chronos_user->valid_username($username)) ||
!($this->chronos_user->unique_username($username))
)
{
$this->chronos_template->set_data('header', array('controller' => 'users', 'action' => 'login', 'title' => 'Login'));
$this->chronos_template->set_view('content', 'user/login_view');
$this->chronos_template->view();
}
//redirect if ok
else {
header("Location http://c4studio.ro");
}
}
//if no form was submitted, just display it
else {
$this->chronos_template->set_data('header', array('controller' => 'users', 'action' => 'login', 'title' => 'Login'));
$this->chronos_template->set_view('content', 'user/login_view');
$this->chronos_template->view();
}
}
//user is already logged in, redirect to profile page
else {
$profile_url = "Location: ";
$profile_url .= site_url();
$profile_url .= "user/profile/";
header($profile_url);
}
}
Valid_username method>
public function valid_username($username) {
if (empty($username)) {
$this->CI->session->set_flashdata('error_messages', 'Value.');
return FALSE;
}
if (strlen($username) < 3) {
$this->CI->session->set_flashdata('error_messages', 'Value11.');
return FALSE;
}
return TRUE;
}
Any ideas? Also if somebody knows a better way to do all this please let me know! Thanks
According to the documentation flashdata exists at the next server request.
But in your case you actually set the flashdata in the same server request as you show the login view which was unsuccesful. Thats the reason it doesn't work.
A better way wuld to just allow your model method to return true or false and use that value instead. The flashdata should only be considered if you redirect the user to an error page or something like that.
As #Repox mentioned, it only works on the 'next refresh'. You are assuming that flashdata works RIGHT AWAY when you set it, but it doesn't you need an new actual page reload / refresh before that is available.
You have the right idea, but you are just using flashdata to implement your message, stick to form messages as a return result, or just a custom variable.
This is really a case of developers designing flashdata for one thing, and users using it for another.
You need to use form_error to return all form errors, don't use flashdata, it will not work as you expect it to.
Examples:
http://codeigniter.com/user_guide/libraries/form_validation.html#settingerrors
You can also override any error message found in the language file.
For example, to change the message for the "required" rule you will do
this:
$this->form_validation->set_message('required', 'Your custom message here');

Resources