diff --git a/app/protected/models/LoginForm.php b/app/protected/models/LoginForm.php index 9067615..d77aa5d 100644 --- a/app/protected/models/LoginForm.php +++ b/app/protected/models/LoginForm.php @@ -18,6 +18,7 @@ class LoginForm extends Model { public $username; public $password; + public $rememberMe = true; public function rules() { @@ -25,6 +26,7 @@ class LoginForm extends Model array('username', 'required'), array('password', 'required'), array('password', 'validatePassword'), + array('rememberMe', 'boolean'), ); } diff --git a/app/protected/views/layouts/main.php b/app/protected/views/layouts/main.php index 092e665..b278ca1 100644 --- a/app/protected/views/layouts/main.php +++ b/app/protected/views/layouts/main.php @@ -5,10 +5,11 @@ */ use yii\helpers\Html; ?> +beginPage(); ?> -beginPage(); ?> + <?php echo Html::encode($this->title); ?> head(); ?> @@ -18,5 +19,5 @@ use yii\helpers\Html; endBody(); ?> -endPage(); ?> +endPage(); ?> \ No newline at end of file diff --git a/app/protected/views/site/login.php b/app/protected/views/site/login.php index 3ddd30a..921332b 100644 --- a/app/protected/views/site/login.php +++ b/app/protected/views/site/login.php @@ -14,13 +14,6 @@ use yii\helpers\Html; beginWidget('yii\widgets\ActiveForm'); ?> field($model, 'username')->textInput(); ?> field($model, 'password')->passwordInput(); ?> - field($model, 'username'); - echo $field->begin() . "\n" - . $field->label() . "\n" - . Html::activeTextInput($model, 'username') . "\n" - . $field->error() . "\n" - . $field->end(); - ?> + field($model, 'rememberMe')->checkbox(); ?> endWidget(); ?> \ No newline at end of file diff --git a/framework/helpers/base/Html.php b/framework/helpers/base/Html.php index 03976a3..16d0f30 100644 --- a/framework/helpers/base/Html.php +++ b/framework/helpers/base/Html.php @@ -771,7 +771,7 @@ class Html * @param array $items the data item used to generate the checkboxes. * The array keys are the labels, while the array values are the corresponding checkbox values. * Note that the labels will NOT be HTML-encoded, while the values will. - * @param array $options options (name => config) for the checkbox list. The following options are specially handled: + * @param array $options options (name => config) for the checkbox list. The following options are supported: * * - unselect: string, the value that should be submitted when none of the checkboxes is selected. * By setting this option, a hidden input will be generated. @@ -785,7 +785,7 @@ class Html * * where $index is the zero-based index of the checkbox in the whole list; $label * is the label for the checkbox; and $name, $value and $checked represent the name, - * value and the checked status of the checkbox input. + * value and the checked status of the checkbox input, respectively. * @return string the generated checkbox list */ public static function checkboxList($name, $selection = null, $items = array(), $options = array()) @@ -829,7 +829,7 @@ class Html * @param array $items the data item used to generate the radio buttons. * The array keys are the labels, while the array values are the corresponding radio button values. * Note that the labels will NOT be HTML-encoded, while the values will. - * @param array $options options (name => config) for the radio button list. The following options are specially handled: + * @param array $options options (name => config) for the radio button list. The following options are supported: * * - unselect: string, the value that should be submitted when none of the radio buttons is selected. * By setting this option, a hidden input will be generated. @@ -843,7 +843,7 @@ class Html * * where $index is the zero-based index of the radio button in the whole list; $label * is the label for the radio button; and $name, $value and $checked represent the name, - * value and the checked status of the radio button input. + * value and the checked status of the radio button input, respectively. * @return string the generated radio button list */ public static function radioList($name, $selection = null, $items = array(), $options = array()) @@ -885,8 +885,9 @@ class Html * If a value is null, the corresponding attribute will not be rendered. * The following options are specially handled: * - * - label: this specifies the label to be displayed. If this is not set, [[Model::getAttributeLabel()]] - * will be called to get the label for display. Note that this will NOT be [[encoded()]]. + * - label: this specifies the label to be displayed. Note that this will NOT be [[encoded()]]. + * If this is not set, [[Model::getAttributeLabel()]] will be called to get the label for display + * (after encoding). * * @return string the generated label tag */ diff --git a/framework/validators/BooleanValidator.php b/framework/validators/BooleanValidator.php index 6d2c671..e336cf5 100644 --- a/framework/validators/BooleanValidator.php +++ b/framework/validators/BooleanValidator.php @@ -70,8 +70,8 @@ class BooleanValidator extends Validator */ public function validateValue($value) { - return $this->strict && ($value == $this->trueValue || $value == $this->falseValue) - || !$this->strict && ($value === $this->trueValue || $value === $this->falseValue); + return !$this->strict && ($value == $this->trueValue || $value == $this->falseValue) + || $this->strict && ($value === $this->trueValue || $value === $this->falseValue); } /** diff --git a/framework/widgets/ActiveField.php b/framework/widgets/ActiveField.php index 2f07c92..5db44cf 100644 --- a/framework/widgets/ActiveField.php +++ b/framework/widgets/ActiveField.php @@ -8,7 +8,6 @@ namespace yii\widgets; use yii\base\Component; -use yii\base\InvalidParamException; use yii\helpers\Html; /** @@ -18,10 +17,6 @@ use yii\helpers\Html; class ActiveField extends Component { /** - * @var string the tag name. Defaults to 'div'. - */ - public $tag; - /** * @var ActiveForm */ public $form; @@ -34,13 +29,15 @@ class ActiveField extends Component */ public $attribute; /** + * @var string the tag name for the field container. + */ + public $tag = 'div'; + /** * @var array */ public $options = array( - 'tag' => 'div', 'class' => 'yii-field', ); - public $autoFieldCssClass = true; /** * @var string the default CSS class that indicates an input is required. */ @@ -57,7 +54,7 @@ class ActiveField extends Component * @var string the default CSS class that indicates an input is currently being validated. */ public $validatingCssClass = 'validating'; - public $layout = "{label}\n{input}\n{error}"; + public $template = "{label}\n{input}\n{error}"; public $errorOptions = array('tag' => 'span', 'class' => 'yii-error-message'); public $labelOptions = array('class' => 'control-label'); @@ -65,21 +62,15 @@ class ActiveField extends Component public function begin() { $options = $this->options; - $this->tag = isset($options['tag']) ? $options['tag'] : 'div'; - unset($options['tag']); $class = isset($options['class']) ? array($options['class']) : array(); - if ($this->autoFieldCssClass) { - $class[] = 'field-' . Html::getInputId($this->model, $this->attribute); - } + $class[] = 'field-' . Html::getInputId($this->model, $this->attribute); if ($this->model->isAttributeRequired($this->attribute)) { $class[] = $this->requiredCssClass; } if ($this->model->hasErrors($this->attribute)) { $class[] = $this->errorCssClass; } - if ($class !== array()) { - $options['class'] = implode(' ', $class); - } + $options['class'] = implode(' ', $class); return Html::beginTag($this->tag, $options); } @@ -88,6 +79,21 @@ class ActiveField extends Component return Html::endTag($this->tag); } + /** + * Generates a label tag for [[attribute]]. + * The label text is the label associated with the attribute, obtained via [[Model::getAttributeLabel()]]. + * @param array $options the tag options in terms of name-value pairs. If this is null, [[labelOptions]] will be used. + * The options will be rendered as the attributes of the resulting tag. The values will be HTML-encoded + * using [[encode()]]. If a value is null, the corresponding attribute will not be rendered. + * + * The following options are specially handled: + * + * - label: this specifies the label to be displayed. Note that this will NOT be [[encoded()]]. + * If this is not set, [[Model::getAttributeLabel()]] will be called to get the label for display + * (after encoding). + * + * @return string the generated label tag + */ public function label($options = null) { if ($options === null) { @@ -96,6 +102,19 @@ class ActiveField extends Component return Html::activeLabel($this->model, $this->attribute, $options); } + /** + * Generates a tag that contains the first validation error of [[attribute]]. + * If there is no validation, the tag will be returned and styled as hidden. + * @param array $options the tag options in terms of name-value pairs. If this is null, [[errorOptions]] will be used. + * The options will be rendered as the attributes of the resulting tag. The values will be HTML-encoded + * using [[encode()]]. If a value is null, the corresponding attribute will not be rendered. + * + * The following options are specially handled: + * + * - tag: this specifies the tag name. If not set, "span" will be used. + * + * @return string the generated label tag + */ public function error($options = null) { if ($options === null) { @@ -111,13 +130,20 @@ class ActiveField extends Component return Html::tag($tag, Html::encode($error), $options); } - protected function render($input) + /** + * Renders the field with the given input HTML. + * This method will generate the label and error tags, and return them together with the given + * input HTML according to [[template]]. + * @param string $input the input HTML + * @return string the rendering result + */ + public function render($input) { - return $this->begin() . "\n" . strtr($this->layout, array( + return $this->begin() . "\n" . strtr($this->template, array( '{input}' => $input, '{label}' => $this->label(), '{error}' => $this->error(), - )) . $this->end(); + )) . "\n" . $this->end(); } /** @@ -200,7 +226,6 @@ class ActiveField extends Component * Generates a radio button tag for the given model attribute. * This method will generate the "name" tag attribute automatically unless it is explicitly specified in `$options`. * This method will generate the "checked" tag attribute according to the model attribute value. - * @param string $value the value tag attribute. If it is null, the value attribute will not be rendered. * @param array $options the tag options in terms of name-value pairs. The following options are specially handled: * * - uncheck: string, the value associated with the uncheck state of the radio button. If not set, @@ -210,28 +235,33 @@ class ActiveField extends Component * * The rest of the options will be rendered as the attributes of the resulting tag. The values will * be HTML-encoded using [[encode()]]. If a value is null, the corresponding attribute will not be rendered. - * + * @param boolean $enclosedByLabel whether to enclose the radio button within the label tag. + * If this is true, [[template]] will be ignored. * @return string the generated radio button tag */ - public function radio($value = '1', $options = array()) - { - return $this->render(Html::activeRadio($this->model, $this->attribute, $value, $options)); - } - - public function radioAlt($value = '1', $options = array()) + public function radio($options = array(), $enclosedByLabel = true) { - $label = Html::encode($this->model->getAttributeLabel($this->attribute)); - return $this->begin() . "\n" - . Html::label(Html::activeRadio($this->model, $this->attribute, $value, $options) . ' ' . $label) . "\n" - . $this->error() . "\n" - . $this->end(); + if ($enclosedByLabel) { + $name = isset($options['name']) ? $options['name'] : Html::getInputName($this->model, $this->attribute); + $checked = Html::getAttributeValue($this->model, $this->attribute); + $radio = Html::radio($name, $checked, $options); + $uncheck = array_key_exists('unchecked', $options) ? $options['uncheck'] : '0'; + unset($options['uncheck']); + $hidden = $uncheck !== null ? Html::hiddenInput($name, $uncheck) : ''; + $label = Html::encode($this->model->getAttributeLabel($this->attribute)); + return $this->begin() . "\n" + . $hidden . Html::label("$radio $label", null, $this->labelOptions) . "\n" + . $this->error() . "\n" + . $this->end(); + } else { + return Html::activeRadio($this->model, $this->attribute, $options); + } } /** * Generates a checkbox tag for the given model attribute. * This method will generate the "name" tag attribute automatically unless it is explicitly specified in `$options`. * This method will generate the "checked" tag attribute according to the model attribute value. - * @param string $value the value tag attribute. If it is null, the value attribute will not be rendered. * @param array $options the tag options in terms of name-value pairs. The following options are specially handled: * * - uncheck: string, the value associated with the uncheck state of the radio button. If not set, @@ -241,21 +271,27 @@ class ActiveField extends Component * * The rest of the options will be rendered as the attributes of the resulting tag. The values will * be HTML-encoded using [[encode()]]. If a value is null, the corresponding attribute will not be rendered. - * + * @param boolean $enclosedByLabel whether to enclose the checkbox within the label tag. + * If this is true, [[template]] will be ignored. * @return string the generated checkbox tag */ - public function checkbox($value = '1', $options = array()) + public function checkbox($options = array(), $enclosedByLabel = true) { - return $this->render(Html::activeCheckbox($this->model, $this->attribute, $value, $options)); - } - - public function checkboxAlt($value = '1', $options = array()) - { - $label = Html::encode($this->model->getAttributeLabel($this->attribute)); - return $this->begin() . "\n" - . Html::label(Html::activeCheckbox($this->model, $this->attribute, $value, $options) . ' ' . $label) . "\n" - . $this->error() . "\n" - . $this->end(); + if ($enclosedByLabel) { + $name = isset($options['name']) ? $options['name'] : Html::getInputName($this->model, $this->attribute); + $checked = Html::getAttributeValue($this->model, $this->attribute); + $checkbox = Html::checkbox($name, $checked, $options); + $uncheck = array_key_exists('unchecked', $options) ? $options['uncheck'] : '0'; + unset($options['uncheck']); + $hidden = $uncheck !== null ? Html::hiddenInput($name, $uncheck) : ''; + $label = Html::encode($this->model->getAttributeLabel($this->attribute)); + return $this->begin() . "\n" + . $hidden . Html::label("$checkbox $label", null, $this->labelOptions) . "\n" + . $this->error() . "\n" + . $this->end(); + } else { + return Html::activeCheckbox($this->model, $this->attribute, $options); + } } /** @@ -362,7 +398,11 @@ class ActiveField extends Component */ public function checkboxList($items, $options = array()) { - return Html::activeCheckboxList($this->model, $this->attribute, $items, $options); + return $this->render( + '
' + . Html::activeCheckboxList($this->model, $this->attribute, $items, $options) + . '
' + ); } /** @@ -391,6 +431,10 @@ class ActiveField extends Component */ public function radioList($items, $options = array()) { - return Html::activeRadioList($this->model, $this->attribute, $items, $options); + return $this->render( + '
' + . Html::activeRadioList($this->model, $this->attribute, $items, $options) + . '
' + ); } } \ No newline at end of file diff --git a/framework/widgets/ActiveForm.php b/framework/widgets/ActiveForm.php index 06549a2..5081145 100644 --- a/framework/widgets/ActiveForm.php +++ b/framework/widgets/ActiveForm.php @@ -30,6 +30,11 @@ class ActiveForm extends Widget * Defaults to 'post'. */ public $method = 'post'; + /** + * @param array $options the attributes (name-value pairs) for the form tag. + * The values will be HTML-encoded using [[encode()]]. + * If a value is null, the corresponding attribute will not be rendered. + */ public $options = array(); /** * @var string the default CSS class for the error summary container. @@ -37,12 +42,14 @@ class ActiveForm extends Widget */ public $errorSummaryCssClass = 'yii-error-summary'; /** - * @var boolean whether to enable client-side data validation. Defaults to false. - * When this property is set true, client-side validation will be performed by validators - * that support it (see {@link CValidator::enableClientValidation} and {@link CValidator::clientValidateAttribute}). + * @var boolean whether to enable client-side data validation. + * Client-side validation will be performed by validators that support it + * (see [[\yii\validators\Validator::enableClientValidation]] and [[\yii\validators\Validator::clientValidateAttribute()]]). + */ + public $enableClientValidation = true; + /** + * @var array the default configuration used by [[field()]] when creating a new field object. */ - public $enableClientValidation = false; - public $fieldConfig = array( 'class' => 'yii\widgets\ActiveField', );