Overview

Packages

  • application
    • commands
    • components
      • actions
      • filters
      • leftWidget
      • permissions
      • sortableWidget
      • util
      • webupdater
      • x2flow
        • actions
        • triggers
      • X2GridView
      • X2Settings
    • controllers
    • models
      • embedded
    • modules
      • accounts
        • controllers
        • models
      • actions
        • controllers
        • models
      • calendar
        • controllers
        • models
      • charts
        • models
      • contacts
        • controllers
        • models
      • docs
        • components
        • controllers
        • models
      • groups
        • controllers
        • models
      • marketing
        • components
        • controllers
        • models
      • media
        • controllers
        • models
      • mobile
        • components
      • opportunities
        • controllers
        • models
      • products
        • controllers
        • models
      • quotes
        • controllers
        • models
      • services
        • controllers
        • models
      • template
        • models
      • users
        • controllers
        • models
      • workflow
        • controllers
        • models
      • x2Leads
        • controllers
        • models
  • Net
  • None
  • PHP
  • system
    • base
    • caching
      • dependencies
    • collections
    • console
    • db
      • ar
      • schema
        • cubrid
        • mssql
        • mysql
        • oci
        • pgsql
        • sqlite
    • i18n
      • gettext
    • logging
    • test
    • utils
    • validators
    • web
      • actions
      • auth
      • filters
      • form
      • helpers
      • renderers
      • services
      • widgets
        • captcha
        • pagers
  • Text
    • Highlighter
  • zii
    • behaviors
    • widgets
      • grid
      • jui

Classes

  • ActionActiveForm
  • ActionActiveFormBase
  • CActiveForm
  • CalendarEventActiveForm
  • CallActiveForm
  • CClipWidget
  • CContentDecorator
  • CFilterWidget
  • CFlexWidget
  • CHtmlPurifier
  • CInputWidget
  • CMarkdown
  • CMaskedTextField
  • CMultiFileUpload
  • COutputCache
  • COutputProcessor
  • CStarRating
  • CTabView
  • CTextHighlighter
  • CTreeView
  • CWidget
  • EventActiveForm
  • MobileActiveForm
  • NoteActiveForm
  • TimeActiveForm
  • X2ActiveForm
  • X2StarRating
  • Overview
  • Package
  • Class
  • Tree
   1: <?php
   2: /**
   3:  * CActiveForm class file.
   4:  *
   5:  * @author Qiang Xue <qiang.xue@gmail.com>
   6:  * @link http://www.yiiframework.com/
   7:  * @copyright 2008-2013 Yii Software LLC
   8:  * @license http://www.yiiframework.com/license/
   9:  */
  10: 
  11: /**
  12:  * CActiveForm provides a set of methods that can help to simplify the creation
  13:  * of complex and interactive HTML forms that are associated with data models.
  14:  *
  15:  * The 'beginWidget' and 'endWidget' call of CActiveForm widget will render
  16:  * the open and close form tags. Most other methods of CActiveForm are wrappers
  17:  * of the corresponding 'active' methods in {@link CHtml}. Calling them in between
  18:  * the 'beginWidget' and 'endWidget' calls will render text labels, input fields,
  19:  * etc. For example, calling {@link CActiveForm::textField}
  20:  * would generate an input field for a specified model attribute.
  21:  *
  22:  * What makes CActiveForm extremely useful is its support for data validation.
  23:  * CActiveForm supports data validation at three levels:
  24:  * <ul>
  25:  * <li>server-side validation: the validation is performed at server side after
  26:  * the whole page containing the form is submitted. If there is any validation error,
  27:  * CActiveForm will render the error in the page back to user.</li>
  28:  * <li>AJAX-based validation: when the user enters data into an input field,
  29:  * an AJAX request is triggered which requires server-side validation. The validation
  30:  * result is sent back in AJAX response and the input field changes its appearance
  31:  * accordingly.</li>
  32:  * <li>client-side validation (available since version 1.1.7):
  33:  * when the user enters data into an input field,
  34:  * validation is performed on the client side using JavaScript. No server contact
  35:  * will be made, which reduces the workload on the server.</li>
  36:  * </ul>
  37:  *
  38:  * All these validations share the same set of validation rules declared in
  39:  * the associated model class. CActiveForm is designed in such a way that
  40:  * all these validations will lead to the same user interface changes and error
  41:  * message content.
  42:  *
  43:  * To ensure data validity, server-side validation is always performed.
  44:  * By setting {@link enableAjaxValidation} to true, one can enable AJAX-based validation;
  45:  * and by setting {@link enableClientValidation} to true, one can enable client-side validation.
  46:  * Note that in order to make the latter two validations work, the user's browser
  47:  * must has its JavaScript enabled. If not, only the server-side validation will
  48:  * be performed.
  49:  *
  50:  * The AJAX-based validation and client-side validation may be used together
  51:  * or separately. For example, in a user registration form, one may use AJAX-based
  52:  * validation to check if the user has picked a unique username, and use client-side
  53:  * validation to ensure all required fields are entered with data.
  54:  * Because the AJAX-based validation may bring extra workload on the server,
  55:  * if possible, one should mainly use client-side validation.
  56:  *
  57:  * The AJAX-based validation has a few limitations. First, it does not work
  58:  * with file upload fields. Second, it should not be used to perform validations that
  59:  * may cause server-side state changes. Third, it is not designed
  60:  * to work with tabular data input for the moment.
  61:  *
  62:  * Support for client-side validation varies for different validators. A validator
  63:  * will support client-side validation only if it implements {@link CValidator::clientValidateAttribute}
  64:  * and has its {@link CValidator::enableClientValidation} property set true.
  65:  * At this moment, the following core validators support client-side validation:
  66:  * <ul>
  67:  * <li>{@link CBooleanValidator}</li>
  68:  * <li>{@link CCaptchaValidator}</li>
  69:  * <li>{@link CCompareValidator}</li>
  70:  * <li>{@link CEmailValidator}</li>
  71:  * <li>{@link CNumberValidator}</li>
  72:  * <li>{@link CRangeValidator}</li>
  73:  * <li>{@link CRegularExpressionValidator}</li>
  74:  * <li>{@link CRequiredValidator}</li>
  75:  * <li>{@link CStringValidator}</li>
  76:  * <li>{@link CUrlValidator}</li>
  77:  * </ul>
  78:  *
  79:  * CActiveForm relies on CSS to customize the appearance of input fields
  80:  * which are in different validation states. In particular, each input field
  81:  * may be one of the four states: initial (not validated),
  82:  * validating, error and success. To differentiate these states, CActiveForm
  83:  * automatically assigns different CSS classes for the last three states
  84:  * to the HTML element containing the input field.
  85:  * By default, these CSS classes are named as 'validating', 'error' and 'success',
  86:  * respectively. We may customize these CSS classes by configuring the
  87:  * {@link clientOptions} property or specifying in the {@link error} method.
  88:  *
  89:  * The following is a piece of sample view code showing how to use CActiveForm:
  90:  *
  91:  * <pre>
  92:  * <?php $form = $this->beginWidget('CActiveForm', array(
  93:  *     'id'=>'user-form',
  94:  *     'enableAjaxValidation'=>true,
  95:  *     'enableClientValidation'=>true,
  96:  *     'focus'=>array($model,'firstName'),
  97:  * )); ?>
  98:  *
  99:  * <?php echo $form->errorSummary($model); ?>
 100:  *
 101:  * <div class="row">
 102:  *     <?php echo $form->labelEx($model,'firstName'); ?>
 103:  *     <?php echo $form->textField($model,'firstName'); ?>
 104:  *     <?php echo $form->error($model,'firstName'); ?>
 105:  * </div>
 106:  * <div class="row">
 107:  *     <?php echo $form->labelEx($model,'lastName'); ?>
 108:  *     <?php echo $form->textField($model,'lastName'); ?>
 109:  *     <?php echo $form->error($model,'lastName'); ?>
 110:  * </div>
 111:  *
 112:  * <?php $this->endWidget(); ?>
 113:  * </pre>
 114:  *
 115:  * To respond to the AJAX validation requests, we need the following class code:
 116:  * <pre>
 117:  * public function actionCreate()
 118:  * {
 119:  *     $model=new User;
 120:  *     $this->performAjaxValidation($model);
 121:  *     if(isset($_POST['User']))
 122:  *     {
 123:  *         $model->attributes=$_POST['User'];
 124:  *         if($model->save())
 125:  *             $this->redirect('index');
 126:  *     }
 127:  *     $this->render('create',array('model'=>$model));
 128:  * }
 129:  *
 130:  * protected function performAjaxValidation($model)
 131:  * {
 132:  *     if(isset($_POST['ajax']) && $_POST['ajax']==='user-form')
 133:  *     {
 134:  *         echo CActiveForm::validate($model);
 135:  *         Yii::app()->end();
 136:  *     }
 137:  * }
 138:  * </pre>
 139:  *
 140:  * In the above code, if we do not enable the AJAX-based validation, we can remove
 141:  * the <code>performAjaxValidation</code> method and its invocation.
 142:  *
 143:  * @author Qiang Xue <qiang.xue@gmail.com>
 144:  * @package system.web.widgets
 145:  * @since 1.1.1
 146:  */
 147: class CActiveForm extends CWidget
 148: {
 149:     /**
 150:      * @var mixed the form action URL (see {@link CHtml::normalizeUrl} for details about this parameter).
 151:      * If not set, the current page URL is used.
 152:      */
 153:     public $action='';
 154:     /**
 155:      * @var string the form submission method. This should be either 'post' or 'get'.
 156:      * Defaults to 'post'.
 157:      */
 158:     public $method='post';
 159:     /**
 160:      * @var boolean whether to generate a stateful form (See {@link CHtml::statefulForm}). Defaults to false.
 161:      */
 162:     public $stateful=false;
 163:     /**
 164:      * @var string the CSS class name for error messages.
 165:      * Since 1.1.14 this defaults to 'errorMessage' defined in {@link CHtml::$errorMessageCss}.
 166:      * Individual {@link error} call may override this value by specifying the 'class' HTML option.
 167:      */
 168:     public $errorMessageCssClass;
 169:     /**
 170:      * @var array additional HTML attributes that should be rendered for the form tag.
 171:      */
 172:     public $htmlOptions=array();
 173:     /**
 174:      * @var array the options to be passed to the javascript validation plugin.
 175:      * The following options are supported:
 176:      * <ul>
 177:      * <li>ajaxVar: string, the name of the parameter indicating the request is an AJAX request.
 178:      * When the AJAX validation is triggered, a parameter named as this property will be sent
 179:      * together with the other form data to the server. The parameter value is the form ID.
 180:      * The server side can then detect who triggers the AJAX validation and react accordingly.
 181:      * Defaults to 'ajax'.</li>
 182:      * <li>validationUrl: string, the URL that performs the AJAX validations.
 183:      * If not set, it will take the value of {@link action}.</li>
 184:      * <li>validationDelay: integer, the number of milliseconds that an AJAX validation should be
 185:      * delayed after an input is changed. A value 0 means the validation will be triggered immediately
 186:      * when an input is changed. A value greater than 0 means changing several inputs may only
 187:      * trigger a single validation if they happen fast enough, which may help reduce the server load.
 188:      * Defaults to 200 (0.2 second).</li>
 189:      * <li>validateOnSubmit: boolean, whether to perform AJAX validation when the form is being submitted.
 190:      * If there are any validation errors, the form submission will be stopped.
 191:      * Defaults to false.</li>
 192:      * <li>validateOnChange: boolean, whether to trigger an AJAX validation
 193:      * each time when an input's value is changed.  You may want to turn this off
 194:      * if it causes too much performance impact, because each AJAX validation request
 195:      * will submit the data of the whole form. Defaults to true.</li>
 196:      * <li>validateOnType: boolean, whether to trigger an AJAX validation each time when the user
 197:      * presses a key. When setting this property to be true, you should tune up the 'validationDelay'
 198:      * option to avoid triggering too many AJAX validations. Defaults to false.</li>
 199:      * <li>hideErrorMessage: boolean, whether to hide the error message even if there is an error.
 200:      * Defaults to false, which means the error message will show up whenever the input has an error.</li>
 201:      * <li>inputContainer: string, the jQuery selector for the HTML element containing the input field.
 202:      * During the validation process, CActiveForm will set different CSS class for the container element
 203:      * to indicate the state change. If not set, it means the closest 'div' element that contains the input field.</li>
 204:      * <li>errorCssClass: string, the CSS class to be assigned to the container whose associated input
 205:      * has AJAX validation error. Defaults to 'error'.</li>
 206:      * <li>successCssClass: string, the CSS class to be assigned to the container whose associated input
 207:      * passes AJAX validation without any error. Defaults to 'success'.</li>
 208:      * <li>validatingCssClass: string, the CSS class to be assigned to the container whose associated input
 209:      * is currently being validated via AJAX. Defaults to 'validating'.</li>
 210:      * <li>errorMessageCssClass: string, the CSS class assigned to the error messages returned
 211:      * by AJAX validations. Defaults to 'errorMessage'.</li>
 212:      * <li>beforeValidate: function, the function that will be invoked before performing ajax-based validation
 213:      * triggered by form submission action (available only when validateOnSubmit is set true).
 214:      * The expected function signature should be <code>beforeValidate(form) {...}</code>, where 'form' is
 215:      * the jquery representation of the form object. If the return value of this function is NOT true, the validation
 216:      * will be cancelled.
 217:      *
 218:      * Note that because this option refers to a js function, you should wrap the value with {@link CJavaScriptExpression} to prevent it
 219:      * from being encoded as a string. This option has been available since version 1.1.3.</li>
 220:      * <li>afterValidate: function, the function that will be invoked after performing ajax-based validation
 221:      * triggered by form submission action (available only when validateOnSubmit is set true).
 222:      * The expected function signature should be <code>afterValidate(form, data, hasError) {...}</code>, where 'form' is
 223:      * the jquery representation of the form object; 'data' is the JSON response from the server-side validation; 'hasError'
 224:      * is a boolean value indicating whether there is any validation error. If the return value of this function is NOT true,
 225:      * the normal form submission will be cancelled.
 226:      *
 227:      * Note that because this option refers to a js function, you should wrap the value with {@link CJavaScriptExpression} to prevent it
 228:      * from being encoded as a string. This option has been available since version 1.1.3.</li>
 229:      * <li>beforeValidateAttribute: function, the function that will be invoked before performing ajax-based validation
 230:      * triggered by a single attribute input change. The expected function signature should be
 231:      * <code>beforeValidateAttribute(form, attribute) {...}</code>, where 'form' is the jquery representation of the form object
 232:      * and 'attribute' refers to the js options for the triggering attribute (see {@link error}).
 233:      * If the return value of this function is NOT true, the validation will be cancelled.
 234:      *
 235:      * Note that because this option refers to a js function, you should wrap the value with {@link CJavaScriptExpression} to prevent it
 236:      * from being encoded as a string. This option has been available since version 1.1.3.</li>
 237:      * <li>afterValidateAttribute: function, the function that will be invoked after performing ajax-based validation
 238:      * triggered by a single attribute input change. The expected function signature should be
 239:      * <code>afterValidateAttribute(form, attribute, data, hasError) {...}</code>, where 'form' is the jquery
 240:      * representation of the form object; 'attribute' refers to the js options for the triggering attribute (see {@link error});
 241:      * 'data' is the JSON response from the server-side validation; 'hasError' is a boolean value indicating whether
 242:      * there is any validation error.
 243:      *
 244:      * Note that because this option refers to a js function, you should wrap the value with {@link CJavaScriptExpression} to prevent it
 245:      * from being encoded as a string. This option has been available since version 1.1.3.</li>
 246:      * </ul>
 247:      *
 248:      * Some of the above options may be overridden in individual calls of {@link error()}.
 249:      * They include: validationDelay, validateOnChange, validateOnType, hideErrorMessage,
 250:      * inputContainer, errorCssClass, successCssClass, validatingCssClass, beforeValidateAttribute, afterValidateAttribute.
 251:      */
 252:     public $clientOptions=array();
 253:     /**
 254:      * @var boolean whether to enable data validation via AJAX. Defaults to false.
 255:      * When this property is set true, you should respond to the AJAX validation request on the server side as shown below:
 256:      * <pre>
 257:      * public function actionCreate()
 258:      * {
 259:      *     $model=new User;
 260:      *     if(isset($_POST['ajax']) && $_POST['ajax']==='user-form')
 261:      *     {
 262:      *         echo CActiveForm::validate($model);
 263:      *         Yii::app()->end();
 264:      *     }
 265:      *     ......
 266:      * }
 267:      * </pre>
 268:      */
 269:     public $enableAjaxValidation=false;
 270:     /**
 271:      * @var boolean whether to enable client-side data validation. Defaults to false.
 272:      *
 273:      * When this property is set true, client-side validation will be performed by validators
 274:      * that support it (see {@link CValidator::enableClientValidation} and {@link CValidator::clientValidateAttribute}).
 275:      *
 276:      * @see error
 277:      * @since 1.1.7
 278:      */
 279:     public $enableClientValidation=false;
 280: 
 281:     /**
 282:      * @var mixed form element to get initial input focus on page load.
 283:      *
 284:      * Defaults to null meaning no input field has a focus.
 285:      * If set as array, first element should be model and second element should be the attribute.
 286:      * If set as string any jQuery selector can be used
 287:      *
 288:      * Example - set input focus on page load to:
 289:      * <ul>
 290:      * <li>'focus'=>array($model,'username') - $model->username input filed</li>
 291:      * <li>'focus'=>'#'.CHtml::activeId($model,'username') - $model->username input field</li>
 292:      * <li>'focus'=>'#LoginForm_username' - input field with ID LoginForm_username</li>
 293:      * <li>'focus'=>'input[type="text"]:first' - first input element of type text</li>
 294:      * <li>'focus'=>'input:visible:enabled:first' - first visible and enabled input element</li>
 295:      * <li>'focus'=>'input:text[value=""]:first' - first empty input</li>
 296:      * </ul>
 297:      *
 298:      * @since 1.1.4
 299:      */
 300:     public $focus;
 301:     /**
 302:      * @var array the javascript options for model attributes (input ID => options)
 303:      * @see error
 304:      * @since 1.1.7
 305:      */
 306:     protected $attributes=array();
 307:     /**
 308:      * @var string the ID of the container element for error summary
 309:      * @see errorSummary
 310:      * @since 1.1.7
 311:      */
 312:     protected $summaryID;
 313:     /**
 314:      * @var string[] attribute IDs to be used to display error summary.
 315:      * @since 1.1.14
 316:      */
 317:     private $_summaryAttributes=array();
 318: 
 319:     /**
 320:      * Initializes the widget.
 321:      * This renders the form open tag.
 322:      */
 323:     public function init()
 324:     {
 325:         if(!isset($this->htmlOptions['id']))
 326:             $this->htmlOptions['id']=$this->id;
 327:         else
 328:             $this->id=$this->htmlOptions['id'];
 329: 
 330:         if($this->stateful)
 331:             echo CHtml::statefulForm($this->action, $this->method, $this->htmlOptions);
 332:         else
 333:             echo CHtml::beginForm($this->action, $this->method, $this->htmlOptions);
 334: 
 335:         if($this->errorMessageCssClass===null)
 336:             $this->errorMessageCssClass=CHtml::$errorMessageCss;
 337:     }
 338: 
 339:     /**
 340:      * Runs the widget.
 341:      * This registers the necessary javascript code and renders the form close tag.
 342:      */
 343:     public function run()
 344:     {
 345:         if(is_array($this->focus))
 346:             $this->focus="#".CHtml::activeId($this->focus[0],$this->focus[1]);
 347: 
 348:         echo CHtml::endForm();
 349:         $cs=Yii::app()->clientScript;
 350:         if(!$this->enableAjaxValidation && !$this->enableClientValidation || empty($this->attributes))
 351:         {
 352:             if($this->focus!==null)
 353:             {
 354:                 $cs->registerCoreScript('jquery');
 355:                 $cs->registerScript('CActiveForm#focus',"
 356:                     if(!window.location.hash)
 357:                         jQuery('".$this->focus."').focus();
 358:                 ");
 359:             }
 360:             return;
 361:         }
 362: 
 363:         $options=$this->clientOptions;
 364:         if(isset($this->clientOptions['validationUrl']) && is_array($this->clientOptions['validationUrl']))
 365:             $options['validationUrl']=CHtml::normalizeUrl($this->clientOptions['validationUrl']);
 366: 
 367:         foreach($this->_summaryAttributes as $attribute)
 368:             $this->attributes[$attribute]['summary']=true;
 369:         $options['attributes']=array_values($this->attributes);
 370: 
 371:         if($this->summaryID!==null)
 372:             $options['summaryID']=$this->summaryID;
 373: 
 374:         if($this->focus!==null)
 375:             $options['focus']=$this->focus;
 376: 
 377:         if(!empty(CHtml::$errorCss))
 378:             $options['errorCss']=CHtml::$errorCss;
 379: 
 380:         $options=CJavaScript::encode($options);
 381:         $cs->registerCoreScript('yiiactiveform');
 382:         $id=$this->id;
 383:         $cs->registerScript(__CLASS__.'#'.$id,"jQuery('#$id').yiiactiveform($options);");
 384:     }
 385: 
 386:     /**
 387:      * Displays the first validation error for a model attribute.
 388:      * This is similar to {@link CHtml::error} except that it registers the model attribute
 389:      * so that if its value is changed by users, an AJAX validation may be triggered.
 390:      * @param CModel $model the data model
 391:      * @param string $attribute the attribute name
 392:      * @param array $htmlOptions additional HTML attributes to be rendered in the container div tag.
 393:      * Besides all those options available in {@link CHtml::error}, the following options are recognized in addition:
 394:      * <ul>
 395:      * <li>validationDelay</li>
 396:      * <li>validateOnChange</li>
 397:      * <li>validateOnType</li>
 398:      * <li>hideErrorMessage</li>
 399:      * <li>inputContainer</li>
 400:      * <li>errorCssClass</li>
 401:      * <li>successCssClass</li>
 402:      * <li>validatingCssClass</li>
 403:      * <li>beforeValidateAttribute</li>
 404:      * <li>afterValidateAttribute</li>
 405:      * </ul>
 406:      * These options override the corresponding options as declared in {@link options} for this
 407:      * particular model attribute. For more details about these options, please refer to {@link clientOptions}.
 408:      * Note that these options are only used when {@link enableAjaxValidation} or {@link enableClientValidation}
 409:      * is set true.
 410:      * <ul>
 411:      * <li>inputID</li>
 412:      * </ul>
 413:      * When an CActiveForm input field uses a custom ID, for ajax/client validation to work properly
 414:      * inputID should be set to the same ID
 415:      *
 416:      * Example:
 417:      * <pre>
 418:      * <div class="form-element">
 419:      *    <?php echo $form->labelEx($model,'attribute'); ?>
 420:      *    <?php echo $form->textField($model,'attribute', array('id'=>'custom-id')); ?>
 421:      *    <?php echo $form->error($model,'attribute',array('inputID'=>'custom-id')); ?>
 422:      * </div>
 423:      * </pre>
 424:      *
 425:      * When client-side validation is enabled, an option named "clientValidation" is also recognized.
 426:      * This option should take a piece of JavaScript code to perform client-side validation. In the code,
 427:      * the variables are predefined:
 428:      * <ul>
 429:      * <li>value: the current input value associated with this attribute.</li>
 430:      * <li>messages: an array that may be appended with new error messages for the attribute.</li>
 431:      * <li>attribute: a data structure keeping all client-side options for the attribute</li>
 432:      * </ul>
 433:      * This should NOT be a function but just the code, Yii will enclose the code you provide inside the
 434:      * actual JS function.
 435:      * @param boolean $enableAjaxValidation whether to enable AJAX validation for the specified attribute.
 436:      * Note that in order to enable AJAX validation, both {@link enableAjaxValidation} and this parameter
 437:      * must be true.
 438:      * @param boolean $enableClientValidation whether to enable client-side validation for the specified attribute.
 439:      * Note that in order to enable client-side validation, both {@link enableClientValidation} and this parameter
 440:      * must be true. This parameter has been available since version 1.1.7.
 441:      * @return string the validation result (error display or success message).
 442:      * @see CHtml::error
 443:      */
 444:     public function error($model,$attribute,$htmlOptions=array(),$enableAjaxValidation=true,$enableClientValidation=true)
 445:     {
 446:         if(!$this->enableAjaxValidation)
 447:             $enableAjaxValidation=false;
 448:         if(!$this->enableClientValidation)
 449:             $enableClientValidation=false;
 450: 
 451:         if(!isset($htmlOptions['class']))
 452:             $htmlOptions['class']=$this->errorMessageCssClass;
 453: 
 454:         if(!$enableAjaxValidation && !$enableClientValidation)
 455:             return CHtml::error($model,$attribute,$htmlOptions);
 456: 
 457:         $id=CHtml::activeId($model,$attribute);
 458:         $inputID=isset($htmlOptions['inputID']) ? $htmlOptions['inputID'] : $id;
 459:         unset($htmlOptions['inputID']);
 460:         if(!isset($htmlOptions['id']))
 461:             $htmlOptions['id']=$inputID.'_em_';
 462: 
 463:         $option=array(
 464:             'id'=>$id,
 465:             'inputID'=>$inputID,
 466:             'errorID'=>$htmlOptions['id'],
 467:             'model'=>get_class($model),
 468:             'name'=>$attribute,
 469:             'enableAjaxValidation'=>$enableAjaxValidation,
 470:         );
 471: 
 472:         $optionNames=array(
 473:             'validationDelay',
 474:             'validateOnChange',
 475:             'validateOnType',
 476:             'hideErrorMessage',
 477:             'inputContainer',
 478:             'errorCssClass',
 479:             'successCssClass',
 480:             'validatingCssClass',
 481:             'beforeValidateAttribute',
 482:             'afterValidateAttribute',
 483:         );
 484:         foreach($optionNames as $name)
 485:         {
 486:             if(isset($htmlOptions[$name]))
 487:             {
 488:                 $option[$name]=$htmlOptions[$name];
 489:                 unset($htmlOptions[$name]);
 490:             }
 491:         }
 492:         if($model instanceof CActiveRecord && !$model->isNewRecord)
 493:             $option['status']=1;
 494: 
 495:         if($enableClientValidation)
 496:         {
 497:             $validators=isset($htmlOptions['clientValidation']) ? array($htmlOptions['clientValidation']) : array();
 498:             unset($htmlOptions['clientValidation']);
 499: 
 500:             $attributeName = $attribute;
 501:             if(($pos=strrpos($attribute,']'))!==false && $pos!==strlen($attribute)-1) // e.g. [a]name
 502:             {
 503:                 $attributeName=substr($attribute,$pos+1);
 504:             }
 505: 
 506:             foreach($model->getValidators($attributeName) as $validator)
 507:             {
 508:                 if($validator->enableClientValidation)
 509:                 {
 510:                     if(($js=$validator->clientValidateAttribute($model,$attributeName))!='')
 511:                         $validators[]=$js;
 512:                 }
 513:             }
 514:             if($validators!==array())
 515:                 $option['clientValidation']=new CJavaScriptExpression("function(value, messages, attribute) {\n".implode("\n",$validators)."\n}");
 516:         }
 517: 
 518:         if(empty($option['hideErrorMessage']) && empty($this->clientOptions['hideErrorMessage']))
 519:             $html=CHtml::error($model,$attribute,$htmlOptions);
 520:         else
 521:             $html='';
 522:         if($html==='')
 523:         {
 524:             if(isset($htmlOptions['style']))
 525:                 $htmlOptions['style']=rtrim($htmlOptions['style'],';').';display:none';
 526:             else
 527:                 $htmlOptions['style']='display:none';
 528:             $html=CHtml::tag(CHtml::$errorContainerTag,$htmlOptions,'');
 529:         }
 530: 
 531:         $this->attributes[$inputID]=$option;
 532:         return $html;
 533:     }
 534: 
 535:     /**
 536:      * Displays a summary of validation errors for one or several models.
 537:      * This method is very similar to {@link CHtml::errorSummary} except that it also works
 538:      * when AJAX validation is performed.
 539:      * @param mixed $models the models whose input errors are to be displayed. This can be either
 540:      * a single model or an array of models.
 541:      * @param string $header a piece of HTML code that appears in front of the errors
 542:      * @param string $footer a piece of HTML code that appears at the end of the errors
 543:      * @param array $htmlOptions additional HTML attributes to be rendered in the container div tag.
 544:      * @return string the error summary. Empty if no errors are found.
 545:      * @see CHtml::errorSummary
 546:      */
 547:     public function errorSummary($models,$header=null,$footer=null,$htmlOptions=array())
 548:     {
 549:         if(!$this->enableAjaxValidation && !$this->enableClientValidation)
 550:             return CHtml::errorSummary($models,$header,$footer,$htmlOptions);
 551: 
 552:         if(!isset($htmlOptions['id']))
 553:             $htmlOptions['id']=$this->id.'_es_';
 554:         $html=CHtml::errorSummary($models,$header,$footer,$htmlOptions);
 555:         if($html==='')
 556:         {
 557:             if($header===null)
 558:                 $header='<p>'.Yii::t('yii','Please fix the following input errors:').'</p>';
 559:             if(!isset($htmlOptions['class']))
 560:                 $htmlOptions['class']=CHtml::$errorSummaryCss;
 561:             $htmlOptions['style']=isset($htmlOptions['style']) ? rtrim($htmlOptions['style'],';').';display:none' : 'display:none';
 562:             $html=CHtml::tag('div',$htmlOptions,$header."\n<ul><li>dummy</li></ul>".$footer);
 563:         }
 564: 
 565:         $this->summaryID=$htmlOptions['id'];
 566:         foreach(is_array($models) ? $models : array($models) as $model)
 567:             foreach($model->getSafeAttributeNames() as $attribute)
 568:                 $this->_summaryAttributes[]=CHtml::activeId($model,$attribute);
 569: 
 570:         return $html;
 571:     }
 572: 
 573:     /**
 574:      * Renders an HTML label for a model attribute.
 575:      * This method is a wrapper of {@link CHtml::activeLabel}.
 576:      * Please check {@link CHtml::activeLabel} for detailed information
 577:      * about the parameters for this method.
 578:      * @param CModel $model the data model
 579:      * @param string $attribute the attribute
 580:      * @param array $htmlOptions additional HTML attributes.
 581:      * @return string the generated label tag
 582:      */
 583:     public function label($model,$attribute,$htmlOptions=array())
 584:     {
 585:         return CHtml::activeLabel($model,$attribute,$htmlOptions);
 586:     }
 587: 
 588:     /**
 589:      * Renders an HTML label for a model attribute.
 590:      * This method is a wrapper of {@link CHtml::activeLabelEx}.
 591:      * Please check {@link CHtml::activeLabelEx} for detailed information
 592:      * about the parameters for this method.
 593:      * @param CModel $model the data model
 594:      * @param string $attribute the attribute
 595:      * @param array $htmlOptions additional HTML attributes.
 596:      * @return string the generated label tag
 597:      */
 598:     public function labelEx($model,$attribute,$htmlOptions=array())
 599:     {
 600:         return CHtml::activeLabelEx($model,$attribute,$htmlOptions);
 601:     }
 602: 
 603:     /**
 604:      * Renders a url field for a model attribute.
 605:      * This method is a wrapper of {@link CHtml::activeUrlField}.
 606:      * Please check {@link CHtml::activeUrlField} for detailed information
 607:      * about the parameters for this method.
 608:      * @param CModel $model the data model
 609:      * @param string $attribute the attribute
 610:      * @param array $htmlOptions additional HTML attributes.
 611:      * @return string the generated input field
 612:      * @since 1.1.11
 613:      */
 614:     public function urlField($model,$attribute,$htmlOptions=array())
 615:     {
 616:         return CHtml::activeUrlField($model,$attribute,$htmlOptions);
 617:     }
 618: 
 619:     /**
 620:      * Renders an email field for a model attribute.
 621:      * This method is a wrapper of {@link CHtml::activeEmailField}.
 622:      * Please check {@link CHtml::activeEmailField} for detailed information
 623:      * about the parameters for this method.
 624:      * @param CModel $model the data model
 625:      * @param string $attribute the attribute
 626:      * @param array $htmlOptions additional HTML attributes.
 627:      * @return string the generated input field
 628:      * @since 1.1.11
 629:      */
 630:     public function emailField($model,$attribute,$htmlOptions=array())
 631:     {
 632:         return CHtml::activeEmailField($model,$attribute,$htmlOptions);
 633:     }
 634: 
 635:     /**
 636:      * Renders a number field for a model attribute.
 637:      * This method is a wrapper of {@link CHtml::activeNumberField}.
 638:      * Please check {@link CHtml::activeNumberField} for detailed information
 639:      * about the parameters for this method.
 640:      * @param CModel $model the data model
 641:      * @param string $attribute the attribute
 642:      * @param array $htmlOptions additional HTML attributes.
 643:      * @return string the generated input field
 644:      * @since 1.1.11
 645:      */
 646:     public function numberField($model,$attribute,$htmlOptions=array())
 647:     {
 648:         return CHtml::activeNumberField($model,$attribute,$htmlOptions);
 649:     }
 650: 
 651:     /**
 652:      * Generates a range field for a model attribute.
 653:      * This method is a wrapper of {@link CHtml::activeRangeField}.
 654:      * Please check {@link CHtml::activeRangeField} for detailed information
 655:      * about the parameters for this method.
 656:      * @param CModel $model the data model
 657:      * @param string $attribute the attribute
 658:      * @param array $htmlOptions additional HTML attributes.
 659:      * @return string the generated input field
 660:      * @since 1.1.11
 661:      */
 662:     public function rangeField($model,$attribute,$htmlOptions=array())
 663:     {
 664:         return CHtml::activeRangeField($model,$attribute,$htmlOptions);
 665:     }
 666: 
 667:     /**
 668:      * Renders a date field for a model attribute.
 669:      * This method is a wrapper of {@link CHtml::activeDateField}.
 670:      * Please check {@link CHtml::activeDateField} for detailed information
 671:      * about the parameters for this method.
 672:      * @param CModel $model the data model
 673:      * @param string $attribute the attribute
 674:      * @param array $htmlOptions additional HTML attributes.
 675:      * @return string the generated input field
 676:      * @since 1.1.11
 677:      */
 678:     public function dateField($model,$attribute,$htmlOptions=array())
 679:     {
 680:         return CHtml::activeDateField($model,$attribute,$htmlOptions);
 681:     }
 682: 
 683: 
 684:     /**
 685:      * Renders a time field for a model attribute.
 686:      * This method is a wrapper of {@link CHtml::activeTimeField}.
 687:      * Please check {@link CHtml::activeTimeField} for detailed information
 688:      * about the parameters for this method.
 689:      * @param CModel $model the data model
 690:      * @param string $attribute the attribute
 691:      * @param array $htmlOptions additional HTML attributes.
 692:      * @return string the generated input field
 693:      * @since 1.1.14
 694:      */
 695:     public function timeField($model,$attribute,$htmlOptions=array())
 696:     {
 697:         return CHtml::activeTimeField($model,$attribute,$htmlOptions);
 698:     }
 699: 
 700:     /**
 701:      * Renders a datetime field for a model attribute.
 702:      * This method is a wrapper of {@link CHtml::activeDateTimeField}.
 703:      * Please check {@link CHtml::activeDateTimeField} for detailed information
 704:      * about the parameters for this method.
 705:      * @param CModel $model the data model
 706:      * @param string $attribute the attribute
 707:      * @param array $htmlOptions additional HTML attributes.
 708:      * @return string the generated input field
 709:      * @since 1.1.16
 710:      */
 711:     public function dateTimeField($model,$attribute,$htmlOptions=array())
 712:     {
 713:         return CHtml::activeDateTimeField($model,$attribute,$htmlOptions);
 714:     }
 715: 
 716:     /**
 717:      * Renders a local datetime field for a model attribute.
 718:      * This method is a wrapper of {@link CHtml::activeDateTimeLocalField}.
 719:      * Please check {@link CHtml::activeDateTimeLocalField} for detailed information
 720:      * about the parameters for this method.
 721:      * @param CModel $model the data model
 722:      * @param string $attribute the attribute
 723:      * @param array $htmlOptions additional HTML attributes.
 724:      * @return string the generated input field
 725:      * @since 1.1.16
 726:      */
 727:     public function dateTimeLocalField($model,$attribute,$htmlOptions=array())
 728:     {
 729:         return CHtml::activeDateTimeLocalField($model,$attribute,$htmlOptions);
 730:     }
 731: 
 732:     /**
 733:      * Renders a week field for a model attribute.
 734:      * This method is a wrapper of {@link CHtml::activeWeekField}.
 735:      * Please check {@link CHtml::activeWeekField} for detailed information
 736:      * about the parameters for this method.
 737:      * @param CModel $model the data model
 738:      * @param string $attribute the attribute
 739:      * @param array $htmlOptions additional HTML attributes.
 740:      * @return string the generated input field
 741:      * @since 1.1.16
 742:      */
 743:     public function weekField($model,$attribute,$htmlOptions=array())
 744:     {
 745:         return CHtml::activeWeekField($model,$attribute,$htmlOptions);
 746:     }
 747: 
 748:     /**
 749:      * Renders a color picker field for a model attribute.
 750:      * This method is a wrapper of {@link CHtml::activeColorField}.
 751:      * Please check {@link CHtml::activeColorField} for detailed information
 752:      * about the parameters for this method.
 753:      * @param CModel $model the data model
 754:      * @param string $attribute the attribute
 755:      * @param array $htmlOptions additional HTML attributes.
 756:      * @return string the generated input field
 757:      * @since 1.1.16
 758:      */
 759:     public function colorField($model,$attribute,$htmlOptions=array())
 760:     {
 761:         return CHtml::activeColorField($model,$attribute,$htmlOptions);
 762:     }
 763: 
 764:     /**
 765:      * Renders a tel field for a model attribute.
 766:      * This method is a wrapper of {@link CHtml::activeTelField}.
 767:      * Please check {@link CHtml::activeTelField} for detailed information
 768:      * about the parameters for this method.
 769:      * @param CModel $model the data model
 770:      * @param string $attribute the attribute
 771:      * @param array $htmlOptions additional HTML attributes.
 772:      * @return string the generated input field
 773:      * @since 1.1.14
 774:      */
 775:     public function telField($model,$attribute,$htmlOptions=array())
 776:     {
 777:         return CHtml::activeTelField($model,$attribute,$htmlOptions);
 778:     }
 779: 
 780:     /**
 781:      * Renders a text field for a model attribute.
 782:      * This method is a wrapper of {@link CHtml::activeTextField}.
 783:      * Please check {@link CHtml::activeTextField} for detailed information
 784:      * about the parameters for this method.
 785:      * @param CModel $model the data model
 786:      * @param string $attribute the attribute
 787:      * @param array $htmlOptions additional HTML attributes.
 788:      * @return string the generated input field
 789:      */
 790:     public function textField($model,$attribute,$htmlOptions=array())
 791:     {
 792:         return CHtml::activeTextField($model,$attribute,$htmlOptions);
 793:     }
 794: 
 795:     /**
 796:      * Renders a search field for a model attribute.
 797:      * This method is a wrapper of {@link CHtml::activeSearchField}.
 798:      * Please check {@link CHtml::activeSearchField} for detailed information
 799:      * about the parameters for this method.
 800:      * @param CModel $model the data model
 801:      * @param string $attribute the attribute
 802:      * @param array $htmlOptions additional HTML attributes.
 803:      * @return string the generated input field
 804:      * @since 1.1.14
 805:      */
 806:     public function searchField($model,$attribute,$htmlOptions=array())
 807:     {
 808:         return CHtml::activeSearchField($model,$attribute,$htmlOptions);
 809:     }
 810: 
 811:     /**
 812:      * Renders a hidden field for a model attribute.
 813:      * This method is a wrapper of {@link CHtml::activeHiddenField}.
 814:      * Please check {@link CHtml::activeHiddenField} for detailed information
 815:      * about the parameters for this method.
 816:      * @param CModel $model the data model
 817:      * @param string $attribute the attribute
 818:      * @param array $htmlOptions additional HTML attributes.
 819:      * @return string the generated input field
 820:      */
 821:     public function hiddenField($model,$attribute,$htmlOptions=array())
 822:     {
 823:         return CHtml::activeHiddenField($model,$attribute,$htmlOptions);
 824:     }
 825: 
 826:     /**
 827:      * Renders a password field for a model attribute.
 828:      * This method is a wrapper of {@link CHtml::activePasswordField}.
 829:      * Please check {@link CHtml::activePasswordField} for detailed information
 830:      * about the parameters for this method.
 831:      * @param CModel $model the data model
 832:      * @param string $attribute the attribute
 833:      * @param array $htmlOptions additional HTML attributes.
 834:      * @return string the generated input field
 835:      */
 836:     public function passwordField($model,$attribute,$htmlOptions=array())
 837:     {
 838:         return CHtml::activePasswordField($model,$attribute,$htmlOptions);
 839:     }
 840: 
 841:     /**
 842:      * Renders a text area for a model attribute.
 843:      * This method is a wrapper of {@link CHtml::activeTextArea}.
 844:      * Please check {@link CHtml::activeTextArea} for detailed information
 845:      * about the parameters for this method.
 846:      * @param CModel $model the data model
 847:      * @param string $attribute the attribute
 848:      * @param array $htmlOptions additional HTML attributes.
 849:      * @return string the generated text area
 850:      */
 851:     public function textArea($model,$attribute,$htmlOptions=array())
 852:     {
 853:         return CHtml::activeTextArea($model,$attribute,$htmlOptions);
 854:     }
 855: 
 856:     /**
 857:      * Renders a file field for a model attribute.
 858:      * This method is a wrapper of {@link CHtml::activeFileField}.
 859:      * Please check {@link CHtml::activeFileField} for detailed information
 860:      * about the parameters for this method.
 861:      * @param CModel $model the data model
 862:      * @param string $attribute the attribute
 863:      * @param array $htmlOptions additional HTML attributes
 864:      * @return string the generated input field
 865:      */
 866:     public function fileField($model,$attribute,$htmlOptions=array())
 867:     {
 868:         return CHtml::activeFileField($model,$attribute,$htmlOptions);
 869:     }
 870: 
 871:     /**
 872:      * Renders a radio button for a model attribute.
 873:      * This method is a wrapper of {@link CHtml::activeRadioButton}.
 874:      * Please check {@link CHtml::activeRadioButton} for detailed information
 875:      * about the parameters for this method.
 876:      * @param CModel $model the data model
 877:      * @param string $attribute the attribute
 878:      * @param array $htmlOptions additional HTML attributes.
 879:      * @return string the generated radio button
 880:      */
 881:     public function radioButton($model,$attribute,$htmlOptions=array())
 882:     {
 883:         return CHtml::activeRadioButton($model,$attribute,$htmlOptions);
 884:     }
 885: 
 886:     /**
 887:      * Renders a checkbox for a model attribute.
 888:      * This method is a wrapper of {@link CHtml::activeCheckBox}.
 889:      * Please check {@link CHtml::activeCheckBox} for detailed information
 890:      * about the parameters for this method.
 891:      * @param CModel $model the data model
 892:      * @param string $attribute the attribute
 893:      * @param array $htmlOptions additional HTML attributes.
 894:      * @return string the generated check box
 895:      */
 896:     public function checkBox($model,$attribute,$htmlOptions=array())
 897:     {
 898:         return CHtml::activeCheckBox($model,$attribute,$htmlOptions);
 899:     }
 900: 
 901:     /**
 902:      * Renders a dropdown list for a model attribute.
 903:      * This method is a wrapper of {@link CHtml::activeDropDownList}.
 904:      * Please check {@link CHtml::activeDropDownList} for detailed information
 905:      * about the parameters for this method.
 906:      * @param CModel $model the data model
 907:      * @param string $attribute the attribute
 908:      * @param array $data data for generating the list options (value=>display)
 909:      * @param array $htmlOptions additional HTML attributes.
 910:      * @return string the generated drop down list
 911:      */
 912:     public function dropDownList($model,$attribute,$data,$htmlOptions=array())
 913:     {
 914:         return CHtml::activeDropDownList($model,$attribute,$data,$htmlOptions);
 915:     }
 916: 
 917:     /**
 918:      * Renders a list box for a model attribute.
 919:      * This method is a wrapper of {@link CHtml::activeListBox}.
 920:      * Please check {@link CHtml::activeListBox} for detailed information
 921:      * about the parameters for this method.
 922:      * @param CModel $model the data model
 923:      * @param string $attribute the attribute
 924:      * @param array $data data for generating the list options (value=>display)
 925:      * @param array $htmlOptions additional HTML attributes.
 926:      * @return string the generated list box
 927:      */
 928:     public function listBox($model,$attribute,$data,$htmlOptions=array())
 929:     {
 930:         return CHtml::activeListBox($model,$attribute,$data,$htmlOptions);
 931:     }
 932: 
 933:     /**
 934:      * Renders a checkbox list for a model attribute.
 935:      * This method is a wrapper of {@link CHtml::activeCheckBoxList}.
 936:      * Please check {@link CHtml::activeCheckBoxList} for detailed information
 937:      * about the parameters for this method.
 938:      * @param CModel $model the data model
 939:      * @param string $attribute the attribute
 940:      * @param array $data value-label pairs used to generate the check box list.
 941:      * @param array $htmlOptions addtional HTML options.
 942:      * @return string the generated check box list
 943:      */
 944:     public function checkBoxList($model,$attribute,$data,$htmlOptions=array())
 945:     {
 946:         return CHtml::activeCheckBoxList($model,$attribute,$data,$htmlOptions);
 947:     }
 948: 
 949:     /**
 950:      * Renders a radio button list for a model attribute.
 951:      * This method is a wrapper of {@link CHtml::activeRadioButtonList}.
 952:      * Please check {@link CHtml::activeRadioButtonList} for detailed information
 953:      * about the parameters for this method.
 954:      * @param CModel $model the data model
 955:      * @param string $attribute the attribute
 956:      * @param array $data value-label pairs used to generate the radio button list.
 957:      * @param array $htmlOptions addtional HTML options.
 958:      * @return string the generated radio button list
 959:      */
 960:     public function radioButtonList($model,$attribute,$data,$htmlOptions=array())
 961:     {
 962:         return CHtml::activeRadioButtonList($model,$attribute,$data,$htmlOptions);
 963:     }
 964: 
 965:     /**
 966:      * Validates one or several models and returns the results in JSON format.
 967:      * This is a helper method that simplifies the way of writing AJAX validation code.
 968:      * @param mixed $models a single model instance or an array of models.
 969:      * @param array $attributes list of attributes that should be validated. Defaults to null,
 970:      * meaning any attribute listed in the applicable validation rules of the models should be
 971:      * validated. If this parameter is given as a list of attributes, only
 972:      * the listed attributes will be validated.
 973:      * @param boolean $loadInput whether to load the data from $_POST array in this method.
 974:      * If this is true, the model will be populated from <code>$_POST[ModelClass]</code>.
 975:      * @return string the JSON representation of the validation error messages.
 976:      */
 977:     public static function validate($models, $attributes=null, $loadInput=true)
 978:     {
 979:         $result=array();
 980:         if(!is_array($models))
 981:             $models=array($models);
 982:         foreach($models as $model)
 983:         {
 984:             $modelName=CHtml::modelName($model);
 985:             if($loadInput && isset($_POST[$modelName]))
 986:                 $model->attributes=$_POST[$modelName];
 987:             $model->validate($attributes);
 988:             foreach($model->getErrors() as $attribute=>$errors)
 989:                 $result[CHtml::activeId($model,$attribute)]=$errors;
 990:         }
 991:         return function_exists('json_encode') ? json_encode($result) : CJSON::encode($result);
 992:     }
 993: 
 994:     /**
 995:      * Validates an array of model instances and returns the results in JSON format.
 996:      * This is a helper method that simplifies the way of writing AJAX validation code for tabular input.
 997:      * @param mixed $models an array of model instances.
 998:      * @param array $attributes list of attributes that should be validated. Defaults to null,
 999:      * meaning any attribute listed in the applicable validation rules of the models should be
1000:      * validated. If this parameter is given as a list of attributes, only
1001:      * the listed attributes will be validated.
1002:      * @param boolean $loadInput whether to load the data from $_POST array in this method.
1003:      * If this is true, the model will be populated from <code>$_POST[ModelClass][$i]</code>.
1004:      * @return string the JSON representation of the validation error messages.
1005:      */
1006:     public static function validateTabular($models, $attributes=null, $loadInput=true)
1007:     {
1008:         $result=array();
1009:         if(!is_array($models))
1010:             $models=array($models);
1011:         foreach($models as $i=>$model)
1012:         {
1013:             $modelName=CHtml::modelName($model);
1014:             if($loadInput && isset($_POST[$modelName][$i]))
1015:                 $model->attributes=$_POST[$modelName][$i];
1016:             $model->validate($attributes);
1017:             foreach($model->getErrors() as $attribute=>$errors)
1018:                 $result[CHtml::activeId($model,'['.$i.']'.$attribute)]=$errors;
1019:         }
1020:         return function_exists('json_encode') ? json_encode($result) : CJSON::encode($result);
1021:     }
1022: }
1023: 
API documentation generated by ApiGen 2.8.0