Hi all,
I thought I’d make my first post something about a little something I came up whilst working with CActiveForm and CFormModel.
I was using CHtml::ajaxButton to send a form. This worked perfect but I couldn’t get the validation errors (defined by CModel) to display on ajax success. Here’s the solution I came up with:
In the view file:
echo CHtml::ajaxButton(
'',
array('login/AjaxRegisterStaff'),
array(
'type' => 'POST',
'dataType' => 'json',
'beforeSend' => 'function(){
//loading gif
}',
'complete' => 'function(data){
var jsonResponseObj = jQuery.parseJSON(data.responseText);
if (!jsonResponseObj.validates) {
jQuery("#staffRegFormError").html(jsonResponseObj.formError);
jQuery("#staffRegFormError").slideDown(!00);
}
else {
window.location = jsonResponseObj.redirectUrl;
}
}'
),
array('class' => 'registerButton')
);
Notice the second argument of ajaxButton(), it is the controller/action pair (I love how easy this is in Yii). This form will now be posted to LoginController / actionAjaxRegisterStaff.
Here’s the action function in the controller class:
public function actionAjaxRegisterStaff() {
$staffRegistrationModel = new StaffRegistrationForm;
if (isset($_POST['StaffRegistrationForm'])) {
$staffRegistrationModel->attributes = $_POST['StaffRegistrationForm'];
if($staffRegistrationModel->validate()) {
echo CJSON::encode(array('validates' => true, 'redirectUrl' => $redirectUrl));
}
else {
$formErrors = $staffRegistrationModel->getErrors();
$formErrors['validates'] = false;
echo CJSON::encode($formErrors);
}
}
}
The part I want you to focus on is the else statement. $staffRegistrationModel->getErrors() returns an array with key value pairs. I add an additional validates = false so that the JS in the view file can execute the correct action accordingly.
Here’s a function in the class I extended from CModelForm in order to create the RegistrationFormModel:
public function authenticatePass($attribute,$params) {
if (!$this->hasErrors()) { // we only want to authenticate when no input errors
$identity = new StaffIdentity($this->email, $this->password);
$identity->authenticate();
switch ($identity->errorCode) {
case PharmacyIdentity::ERROR_NONE:
break;
default: // UserIdentity::ERROR_PASSWORD_INVALID
$this->addError('formError','Sorry, your login details were incorrect.');
break;
}
}
}
This function is attached to the password field by adding it to the rules() array:
public function rules() {
return array(
array('email, password', 'required'),
array('email', 'email'),
array('password', 'authenticatePass'),
);
}
Hope this helps with anyone facing ajax error handling issues!