Hello Yii-community,
I’m currently up to the problem that I’d like to replace the default styling and technic to display the errors for a CActiveForm with enabled ajaxValidation and clientValidation.
Instead of the default method I’d like to use my custom method triggering qTip that is targeted to the input-field (http://craigsworks.com/projects/qtip2/docs/).
Currently I’m trying to overide the JS function $.fn.yiiactiveform.updateInput within a seperate JS-file but I think this is really dirty.
Is there a better solution to replace this method?
Kind regards,
Dominik
//Edit: My Current solution looks like this
ActiveForm.php
<?php
class ActiveForm extends CActiveForm
{
public function init() {
parent::init();
Yii::app()->getClientScript()->registerScriptFile('/js/'.Yii::app()->params['sysVersion'].'/form.js');
}
public function error($model,$attribute,$htmlOptions=array(),$enableAjaxValidation=true,$enableClientValidation=true)
{
$parentError = parent::error($model, $attribute, $htmlOptions, $enableAjaxValidation, $enableClientValidation);
if (($error = $model->getError($attribute)))
{
$id=CHtml::activeId($model,$attribute);
$inputID=isset($htmlOptions['inputID']) ? $htmlOptions['inputID'] : $id;
unset($htmlOptions['inputID']);
if(!isset($htmlOptions['id']))
$htmlOptions['id']=$inputID.'_em_';
Yii::app()->getClientScript()->registerScript('error_ipt-'.$inputID, "formError_show('{$inputID}', '{$error}');$('#{$htmlOptions['id']}').hide();");
}
//Keep the original Error in case of disabled javascript
return $parentError;
}
}
The used JS File form.js
function formError_show(inputID, message)
{
var $el = $('#' + inputID);
if ($el.length)
{
$el.qtip({
content: {
text : message
},
position: {
my : 'center left', // ...at the center of the viewport
at : 'center right',
adjust: {
x: -4
}
},
show: {
event: null,
solo: false // ...and hide all other tooltips...
},
hide: {
event:null
},
style: 'ui-tooltip-red ui-tooltip-shadow ui-tooltip-rounded'
});
$el.qtip('api').show();
}
}
(function ($) {
var getAFValue = function (o) {
var type,
c = [];
if (!o.length) {
return undefined;
}
if (o[0].tagName.toLowerCase() === 'span') {
o.find(':checked').each(function () {
c.push(this.value);
});
return c.join(',');
}
type = o.attr('type');
if (type === 'checkbox' || type === 'radio') {
return o.filter(':checked').val();
} else {
return o.val();
}
};
/**
* updates the error message and the input container for a particular attribute.
* @param attribute object the configuration for a particular attribute.
* @param messages array the json data obtained from the ajax validation request
* @param form the form jQuery object
* @return boolean whether there is a validation error for the specified attribute
*/
$.fn.yiiactiveform.updateInput = function (attribute, messages, form) {
attribute.status = 1;
var $container,
hasError = false,
$el = form.find('#' + attribute.inputID);
if ($el.length) {
hasError = messages !== null && $.isArray(messages[attribute.id]) && messages[attribute.id].length > 0;
$container = $.fn.yiiactiveform.getInputContainer(attribute, form);
$container.removeClass(
attribute.validatingCssClass + ' ' +
attribute.errorCssClass + ' ' +
attribute.successCssClass
);
if (hasError) {
formError_show(attribute.inputID, messages[attribute.id][0]);
$container.addClass(attribute.errorCssClass);
} else if (attribute.enableAjaxValidation || attribute.clientValidation) {
if ($el.qtip('api') != undefined)
$el.qtip('api').hide();
$container.addClass(attribute.successCssClass);
}
attribute.value = getAFValue($el);
}
return hasError;
};
})(jQuery);
As I say, I’m not happy with this solution especially because of possible issues when upgrading Yii.
Is there a better solution that just doesn’t come to my mind?