This topic is rather old, but still an issue I had to deal with. I came up with a solution that is not as nice as I would have liked, but works.
The basic idea is use what is working of each button, by that I mean that I create two buttons (submitButton and ajaxSubmitButton) and hide the ajaxSubmitButton. Once you click the submitButton, it will do the validation, but I stop the submit action from being done. If there were no errors, then I use the ajaxSubmitButton that was hidden to submit the form.
To do that without the need of creating the functionality each time you are going to use it, I simply extend CHtml:
protected/helpers/THtml.php:
<?php
class THtml extends CHtml {
//This method allows to have a working ajaxSubmitButton that validates before doing the actual data submission
//This requires the form to have the afterValidate param set to the ajaxAfterValidate function
// 'afterValidate'=>'js:ajaxAfterValidate'
public static function ajaxSubmitValidatedButton($label,$url,$ajaxOptions=array(),$htmlOptions=array()){
if(isset($htmlOptions['id']))
$id=$htmlOptions['id'];
else
$id=$htmlOptions['id']=isset($htmlOptions['name'])?$htmlOptions['name']:self::ID_PREFIX.self::$count++;
$ajaxHtmlOptions['id'] = 'submitAjax_'.$id;
$buttons = parent::ajaxSubmitButton($label,$url,$ajaxOptions,$ajaxHtmlOptions);
$buttons .= parent::submitButton($label,$htmlOptions);
$cs=Yii::app()->getClientScript();
$cs->registerScriptFile("/js/ajaxSubmitButton.js");
$cs->registerScript('Yii.THtml.#' . $id,
"$('body').on('submit','#$id',function(){return false;});
$('#{$ajaxHtmlOptions['id']}').hide();");
return $buttons;
}
}
In the form I indicate the params:
$form=$this->beginWidget('CActiveForm', array(
'id'=>'site-form',
'enableAjaxValidation'=>true,
'clientOptions'=>array('validateOnSubmit'=>true,
'afterValidate'=>'js:ajaxAfterValidate'),
The afterValidate parameter what is going to do, is to call a js function to click the ajaxSubmitButton that was hidden once there are no validation errors
A sample of that function is:
js/ajaxSubmitButton.js
function ajaxAfterValidate(form, data, hasError){
if(!hasError)
$('[id^="submitAjax_"]',form).click();
}
Finally, I just use the newly created button with the same params as I would create the ajaxSubmitButton:
echo THtml::ajaxSubmitValidatedButton('Create',CController::createUrl( 'site/create'), array('update'=>'#content'),array('name'=>'buttonId'));
Hope this helps!