* @since 2.0 */ class Html { /** * @var integer the counter for generating automatic input field names. */ public static $count = 0; /** * @var boolean whether to close single tags. Defaults to true. Can be set to false for HTML5. */ public static $closeSingleTags = true; /** * @var boolean whether to render special attributes value. Defaults to true. Can be set to false for HTML5. */ public static $renderSpecialAttributesValue = true; /** * Encodes special characters into HTML entities. * The {@link CApplication::charset application charset} will be used for encoding. * @param string $text data to be encoded * @return string the encoded data * @see http://www.php.net/manual/en/function.htmlspecialchars.php */ public static function encode($text) { return htmlspecialchars($text, ENT_QUOTES, Yii::$app->charset); } /** * Decodes special HTML entities back to the corresponding characters. * This is the opposite of {@link encode()}. * @param string $text data to be decoded * @return string the decoded data * @see http://www.php.net/manual/en/function.htmlspecialchars-decode.php */ public static function decode($text) { return htmlspecialchars_decode($text, ENT_QUOTES); } /** * Encodes special characters in an array of strings into HTML entities. * Both the array keys and values will be encoded if needed. * If a value is an array, this method will also encode it recursively. * The {@link CApplication::charset application charset} will be used for encoding. * @param array $data data to be encoded * @return array the encoded data * @see http://www.php.net/manual/en/function.htmlspecialchars.php */ public static function encodeArray($data) { $d = array(); foreach ($data as $key => $value) { if (is_string($key)) { $key = htmlspecialchars($key, ENT_QUOTES, Yii::$app->charset); } if (is_string($value)) { $value = htmlspecialchars($value, ENT_QUOTES, Yii::$app->charset); } elseif (is_array($value)) { $value = static::encodeArray($value); } $d[$key] = $value; } return $d; } /** * Generates an HTML element. * @param string $tag the tag name * @param array $htmlOptions the element attributes. The values will be HTML-encoded using {@link encode()}. * If an 'encode' attribute is given and its value is false, * the rest of the attribute values will NOT be HTML-encoded. * Since version 1.1.5, attributes whose value is null will not be rendered. * @param mixed $content the content to be enclosed between open and close element tags. It will not be HTML-encoded. * If false, it means there is no body content. * @param boolean $closeTag whether to generate the close tag. * @return string the generated HTML element tag */ public static function tag($tag, $htmlOptions = array(), $content = false, $closeTag = true) { $html = '<' . $tag . static::renderAttributes($htmlOptions); if ($content === false) { return $closeTag && static::$closeSingleTags ? $html . ' />' : $html . '>'; } else { return $closeTag ? $html . '>' . $content . '' : $html . '>' . $content; } } /** * Generates an open HTML element. * @param string $tag the tag name * @param array $htmlOptions the element attributes. The values will be HTML-encoded using {@link encode()}. * If an 'encode' attribute is given and its value is false, * the rest of the attribute values will NOT be HTML-encoded. * Since version 1.1.5, attributes whose value is null will not be rendered. * @return string the generated HTML element tag */ public static function openTag($tag, $htmlOptions = array()) { return '<' . $tag . static::renderAttributes($htmlOptions) . '>'; } /** * Generates a close HTML element. * @param string $tag the tag name * @return string the generated HTML element tag */ public static function closeTag($tag) { return ''; } /** * Encloses the given string within a CDATA tag. * @param string $text the string to be enclosed * @return string the CDATA tag with the enclosed content. */ public static function cdata($text) { return ''; } /** * Generates a meta tag that can be inserted in the head section of HTML page. * @param string $content content attribute of the meta tag * @param string $name name attribute of the meta tag. If null, the attribute will not be generated * @param string $httpEquiv http-equiv attribute of the meta tag. If null, the attribute will not be generated * @param array $options other options in name-value pairs (e.g. 'scheme', 'lang') * @return string the generated meta tag */ public static function metaTag($content, $name = null, $httpEquiv = null, $options = array()) { if ($name !== null) { $options['name'] = $name; } if ($httpEquiv !== null) { $options['http-equiv'] = $httpEquiv; } $options['content'] = $content; return static::tag('meta', $options); } /** * Generates a link tag that can be inserted in the head section of HTML page. * Do not confuse this method with {@link link()}. The latter generates a hyperlink. * @param string $relation rel attribute of the link tag. If null, the attribute will not be generated. * @param string $type type attribute of the link tag. If null, the attribute will not be generated. * @param string $href href attribute of the link tag. If null, the attribute will not be generated. * @param string $media media attribute of the link tag. If null, the attribute will not be generated. * @param array $options other options in name-value pairs * @return string the generated link tag */ public static function linkTag($relation = null, $type = null, $href = null, $media = null, $options = array()) { if ($relation !== null) { $options['rel'] = $relation; } if ($type !== null) { $options['type'] = $type; } if ($href !== null) { $options['href'] = $href; } if ($media !== null) { $options['media'] = $media; } return static::tag('link', $options); } /** * Encloses the given CSS content with a CSS tag. * @param string $text the CSS content * @param string $media the media that this CSS should apply to. * @return string the CSS properly enclosed */ public static function css($text, $media = '') { if ($media !== '') { $media = ' media="' . $media . '"'; } return ""; } /** * Registers a 'refresh' meta tag. * This method can be invoked anywhere in a view. It will register a 'refresh' * meta tag with {@link CClientScript} so that the page can be refreshed in * the specified seconds. * @param integer $seconds the number of seconds to wait before refreshing the page * @param string $url the URL to which the page should be redirected to. If empty, it means the current page. * @since 1.1.1 */ public static function refresh($seconds, $url = '') { $content = "$seconds"; if ($url !== '') { $content .= ';' . static::normalizeUrl($url); } Yii::app()->clientScript->registerMetaTag($content, null, 'refresh'); } /** * Links to the specified CSS file. * @param string $url the CSS URL * @param string $media the media that this CSS should apply to. * @return string the CSS link. */ public static function cssFile($url, $media = '') { return CHtml::linkTag('stylesheet', 'text/css', $url, $media !== '' ? $media : null); } /** * Encloses the given JavaScript within a script tag. * @param string $text the JavaScript to be enclosed * @return string the enclosed JavaScript */ public static function script($text) { return ""; } /** * Includes a JavaScript file. * @param string $url URL for the JavaScript file * @return string the JavaScript file tag */ public static function scriptFile($url) { return ''; } /** * Generates an opening form tag. * This is a shortcut to {@link beginForm}. * @param mixed $action the form action URL (see {@link normalizeUrl} for details about this parameter.) * @param string $method form method (e.g. post, get) * @param array $htmlOptions additional HTML attributes (see {@link tag}). * @return string the generated form tag. */ public static function form($action = '', $method = 'post', $htmlOptions = array()) { return static::beginForm($action, $method, $htmlOptions); } /** * Generates an opening form tag. * Note, only the open tag is generated. A close tag should be placed manually * at the end of the form. * @param mixed $action the form action URL (see {@link normalizeUrl} for details about this parameter.) * @param string $method form method (e.g. post, get) * @param array $htmlOptions additional HTML attributes (see {@link tag}). * @return string the generated form tag. * @see endForm */ public static function beginForm($action = '', $method = 'post', $htmlOptions = array()) { $htmlOptions['action'] = $url = static::normalizeUrl($action); $htmlOptions['method'] = $method; $form = static::tag('form', $htmlOptions, false, false); $hiddens = array(); if (!strcasecmp($method, 'get') && ($pos = strpos($url, '?')) !== false) { foreach (explode('&', substr($url, $pos + 1)) as $pair) { if (($pos = strpos($pair, '=')) !== false) { $hiddens[] = static::hiddenField(urldecode(substr($pair, 0, $pos)), urldecode(substr($pair, $pos + 1)), array('id' => false)); } else { $hiddens[] = static::hiddenField(urldecode($pair), '', array('id' => false)); } } } $request = Yii::app()->request; if ($request->enableCsrfValidation && !strcasecmp($method, 'post')) { $hiddens[] = static::hiddenField($request->csrfTokenName, $request->getCsrfToken(), array('id' => false)); } if ($hiddens !== array()) { $form .= "\n" . static::tag('div', array('style' => 'display:none'), implode("\n", $hiddens)); } return $form; } /** * Generates a closing form tag. * @return string the generated tag * @see beginForm */ public static function endForm() { return ''; } /** * Generates a hyperlink tag. * @param string $text link body. It will NOT be HTML-encoded. Therefore you can pass in HTML code such as an image tag. * @param mixed $url a URL or an action route that can be used to create a URL. * See {@link normalizeUrl} for more details about how to specify this parameter. * @param array $htmlOptions additional HTML attributes. Besides normal HTML attributes, a few special * attributes are also recognized (see {@link clientChange} and {@link tag} for more details.) * @return string the generated hyperlink * @see normalizeUrl * @see clientChange */ public static function link($text, $url = '#', $htmlOptions = array()) { if ($url !== '') { $htmlOptions['href'] = static::normalizeUrl($url); } static::clientChange('click', $htmlOptions); return static::tag('a', $htmlOptions, $text); } /** * Generates a mailto link. * @param string $text link body. It will NOT be HTML-encoded. Therefore you can pass in HTML code such as an image tag. * @param string $email email address. If this is empty, the first parameter (link body) will be treated as the email address. * @param array $htmlOptions additional HTML attributes. Besides normal HTML attributes, a few special * attributes are also recognized (see {@link clientChange} and {@link tag} for more details.) * @return string the generated mailto link * @see clientChange */ public static function mailto($text, $email = '', $htmlOptions = array()) { if ($email === '') { $email = $text; } return static::link($text, 'mailto:' . $email, $htmlOptions); } /** * Generates an image tag. * @param string $src the image URL * @param string $alt the alternative text display * @param array $htmlOptions additional HTML attributes (see {@link tag}). * @return string the generated image tag */ public static function image($src, $alt = '', $htmlOptions = array()) { $htmlOptions['src'] = $src; $htmlOptions['alt'] = $alt; return static::tag('img', $htmlOptions); } /** * Generates a button. * @param string $label the button label * @param array $htmlOptions additional HTML attributes. Besides normal HTML attributes, a few special * attributes are also recognized (see {@link clientChange} and {@link tag} for more details.) * @return string the generated button tag * @see clientChange */ public static function button($name, $label = 'button', $htmlOptions = array()) { if (!isset($htmlOptions['name'])) { if (!array_key_exists('name', $htmlOptions)) { $htmlOptions['name'] = static::ID_PREFIX . static::$count++; } } if (!isset($htmlOptions['type'])) { $htmlOptions['type'] = 'button'; } if (!isset($htmlOptions['value'])) { $htmlOptions['value'] = $label; } static::clientChange('click', $htmlOptions); return static::tag('input', $htmlOptions); } /** * Generates a button using HTML button tag. * This method is similar to {@link button} except that it generates a 'button' * tag instead of 'input' tag. * @param string $label the button label. Note that this value will be directly inserted in the button element * without being HTML-encoded. * @param array $htmlOptions additional HTML attributes. Besides normal HTML attributes, a few special * attributes are also recognized (see {@link clientChange} and {@link tag} for more details.) * @return string the generated button tag * @see clientChange */ public static function htmlButton($label = 'button', $htmlOptions = array()) { if (!isset($htmlOptions['name'])) { $htmlOptions['name'] = static::ID_PREFIX . static::$count++; } if (!isset($htmlOptions['type'])) { $htmlOptions['type'] = 'button'; } static::clientChange('click', $htmlOptions); return static::tag('button', $htmlOptions, $label); } /** * Generates a submit button. * @param string $label the button label * @param array $htmlOptions additional HTML attributes. Besides normal HTML attributes, a few special * attributes are also recognized (see {@link clientChange} and {@link tag} for more details.) * @return string the generated button tag * @see clientChange */ public static function submitButton($label = 'submit', $htmlOptions = array()) { $htmlOptions['type'] = 'submit'; return static::button($label, $htmlOptions); } /** * Generates a reset button. * @param string $label the button label * @param array $htmlOptions additional HTML attributes. Besides normal HTML attributes, a few special * attributes are also recognized (see {@link clientChange} and {@link tag} for more details.) * @return string the generated button tag * @see clientChange */ public static function resetButton($label = 'reset', $htmlOptions = array()) { $htmlOptions['type'] = 'reset'; return static::button($label, $htmlOptions); } /** * Generates an image submit button. * @param string $src the image URL * @param array $htmlOptions additional HTML attributes. Besides normal HTML attributes, a few special * attributes are also recognized (see {@link clientChange} and {@link tag} for more details.) * @return string the generated button tag * @see clientChange */ public static function imageButton($src, $htmlOptions = array()) { $htmlOptions['src'] = $src; $htmlOptions['type'] = 'image'; return static::button('submit', $htmlOptions); } /** * Generates a link submit button. * @param string $label the button label * @param array $htmlOptions additional HTML attributes. Besides normal HTML attributes, a few special * attributes are also recognized (see {@link clientChange} and {@link tag} for more details.) * @return string the generated button tag * @see clientChange */ public static function linkButton($label = 'submit', $htmlOptions = array()) { if (!isset($htmlOptions['submit'])) { $htmlOptions['submit'] = isset($htmlOptions['href']) ? $htmlOptions['href'] : ''; } return static::link($label, '#', $htmlOptions); } /** * Generates a label tag. * @param string $label label text. Note, you should HTML-encode the text if needed. * @param string $for the ID of the HTML element that this label is associated with. * If this is false, the 'for' attribute for the label tag will not be rendered. * @param array $htmlOptions additional HTML attributes. * The following HTML option is recognized: * * @return string the generated label tag */ public static function label($label, $for, $htmlOptions = array()) { if ($for === false) { unset($htmlOptions['for']); } else { $htmlOptions['for'] = $for; } if (isset($htmlOptions['required'])) { if ($htmlOptions['required']) { if (isset($htmlOptions['class'])) { $htmlOptions['class'] .= ' ' . static::$requiredCss; } else { $htmlOptions['class'] = static::$requiredCss; } $label = static::$beforeRequiredLabel . $label . static::$afterRequiredLabel; } unset($htmlOptions['required']); } return static::tag('label', $htmlOptions, $label); } /** * Generates a text field input. * @param string $name the input name * @param string $value the input value * @param array $htmlOptions additional HTML attributes. Besides normal HTML attributes, a few special * attributes are also recognized (see {@link clientChange} and {@link tag} for more details.) * @return string the generated input field * @see clientChange * @see inputField */ public static function textField($name, $value = '', $htmlOptions = array()) { static::clientChange('change', $htmlOptions); return static::inputField('text', $name, $value, $htmlOptions); } /** * Generates a hidden input. * @param string $name the input name * @param string $value the input value * @param array $htmlOptions additional HTML attributes (see {@link tag}). * @return string the generated input field * @see inputField */ public static function hiddenField($name, $value = '', $htmlOptions = array()) { return static::inputField('hidden', $name, $value, $htmlOptions); } /** * Generates a password field input. * @param string $name the input name * @param string $value the input value * @param array $htmlOptions additional HTML attributes. Besides normal HTML attributes, a few special * attributes are also recognized (see {@link clientChange} and {@link tag} for more details.) * @return string the generated input field * @see clientChange * @see inputField */ public static function passwordField($name, $value = '', $htmlOptions = array()) { static::clientChange('change', $htmlOptions); return static::inputField('password', $name, $value, $htmlOptions); } /** * Generates a file input. * Note, you have to set the enclosing form's 'enctype' attribute to be 'multipart/form-data'. * After the form is submitted, the uploaded file information can be obtained via $_FILES[$name] (see * PHP documentation). * @param string $name the input name * @param string $value the input value * @param array $htmlOptions additional HTML attributes (see {@link tag}). * @return string the generated input field * @see inputField */ public static function fileField($name, $value = '', $htmlOptions = array()) { return static::inputField('file', $name, $value, $htmlOptions); } /** * Generates a text area input. * @param string $name the input name * @param string $value the input value * @param array $htmlOptions additional HTML attributes. Besides normal HTML attributes, a few special * attributes are also recognized (see {@link clientChange} and {@link tag} for more details.) * @return string the generated text area * @see clientChange * @see inputField */ public static function textArea($name, $value = '', $htmlOptions = array()) { $htmlOptions['name'] = $name; if (!isset($htmlOptions['id'])) { $htmlOptions['id'] = static::getIdByName($name); } elseif ($htmlOptions['id'] === false) { unset($htmlOptions['id']); } static::clientChange('change', $htmlOptions); return static::tag('textarea', $htmlOptions, isset($htmlOptions['encode']) && !$htmlOptions['encode'] ? $value : static::encode($value)); } /** * Generates a radio button. * @param string $name the input name * @param boolean $checked whether the radio button is checked * @param array $htmlOptions additional HTML attributes. Besides normal HTML attributes, a few special * attributes are also recognized (see {@link clientChange} and {@link tag} for more details.) * Since version 1.1.2, a special option named 'uncheckValue' is available that can be used to specify * the value returned when the radio button is not checked. When set, a hidden field is rendered so that * when the radio button is not checked, we can still obtain the posted uncheck value. * If 'uncheckValue' is not set or set to NULL, the hidden field will not be rendered. * @return string the generated radio button * @see clientChange * @see inputField */ public static function radioButton($name, $checked = false, $htmlOptions = array()) { if ($checked) { $htmlOptions['checked'] = 'checked'; } else { unset($htmlOptions['checked']); } $value = isset($htmlOptions['value']) ? $htmlOptions['value'] : 1; static::clientChange('click', $htmlOptions); if (array_key_exists('uncheckValue', $htmlOptions)) { $uncheck = $htmlOptions['uncheckValue']; unset($htmlOptions['uncheckValue']); } else { $uncheck = null; } if ($uncheck !== null) { // add a hidden field so that if the radio button is not selected, it still submits a value if (isset($htmlOptions['id']) && $htmlOptions['id'] !== false) { $uncheckOptions = array('id' => static::ID_PREFIX . $htmlOptions['id']); } else { $uncheckOptions = array('id' => false); } $hidden = static::hiddenField($name, $uncheck, $uncheckOptions); } else { $hidden = ''; } // add a hidden field so that if the radio button is not selected, it still submits a value return $hidden . static::inputField('radio', $name, $value, $htmlOptions); } /** * Generates a check box. * @param string $name the input name * @param boolean $checked whether the check box is checked * @param array $htmlOptions additional HTML attributes. Besides normal HTML attributes, a few special * attributes are also recognized (see {@link clientChange} and {@link tag} for more details.) * Since version 1.1.2, a special option named 'uncheckValue' is available that can be used to specify * the value returned when the checkbox is not checked. When set, a hidden field is rendered so that * when the checkbox is not checked, we can still obtain the posted uncheck value. * If 'uncheckValue' is not set or set to NULL, the hidden field will not be rendered. * @return string the generated check box * @see clientChange * @see inputField */ public static function checkBox($name, $checked = false, $htmlOptions = array()) { if ($checked) { $htmlOptions['checked'] = 'checked'; } else { unset($htmlOptions['checked']); } $value = isset($htmlOptions['value']) ? $htmlOptions['value'] : 1; static::clientChange('click', $htmlOptions); if (array_key_exists('uncheckValue', $htmlOptions)) { $uncheck = $htmlOptions['uncheckValue']; unset($htmlOptions['uncheckValue']); } else { $uncheck = null; } if ($uncheck !== null) { // add a hidden field so that if the check box is not checked, it still submits a value if (isset($htmlOptions['id']) && $htmlOptions['id'] !== false) { $uncheckOptions = array('id' => static::ID_PREFIX . $htmlOptions['id']); } else { $uncheckOptions = array('id' => false); } $hidden = static::hiddenField($name, $uncheck, $uncheckOptions); } else { $hidden = ''; } // add a hidden field so that if the check box is not checked, it still submits a value return $hidden . static::inputField('checkbox', $name, $value, $htmlOptions); } /** * Generates a drop down list. * @param string $name the input name * @param string $select the selected value * @param array $data data for generating the list options (value=>display). * You may use {@link listData} to generate this data. * Please refer to {@link listOptions} on how this data is used to generate the list options. * Note, the values and labels will be automatically HTML-encoded by this method. * @param array $htmlOptions additional HTML attributes. Besides normal HTML attributes, a few special * attributes are recognized. See {@link clientChange} and {@link tag} for more details. * In addition, the following options are also supported specifically for dropdown list: * * Since 1.1.13, a special option named 'unselectValue' is available. It can be used to set the value * that will be returned when no option is selected in multiple mode. When set, a hidden field is * rendered so that if no option is selected in multiple mode, we can still obtain the posted * unselect value. If 'unselectValue' is not set or set to NULL, the hidden field will not be rendered. * @return string the generated drop down list * @see clientChange * @see inputField * @see listData */ public static function dropDownList($name, $select, $data, $htmlOptions = array()) { $htmlOptions['name'] = $name; if (!isset($htmlOptions['id'])) { $htmlOptions['id'] = static::getIdByName($name); } elseif ($htmlOptions['id'] === false) { unset($htmlOptions['id']); } static::clientChange('change', $htmlOptions); $options = "\n" . static::listOptions($select, $data, $htmlOptions); $hidden = ''; if (isset($htmlOptions['multiple'])) { if (substr($htmlOptions['name'], -2) !== '[]') { $htmlOptions['name'] .= '[]'; } if (isset($htmlOptions['unselectValue'])) { $hiddenOptions = isset($htmlOptions['id']) ? array('id' => static::ID_PREFIX . $htmlOptions['id']) : array('id' => false); $hidden = static::hiddenField(substr($htmlOptions['name'], 0, -2), $htmlOptions['unselectValue'], $hiddenOptions); unset($htmlOptions['unselectValue']); } } // add a hidden field so that if the option is not selected, it still submits a value return $hidden . static::tag('select', $htmlOptions, $options); } /** * Generates a list box. * @param string $name the input name * @param mixed $select the selected value(s). This can be either a string for single selection or an array for multiple selections. * @param array $data data for generating the list options (value=>display) * You may use {@link listData} to generate this data. * Please refer to {@link listOptions} on how this data is used to generate the list options. * Note, the values and labels will be automatically HTML-encoded by this method. * @param array $htmlOptions additional HTML attributes. Besides normal HTML attributes, a few special * attributes are also recognized. See {@link clientChange} and {@link tag} for more details. * In addition, the following options are also supported specifically for list box: * * @return string the generated list box * @see clientChange * @see inputField * @see listData */ public static function listBox($name, $select, $data, $htmlOptions = array()) { if (!isset($htmlOptions['size'])) { $htmlOptions['size'] = 4; } if (isset($htmlOptions['multiple'])) { if (substr($name, -2) !== '[]') { $name .= '[]'; } } return static::dropDownList($name, $select, $data, $htmlOptions); } /** * Generates a check box list. * A check box list allows multiple selection, like {@link listBox}. * As a result, the corresponding POST value is an array. * @param string $name name of the check box list. You can use this name to retrieve * the selected value(s) once the form is submitted. * @param mixed $select selection of the check boxes. This can be either a string * for single selection or an array for multiple selections. * @param array $data value-label pairs used to generate the check box list. * Note, the values will be automatically HTML-encoded, while the labels will not. * @param array $htmlOptions additional HTML options. The options will be applied to * each checkbox input. The following special options are recognized: * * @return string the generated check box list */ public static function checkBoxList($name, $select, $data, $htmlOptions = array()) { $template = isset($htmlOptions['template']) ? $htmlOptions['template'] : '{input} {label}'; $separator = isset($htmlOptions['separator']) ? $htmlOptions['separator'] : "
\n"; $container = isset($htmlOptions['container']) ? $htmlOptions['container'] : 'span'; unset($htmlOptions['template'], $htmlOptions['separator'], $htmlOptions['container']); if (substr($name, -2) !== '[]') { $name .= '[]'; } if (isset($htmlOptions['checkAll'])) { $checkAllLabel = $htmlOptions['checkAll']; $checkAllLast = isset($htmlOptions['checkAllLast']) && $htmlOptions['checkAllLast']; } unset($htmlOptions['checkAll'], $htmlOptions['checkAllLast']); $labelOptions = isset($htmlOptions['labelOptions']) ? $htmlOptions['labelOptions'] : array(); unset($htmlOptions['labelOptions']); $items = array(); $baseID = isset($htmlOptions['baseID']) ? $htmlOptions['baseID'] : static::getIdByName($name); unset($htmlOptions['baseID']); $id = 0; $checkAll = true; foreach ($data as $value => $label) { $checked = !is_array($select) && !strcmp($value, $select) || is_array($select) && in_array($value, $select); $checkAll = $checkAll && $checked; $htmlOptions['value'] = $value; $htmlOptions['id'] = $baseID . '_' . $id++; $option = static::checkBox($name, $checked, $htmlOptions); $label = static::label($label, $htmlOptions['id'], $labelOptions); $items[] = strtr($template, array('{input}' => $option, '{label}' => $label)); } if (isset($checkAllLabel)) { $htmlOptions['value'] = 1; $htmlOptions['id'] = $id = $baseID . '_all'; $option = static::checkBox($id, $checkAll, $htmlOptions); $label = static::label($checkAllLabel, $id, $labelOptions); $item = strtr($template, array('{input}' => $option, '{label}' => $label)); if ($checkAllLast) { $items[] = $item; } else { array_unshift($items, $item); } $name = strtr($name, array('[' => '\\[', ']' => '\\]')); $js = <<getClientScript(); $cs->registerCoreScript('jquery'); $cs->registerScript($id, $js); } if (empty($container)) { return implode($separator, $items); } else { return static::tag($container, array('id' => $baseID), implode($separator, $items)); } } /** * Generates a radio button list. * A radio button list is like a {@link checkBoxList check box list}, except that * it only allows single selection. * @param string $name name of the radio button list. You can use this name to retrieve * the selected value(s) once the form is submitted. * @param string $select selection of the radio buttons. * @param array $data value-label pairs used to generate the radio button list. * Note, the values will be automatically HTML-encoded, while the labels will not. * @param array $htmlOptions additional HTML options. The options will be applied to * each radio button input. The following special options are recognized: * * @return string the generated radio button list */ public static function radioButtonList($name, $select, $data, $htmlOptions = array()) { $template = isset($htmlOptions['template']) ? $htmlOptions['template'] : '{input} {label}'; $separator = isset($htmlOptions['separator']) ? $htmlOptions['separator'] : "
\n"; $container = isset($htmlOptions['container']) ? $htmlOptions['container'] : 'span'; unset($htmlOptions['template'], $htmlOptions['separator'], $htmlOptions['container']); $labelOptions = isset($htmlOptions['labelOptions']) ? $htmlOptions['labelOptions'] : array(); unset($htmlOptions['labelOptions']); $items = array(); $baseID = isset($htmlOptions['baseID']) ? $htmlOptions['baseID'] : static::getIdByName($name); unset($htmlOptions['baseID']); $id = 0; foreach ($data as $value => $label) { $checked = !strcmp($value, $select); $htmlOptions['value'] = $value; $htmlOptions['id'] = $baseID . '_' . $id++; $option = static::radioButton($name, $checked, $htmlOptions); $label = static::label($label, $htmlOptions['id'], $labelOptions); $items[] = strtr($template, array('{input}' => $option, '{label}' => $label)); } if (empty($container)) { return implode($separator, $items); } else { return static::tag($container, array('id' => $baseID), implode($separator, $items)); } } /** * Normalizes the input parameter to be a valid URL. * * If the input parameter is an empty string, the currently requested URL will be returned. * * If the input parameter is a non-empty string, it is treated as a valid URL and will * be returned without any change. * * If the input parameter is an array, it is treated as a controller route and a list of * GET parameters, and the {@link CController::createUrl} method will be invoked to * create a URL. In this case, the first array element refers to the controller route, * and the rest key-value pairs refer to the additional GET parameters for the URL. * For example, array('post/list', 'page'=>3) may be used to generate the URL * /index.php?r=post/list&page=3. * * @param mixed $url the parameter to be used to generate a valid URL * @return string the normalized URL */ public static function normalizeUrl($url) { if (is_array($url)) { if (isset($url[0])) { if (($c = Yii::app()->getController()) !== null) { $url = $c->createUrl($url[0], array_splice($url, 1)); } else { $url = Yii::app()->createUrl($url[0], array_splice($url, 1)); } } else { $url = ''; } } return $url === '' ? Yii::app()->getRequest()->getUrl() : $url; } /** * Generates an input HTML tag. * This method generates an input HTML tag based on the given input name and value. * @param string $type the input type (e.g. 'text', 'radio') * @param string $name the input name * @param string $value the input value * @param array $htmlOptions additional HTML attributes for the HTML tag (see {@link tag}). * @return string the generated input tag */ protected static function inputField($type, $name, $value, $htmlOptions) { $htmlOptions['type'] = $type; $htmlOptions['value'] = $value; $htmlOptions['name'] = $name; if (!isset($htmlOptions['id'])) { $htmlOptions['id'] = static::getIdByName($name); } elseif ($htmlOptions['id'] === false) { unset($htmlOptions['id']); } return static::tag('input', $htmlOptions); } /** * Generates the list options. * @param mixed $selection the selected value(s). This can be either a string for single selection or an array for multiple selections. * @param array $listData the option data (see {@link listData}) * @param array $htmlOptions additional HTML attributes. The following two special attributes are recognized: * * @return string the generated list options */ public static function listOptions($selection, $listData, &$htmlOptions) { $raw = isset($htmlOptions['encode']) && !$htmlOptions['encode']; $content = ''; if (isset($htmlOptions['prompt'])) { $content .= '\n"; unset($htmlOptions['prompt']); } if (isset($htmlOptions['empty'])) { if (!is_array($htmlOptions['empty'])) { $htmlOptions['empty'] = array('' => $htmlOptions['empty']); } foreach ($htmlOptions['empty'] as $value => $label) { $content .= '\n"; } unset($htmlOptions['empty']); } if (isset($htmlOptions['options'])) { $options = $htmlOptions['options']; unset($htmlOptions['options']); } else { $options = array(); } $key = isset($htmlOptions['key']) ? $htmlOptions['key'] : 'primaryKey'; if (is_array($selection)) { foreach ($selection as $i => $item) { if (is_object($item)) { $selection[$i] = $item->$key; } } } elseif (is_object($selection)) { $selection = $selection->$key; } foreach ($listData as $key => $value) { if (is_array($value)) { $content .= '\n"; $dummy = array('options' => $options); if (isset($htmlOptions['encode'])) { $dummy['encode'] = $htmlOptions['encode']; } $content .= static::listOptions($selection, $value, $dummy); $content .= '' . "\n"; } else { $attributes = array('value' => (string)$key, 'encode' => !$raw); if (!is_array($selection) && !strcmp($key, $selection) || is_array($selection) && in_array($key, $selection)) { $attributes['selected'] = 'selected'; } if (isset($options[$key])) { $attributes = array_merge($attributes, $options[$key]); } $content .= static::tag('option', $attributes, $raw ? (string)$value : static::encode((string)$value)) . "\n"; } } unset($htmlOptions['key']); return $content; } /** * Renders the HTML tag attributes. * Since version 1.1.5, attributes whose value is null will not be rendered. * Special attributes, such as 'checked', 'disabled', 'readonly', will be rendered * properly based on their corresponding boolean value. * @param array $attributes attributes to be rendered * @return string the rendering result */ public static function renderAttributes($attributes) { static $specialAttributes = array( 'async' => 1, 'autofocus' => 1, 'autoplay' => 1, 'checked' => 1, 'controls' => 1, 'declare' => 1, 'default' => 1, 'defer' => 1, 'disabled' => 1, 'formnovalidate' => 1, 'hidden' => 1, 'ismap' => 1, 'loop' => 1, 'multiple' => 1, 'muted' => 1, 'nohref' => 1, 'noresize' => 1, 'novalidate' => 1, 'open' => 1, 'readonly' => 1, 'required' => 1, 'reversed' => 1, 'scoped' => 1, 'seamless' => 1, 'selected' => 1, 'typemustmatch' => 1, ); if ($attributes === array()) { return ''; } $html = ''; if (isset($attributes['encode'])) { $raw = !$attributes['encode']; unset($attributes['encode']); } else { $raw = false; } foreach ($attributes as $name => $value) { if (isset($specialAttributes[$name])) { if ($value) { $html .= ' ' . $name; if (static::$renderSpecialAttributesValue) { $html .= '="' . $name . '"'; } } } elseif ($value !== null) { $html .= ' ' . $name . '="' . ($raw ? $value : static::encode($value)) . '"'; } } return $html; } }