I created a static option list in a page and I want to validate using JavaScript instead of AJAX:
<?php echo $form->labelEx($model,'emlevel'); ?>
<?php
echo $form->radioButtonList($model,'emlevel',
array('L'=>'Low','M'=>'Moderate','X'=>'Low Moderate', 'H'=>'High'),
array('separator' => " " ));
?>
<?php echo $form->error($model,'emlevel'); ?>
function chk()
{
// first I checked the value for emlevel to verify it get the value or not
//but it shows undefined
alert (document.forms["ConsultationNew"] ["ConsultationNew[enc_type]"].value);
if (document.forms["ConsultationNew"]["ConsultationNew[emlevel]"].value == null) {
alert ('choose one EMlevel'); return false;
}
}
I am not able to get value by document.getelement ....value. it shows undefined
You probably want to use CActiveForm. Clientside validation is configured as follows:
<?php $form=$this->beginWidget('CActiveForm', array(
'id'=>'login-form',
'enableAjaxValidation'=>false,
'enableClientValidation'=>true,
'clientOptions' => array (
'validateOnSubmit' => true,
'validateOnChange' => true,
'validateOnType' => true,
),
)); ?>
As you are working in Yii already, I would definitely use CActiveForm for client-side validation (and also for Ajax and server-side validation). It works like a charm. You must have better things to do than to reinvent the wheel in programming validation in Javascript.
Related
I don't want to use the FormHelper from CakePHP, because I want to use some Ajax in my app.
How can I pass the data from the form to the Controller? I'm using $.post from jQuery but I always get an error.
Thanks!
You can use Ajax with the CakePHP Form Helper.
In your view file .ctp put:
echo $this->Form->create('Model', array('id'=>'YourFormId', array('default'=>false)));
echo $this->Form->input('field');
echo $this->Form->submit('Save');
echo $this->Form-->end
Notice in your form->create your passing a default=>false which tells the form to not do a normal "Submit".
At the bottom of your view file .ctp put:
$data = $this->Js->get('#YourFormId')->serializeForm(array('isForm' => true, 'inline' => true));
$this->Js->get('#YourFormId')->event(
'submit',
$this->Js->request(
array('action' => 'yourAction', 'controller' => 'yourController'),
array(
'update' => '#flash',
'data' => $data,
'async' => true,
'dataExpression'=>true,
'method' => 'POST'
)
)
);
echo $this->Js->writeBuffer();
The above is CakePHP JS helper to help you write Ajax and Javascript which PHP. It basically grabs the form data that is being submitted and serializes it and passed it to /yourcontroller/youraction via ajax. The update=>#flash is telling Cake to Update the #flash div after the action is done.
Remember in your Controller to have public
public $helpers = array('Js');
public $components = array('RequestHandler');
-- jQuery --
$.post('<?=$this->Html->url(array('controller'=>'xxx','action'=>'yyy'))?>', {a:1,b:2});
-- cakePHP --
function yyy() {
$a = $this->request->data['a'];
$b = $this->request->data['b'];
}
can i pass form dropdown value in my controller and after this, i can send the value in my DB table....please help me i m new in cakephp here is my job_content.ctp
echo'<div class="AcceptButtonFormData">';
echo $this->Form->create('Job' ,array('action' => 'view'));
$ipr_value=array('0'=>0.0,'1'=>.1,'2'=>.2,'3'=>.3);
echo $this->Form->input('IPR_teeth_pair12',array('type' => 'select','name'=>'drop12', 'options' => $ipr_value,'default'=>0));
echo $this->Form->input('IPR_teeth_pair23',array('type' => 'select','name'=>'drop23', 'options' => $ipr_value,'default'=>0));
echo $this->Form->input('IPR_teeth_pair34',array('type' => 'select','name'=>'drop34', 'options' => $ipr_value,'default'=>0));
echo $this->Form->end();
echo '</div>'
yes you can save it. As per above form this will post to you controller action in view
public function view() {
// Has any form data been POSTed?
if ($this->request->is('post')) {
// If the form data can be validated and saved...
if ($this->Job->save($this->request->data)) {
// Set a session flash message and redirect.
$this->Session->setFlash('JobSaved!');
$this->redirect('/jobs');
}
}
// If no form data, find the recipe to be edited
// and hand it to the view.
$this->set('jobs', $this->Job->findAll());
}
below is just sudo code you can change as per you need and for more understanding you can visit cakephp.org
First post here on stack overflow so I hope I do it right, I have searched but cannot find what I am looking for.
i am new to cakephp and fairly new to php. I was able to get up and running yesterday no problem and can send data to my database. to day I wanted to work on validation with ajax but I think I am going to leave the ajax out of it for a little while as I have a problem with the validation errors displaying.
The validation is set up for the first two form fields like this;
<?php
class people extends AppModel
{
public $name = 'people';
public $useTable = 'people';
public $validate = array(
'firstName'=>array(
'rule'=>'notEmpty',
'message'=>'Enter You First Name'
),
'secondName'=>array(
'rule'=>'notEmpty',
'message'=>'Enter Your Second/Family Name'
),
);
}?>
and it works fine if those fields are empty it wont write to the database so far so good. However, when I hit submit on the form the page refreshes, the error messages appear under the form fields but it also adds a completely new form under the previous one. here is the controller. Note: the validate_form function is from an cakephp with ajax tutorial i was following and is commented out
<?php
class peoplesController extends AppController
{
public $name = "peoples";
public $helpers = array('Html', 'form', 'Js');
public $components = array('RequestHandler');
public function index() {
if( $this->request->is('post'))
{
$data = $this->request->data;
$this->people->save($data);
}
}
/*public function validate_form() {
if ($this->RequestHandler->isAjax()) {
$this->data['people'][$this->params['form']['field']] = $this->params['form']['value'];
$this->people->set($this->data);
if ($this->people->validates()) {
$this->autoRender = FALSE;
}
else {
$error = $this->validateErrors($this->people);
$this->set('error', $error[$this->params['form']['field']]);
}
}
}*/
}
?>
and the view. note: the divs with id sending and success are also from the tutorial I was following but I dont think would have an effect on this particular issue.
<div id="success"></div>
<h2> Fill in your profile details </h2>
<?php
echo $this->Form->create('people');
echo $this->Form->input('firstName');
echo $this->Form->input('secondName');
echo $this->Form->input('addressOne');
echo $this->Form->input('addressTwo');
echo $this->Form->input('city');
echo $this->Form->input('county');
echo $this->Form->input('country');
echo $this->Form->input('postCode', array(
'label' => 'Zip Code',
));
echo $this->Form->input('dob', array(
'label' => 'Date of birth',
'dateFormat' => 'DMY',
'minYear' => date('Y') - 70,
'maxYear' => date('Y') - 18,
));
echo $this->Form->input('homePhone');
echo $this->Form->input('mobilePhone');
echo $this->Form->input('email', array(
'type' => 'email'
));
$goptions = array(1 => 'Male', 2 => 'Female');
$gattributes = array('legend' => false);
echo $this->Form->radio('gender',
$goptions, $gattributes
);
echo $this->Form->input('weight');
echo $this->Form->input('height');
$toptions = array(1 => 'Tandem', 2 => 'Solo');
$tattributes = array('legend' => false);
echo $this->Form->radio('trained',
$toptions, $tattributes
);
echo $this->Form->input('referedBy');
/*echo $this->Form->submit('submit');*/
echo $this->Js->submit('Send', array(
'before'=>$this->Js->get('#sending')->effect('fadeIn'),
'success'=>$this->Js->get('#sending')->effect('fadeOut'),
'update'=>'#success'
));
echo $this->Form->end();
?>
<div id="sending" style="display: none; background-color: lightgreen">Sending.... </div>
<?php
echo $this->Html->script(
'validation', FALSE);
?>
so the creation of the second identical form on the same page is my primary problem, I think it has something to do with the controller taking the first form and sending it back to the same view but I dont know how to trouble shoot this.
a second problem is that for some reason if I use
echo $this->Form->submit('submit');
instead of
echo $this->Js->submit('send', array(
'before'=>$this->Js->get('#sending')->effect('fadeIn'),
'success'=>$this->Js->get('sending')->effect('fadeOut'),
'update'=>'#success'));
Then I dont get my error messages anymore I instead just get a bubble that appears and says 'please fill in this field' I am sure this is a jquery issue but again I dont know how to trouble shoot it so that that bullbe does not appear and it instead shows the error messages I want
Thanks in advance
Couple things:
1) Use Caps for your classnames. So People, PeoplesController, etc
2) Don't mess with Ajax until you get the standard flow working. So go back to $this->Form->submit('submit');.
3) That "required" tooltip is HTML5. Since you set the validation to notEmpty, Cake adds HTML5 markup to make the field required. Modify your Form->create call to bypass that for now (if you need to, but it provides client-side validation which is more efficient):
$this->Form->create('People', array('novalidate' => true));
See the FormHelper docs for more info on HTML5 validations
About CActiveForm in document is:(clientOptions section)
ajaxVar: string, the name of the parameter indicating the request is an AJAX request. When the AJAX validation is triggered, a parameter named as this property will be sent together with the other form data to the server. The parameter value is the form ID. The server side can then detect who triggers the AJAX validation and react accordingly. Defaults to 'ajax'.
Now take a look in my example:
Summary: i have a form with two fields mail and newEmail, i submitted form via ajaxSubmitButton(if you need form code tell me put it). In following i get var_dump($_POST) content in two state:
First: Following var_dump($_POST) is for when a field(newEmail) is left empty:
array
'User' =>
array
'email' => string 'user#gmail.com' (length=14)
'newEmail' => string '' (length=0)
Second: Following var_dump($_POST) is for when all the fields are filled:
array
'User' =>
array
'email' => string 'user#gmail.com' (length=14)
'newEmail' => string 'admin#gmail.net' (length=19)
'ajax' => string 'email-form' (length=10)
'yt0' => string 'update' (length=18)
As you see only when all fields are filled the ajaxVar(ajax) exist in $_POST. When ajaxVar(ajax) initialized in CActiveForm?
Edit
email-form:
<?php
<div class="form">
<?php $form = $this->beginWidget('CActiveForm',array(
'id'=>'email-form',
'enableAjaxValidation'=>true,
'clientOptions'=>array(
'validateOnSubmit'=>true,
'focus'=>'input[type="email"]:first',
)
)); ?>
<div class="row">
<?php echo $form->label($model,'email') ?>
<?php echo $form->textField($model,'email') ?>
<?php echo $form->error($model,'email') ?>
</div>
<div class="row">
<?php echo $form->label($model,'newEmail') ?>
<?php echo $form->textField($model,'newEmail') ?>
<?php echo $form->error($model,'newEmail') ?>
</div>
<hr>
<div class="row">
<?php echo CHtml::ajaxSubmitButton(
'update',
Yii::app()->createUrl('upanel/user/CEmail'),
array(
'dataType'=>'json',
'type' => 'POST',
'data' => "js:$('#email-form').serialize()",
'success'=>'function(data){
if(data.status=="success")
{
//alert(data.status);
hideFormErrors(form="#email-form");
callback(status=data.status);
}else{
formErrors(data,form="#email-form");
}
}',
'beforeSend'=>'before',
),
array(
'id' => 'update-button'.uniqid(),
'class'=>'submit-button'
)
);
?>
</div>
<?php $this->endWidget() ?>
</div>
<?php echo $form->errorSummary($model,'please solve following errors:') ?>
actionCEmail:
public function actionCEmail()
{
/*ob_start();
var_dump($_POST);
$log=ob_get_contents();
$fp = fopen('data.html', 'w');
fwrite($fp, $log);
fclose($fp);
Yii::app()->end();*/ //This block active whenever i want see the $_POST content
$model = $this->loadModel(Yii::app()->user->id);
$model->scenario = 'CEmail';
$this->performAjaxValidation($model,'email-form');
if(Yii::app()->request->isAjaxRequest)
$this->renderPartial('_cemail',array('model'=>$model),false,true);
else
$this->render('update',array('model'=>$model,'form'=>'_cemail'));
}
protected function performAjaxValidation($model,$form)
{
if(isset($_POST['ajax']) && $_POST['ajax']===$form)
{
echo CActiveForm::validate($model);
Yii::app()->end();
}
}
ajaxVar
initialized onsubmit if 'validateOnSubmit'=>true,. Try to use validateOnChange=>true and show your cactiveform code when init it.
And really stop invent "a bycicle".
Try to read http://learnyii.blogspot.com/2010/12/yii.html if you didnt understand my code in previous question.
I showed you working code of ajax validation which i use on working project. And with that method your $_POST will update on change of all fields with JSON object wich will contain errors for form.
Stop flooding community. Regards.
In your action:
public function actionCEmail()
{
$model = $this->loadModel(Yii::app()->user->id);
$model->scenario = 'CEmail';
if(Yii::app()->request->isAjaxRequest)
{
$error = CActiveForm::validate($model);
if($error!='[]')
{
echo $error;
Yii::app()->end();
}
}
if(isset($_POST['CEmailForm']))
{
//put form name in POST above
//do whatever you need with model here
//save / edit etc.
//in the end
echo CJSON::encode(array(
'status'=>'success',
));
Yii::app()->end();
}
if(Yii::app()->request->isAjaxRequest) //check renders
$this->renderPartial('_cemail',array('model'=>$model),false,true);
else
$this->render('update',array('model'=>$model,'form'=>'_cemail'));
}
In your view submit button:
<?php echo CHtml::ajaxSubmitButton ("Save", Yii::app()->request->url, array (
'dataType' => 'json',
'type'=>'post',
'success' =>
'js:function (data) {
if(data.status=="success"){
//do whatever you need on success
//show flash/notification
};
}
else {//show errors here
$.each(data, function(key, val) {
$("#YourFormIDhere #"+key+"_em_").text(val);
$("#YourFormIDhere #"+key+"_em_").css(\'display\',\'block\');
});
//can show error summarry here or custom notifications
};
}',
), array (
'id' => 'yourbuttonid_submit_'.rand(1,255), // Need a unique id or they start to conflict with more than one load.
));?>
Try to do like this. It works. Keep it simple. You lost 2? days to validation of 2 fields.
I just made this on my changepassword form. It took me 5 minutes.
My post when trying to save with default empty field:
{"UserChangePassword_verifyPassword":["Required field","Retype Password is incorrect."]}
Make like this and dont loose time. Regards.
i need to return the form validation because i lost it after submitting
i'm on News/view/30 ---view a report details----
in that page we have add comment Form :
<h2>Add comment</h2>
<?php
echo $this->Form->create("Comment", array(
'url' => array('controller' => 'Comments', 'action' => 'add')
));
echo $this->Form->label("name");
echo $this->Form->input("name", array("label" => false, "class" => "textfield"));
echo $this->Form->label("email");
echo $this->Form->input("email", array("label" => false, "class" => "textfield"));
echo $this->Form->label("text");
echo $this->Form->textarea("text", array("label" => false));
echo $this->Form->input("object_id", array("type" => "hidden", "value" => $data['News']['id']));
echo $this->Form->input("type", array("type" => "hidden", "value" => "news"));
echo $this->Html->Link("Add Comment", "#", array("class" => "add_button", "onclick" => "$('#CommentViewForm').submit()"));
echo $this->Form->end();
?>
the form is submiting on Comment controller :
in comment/add :
$isSuccess = $this->Comment->save($this->request->data);
if ($isSuccess) {
$this->Session->setFlash('your Comments has been added successfully and pending admin aproval.thanks ', 'default', array(), 'good');
} else {
$this->Session->setFlash('Failed to add your comment: <br/>Fill all the required fileds <br/>type correct Email', 'default', array(), 'bad');
}
$this->redirect(array("controller" => "News", "action" => "view", $id));
i did some validation rules on name,email and the comment itself
when there are errors in user inputs return to add Comment Form but didnt show the errors as usual
i hope you understand me very well, and i wait your help
thank alot
just try to add 'error'=>true to each input form helper
like echo $this->Form->input("name", array("label" => false, "class" => "textfield", 'error'=>true));
See if this work .
You should first bake some code, if you didnt' work with CakePHP for that long.
Then you would learn that you should not redirect if the form does not validate:
if ($this->Comment->save($this->request->data)) {
$this->Session->setFlash('your Comments has been added successfully and pending admin aproval.thanks ', 'default', array(), 'good');
$this->redirect(array("controller" => "News", "action" => "view", $id));
} else {
$this->Session->setFlash('Failed to add your comment: <br/>Fill all the required fileds <br/>type correct Email', 'default', array(), 'bad');
// DO NOT redirect
}
The bake templates will bake your controller code this way. This asserts a clean and transparent way of dealing with forms.
Won't your redirect stop you seeing your validation errors? You're redirecting the user to a new page (the view page) even if there are errors, so they'll never see any validation error messages.
Trying commenting out this line:
//$this->redirect(array("controller" => "News", "action" => "view", $id));
or making it conditional on $isSuccess being true.
UPDATE
Re: your comment - the thing is, if you redirect away from the page with the form on, you will not (easily) be able to display you validation error messages. The easiest thing would be to have your form submit to its own action - by the sound of it you're submitting it to an action in another controller.
I think you'll need to handle the form->save in the view action on the News controller, then as others have said, don't redirect away from the page if it fails validation.
If you redirect you'll still see the validation message atleast once (from the session Flash) but you'll lose the filled in form data.
Easiest solution is move the save to your News->view method and if your News and Comment models are associated just use the traversal available to save the Comment there:
$isSuccess = $this->News->Comment->save($this->request->data);