Here is the final solution, form id is #quoteForm. Here you "merge" the settings of the two active forms:
//Add car button
$("#addCar").on('click', function(){
$.get('<?php echo Yii::app()->createAbsoluteUrl('quote/addCar'); ?>' + '?index=' + (carCount+1), function(data) {
var settings = $("#quoteForm").data('settings');
$("#quoteForm").data('settings', null);
$("#carlist").append(data);
var settings_new = $("#quoteForm").data('settings');
carCount++;
$.each(settings_new.attributes, function(k, v) {
settings.attributes.push(v);
});
//set the new settings
$("#quoteForm").data('settings', settings);
});
I actually use ActiveForm class which extends from CActiveForm and has this method which adds JS to the client script without running the widget(extracted form CActiveForm->run()):
public function registerJs()
{
$options=$this->clientOptions;
if(isset($this->clientOptions['validationUrl']) && is_array($this->clientOptions['validationUrl']))
$options['validationUrl']=CHtml::normalizeUrl($this->clientOptions['validationUrl']);
$options['attributes']=array_values($this->attributes);
if($this->summaryID!==null)
$options['summaryID']=$this->summaryID;
if($this->focus!==null)
$options['focus']=$this->focus;
if(!empty(CHtml::$errorCss))
$options['errorCss']=CHtml::$errorCss;
$options=CJavaScript::encode($options);
$cs=Yii::app()->clientScript;
$cs->registerCoreScript('yiiactiveform');
$id=$this->id;
$cs->registerScript(__CLASS__.'#'.$id,"jQuery('#$id').yiiactiveform($options);");
}
And here is the controller part. You create a form but only render fields, not using it as a widget:
$form = new ActiveForm();
$form->enableAjaxValidation = false;
$form->enableClientValidation = true;
$form->id = 'quoteForm';
$car = new \QuotesHistory();
$this->renderPartial('car_row', compact('car', 'carMakes', 'index', 'form'), false, true);
Here is a small part of the partial view($index is actually the carCount that is passed in the get request), also this partial has a lot more fields and they all validate and submit correctly:
<div class="field-box">
<?php
echo $form->hiddenField($car, "[$index]id");
echo $form->label($car, "[$index]automake_id", array('class'=>'form-label'));
echo $form->dropDownRow($car, "[$index]automake_id", CHtml::listData($carMakes, 'id', 'name'), array(
'data-target' => CHtml::activeId($car, "[$index]automodel_id"),
'empty'=>'Select Make',
));
echo $form->error($car, "[$index]automake_id", array(
'class'=>'alert-msg',
'style'=>'margin: 0;'
));
?>
</div>
And on the last partial you need to add this in the end of the view so that the JS is registered.:
<?php
if(Yii::app()->request->isAjaxRequest) //we dont need this in normal render
$form->registerJs();
?>
One final step: In order all this to works you should not double include any JS libs in the ajax response. You can do this in jQuery - http://www.eirikhoem.net/blog/2011/08/29/yii-framework-preventing-duplicate-jscss-includes-for-ajax-requests/
I've tested this code now and it works. If I remove elements I have no problem submitting the form.