Situation
I used the wiki article on Yii’s site, Collecting Tabular Input, to follow as an example.
I don’t believe I need to validate tabular input in a traditional sense against multiple models. I only have one model, but I’m dynamically creating the number of fields in the form. Here’s a bit more background.
I’m importing CSV files where its headers vary in order among the different files. Before correctly parsing the files, the user needs to map which header would map to what table/column.
I have a single model, ImportParseForm extended from CFormModel. It really only has one rule:
public function rules()
{
return array(
array('header', 'required'),
);
}
Here’s a snippet of my view:
<?php foreach($headers as $h => $hItem): ?>
<div class="row">
<?php echo CHtml::label(CHtml::encode($hItem), "[$h]header"); ?> maps to
<?php echo $fParse->textField($mForm, "[$h]header"); ?>
<?php echo $fParse->error($mForm, "[$h]header"); ?>
</div>
<?php endforeach; ?>
Here’s a snippet of my controller:
$mForm = new ImportParseForm;
$valid = true;
if (isset($_POST['ImportParseForm'])){
foreach ($headers as $h => $hVal){
if (isset($_POST['ImportParseForm'][$h])){
$mForm->attributes = $_POST['ImportParseForm'][$h];
$valid = $mForm->validate() && $valid;
}
}
if ($valid){
// Process CSV
}
}
If all fields are valid, then it passes as expected. The problem is if one of the fields are invalid (or in this case, empty), then all fields are flagged as invalid.
In Yii 1.1.10, they added CActiveForm::validateTabular(), but it looks like it’s for multiple models. Not quite what I have here. But for kicks, I added the following to my controller (removed the other type of validation, of course):
CActiveForm::validateTabular($mForm, array('header'));
The form itself is only valid if the first element is populated. If the first element is populated, it will set all the other elements with that same value (and passes validation).
Question
Basically, can I use CActiveForm to do validation against fields that are dynamically generated (similar to tabular input, but with only one model)?
After reading Collecting Tabular Input a bit closer, I am using “multiple” models. I misunderstood that multiple models would mean multiple different structured models and not just multiple of the same structured model in an array. For example, in the wiki there’s a piece that shows what items (array of models) to update:
$items=$this->getItemsToUpdate();. My corrected assumption is that that particular method grabs multiple of the same structured model but with different primary keys… or different records. Understanding that, the rest of the article makes more sense 😉But here’s my model solution on how to create a CSV header mapping form.
Here is a snippet in my controller on what my equivalent to
$items=$this->getItemsToUpdate();(again, the goal is to collect an array of models) would look likePush
$mFormto your view. Now in your view, iterate through$mFormfor your form like so (similar to the wiki article, but I’m using a CActiveForm widget here):Validation works as expected.
If you want to use AJAX validation, use
CActiveForm::validateTabular()in your controller (instead of the normalvalidate()).Hope this helps other Yii beginners! 🙂