1<?php
2/**
3 * TbActiveForm class file.
4 * @author Antonio Ramirez <ramirez.cobos@gmail.com>
5 * @copyright Copyright &copy; Christoffer Niska 2013-
6 * @license http://www.opensource.org/licenses/bsd-license.php New BSD License
7 * @package bootstrap.widgets
8 */
9
10/**
11 * Bootstrap active form widget.
12 *
13 * @method null copyId() via TbWidget
14 */
15class TbActiveForm extends CActiveForm
16{
17    /**
18     * @var string the form layout.
19     */
20    public $layout;
21    /**
22     * @var string the help type. Valid values are TbHtml::HELP_INLINE and TbHtml::HELP_BLOCK.
23     */
24    public $helpType = TbHtml::HELP_TYPE_BLOCK;
25    /**
26     * @var string the CSS class name for error messages.
27     */
28    public $errorMessageCssClass = 'error';
29    /**
30     * @var string the CSS class name for success messages.
31     */
32    public $successMessageCssClass = 'success';
33    /**
34     * @var boolean whether to hide inline errors. Defaults to false.
35     */
36    public $hideInlineErrors = false;
37    /**
38     * @var string class width label for horizontal forms.
39     */
40    public $labelWidthClass = 'col-sm-2';
41    /**
42     * @var string class width control for horizontal forms.
43     */
44    public $controlWidthClass = 'col-sm-10';
45
46    /**
47     * Initializes the widget.
48     */
49    public function init()
50    {
51        $this->attachBehavior('TbWidget', new TbWidget);
52        $this->copyId();
53        if ($this->stateful) {
54            echo TbHtml::statefulFormTb($this->layout, $this->action, $this->method, $this->htmlOptions);
55        } else {
56            echo TbHtml::beginFormTb($this->layout, $this->action, $this->method, $this->htmlOptions);
57        }
58    }
59
60    /**
61     * Displays the first validation error for a model attribute.
62     * @param CModel $model the data model
63     * @param string $attribute the attribute name
64     * @param array $htmlOptions additional HTML attributes to be rendered in the container div tag.
65     * @param boolean $enableAjaxValidation whether to enable AJAX validation for the specified attribute.
66     * @param boolean $enableClientValidation whether to enable client-side validation for the specified attribute.
67     * @return string the validation result (error display or success message).
68     */
69    public function error(
70        $model,
71        $attribute,
72        $htmlOptions = array(),
73        $enableAjaxValidation = true,
74        $enableClientValidation = true
75    ) {
76        if (!$this->enableAjaxValidation) {
77            $enableAjaxValidation = false;
78        }
79        if (!$this->enableClientValidation) {
80            $enableClientValidation = false;
81        }
82        if (!$enableAjaxValidation && !$enableClientValidation) {
83            return TbHtml::error($model, $attribute, $htmlOptions);
84        }
85        $id = CHtml::activeId($model, $attribute);
86        $inputID = TbArray::getValue('inputID', $htmlOptions, $id);
87        unset($htmlOptions['inputID']);
88        TbArray::defaultValue('id', $inputID . '_em_', $htmlOptions);
89        $option = array(
90            'id' => $id,
91            'inputID' => $inputID,
92            'errorID' => $htmlOptions['id'],
93            'model' => get_class($model),
94            'name' => $attribute,
95            'enableAjaxValidation' => $enableAjaxValidation,
96            'inputContainer' => 'div.form-group', // Bootstrap requires this
97            'errorCssClass' => 'has-error',
98            'successCssClass' => 'has-success',
99        );
100        $optionNames = array(
101            'validationDelay',
102            'validateOnChange',
103            'validateOnType',
104            'hideErrorMessage',
105            'inputContainer',
106            'errorCssClass',
107            'successCssClass',
108            'validatingCssClass',
109            'beforeValidateAttribute',
110            'afterValidateAttribute',
111        );
112        foreach ($optionNames as $name) {
113            if (isset($htmlOptions[$name])) {
114                $option[$name] = TbArray::popValue($name, $htmlOptions);
115            }
116        }
117        if ($model instanceof CActiveRecord && !$model->isNewRecord) {
118            $option['status'] = 1;
119        }
120        if ($enableClientValidation) {
121            $validators = (array) TbArray::popValue('clientValidation', $htmlOptions, array());
122            $attributeName = $attribute;
123            if (($pos = strrpos($attribute, ']')) !== false && $pos !== strlen($attribute) - 1) // e.g. [a]name
124            {
125                $attributeName = substr($attribute, $pos + 1);
126            }
127            /** @var CValidator $validator */
128            foreach ($model->getValidators($attributeName) as $validator) {
129                if ($validator->enableClientValidation) {
130                    if (($js = $validator->clientValidateAttribute($model, $attributeName)) != '') {
131                        $validators[] = $js;
132                    }
133                }
134            }
135            if ($validators !== array()) {
136                $validators = implode("\n", $validators);
137                $option['clientValidation'] = "js:function(value, messages, attribute) {\n$validators\n}";
138            }
139        }
140        $html = TbHtml::error($model, $attribute, $htmlOptions);
141        if ($html === '') {
142            $htmlOptions['type'] = $this->helpType;
143            TbHtml::addCssStyle('display:none', $htmlOptions);
144            $html = TbHtml::help('', $htmlOptions);
145        }
146        $this->attributes[$inputID] = $option;
147        return $html;
148    }
149
150    /**
151     * Displays a summary of validation errors for one or several models.
152     * @param mixed $models the models whose input errors are to be displayed.
153     * @param string $header a piece of HTML code that appears in front of the errors
154     * @param string $footer a piece of HTML code that appears at the end of the errors
155     * @param array $htmlOptions additional HTML attributes to be rendered in the container div tag.
156     * @return string the error summary. Empty if no errors are found.
157     */
158    public function errorSummary($models, $header = null, $footer = null, $htmlOptions = array())
159    {
160        if (!$this->enableAjaxValidation && !$this->enableClientValidation) {
161            return TbHtml::errorSummary($models, $header, $footer, $htmlOptions);
162        }
163        TbArray::defaultValue('id', $this->id . '_es_', $htmlOptions);
164        $html = TbHtml::errorSummary($models, $header, $footer, $htmlOptions);
165        if ($html === '') {
166            if ($header === null) {
167                $header = '<p>' . Yii::t('yii', 'Please fix the following input errors:') . '</p>';
168            }
169            TbHtml::addCssClass(TbHtml::$errorSummaryCss, $htmlOptions);
170            TbHtml::addCssStyle('display:none', $htmlOptions);
171            $html = CHtml::tag('div', $htmlOptions, $header . '<ul><li>dummy</li></ul>' . $footer);
172        }
173        $this->summaryID = $htmlOptions['id'];
174        return $html;
175    }
176
177    /**
178     * Generates a text field for a model attribute.
179     * @param CModel $model the data model.
180     * @param string $attribute the attribute.
181     * @param array $htmlOptions additional HTML attributes.
182     * @return string the generated input field.
183     * @see TbHtml::activeTextField
184     */
185    public function textField($model, $attribute, $htmlOptions = array())
186    {
187        return $this->createInput(TbHtml::INPUT_TYPE_TEXT, $model, $attribute, $htmlOptions);
188    }
189
190    /**
191     * Generates a password field for a model attribute.
192     * @param CModel $model the data model.
193     * @param string $attribute the attribute.
194     * @param array $htmlOptions additional HTML attributes.
195     * @return string the generated input field.
196     * @see TbHtml::activePasswordField
197     */
198    public function passwordField($model, $attribute, $htmlOptions = array())
199    {
200        return $this->createInput(TbHtml::INPUT_TYPE_PASSWORD, $model, $attribute, $htmlOptions);
201    }
202
203    /**
204     * Generates an url field for a model attribute.
205     * @param CModel $model the data model
206     * @param string $attribute the attribute
207     * @param array $htmlOptions additional HTML attributes.
208     * @return string the generated input field
209     * @see TbHtml::activeUrlField
210     */
211    public function urlField($model, $attribute, $htmlOptions = array())
212    {
213        return $this->createInput(TbHtml::INPUT_TYPE_URL, $model, $attribute, $htmlOptions);
214    }
215
216    /**
217     * Generates an email field for a model attribute.
218     * @param CModel $model the data model.
219     * @param string $attribute the attribute.
220     * @param array $htmlOptions additional HTML attributes.
221     * @return string the generated input field.
222     * @see TbHtml::activeEmailField
223     */
224    public function emailField($model, $attribute, $htmlOptions = array())
225    {
226        return $this->createInput(TbHtml::INPUT_TYPE_EMAIL, $model, $attribute, $htmlOptions);
227    }
228
229    /**
230     * Generates a number field for a model attribute.
231     * @param CModel $model the data model.
232     * @param string $attribute the attribute.
233     * @param array $htmlOptions additional HTML attributes.
234     * @return string the generated input field.
235     * @see TbHtml::activeNumberField
236     */
237    public function numberField($model, $attribute, $htmlOptions = array())
238    {
239        return $this->createInput(TbHtml::INPUT_TYPE_NUMBER, $model, $attribute, $htmlOptions);
240    }
241
242    /**
243     * Generates a range field for a model attribute.
244     * @param CModel $model the data model.
245     * @param string $attribute the attribute.
246     * @param array $htmlOptions additional HTML attributes.
247     * @return string the generated input field.
248     * @see TbHtml::activeRangeField
249     */
250    public function rangeField($model, $attribute, $htmlOptions = array())
251    {
252        return $this->createInput(TbHtml::INPUT_TYPE_RANGE, $model, $attribute, $htmlOptions);
253    }
254
255    /**
256     * Generates a date field for a model attribute.
257     * @param CModel $model the data model.
258     * @param string $attribute the attribute.
259     * @param array $htmlOptions additional HTML attributes.
260     * @return string the generated input field.
261     */
262    public function dateField($model, $attribute, $htmlOptions = array())
263    {
264        return $this->createInput(TbHtml::INPUT_TYPE_DATE, $model, $attribute, $htmlOptions);
265    }
266
267    /**
268     * Generates a text area for a model attribute.
269     * @param CModel $model the data model.
270     * @param string $attribute the attribute.
271     * @param array $htmlOptions additional HTML attributes.
272     * @return string the generated text area.
273     * @see TbHtml::activeTextArea
274     */
275    public function textArea($model, $attribute, $htmlOptions = array())
276    {
277        return $this->createInput(TbHtml::INPUT_TYPE_TEXTAREA, $model, $attribute, $htmlOptions);
278    }
279
280    /**
281     * Generates a file field for a model attribute.
282     * @param CModel $model the data model.
283     * @param string $attribute the attribute.
284     * @param array $htmlOptions additional HTML attributes
285     * @return string the generated input field.
286     * @see TbHtml::activeFileField
287     */
288    public function fileField($model, $attribute, $htmlOptions = array())
289    {
290        return $this->createInput(TbHtml::INPUT_TYPE_FILE, $model, $attribute, $htmlOptions);
291    }
292
293    /**
294     * Generates a radio button for a model attribute.
295     * @param CModel $model the data model.
296     * @param string $attribute the attribute.
297     * @param array $htmlOptions additional HTML attributes.
298     * @return string the generated radio button.
299     * @see TbHtml::activeRadioButton
300     */
301    public function radioButton($model, $attribute, $htmlOptions = array())
302    {
303        return $this->createInput(TbHtml::INPUT_TYPE_RADIOBUTTON, $model, $attribute, $htmlOptions);
304    }
305
306    /**
307     * Generates a checkbox for a model attribute.
308     * @param CModel $model the data model.
309     * @param string $attribute the attribute.
310     * @param array $htmlOptions additional HTML attributes.
311     * @return string the generated check box.
312     * @see TbHtml::activeCheckBox
313     */
314    public function checkBox($model, $attribute, $htmlOptions = array())
315    {
316        return $this->createInput(TbHtml::INPUT_TYPE_CHECKBOX, $model, $attribute, $htmlOptions);
317    }
318
319    /**
320     * Generates a dropdown list for a model attribute.
321     * @param CModel $model the data model.
322     * @param string $attribute the attribute.
323     * @param array $data data for generating the list options (value=>display).
324     * @param array $htmlOptions additional HTML attributes.
325     * @return string the generated drop down list.
326     * @see TbHtml::activeDropDownList
327     */
328    public function dropDownList($model, $attribute, $data, $htmlOptions = array())
329    {
330        return $this->createInput(TbHtml::INPUT_TYPE_DROPDOWNLIST, $model, $attribute, $htmlOptions, $data);
331    }
332
333    /**
334     * Generates a list box for a model attribute.
335     * @param CModel $model the data model.
336     * @param string $attribute the attribute.
337     * @param array $data data for generating the list options (value=>display).
338     * @param array $htmlOptions additional HTML attributes.
339     * @return string the generated list box.
340     * @see TbHtml::activeListBox
341     */
342    public function listBox($model, $attribute, $data, $htmlOptions = array())
343    {
344        return $this->createInput(TbHtml::INPUT_TYPE_LISTBOX, $model, $attribute, $htmlOptions, $data);
345    }
346
347    /**
348     * Generates a radio button list for a model attribute
349     * @param CModel $model the data model.
350     * @param string $attribute the attribute.
351     * @param array $data data for generating the list options (value=>display)
352     * @param array $htmlOptions additional HTML attributes.
353     * @return string the generated radio button list.
354     * @see TbHtml::activeRadioButtonList
355     */
356    public function radioButtonList($model, $attribute, $data, $htmlOptions = array())
357    {
358        return $this->createInput(TbHtml::INPUT_TYPE_RADIOBUTTONLIST, $model, $attribute, $htmlOptions, $data);
359    }
360
361    /**
362     * Generates an inline radio button list for a model attribute
363     * @param CModel $model the data model.
364     * @param string $attribute the attribute.
365     * @param array $data data for generating the list options (value=>display)
366     * @param array $htmlOptions additional HTML attributes.
367     * @return string the generated radio button list.
368     * @see TbHtml::activeInlineRadioButtonList
369     */
370    public function inlineRadioButtonList($model, $attribute, $data, $htmlOptions = array())
371    {
372        $htmlOptions['inline'] = true;
373        return $this->createInput(TbHtml::INPUT_TYPE_RADIOBUTTONLIST, $model, $attribute, $htmlOptions, $data);
374    }
375
376    /**
377     * Generates a checkbox list for a model attribute.
378     * @param CModel $model the data model.
379     * @param string $attribute the attribute.
380     * @param array $data data for generating the list options (value=>display)
381     * @param array $htmlOptions additional HTML attributes.
382     * @return string the generated checkbox list.
383     * @see TbHtml::activeCheckBoxList
384     */
385    public function checkBoxList($model, $attribute, $data, $htmlOptions = array())
386    {
387        return $this->createInput(TbHtml::INPUT_TYPE_CHECKBOXLIST, $model, $attribute, $htmlOptions, $data);
388    }
389
390    /**
391     * Generates an inline checkbox list for a model attribute.
392     * @param CModel $model the data model.
393     * @param string $attribute the attribute.
394     * @param array $data data for generating the list options (value=>display)
395     * @param array $htmlOptions additional HTML attributes.
396     * @return string the generated checkbox list.
397     * @see TbHtml::activeInlineCheckBoxList
398     */
399    public function inlineCheckBoxList($model, $attribute, $data, $htmlOptions = array())
400    {
401        $htmlOptions['inline'] = true;
402        return $this->createInput(TbHtml::INPUT_TYPE_CHECKBOXLIST, $model, $attribute, $htmlOptions, $data);
403    }
404
405    /**
406     * Generates an uneditable field for a model attribute.
407     * @param CModel $model the data model.
408     * @param string $attribute the attribute.
409     * @param array $htmlOptions additional HTML attributes.
410     * @return string the generated field.
411     * @see TbHtml::activeUneditableField
412     */
413    public function uneditableField($model, $attribute, $htmlOptions = array())
414    {
415        return $this->createInput(TbHtml::INPUT_TYPE_UNEDITABLE, $model, $attribute, $htmlOptions);
416    }
417
418    /**
419     * Generates a search query field for a model attribute.
420     * @param CModel $model the data model.
421     * @param string $attribute the attribute.
422     * @param array $htmlOptions additional HTML attributes.
423     * @return string the generated input.
424     * @see TbHtml::activeSearchField
425     */
426    public function searchQuery($model, $attribute, $htmlOptions = array())
427    {
428        return $this->createInput(TbHtml::INPUT_TYPE_SEARCH, $model, $attribute, $htmlOptions);
429    }
430
431    /**
432     * Generates an input for a model attribute.
433     * @param string $type the input type.
434     * @param CModel $model the data model.
435     * @param string $attribute the attribute.
436     * @param array $htmlOptions additional HTML attributes.
437     * @param array $data data for generating the list options (value=>display).
438     * @return string the generated input.
439     * @see TbHtml::createActiveInput
440     */
441    public function createInput($type, $model, $attribute, $htmlOptions = array(), $data = array())
442    {
443        return TbHtml::createActiveInput($type, $model, $attribute, $htmlOptions, $data);
444    }
445
446    /**
447     * Generates a control group with a text field for a model attribute.
448     * @param CModel $model the data model.
449     * @param string $attribute the attribute name.
450     * @param array $htmlOptions additional HTML attributes.
451     * @return string the generated control group.
452     * @see TbHtml::activeTextFieldControlGroup
453     */
454    public function textFieldControlGroup($model, $attribute, $htmlOptions = array())
455    {
456        return $this->createControlGroup(TbHtml::INPUT_TYPE_TEXT, $model, $attribute, $htmlOptions);
457    }
458
459    /**
460     * Generates a control group with a password field for a model attribute.
461     * @param CModel $model the data model.
462     * @param string $attribute the attribute name.
463     * @param array $htmlOptions additional HTML attributes.
464     * @return string the generated control group.
465     * @see TbHtml::activePasswordFieldControlGroup
466     */
467    public function passwordFieldControlGroup($model, $attribute, $htmlOptions = array())
468    {
469        return $this->createControlGroup(TbHtml::INPUT_TYPE_PASSWORD, $model, $attribute, $htmlOptions);
470    }
471
472    /**
473     * Generates a control group with an url field for a model attribute.
474     * @param CModel $model the data model.
475     * @param string $attribute the attribute name.
476     * @param array $htmlOptions additional HTML attributes.
477     * @return string the generated control group.
478     * @see TbHtml::activeUrlFieldControlGroup
479     */
480    public function urlFieldControlGroup($model, $attribute, $htmlOptions = array())
481    {
482        return $this->createControlGroup(TbHtml::INPUT_TYPE_URL, $model, $attribute, $htmlOptions);
483    }
484
485    /**
486     * Generates a control group with an email field for a model attribute.
487     * @param CModel $model the data model.
488     * @param string $attribute the attribute name.
489     * @param array $htmlOptions additional HTML attributes.
490     * @return string the generated control group.
491     * @see TbHtml::activeEmailFieldControlGroup
492     */
493    public function emailFieldControlGroup($model, $attribute, $htmlOptions = array())
494    {
495        return $this->createControlGroup(TbHtml::INPUT_TYPE_EMAIL, $model, $attribute, $htmlOptions);
496    }
497
498    /**
499     * Generates a control group with a number field for a model attribute.
500     * @param CModel $model the data model.
501     * @param string $attribute the attribute name.
502     * @param array $htmlOptions additional HTML attributes.
503     * @return string the generated control group.
504     * @see TbHtml::activeNumberFieldControlGroup
505     */
506    public function numberFieldControlGroup($model, $attribute, $htmlOptions = array())
507    {
508        return $this->createControlGroup(TbHtml::INPUT_TYPE_NUMBER, $model, $attribute, $htmlOptions);
509    }
510
511    /**
512     * Generates a control group with a range field for a model attribute.
513     * @param CModel $model the data model.
514     * @param string $attribute the attribute name.
515     * @param array $htmlOptions additional HTML attributes.
516     * @return string the generated control group.
517     * @see TbHtml::activeRangeFieldControlGroup
518     */
519    public function rangeFieldControlGroup($model, $attribute, $htmlOptions = array())
520    {
521        return $this->createControlGroup(TbHtml::INPUT_TYPE_RANGE, $model, $attribute, $htmlOptions);
522    }
523
524    /**
525     * Generates a control group with a date field for a model attribute.
526     * @param CModel $model the data model.
527     * @param string $attribute the attribute name.
528     * @param array $htmlOptions additional HTML attributes.
529     * @return string the generated control group.
530     * @see TbHtml::activeDateFieldControlGroup
531     */
532    public function dateFieldControlGroup($model, $attribute, $htmlOptions = array())
533    {
534        return $this->createControlGroup(TbHtml::INPUT_TYPE_DATE, $model, $attribute, $htmlOptions);
535    }
536
537    /**
538     * Generates a control group with a text area for a model attribute.
539     * @param CModel $model the data model.
540     * @param string $attribute the attribute name.
541     * @param array $htmlOptions additional HTML attributes.
542     * @return string the generated control group.
543     * @see TbHtml::activeTextAreaControlGroup
544     */
545    public function textAreaControlGroup($model, $attribute, $htmlOptions = array())
546    {
547        return $this->createControlGroup(TbHtml::INPUT_TYPE_TEXTAREA, $model, $attribute, $htmlOptions);
548    }
549
550    /**
551     * Generates a control group with a check box for a model attribute.
552     * @param CModel $model the data model.
553     * @param string $attribute the attribute name.
554     * @param array $htmlOptions additional HTML attributes.
555     * @return string the generated control group.
556     * @see TbHtml::activeCheckBoxControlGroup
557     */
558    public function checkBoxControlGroup($model, $attribute, $htmlOptions = array())
559    {
560        return $this->createControlGroup(TbHtml::INPUT_TYPE_CHECKBOX, $model, $attribute, $htmlOptions);
561    }
562
563    /**
564     * Generates a control group with a radio button for a model attribute.
565     * @param CModel $model the data model.
566     * @param string $attribute the attribute name.
567     * @param array $htmlOptions additional HTML attributes.
568     * @return string the generated control group.
569     * @see TbHtml::activeRadioButtonControlGroup
570     */
571    public function radioButtonControlGroup($model, $attribute, $htmlOptions = array())
572    {
573        return $this->createControlGroup(TbHtml::INPUT_TYPE_RADIOBUTTON, $model, $attribute, $htmlOptions);
574    }
575
576    /**
577     * Generates a control group with a drop down list for a model attribute.
578     * @param CModel $model the data model.
579     * @param string $attribute the attribute name.
580     * @param array $data data for generating the list options (value=>display).
581     * @param array $htmlOptions additional HTML attributes.
582     * @return string the generated control group.
583     * @see TbHtml::activeDropDownListControlGroup
584     */
585    public function dropDownListControlGroup($model, $attribute, $data, $htmlOptions = array())
586    {
587        return $this->createControlGroup(TbHtml::INPUT_TYPE_DROPDOWNLIST, $model, $attribute, $htmlOptions, $data);
588    }
589
590    /**
591     * Generates a control group with a list box for a model attribute.
592     * @param CModel $model the data model.
593     * @param string $attribute the attribute name.
594     * @param array $data data for generating the list options (value=>display).
595     * @param array $htmlOptions additional HTML attributes.
596     * @return string the generated control group.
597     * @see TbHtml::activeListBoxControlGroup
598     */
599    public function listBoxControlGroup($model, $attribute, $data, $htmlOptions = array())
600    {
601        return $this->createControlGroup(TbHtml::INPUT_TYPE_LISTBOX, $model, $attribute, $htmlOptions, $data);
602    }
603
604    /**
605     * Generates a control group with a file field for a model attribute.
606     * @param CModel $model the data model.
607     * @param string $attribute the attribute name.
608     * @param array $htmlOptions additional HTML attributes.
609     * @return string the generated control group.
610     * @see TbHtml::activeFileFieldControlGroup
611     */
612    public function fileFieldControlGroup($model, $attribute, $htmlOptions = array())
613    {
614        return $this->createControlGroup(TbHtml::INPUT_TYPE_FILE, $model, $attribute, $htmlOptions);
615    }
616
617    /**
618     * Generates a control group with a radio button list for a model attribute.
619     * @param CModel $model the data model.
620     * @param string $attribute the attribute name.
621     * @param array $data data for generating the list options (value=>display).
622     * @param array $htmlOptions additional HTML attributes.
623     * @return string the generated control group.
624     * @see TbHtml::activeRadioButtonListControlGroup
625     */
626    public function radioButtonListControlGroup($model, $attribute, $data, $htmlOptions = array())
627    {
628        return $this->createControlGroup(TbHtml::INPUT_TYPE_RADIOBUTTONLIST, $model, $attribute, $htmlOptions, $data);
629    }
630
631    /**
632     * Generates a control group with an inline radio button list for a model attribute.
633     * @param CModel $model the data model.
634     * @param string $attribute the attribute name.
635     * @param array $data data for generating the list options (value=>display).
636     * @param array $htmlOptions additional HTML attributes.
637     * @return string the generated control group.
638     * @see TbHtml::activeInlineCheckBoxListControlGroup
639     */
640    public function inlineRadioButtonListControlGroup($model, $attribute, $data, $htmlOptions = array())
641    {
642        $htmlOptions['inline'] = true;
643        return $this->createControlGroup(TbHtml::INPUT_TYPE_RADIOBUTTONLIST, $model, $attribute, $htmlOptions, $data);
644    }
645
646    /**
647     * Generates a control group with a check box list for a model attribute.
648     * @param CModel $model the data model.
649     * @param string $attribute the attribute name.
650     * @param array $data data for generating the list options (value=>display).
651     * @param array $htmlOptions additional HTML attributes.
652     * @return string the generated control group.
653     * @see TbHtml::activeCheckBoxListControlGroup
654     */
655    public function checkBoxListControlGroup($model, $attribute, $data, $htmlOptions = array())
656    {
657        return $this->createControlGroup(TbHtml::INPUT_TYPE_CHECKBOXLIST, $model, $attribute, $htmlOptions, $data);
658    }
659
660    /**
661     * Generates a control group with an inline check box list for a model attribute.
662     * @param CModel $model the data model.
663     * @param string $attribute the attribute name.
664     * @param array $data data for generating the list options (value=>display).
665     * @param array $htmlOptions additional HTML attributes.
666     * @return string the generated control group.
667     * @see TbHtml::activeInlineCheckBoxListControlGroup
668     */
669    public function inlineCheckBoxListControlGroup($model, $attribute, $data, $htmlOptions = array())
670    {
671        $htmlOptions['inline'] = true;
672        return $this->createControlGroup(TbHtml::INPUT_TYPE_CHECKBOXLIST, $model, $attribute, $htmlOptions, $data);
673    }
674
675    /**
676     * Generates a control group with an uneditable field for a model attribute.
677     * @param CModel $model the data model.
678     * @param string $attribute the attribute name.
679     * @param array $htmlOptions additional HTML attributes.
680     * @return string the generated control group.
681     * @see TbHtml::activeUneditableFieldControlGroup
682     */
683    public function uneditableFieldControlGroup($model, $attribute, $htmlOptions = array())
684    {
685        return $this->createControlGroup(TbHtml::INPUT_TYPE_UNEDITABLE, $model, $attribute, $htmlOptions);
686    }
687
688    /**
689     * Generates a control group with a search field for a model attribute.
690     * @param CModel $model the data model.
691     * @param string $attribute the attribute name.
692     * @param array $htmlOptions additional HTML attributes.
693     * @return string the generated control group.
694     * @see TbHtml::activeSearchFieldControlGroup
695     */
696    public function searchQueryControlGroup($model, $attribute, $htmlOptions = array())
697    {
698        return $this->createControlGroup(TbHtml::INPUT_TYPE_SEARCH, $model, $attribute, $htmlOptions);
699    }
700
701    /**
702     * Generates a control group with a custom (pre-rendered) input for a model attribute.
703     * @param string $input the rendered input.
704     * @param CModel $model the data model.
705     * @param string $attribute the attribute name.
706     * @param array $htmlOptions additional HTML attributes.
707     * @return string the generated control group.
708     * @see TbHtml::activeControlGroup
709     */
710    public function customControlGroup($input, $model, $attribute, $htmlOptions = array())
711    {
712        $htmlOptions['input'] = $input;
713        return $this->createControlGroup(TbHtml::INPUT_TYPE_CUSTOM, $model, $attribute, $htmlOptions);
714    }
715
716    /**
717     * Generates a control group for a model attribute.
718     * @param string $type the input type.
719     * @param CModel $model the data model.
720     * @param string $attribute the attribute name.
721     * @param array $htmlOptions additional HTML attributes.
722     * @param array $data data for generating the list options (value=>display).
723     * @return string the generated control group.
724     * @see TbHtml::activeControlGroup
725     */
726    public function createControlGroup($type, $model, $attribute, $htmlOptions = array(), $data = array())
727    {
728        $htmlOptions = $this->processControlGroupOptions($model, $attribute, $htmlOptions);
729        return TbHtml::activeControlGroup($type, $model, $attribute, $htmlOptions, $data);
730    }
731
732    /**
733     * Generates the form actions container (i.e. submit button, etc).
734     * @param mixed $actions the actions.
735     * @param array $htmlOptions additional HTML attributes.
736     * @return string
737     */
738    public function createFormActions($actions, $htmlOptions = array())
739    {
740        $htmlOptions['formLayout'] = $this->layout;
741        $htmlOptions['labelWidthClass'] = TbArray::getValue('labelWidthClass', $htmlOptions, $this->labelWidthClass);
742        $htmlOptions['controlWidthClass'] = TbArray::getValue('controlWidthClass', $htmlOptions, $this->controlWidthClass);
743        return TbHtml::formActions($actions, $htmlOptions);
744    }
745
746    /**
747     * Processes the options for a input row.
748     * @param CModel $model the data model.
749     * @param string $attribute the attribute name.
750     * @param array $options the options.
751     * @return array the processed options.
752     */
753    protected function processControlGroupOptions($model, $attribute, $options)
754    {
755        $errorOptions = TbArray::popValue('errorOptions', $options, array());
756        $enableAjaxValidation = TbArray::popValue('enableAjaxValidation', $errorOptions, true);
757        $enableClientValidation = TbArray::popValue('enableClientValidation', $errorOptions, true);
758        $errorOptions['type'] = $this->helpType;
759        $error = $this->error($model, $attribute, $errorOptions, $enableAjaxValidation, $enableClientValidation);
760        // kind of a hack for ajax forms but this works for now.
761        if (!empty($error) && strpos($error, 'display:none') === false) {
762            $options['color'] = TbHtml::INPUT_COLOR_ERROR;
763        }
764        if (!$this->hideInlineErrors) {
765            $options['error'] = $error;
766        }
767        $helpOptions = TbArray::popValue('helpOptions', $options, array());
768        $helpOptions['type'] = $this->helpType;
769        $options['helpOptions'] = $helpOptions;
770        if (!TbArray::getValue('formLayout', $options, false)) {
771            $options['formLayout'] = $this->layout;
772        }
773        $options['labelWidthClass'] = TbArray::getValue('labelWidthClass', $options, $this->labelWidthClass);
774        $options['controlWidthClass'] = TbArray::getValue('controlWidthClass', $options, $this->controlWidthClass);
775        return $options;
776    }
777}
778