PageRenderTime 41ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 1ms

/admincrud/extensions/bootstrap/helpers/TbHtml.php

https://github.com/max-rautkin/yii-admincrud
PHP | 4080 lines | 2184 code | 316 blank | 1580 comment | 162 complexity | c7c17d9238ae7d340c9015e511d1ea0d MD5 | raw file
Possible License(s): LGPL-2.1, BSD-3-Clause
  1. <?php
  2. /**
  3. * TbHtml class file.
  4. * @author Antonio Ramirez <ramirez.cobos@gmail.com>
  5. * @author Christoffer Niska <christoffer.niska@gmail.com>
  6. * @copyright Copyright &copy; Christoffer Niska 2013-
  7. * @license http://www.opensource.org/licenses/bsd-license.php New BSD License
  8. * @package bootstrap.helpers
  9. */
  10. /**
  11. * Bootstrap HTML helper.
  12. */
  13. class TbHtml extends CHtml // required in order to access the protected methods in CHtml
  14. {
  15. //
  16. // TYPOGRAPHY
  17. // --------------------------------------------------
  18. const TEXT_ALIGN_LEFT = 'left';
  19. const TEXT_ALIGN_CENTER = 'center';
  20. const TEXT_ALIGN_RIGHT = 'right';
  21. const TEXT_COLOR_DEFAULT = '';
  22. const TEXT_COLOR_WARNING = 'warning';
  23. const TEXT_COLOR_ERROR = 'error';
  24. const TEXT_COLOR_INFO = 'info';
  25. const TEXT_COLOR_SUCCESS = 'success';
  26. const HELP_TYPE_INLINE = 'inline';
  27. const HELP_TYPE_BLOCK = 'block';
  28. //
  29. // FORM
  30. // --------------------------------------------------
  31. const FORM_LAYOUT_VERTICAL = 'vertical';
  32. const FORM_LAYOUT_HORIZONTAL = 'horizontal';
  33. const FORM_LAYOUT_INLINE = 'inline';
  34. const FORM_LAYOUT_SEARCH = 'search';
  35. const INPUT_TYPE_TEXT = 'textField';
  36. const INPUT_TYPE_PASSWORD = 'passwordField';
  37. const INPUT_TYPE_URL = 'urlField';
  38. const INPUT_TYPE_EMAIL = 'emailField';
  39. const INPUT_TYPE_NUMBER = 'numberField';
  40. const INPUT_TYPE_RANGE = 'rangeField';
  41. const INPUT_TYPE_DATE = 'dateField';
  42. const INPUT_TYPE_TEXTAREA = 'textArea';
  43. const INPUT_TYPE_FILE = 'fileField';
  44. const INPUT_TYPE_RADIOBUTTON = 'radioButton';
  45. const INPUT_TYPE_CHECKBOX = 'checkBox';
  46. const INPUT_TYPE_DROPDOWNLIST = 'dropDownList';
  47. const INPUT_TYPE_LISTBOX = 'listBox';
  48. const INPUT_TYPE_CHECKBOXLIST = 'checkBoxList';
  49. const INPUT_TYPE_INLINECHECKBOXLIST = 'inlineCheckBoxList';
  50. const INPUT_TYPE_RADIOBUTTONLIST = 'radioButtonList';
  51. const INPUT_TYPE_INLINERADIOBUTTONLIST = 'inlineRadioButtonList';
  52. const INPUT_TYPE_UNEDITABLE = 'uneditableField';
  53. const INPUT_TYPE_SEARCH = 'searchQuery';
  54. const INPUT_SIZE_MINI = 'mini';
  55. const INPUT_SIZE_SMALL = 'small';
  56. const INPUT_SIZE_DEFAULT = '';
  57. const INPUT_SIZE_MEDIUM = 'medium';
  58. const INPUT_SIZE_LARGE = 'large';
  59. const INPUT_SIZE_XLARGE = 'xlarge';
  60. const INPUT_SIZE_XXLARGE = 'xxlarge';
  61. const INPUT_COLOR_DEFAULT = '';
  62. const INPUT_COLOR_WARNING = 'warning';
  63. const INPUT_COLOR_ERROR = 'error';
  64. const INPUT_COLOR_INFO = 'info';
  65. const INPUT_COLOR_SUCCESS = 'success';
  66. //
  67. // BUTTONS
  68. // --------------------------------------------------
  69. const BUTTON_TYPE_LINK = 'link';
  70. const BUTTON_TYPE_HTML = 'htmlButton';
  71. const BUTTON_TYPE_SUBMIT = 'submitButton';
  72. const BUTTON_TYPE_RESET = 'resetButton';
  73. const BUTTON_TYPE_IMAGE = 'imageButton';
  74. const BUTTON_TYPE_LINKBUTTON = 'linkButton';
  75. const BUTTON_TYPE_AJAXLINK = 'ajaxLink';
  76. const BUTTON_TYPE_AJAXBUTTON = 'ajaxButton';
  77. const BUTTON_TYPE_INPUTBUTTON = 'inputButton';
  78. const BUTTON_TYPE_INPUTSUBMIT = 'inputSubmit';
  79. const BUTTON_COLOR_DEFAULT = '';
  80. const BUTTON_COLOR_PRIMARY = 'primary';
  81. const BUTTON_COLOR_INFO = 'info';
  82. const BUTTON_COLOR_SUCCESS = 'success';
  83. const BUTTON_COLOR_WARNING = 'warning';
  84. const BUTTON_COLOR_DANGER = 'danger';
  85. const BUTTON_COLOR_INVERSE = 'inverse';
  86. const BUTTON_COLOR_LINK = 'link';
  87. const BUTTON_SIZE_MINI = 'mini';
  88. const BUTTON_SIZE_SMALL = 'small';
  89. const BUTTON_SIZE_DEFAULT = '';
  90. const BUTTON_SIZE_LARGE = 'large';
  91. const BUTTON_TOGGLE_CHECKBOX = 'checkbox';
  92. const BUTTON_TOGGLE_RADIO = 'radio';
  93. //
  94. // IMAGES
  95. // --------------------------------------------------
  96. const IMAGE_TYPE_ROUNDED = 'rounded';
  97. const IMAGE_TYPE_CIRCLE = 'circle';
  98. const IMAGE_TYPE_POLAROID = 'polaroid';
  99. //
  100. // NAV
  101. // --------------------------------------------------
  102. const NAV_TYPE_NONE = '';
  103. const NAV_TYPE_TABS = 'tabs';
  104. const NAV_TYPE_PILLS = 'pills';
  105. const NAV_TYPE_LIST = 'list';
  106. const TABS_PLACEMENT_ABOVE = '';
  107. const TABS_PLACEMENT_BELOW = 'below';
  108. const TABS_PLACEMENT_LEFT = 'left';
  109. const TABS_PLACEMENT_RIGHT = 'right';
  110. //
  111. // NAVBAR
  112. // --------------------------------------------------
  113. const NAVBAR_DISPLAY_NONE = '';
  114. const NAVBAR_DISPLAY_FIXEDTOP = 'fixed-top';
  115. const NAVBAR_DISPLAY_FIXEDBOTTOM = 'fixed-bottom';
  116. const NAVBAR_DISPLAY_STATICTOP = 'static-top';
  117. const NAVBAR_COLOR_INVERSE = 'inverse';
  118. //
  119. // PAGINATION
  120. // --------------------------------------------------
  121. const PAGINATION_SIZE_MINI = 'mini';
  122. const PAGINATION_SIZE_SMALL = 'small';
  123. const PAGINATION_SIZE_DEFAULT = '';
  124. const PAGINATION_SIZE_LARGE = 'large';
  125. const PAGINATION_ALIGN_LEFT = 'left';
  126. const PAGINATION_ALIGN_CENTER = 'centered';
  127. const PAGINATION_ALIGN_RIGHT = 'right';
  128. //
  129. // LABELS AND BADGES
  130. // --------------------------------------------------
  131. const LABEL_COLOR_DEFAULT = '';
  132. const LABEL_COLOR_SUCCESS = 'success';
  133. const LABEL_COLOR_WARNING = 'warning';
  134. const LABEL_COLOR_IMPORTANT = 'important';
  135. const LABEL_COLOR_INFO = 'info';
  136. const LABEL_COLOR_INVERSE = 'inverse';
  137. const BADGE_COLOR_DEFAULT = '';
  138. const BADGE_COLOR_SUCCESS = 'success';
  139. const BADGE_COLOR_WARNING = 'warning';
  140. const BADGE_COLOR_IMPORTANT = 'important';
  141. const BADGE_COLOR_INFO = 'info';
  142. const BADGE_COLOR_INVERSE = 'inverse';
  143. //
  144. // TOOLTIPS AND POPOVERS
  145. // --------------------------------------------------
  146. const TOOLTIP_PLACEMENT_TOP = 'top';
  147. const TOOLTIP_PLACEMENT_BOTTOM = 'bottom';
  148. const TOOLTIP_PLACEMENT_LEFT = 'left';
  149. const TOOLTIP_PLACEMENT_RIGHT = 'right';
  150. const TOOLTIP_TRIGGER_CLICK = 'click';
  151. const TOOLTIP_TRIGGER_HOVER = 'hover';
  152. const TOOLTIP_TRIGGER_FOCUS = 'focus';
  153. const TOOLTIP_TRIGGER_MANUAL = 'manual';
  154. const POPOVER_PLACEMENT_TOP = 'top';
  155. const POPOVER_PLACEMENT_BOTTOM = 'bottom';
  156. const POPOVER_PLACEMENT_LEFT = 'left';
  157. const POPOVER_PLACEMENT_RIGHT = 'right';
  158. const POPOVER_TRIGGER_CLICK = 'click';
  159. const POPOVER_TRIGGER_HOVER = 'hover';
  160. const POPOVER_TRIGGER_FOCUS = 'focus';
  161. const POPOVER_TRIGGER_MANUAL = 'manual';
  162. //
  163. // ALERT
  164. // --------------------------------------------------
  165. const ALERT_COLOR_DEFAULT = '';
  166. const ALERT_COLOR_INFO = 'info';
  167. const ALERT_COLOR_SUCCESS = 'success';
  168. const ALERT_COLOR_WARNING = 'warning';
  169. const ALERT_COLOR_ERROR = 'error';
  170. const ALERT_COLOR_DANGER = 'danger';
  171. //
  172. // PROGRESS BARS
  173. // --------------------------------------------------
  174. const PROGRESS_COLOR_DEFAULT = '';
  175. const PROGRESS_COLOR_INFO = 'info';
  176. const PROGRESS_COLOR_SUCCESS = 'success';
  177. const PROGRESS_COLOR_WARNING = 'warning';
  178. const PROGRESS_COLOR_DANGER = 'danger';
  179. //
  180. // MISC
  181. // --------------------------------------------------
  182. const WELL_SIZE_SMALL = 'small';
  183. const WELL_SIZE_DEFAULT = '';
  184. const WELL_SIZE_LARGE = 'large';
  185. const PULL_LEFT = 'left';
  186. const PULL_RIGHT = 'right';
  187. //
  188. // GRID VIEW
  189. // --------------------------------------------------
  190. const GRID_TYPE_STRIPED = 'striped';
  191. const GRID_TYPE_BORDERED = 'bordered';
  192. const GRID_TYPE_CONDENSED = 'condensed';
  193. const GRID_TYPE_HOVER = 'hover';
  194. //
  195. // AFFIX
  196. // --------------------------------------------------
  197. const AFFIX_POSITION_TOP = 'top';
  198. const AFFIX_POSITION_BOTTOM = 'bottom';
  199. //
  200. // ICON
  201. // --------------------------------------------------
  202. const ICON_GLASS = 'icon-glass';
  203. const ICON_MUSIC = 'icon-music';
  204. const ICON_SEARCH = 'icon-search';
  205. const ICON_ENVELOPE = 'icon-envelope';
  206. const ICON_HEART = 'icon-heart';
  207. const ICON_STAR = 'icon-star';
  208. const ICON_STAR_EMPTY = 'icon-star-empty';
  209. const ICON_USER = 'icon-user';
  210. const ICON_FILM = 'icon-film';
  211. const ICON_TH_LARGE = 'icon-th-large';
  212. const ICON_TH = 'icon-th';
  213. const ICON_TH_LIST = 'icon-th-list';
  214. const ICON_OK = 'icon-ok';
  215. const ICON_REMOVE = 'icon-remove';
  216. const ICON_ZOOM_IN = 'icon-zoom-in';
  217. const ICON_ZOOM_OUT = 'icon-zoom-out';
  218. const ICON_OFF = 'icon-off';
  219. const ICON_SIGNAL = 'icon-signal';
  220. const ICON_COG = 'icon-cog';
  221. const ICON_TRASH = 'icon-trash';
  222. const ICON_HOME = 'icon-home';
  223. const ICON_FILE = 'icon-file';
  224. const ICON_TIME = 'icon-time';
  225. const ICON_ROAD = 'icon-road';
  226. const ICON_DOWNLOAD_ALT = 'icon-download-alt';
  227. const ICON_DOWNLOAD = 'icon-download';
  228. const ICON_UPLOAD = 'icon-upload';
  229. const ICON_INBOX = 'icon-inbox';
  230. const ICON_PLAY_CIRCLE = 'icon-play-circle';
  231. const ICON_REPEAT = 'icon-repeat';
  232. const ICON_REFRESH = 'icon-refresh';
  233. const ICON_LIST_ALT = 'icon-list-alt';
  234. const ICON_LOCK = 'icon-lock';
  235. const ICON_FLAG = 'icon-flag';
  236. const ICON_HEADPHONES = 'icon-headphones';
  237. const ICON_VOLUME_OFF = 'icon-volume-off';
  238. const ICON_VOLUME_DOWN = 'icon-volume-down';
  239. const ICON_VOLUME_UP = 'icon-volume-up';
  240. const ICON_QRCODE = 'icon-qrcode';
  241. const ICON_BARCODE = 'icon-barcode';
  242. const ICON_TAG = 'icon-tag';
  243. const ICON_TAGS = 'icon-tags';
  244. const ICON_BOOK = 'icon-book';
  245. const ICON_BOOKMARK = 'icon-bookmark';
  246. const ICON_PRINT = 'icon-print';
  247. const ICON_CAMERA = 'icon-camera';
  248. const ICON_FONT = 'icon-font';
  249. const ICON_BOLD = 'icon-bold';
  250. const ICON_ITALIC = 'icon-italic';
  251. const ICON_TEXT_HEIGHT = 'icon-text-height';
  252. const ICON_TEXT_WIDTH = 'icon-text-width';
  253. const ICON_ALIGN_LEFT = 'icon-align-left';
  254. const ICON_ALIGN_CENTER = 'icon-align-center';
  255. const ICON_ALIGN_RIGHT = 'icon-align-right';
  256. const ICON_ALIGN_JUSTIFY = 'icon-align-justify';
  257. const ICON_LIST = 'icon-list';
  258. const ICON_INDENT_LEFT = 'icon-indent-left';
  259. const ICON_INDENT_RIGHT = 'icon-indent-right';
  260. const ICON_FACETIME_VIDEO = 'icon-facetime-video';
  261. const ICON_PICTURE = 'icon-picture';
  262. const ICON_PENCIL = 'icon-pencil';
  263. const ICON_MAP_MARKER = 'icon-map-marker';
  264. const ICON_ADJUST = 'icon-adjust';
  265. const ICON_TINT = 'icon-tint';
  266. const ICON_EDIT = 'icon-edit';
  267. const ICON_SHARE = 'icon-share';
  268. const ICON_CHECK = 'icon-check';
  269. const ICON_MOVE = 'icon-move';
  270. const ICON_STEP_BACKWARD = 'icon-step-backward';
  271. const ICON_FAST_BACKWARD = 'icon-fast-backward';
  272. const ICON_BACKWARD = 'icon-backward';
  273. const ICON_PLAY = 'icon-play';
  274. const ICON_PAUSE = 'icon-pause';
  275. const ICON_STOP = 'icon-pause';
  276. const ICON_FORWARD = 'icon-forward';
  277. const ICON_FAST_FORWARD = 'icon-fast-forward';
  278. const ICON_STEP_FORWARD = 'icon-step-forward';
  279. const ICON_EJECT = 'icon-eject';
  280. const ICON_CHEVRON_LEFT = 'icon-chevron-left';
  281. const ICON_CHEVRON_RIGHT = 'icon-chevron-right';
  282. const ICON_PLUS_SIGN = 'icon-plus-sign';
  283. const ICON_MINUS_SIGN = 'icon-minus-sign';
  284. const ICON_REMOVE_SIGN = 'icon-remove-sign';
  285. const ICON_OK_SIGN = 'icon-ok-sign';
  286. const ICON_QUESTION_SIGN = 'icon-question-sign';
  287. const ICON_INFO_SIGN = 'icon-info-sign';
  288. const ICON_SCREENSHOT = 'icon-screenshot';
  289. const ICON_REMOVE_CIRCLE = 'icon-remove-circle';
  290. const ICON_OK_CIRCLE = 'icon-ok-circle';
  291. const ICON_BAN_CIRCLE = 'icon-ban-circle';
  292. const ICON_ARROW_LEFT = 'icon-arrow-left';
  293. const ICON_ARROW_RIGHT = 'icon-arrow-right';
  294. const ICON_ARROW_UP = 'icon-arrow-up';
  295. const ICON_ARROW_DOWN = 'icon-arrow-down';
  296. const ICON_SHARE_ALT = 'icon-share-alt';
  297. const ICON_RESIZE_FULL = 'icon-resize-full';
  298. const ICON_RESIZE_SMALL = 'icon-resize-small';
  299. const ICON_PLUS = 'icon-plus';
  300. const ICON_MINUS = 'icon-minus';
  301. const ICON_ASTERISK = 'icon-asterisk';
  302. const ICON_EXCLAMATION_SIGN = 'icon-exclamation-sign';
  303. const ICON_GIFT = 'icon-gift';
  304. const ICON_LEAF = 'icon-leaf';
  305. const ICON_FIRE = 'icon-fire';
  306. const ICON_EYE_OPEN = 'icon-eye-open';
  307. const ICON_EYE_CLOSE = 'icon-eye-close';
  308. const ICON_WARNING_SIGN = 'icon-warning-sign';
  309. const ICON_PLANE = 'icon-plane';
  310. const ICON_CALENDAR = 'icon-calendar';
  311. const ICON_RANDOM = 'icon-random';
  312. const ICON_COMMENT = 'icon-comment';
  313. const ICON_MAGNET = 'icon-magnet';
  314. const ICON_CHEVRON_UP = 'icon-chevron-up';
  315. const ICON_CHEVRON_DOWN = 'icon-chevron-down';
  316. const ICON_RETWEET = 'icon-retweet';
  317. const ICON_SHOPPING_CART = 'icon-shopping-cart';
  318. const ICON_FOLDER_CLOSE = 'icon-folder-close';
  319. const ICON_FOLDER_OPEN = 'icon-folder-open';
  320. const ICON_RESIZE_VERTICAL = 'icon-resize-vertical';
  321. const ICON_RESIZE_HORIZONTAL = 'icon-resize-horizontal';
  322. const ICON_HDD = 'icon-hdd';
  323. const ICON_BULLHORN = 'icon-bullhorn';
  324. const ICON_BELL = 'icon-bell';
  325. const ICON_CERTFICATE = 'icon-certificate';
  326. const ICON_THUMBS_UP = 'icon-thumbs-up';
  327. const ICON_THUMBS_DOWN = 'icon-thumbs-down';
  328. const ICON_HAND_RIGHT = 'icon-hand-right';
  329. const ICON_HAND_LEFT = 'icon-hand-left';
  330. const ICON_HAND_UP = 'icon-hand-up';
  331. const ICON_HAND_DOWN = 'icon-hand-down';
  332. const ICON_CIRCLE_ARROW_RIGHT = 'icon-circle-arrow-right';
  333. const ICON_CIRCLE_ARROW_LEFT = 'icon-circle-arrow-left';
  334. const ICON_CIRCLE_ARROW_UP = 'icon-circle-arrow-up';
  335. const ICON_CIRCLE_ARROW_DOWN = 'icon-circle-arrow-down';
  336. const ICON_GLOBE = 'icon-globe';
  337. const ICON_WRENCH = 'icon-wrench';
  338. const ICON_TASKS = 'icon-tasks';
  339. const ICON_FILTER = 'icon-filter';
  340. const ICON_BRIEFCASE = 'icon-briefcase';
  341. const ICON_FULLSCREEN = 'icon-fullscreen';
  342. // Default close text.
  343. const CLOSE_TEXT = '&times;';
  344. //
  345. // BASE CSS
  346. // --------------------------------------------------
  347. // Typography
  348. // http://twitter.github.com/bootstrap/base-css.html#typography
  349. // --------------------------------------------------
  350. /**
  351. * Generates a paragraph that stands out.
  352. * @param string $text the lead text.
  353. * @param array $htmlOptions additional HTML attributes.
  354. * @return string the generated paragraph.
  355. */
  356. public static function lead($text, $htmlOptions = array())
  357. {
  358. $htmlOptions = self::addClassName('lead', $htmlOptions);
  359. return self::tag('p', $htmlOptions, $text);
  360. }
  361. /**
  362. * Generates small text.
  363. * @param string $text the text to style.
  364. * @param array $htmlOptions additional HTML attributes.
  365. * @return string the generated text.
  366. */
  367. public static function small($text, $htmlOptions = array())
  368. {
  369. return self::tag('small', $htmlOptions, $text);
  370. }
  371. /**
  372. * Generates bold text.
  373. * @param string $text the text to style.
  374. * @param array $htmlOptions additional HTML attributes.
  375. * @return string the generated text.
  376. */
  377. public static function b($text, $htmlOptions = array())
  378. {
  379. return self::tag('strong', $htmlOptions, $text);
  380. }
  381. /**
  382. * Generates italic text.
  383. * @param string $text the text to style.
  384. * @param array $htmlOptions additional HTML attributes.
  385. * @return string the generated text.
  386. */
  387. public static function i($text, $htmlOptions = array())
  388. {
  389. return self::tag('em', $htmlOptions, $text);
  390. }
  391. /**
  392. * Generates an emphasized text.
  393. * @param string $style the text style.
  394. * @param string $text the text to emphasize.
  395. * @param array $htmlOptions additional HTML attributes.
  396. * @param string $tag the HTML tag.
  397. * @return string the generated text.
  398. */
  399. public static function em($text, $htmlOptions = array(), $tag = 'p')
  400. {
  401. $color = self::popOption('color', $htmlOptions);
  402. if (self::popOption('muted', $htmlOptions, false))
  403. $htmlOptions = self::addClassName('muted', $htmlOptions);
  404. else if (!empty($color))
  405. $htmlOptions = self::addClassName('text-' . $color, $htmlOptions);
  406. return self::tag($tag, $htmlOptions, $text);
  407. }
  408. /**
  409. * Generates a muted text block.
  410. * @param string $text the text.
  411. * @param array $htmlOptions additional HTML attributes.
  412. * @param string $tag the HTML tag.
  413. * @return string the generated text block.
  414. */
  415. public static function muted($text, $htmlOptions = array(), $tag = 'p')
  416. {
  417. $htmlOptions['muted'] = true;
  418. return self::em($text, $htmlOptions, $tag);
  419. }
  420. /**
  421. * Generates a muted span.
  422. * @param string $text the text.
  423. * @param array $htmlOptions additional HTML attributes.
  424. * @param string $tag the HTML tag.
  425. * @return string the generated span.
  426. */
  427. public static function mutedSpan($text, $htmlOptions = array())
  428. {
  429. return self::muted($text, $htmlOptions, 'span');
  430. }
  431. /**
  432. * Generates an abbreviation with a help text.
  433. * @param string $text the abbreviation.
  434. * @param string $word the word the abbreviation is for.
  435. * @param array $htmlOptions additional HTML attributes.
  436. * @return string the generated abbreviation.
  437. */
  438. public static function abbr($text, $word, $htmlOptions = array())
  439. {
  440. if (self::popOption('small', $htmlOptions, false))
  441. $htmlOptions = self::addClassName('initialism', $htmlOptions);
  442. $htmlOptions['title'] = $word;
  443. return self::tag('abbr', $htmlOptions, $text);
  444. }
  445. /**
  446. * Generates a small abbreviation with a help text.
  447. * @param string $text the abbreviation.
  448. * @param string $word the word the abbreviation is for.
  449. * @param array $htmlOptions additional HTML attributes.
  450. * @return string the generated abbreviation.
  451. */
  452. public static function smallAbbr($text, $word, $htmlOptions = array())
  453. {
  454. $htmlOptions['small'] = true;
  455. return self::abbr($text, $word, $htmlOptions);
  456. }
  457. /**
  458. * Generates an address block.
  459. * @param string $quote the address text.
  460. * @param array $htmlOptions additional HTML attributes.
  461. * @return string the generated block.
  462. */
  463. public static function address($text, $htmlOptions = array())
  464. {
  465. return self::tag('address', $htmlOptions, $text);
  466. }
  467. /**
  468. * Generates a quote.
  469. * @param string $text the quoted text.
  470. * @param array $htmlOptions additional HTML attributes.
  471. * @return string the generated quote.
  472. */
  473. public static function quote($text, $htmlOptions = array())
  474. {
  475. $paragraphOptions = self::popOption('paragraphOptions', $htmlOptions, array());
  476. $source = self::popOption('source', $htmlOptions);
  477. $sourceOptions = self::popOption('sourceOptions', $htmlOptions, array());
  478. $cite = self::popOption('cite', $htmlOptions);
  479. $citeOptions = self::popOption('citeOptions', $htmlOptions, array());
  480. $cite = isset($cite) ? self::tag('cite', $citeOptions, $cite) : '';
  481. $source = isset($source) ? self::tag('small', $sourceOptions, $source . ' ' . $cite) : '';
  482. $text = self::tag('p', $paragraphOptions, $text) . $source;
  483. return self::tag('blockquote', $htmlOptions, $text);
  484. }
  485. /**
  486. * Generates a help text.
  487. * @param string $text the help text.
  488. * @param array $htmlOptions additional HTML attributes.
  489. * @return string the generated text.
  490. */
  491. public static function help($text, $htmlOptions = array())
  492. {
  493. $htmlOptions = self::addClassName('help-inline', $htmlOptions);
  494. return self::tag('span', $htmlOptions, $text);
  495. }
  496. /**
  497. * Generates a help block.
  498. * @param string $text the help text.
  499. * @param array $htmlOptions additional HTML attributes.
  500. * @return string the generated block.
  501. */
  502. public static function helpBlock($text, $htmlOptions = array())
  503. {
  504. $htmlOptions = self::addClassName('help-block', $htmlOptions);
  505. return self::tag('p', $htmlOptions, $text);
  506. }
  507. // Code
  508. // http://twitter.github.com/bootstrap/base-css.html#code
  509. // --------------------------------------------------
  510. /**
  511. * Generates inline code.
  512. * @param string $code the code.
  513. * @param array $htmlOptions additional HTML attributes.
  514. * @return string the generated code.
  515. */
  516. public static function code($code, $htmlOptions = array())
  517. {
  518. return self::tag('code', $htmlOptions, $code);
  519. }
  520. /**
  521. * Generates a code block.
  522. * @param string $code the code.
  523. * @param array $htmlOptions additional HTML attributes.
  524. * @return string the generated block.
  525. */
  526. public static function codeBlock($code, $htmlOptions = array())
  527. {
  528. return self::tag('pre', $htmlOptions, $code);
  529. }
  530. /**
  531. * Generates an HTML element.
  532. * @param string $tag the tag name.
  533. * @param array $htmlOptions the element attributes.
  534. * @param mixed $content the content to be enclosed between open and close element tags.
  535. * @param boolean $closeTag whether to generate the close tag.
  536. * @return string the generated HTML element tag.
  537. */
  538. public static function tag($tag, $htmlOptions = array(), $content = false, $closeTag = true)
  539. {
  540. $textAlign = self::popOption('textAlign', $htmlOptions);
  541. if (!empty($textAlign))
  542. $htmlOptions = self::addClassName('text-' . $textAlign, $htmlOptions);
  543. $pull = self::popOption('pull', $htmlOptions);
  544. if (!empty($pull))
  545. $htmlOptions = self::addClassName('pull-' . $pull, $htmlOptions);
  546. self::addSpanClass($htmlOptions);
  547. return CHtml::tag($tag, $htmlOptions, $content, $closeTag);
  548. }
  549. /**
  550. * Generates an open HTML element.
  551. * @param string $tag the tag name.
  552. * @param array $htmlOptions the element attributes.
  553. * @return string the generated HTML element tag.
  554. */
  555. public static function openTag($tag, $htmlOptions = array())
  556. {
  557. return self::tag($tag, $htmlOptions);
  558. }
  559. // Tables
  560. // http://twitter.github.com/bootstrap/base-css.html#forms
  561. // --------------------------------------------------
  562. // todo: create table methods here.
  563. // Forms
  564. // http://twitter.github.com/bootstrap/base-css.html#tables
  565. // --------------------------------------------------
  566. /**
  567. * Generates a form tag.
  568. * @param string $layout the form layout.
  569. * @param string $action the form action URL.
  570. * @param string $method form method (e.g. post, get).
  571. * @param array $htmlOptions additional HTML attributes.
  572. * @return string the generated tag.
  573. */
  574. public static function formTb($layout = self::FORM_LAYOUT_VERTICAL, $action = '', $method = 'post', $htmlOptions = array())
  575. {
  576. return self::beginFormTb($layout, $action, $method, $htmlOptions);
  577. }
  578. /**
  579. * Generates an open form tag.
  580. * @param string $layout the form layout.
  581. * @param string $action the form action URL.
  582. * @param string $method form method (e.g. post, get).
  583. * @param array $htmlOptions additional HTML attributes.
  584. * @return string the generated tag.
  585. */
  586. public static function beginFormTb($layout = self::FORM_LAYOUT_VERTICAL, $action = '', $method = 'post', $htmlOptions = array())
  587. {
  588. $htmlOptions = self::addClassName('form-' . $layout, $htmlOptions);
  589. return CHtml::beginForm($action, $method, $htmlOptions);
  590. }
  591. /**
  592. * Generates a stateful form tag.
  593. * @param mixed $action the form action URL.
  594. * @param string $method form method (e.g. post, get).
  595. * @param array $htmlOptions additional HTML attributes.
  596. * @return string the generated form tag.
  597. */
  598. public static function statefulFormTb($layout = self::FORM_LAYOUT_VERTICAL, $action = '', $method = 'post', $htmlOptions = array())
  599. {
  600. return self::formTb($layout, $action, $method, $htmlOptions)
  601. . self::tag('div', array('style' => 'display:none'), CHtml::pageStateField(''));
  602. }
  603. /**
  604. * Generates a text field input.
  605. * @param string $name the input name.
  606. * @param string $value the input value.
  607. * @param array $htmlOptions additional HTML attributes.
  608. * @return string the generated input field.
  609. * @see TbHtml::textInputField
  610. */
  611. public static function textField($name, $value = '', $htmlOptions = array())
  612. {
  613. return self::textInputField('text', $name, $value, $htmlOptions);
  614. }
  615. /**
  616. * Generates a password field input.
  617. * @param string $name the input name.
  618. * @param string $value the input value.
  619. * @param array $htmlOptions additional HTML attributes.
  620. * @return string the generated input field.
  621. * @see TbHtml::textInputField
  622. */
  623. public static function passwordField($name, $value = '', $htmlOptions = array())
  624. {
  625. return self::textInputField('password', $name, $value, $htmlOptions);
  626. }
  627. /**
  628. * Generates an url field input.
  629. * @param string $name the input name.
  630. * @param string $value the input value.
  631. * @param array $htmlOptions additional HTML attributes.
  632. * @return string the generated input field.
  633. * @see TbHtml::textInputField
  634. */
  635. public static function urlField($name, $value = '', $htmlOptions = array())
  636. {
  637. return self::textInputField('url', $name, $value, $htmlOptions);
  638. }
  639. /**
  640. * Generates an email field input.
  641. * @param string $name the input name.
  642. * @param string $value the input value.
  643. * @param array $htmlOptions additional HTML attributes.
  644. * @return string the generated input field.
  645. * @see TbHtml::textInputField
  646. */
  647. public static function emailField($name, $value = '', $htmlOptions = array())
  648. {
  649. return self::textInputField('email', $name, $value, $htmlOptions);
  650. }
  651. /**
  652. * Generates a number field input.
  653. * @param string $name the input name.
  654. * @param string $value the input value.
  655. * @param array $htmlOptions additional HTML attributes.
  656. * @return string the generated input field.
  657. * @see TbHtml::textInputField
  658. */
  659. public static function numberField($name, $value = '', $htmlOptions = array())
  660. {
  661. return self::textInputField('number', $name, $value, $htmlOptions);
  662. }
  663. /**
  664. * Generates a range field input.
  665. * @param string $name the input name.
  666. * @param string $value the input value.
  667. * @param array $htmlOptions additional HTML attributes.
  668. * @return string the generated input field.
  669. * @see TbHtml::textInputField
  670. */
  671. public static function rangeField($name, $value = '', $htmlOptions = array())
  672. {
  673. return self::textInputField('range', $name, $value, $htmlOptions);
  674. }
  675. /**
  676. * Generates a date field input.
  677. * @param string $name the input name.
  678. * @param string $value the input value.
  679. * @param array $htmlOptions additional HTML attributes.
  680. * @return string the generated input field.
  681. * @see TbHtml::textInputField
  682. */
  683. public static function dateField($name, $value = '', $htmlOptions = array())
  684. {
  685. return self::textInputField('date', $name, $value, $htmlOptions);
  686. }
  687. /**
  688. * Generates a text area input.
  689. * @param string $name the input name.
  690. * @param string $value the input value.
  691. * @param array $htmlOptions additional HTML attributes.
  692. * @return string the generated text area.
  693. */
  694. public static function textArea($name, $value = '', $htmlOptions = array())
  695. {
  696. $htmlOptions = self::normalizeInputOptions($htmlOptions);
  697. return CHtml::textArea($name, $value, $htmlOptions);
  698. }
  699. /**
  700. * Generates a radio button.
  701. * @param string $name the input name.
  702. * @param boolean $checked whether the radio button is checked.
  703. * @param array $htmlOptions additional HTML attributes.
  704. * @return string the generated radio button.
  705. */
  706. public static function radioButton($name, $checked = false, $htmlOptions = array())
  707. {
  708. $label = self::popOption('label', $htmlOptions, false);
  709. $labelOptions = self::popOption('labelOptions', $htmlOptions, array());
  710. $labelOptions = self::addClassName('radio', $labelOptions);
  711. $radioButton = CHtml::radioButton($name, $checked, $htmlOptions);
  712. return $label !== false ? self::tag('label', $labelOptions, $radioButton . $label) : $radioButton;
  713. }
  714. /**
  715. * Generates a check box.
  716. * @param string $name the input name.
  717. * @param boolean $checked whether the check box is checked.
  718. * @param array $htmlOptions additional HTML attributes.
  719. * @return string the generated check box.
  720. */
  721. public static function checkBox($name, $checked = false, $htmlOptions = array())
  722. {
  723. $label = self::popOption('label', $htmlOptions, false);
  724. $labelOptions = self::popOption('labelOptions', $htmlOptions, array());
  725. $labelOptions = self::addClassName('checkbox', $labelOptions);
  726. $checkBox = CHtml::checkBox($name, $checked, $htmlOptions);
  727. return $label !== false ? self::tag('label', $labelOptions, $checkBox . $label) : $checkBox;
  728. }
  729. /**
  730. * Generates a drop down list.
  731. * @param string $name the input name.
  732. * @param string $select the selected value.
  733. * @param array $data data for generating the list options (value=>display).
  734. * @return string the generated drop down list.
  735. */
  736. public static function dropDownList($name, $select, $data, $htmlOptions = array())
  737. {
  738. $htmlOptions = self::normalizeInputOptions($htmlOptions);
  739. return CHtml::dropDownList($name, $select, $data, $htmlOptions);
  740. }
  741. /**
  742. * Generates a list box.
  743. * @param string $name the input name.
  744. * @param mixed $select the selected value(s).
  745. * @param array $data data for generating the list options (value=>display).
  746. * @param array $htmlOptions additional HTML attributes.
  747. * @return string the generated list box
  748. */
  749. public static function listBox($name, $select, $data, $htmlOptions = array())
  750. {
  751. $htmlOptions = self::defaultOption('size', 4, $htmlOptions);
  752. if (isset($htmlOptions['multiple']))
  753. {
  754. if (substr($name, -2) !== '[]')
  755. $name .= '[]';
  756. }
  757. return self::dropDownList($name, $select, $data, $htmlOptions);
  758. }
  759. /**
  760. * Generates a radio button list.
  761. * @param string $name name of the radio button list.
  762. * @param mixed $select selection of the radio buttons.
  763. * @param array $data $data value-label pairs used to generate the radio button list.
  764. * @param array $htmlOptions additional HTML attributes.
  765. * @return string the generated list.
  766. */
  767. public static function radioButtonList($name, $select, $data, $htmlOptions = array())
  768. {
  769. $inline = self::popOption('inline', $htmlOptions, false);
  770. $separator = self::popOption('separator', $htmlOptions, ' ');
  771. $container = self::popOption('container', $htmlOptions);
  772. $containerOptions = self::popOption('containerOptions', $htmlOptions, array());
  773. $labelOptions = self::popOption('labelOptions', $htmlOptions, array());
  774. $labelOptions = self::addClassName('radio', $labelOptions);
  775. if ($inline)
  776. $labelOptions = self::addClassName('inline', $labelOptions);
  777. $items = array();
  778. $baseID = $containerOptions['id'] = self::popOption('baseID', $htmlOptions, CHtml::getIdByName($name));
  779. $id = 0;
  780. foreach ($data as $value => $label)
  781. {
  782. $checked = !strcmp($value, $select);
  783. $htmlOptions['value'] = $value;
  784. $htmlOptions['id'] = $baseID . '_' . $id++;
  785. if ($inline)
  786. {
  787. $htmlOptions['label'] = $label;
  788. $htmlOptions['labelOptions'] = $labelOptions;
  789. $items[] = self::radioButton($name, $checked, $htmlOptions);
  790. }
  791. else
  792. {
  793. $option = self::radioButton($name, $checked, $htmlOptions);
  794. $items[] = self::label($option . ' ' . $label, false, $labelOptions);
  795. }
  796. }
  797. $inputs = implode($separator, $items);
  798. return !empty($container) ? self::tag($container, $containerOptions, $inputs) : $inputs;
  799. }
  800. /**
  801. * Generates an inline radio button list.
  802. * @param string $name name of the radio button list.
  803. * @param mixed $select selection of the radio buttons.
  804. * @param array $data $data value-label pairs used to generate the radio button list.
  805. * @param array $htmlOptions additional HTML attributes.
  806. * @return string the generated list.
  807. */
  808. public static function inlineRadioButtonList($name, $select, $data, $htmlOptions = array())
  809. {
  810. $htmlOptions['inline'] = true;
  811. return self::radioButtonList($name, $select, $data, $htmlOptions);
  812. }
  813. /**
  814. * Generates a check box list.
  815. * @param string $name name of the check box list.
  816. * @param mixed $select selection of the check boxes.
  817. * @param array $data $data value-label pairs used to generate the check box list.
  818. * @param array $htmlOptions additional HTML attributes.
  819. * @return string the generated list.
  820. */
  821. public static function checkBoxList($name, $select, $data, $htmlOptions = array())
  822. {
  823. $inline = self::popOption('inline', $htmlOptions, false);
  824. $separator = self::popOption('separator', $htmlOptions, ' ');
  825. $container = self::popOption('container', $htmlOptions);
  826. $containerOptions = self::popOption('containerOptions', $htmlOptions, array());
  827. if (substr($name, -2) !== '[]')
  828. $name .= '[]';
  829. $checkAllLabel = self::popOption('checkAll', $htmlOptions);
  830. $checkAllLast = self::popOption('checkAllLast', $htmlOptions);
  831. $labelOptions = self::popOption('labelOptions', $htmlOptions, array());
  832. $labelOptions = self::addClassName('checkbox', $labelOptions);
  833. if ($inline)
  834. $labelOptions = self::addClassName('inline', $labelOptions);
  835. $items = array();
  836. $baseID = $containerOptions['id'] = self::popOption('baseID', $htmlOptions, CHtml::getIdByName($name));
  837. $id = 0;
  838. $checkAll = true;
  839. foreach ($data as $value => $label)
  840. {
  841. $checked = !is_array($select) && !strcmp($value, $select) || is_array($select) && in_array($value, $select);
  842. $checkAll = $checkAll && $checked;
  843. $htmlOptions['value'] = $value;
  844. $htmlOptions['id'] = $baseID . '_' . $id++;
  845. if ($inline)
  846. {
  847. $htmlOptions['label'] = $label;
  848. $htmlOptions['labelOptions'] = $labelOptions;
  849. $items[] = self::checkBox($name, $checked, $htmlOptions);
  850. }
  851. else
  852. {
  853. $option = self::checkBox($name, $checked, $htmlOptions);
  854. $items[] = self::label($option . ' ' . $label, false, $labelOptions);
  855. }
  856. }
  857. if (isset($checkAllLabel))
  858. {
  859. $htmlOptions['value'] = 1;
  860. $htmlOptions['id'] = $id = $baseID . '_all';
  861. $option = self::checkBox($id, $checkAll, $htmlOptions);
  862. $label = self::label($checkAllLabel, '', $labelOptions);
  863. $item = self::label($option . ' ' . $label, '', $labelOptions);
  864. if ($checkAllLast)
  865. $items[] = $item;
  866. else
  867. array_unshift($items, $item);
  868. $name = strtr($name, array('[' => '\\[', ']' => '\\]'));
  869. $js = <<<EOD
  870. jQuery('#$id').click(function() {
  871. jQuery("input[name='$name']").prop('checked', this.checked);
  872. });
  873. jQuery("input[name='$name']").click(function() {
  874. jQuery('#$id').prop('checked', !jQuery("input[name='$name']:not(:checked)").length);
  875. });
  876. jQuery('#$id').prop('checked', !jQuery("input[name='$name']:not(:checked)").length);
  877. EOD;
  878. $cs = Yii::app()->getClientScript();
  879. $cs->registerCoreScript('jquery');
  880. $cs->registerScript($id, $js);
  881. }
  882. $inputs = implode($separator, $items);
  883. return !empty($container) ? self::tag($container, $containerOptions, $inputs) : $inputs;
  884. }
  885. /**
  886. * Generates an inline check box list.
  887. * @param string $name name of the check box list.
  888. * @param mixed $select selection of the check boxes.
  889. * @param array $data $data value-label pairs used to generate the check box list.
  890. * @param array $htmlOptions additional HTML attributes.
  891. * @return string the generated list.
  892. */
  893. public static function inlineCheckBoxList($name, $select, $data, $htmlOptions = array())
  894. {
  895. $htmlOptions['inline'] = true;
  896. return self::checkBoxList($name, $select, $data, $htmlOptions);
  897. }
  898. /**
  899. * Generates an uneditable input.
  900. * @param string $value the value.
  901. * @param array $htmlOptions additional HTML attributes.
  902. * @return string the generated input.
  903. */
  904. public static function uneditableField($value = '', $htmlOptions = array())
  905. {
  906. $htmlOptions = self::addClassName('uneditable-input', $htmlOptions);
  907. $htmlOptions = self::normalizeInputOptions($htmlOptions);
  908. return self::tag('span', $htmlOptions, $value);
  909. }
  910. /**
  911. * Generates a search input.
  912. * @param string $name the input name.
  913. * @param string $value the input value.
  914. * @param array $htmlOptions additional HTML attributes.
  915. * @return string the generated input.
  916. */
  917. public static function searchField($name, $value = '', $htmlOptions = array())
  918. {
  919. $htmlOptions = self::addClassName('search-query', $htmlOptions);
  920. return self::textField($name, $value, $htmlOptions);
  921. }
  922. /**
  923. * Generates a control group with a text field.
  924. * @param string $name the input name.
  925. * @param string $value the input value.
  926. * @param array $htmlOptions additional HTML attributes.
  927. * @return string the generated control group.
  928. * @see TbHtml::controlGroup
  929. */
  930. public static function textFieldControlGroup($name, $value = '', $htmlOptions = array())
  931. {
  932. return self::controlGroup(self::INPUT_TYPE_TEXT, $name, $value, $htmlOptions);
  933. }
  934. /**
  935. * Generates a control group with a password field.
  936. * @param string $name the input name.
  937. * @param string $value the input value.
  938. * @param array $htmlOptions additional HTML attributes.
  939. * @return string the generated control group.
  940. * @see TbHtml::textInputField
  941. */
  942. public static function passwordFieldControlGroup($name, $value = '', $htmlOptions = array())
  943. {
  944. return self::controlGroup(self::INPUT_TYPE_PASSWORD, $name, $value, $htmlOptions);
  945. }
  946. /**
  947. * Generates a control group with an url field.
  948. * @param string $name the input name.
  949. * @param string $value the input value.
  950. * @param array $htmlOptions additional HTML attributes.
  951. * @return string the generated control group.
  952. * @see TbHtml::controlGroup
  953. */
  954. public static function urlFieldControlGroup($name, $value = '', $htmlOptions = array())
  955. {
  956. return self::controlGroup(self::INPUT_TYPE_URL, $name, $value, $htmlOptions);
  957. }
  958. /**
  959. * Generates a control group with an email field.
  960. * @param string $name the input name.
  961. * @param string $value the input value.
  962. * @param array $htmlOptions additional HTML attributes.
  963. * @return string the generated control group.
  964. * @see TbHtml::controlGroup
  965. */
  966. public static function emailFieldControlGroup($name, $value = '', $htmlOptions = array())
  967. {
  968. return self::controlGroup(self::INPUT_TYPE_EMAIL, $name, $value, $htmlOptions);
  969. }
  970. /**
  971. * Generates a control group with a number field.
  972. * @param string $name the input name.
  973. * @param string $value the input value.
  974. * @param array $htmlOptions additional HTML attributes.
  975. * @return string the generated control group.
  976. * @see TbHtml::textInputField
  977. */
  978. public static function numberFieldControlGroup($name, $value = '', $htmlOptions = array())
  979. {
  980. return self::controlGroup(self::INPUT_TYPE_NUMBER, $name, $value, $htmlOptions);
  981. }
  982. /**
  983. * Generates a control group with a range field.
  984. * @param string $name the input name
  985. * @param string $value the input value
  986. * @param array $htmlOptions additional HTML attributes.
  987. * @return string the generated control group.
  988. * @see TbHtml::controlGroup
  989. */
  990. public static function rangeFieldControlGroup($name, $value = '', $htmlOptions = array())
  991. {
  992. return self::controlGroup(self::INPUT_TYPE_RANGE, $name, $value, $htmlOptions);
  993. }
  994. /**
  995. * Generates a control group with a date field.
  996. * @param string $name the input name.
  997. * @param string $value the input value.
  998. * @param array $htmlOptions additional HTML attributes.
  999. * @return string the generated control group.
  1000. * @see TbHtml::controlGroup
  1001. */
  1002. public static function dateFieldControlGroup($name, $value = '', $htmlOptions = array())
  1003. {
  1004. return self::controlGroup(self::INPUT_TYPE_DATE, $name, $value, $htmlOptions);
  1005. }
  1006. /**
  1007. * Generates a control group with a text area.
  1008. * @param string $name the input name.
  1009. * @param string $value the input value.
  1010. * @param array $htmlOptions additional HTML attributes.
  1011. * @return string the generated control group.
  1012. * @see TbHtml::controlGroup
  1013. */
  1014. public static function textAreaControlGroup($name, $value = '', $htmlOptions = array())
  1015. {
  1016. return self::controlGroup(self::INPUT_TYPE_TEXTAREA, $name, $value, $htmlOptions);
  1017. }
  1018. /**
  1019. * Generates a control group with a file field.
  1020. * @param string $name the input name.
  1021. * @param string $value the input value.
  1022. * @param array $htmlOptions additional HTML attributes.
  1023. * @return string the generated control group.
  1024. * @see TbHtml::controlGroup
  1025. */
  1026. public static function fileFieldControlGroup($name, $value = '', $htmlOptions = array())
  1027. {
  1028. return self::controlGroup(self::INPUT_TYPE_FILE, $name, $value, $htmlOptions);
  1029. }
  1030. /**
  1031. * Generates a control group with a radio button.
  1032. * @param string $name the input name.
  1033. * @param string $checked whether the radio button is checked.
  1034. * @param array $htmlOptions additional HTML attributes.
  1035. * @return string the generated control group.
  1036. * @see TbHtml::controlGroup
  1037. */
  1038. public static function radioButtonControlGroup($name, $checked = false, $htmlOptions = array())
  1039. {
  1040. return self::controlGroup(self::INPUT_TYPE_RADIOBUTTON, $name, $checked, $htmlOptions);
  1041. }
  1042. /**
  1043. * Generates a control group with a check box.
  1044. * @param string $name the input name.
  1045. * @param string $checked whether the check box is checked.
  1046. * @param array $htmlOptions additional HTML attributes.
  1047. * @return string the generated control group.
  1048. * @see TbHtml::controlGroup
  1049. */
  1050. public static function checkBoxControlGroup($name, $checked = false, $htmlOptions = array())
  1051. {
  1052. return self::controlGroup(self::INPUT_TYPE_CHECKBOX, $name, $checked, $htmlOptions);
  1053. }
  1054. /**
  1055. * Generates a control group with a drop down list.
  1056. * @param string $name the input name.
  1057. * @param string $select the selected value.
  1058. * @param array $data data for generating the list options (value=>display).
  1059. * @param array $htmlOptions additional HTML attributes.
  1060. * @return string the generated control group.
  1061. * @see TbHtml::controlGroup
  1062. */
  1063. public static function dropDownListControlGroup($name, $select = '', $data = array(), $htmlOptions = array())
  1064. {
  1065. return self::controlGroup(self::INPUT_TYPE_DROPDOWNLIST, $name, $select, $htmlOptions, $data);
  1066. }
  1067. /**
  1068. * Generates a control group with a list box.
  1069. * @param string $name the input name.
  1070. * @param string $select the selected value.
  1071. * @param array $data data for generating the list options (value=>display).
  1072. * @param array $htmlOptions additional HTML attributes.
  1073. * @return string the generated control group.
  1074. * @see TbHtml::controlGroup
  1075. */
  1076. public static function listBoxControlGroup($name, $select = '', $data = array(), $htmlOptions = array())
  1077. {
  1078. return self::controlGroup(self::INPUT_TYPE_LISTBOX, $name, $select, $htmlOptions, $data);
  1079. }
  1080. /**
  1081. * Generates a control group with a radio button list.
  1082. * @param string $name the input name.
  1083. * @param string $select the selected value.
  1084. * @param array $data data for generating the list options (value=>display).
  1085. * @param array $htmlOptions additional HTML attributes.
  1086. * @return string the generated control group.
  1087. * @see TbHtml::controlGroup
  1088. */
  1089. public static function radioButtonListControlGroup($name, $select = '', $data = array(), $htmlOptions = array())
  1090. {
  1091. return self::controlGroup(self::INPUT_TYPE_RADIOBUTTONLIST, $name, $select, $htmlOptions, $data);
  1092. }
  1093. /**
  1094. * Generates a control group with an inline radio button list.
  1095. * @param string $name the input name.
  1096. * @param string $select the selected value.
  1097. * @param array $data data for generating the list options (value=>display).
  1098. * @param array $htmlOptions additional HTML attributes.
  1099. * @return string the generated control group.
  1100. * @see TbHtml::controlGroup
  1101. */
  1102. public static function inlineRadioButtonListControlGroup($name, $select = '', $data = array(), $htmlOptions = array())
  1103. {
  1104. return self::controlGroup(self::INPUT_TYPE_INLINERADIOBUTTONLIST, $name, $select, $htmlOptions, $data);
  1105. }
  1106. /**
  1107. * Generates a control group with a check box list.
  1108. * @param string $name the input name.
  1109. * @param string $select the selected value.
  1110. * @param array $data data for generating the list options (value=>display).
  1111. * @param array $htmlOptions additional HTML attributes.
  1112. * @return string the generated control group.
  1113. * @see TbHtml::controlGroup
  1114. */
  1115. public static function checkBoxListControlGroup($name, $select = '', $data = array(), $htmlOptions = array())
  1116. {
  1117. return self::controlGroup(self::INPUT_TYPE_CHECKBOXLIST, $name, $select, $htmlOptions, $data);
  1118. }
  1119. /**
  1120. * Generates a control group with an inline check box list.
  1121. * @param string $name the input name.
  1122. * @param string $select the selected value.
  1123. * @param array $data data for generating the list options (value=>display).
  1124. * @param array $htmlOptions additional HTML attributes.
  1125. * @return string the generated control group.
  1126. * @see TbHtml::controlGroup
  1127. */
  1128. public static function inlineCheckBoxListControlGroup($name, $select = '', $data = array(), $htmlOptions = array())
  1129. {
  1130. return self::controlGroup(self::INPUT_TYPE_INLINECHECKBOXLIST, $name, $select, $htmlOptions, $data);
  1131. }
  1132. /**
  1133. * Generates a control group with an uneditable field.
  1134. * @param string $select the input value.
  1135. * @param array $htmlOptions additional HTML attributes.
  1136. * @return string the generated control group.
  1137. * @see TbHtml::controlGroup
  1138. */
  1139. public static function uneditableFieldControlGroup($value = '', $htmlOptions = array())
  1140. {
  1141. return self::controlGroup(self::INPUT_TYPE_UNEDITABLE, '', $value, $htmlOptions);
  1142. }
  1143. /**
  1144. * Generates a control group with a search field.
  1145. * @param string $name the input name.
  1146. * @param string $select the input value.
  1147. * @param array $htmlOptions additional HTML attributes.
  1148. * @return string the generated control group.
  1149. * @see TbHtml::controlGroup
  1150. */
  1151. public static function searchFieldControlGroup($name, $value = '', $htmlOptions = array())
  1152. {
  1153. return self::controlGroup(self::INPUT_TYPE_SEARCH, $name, $value, $htmlOptions);
  1154. }
  1155. /**
  1156. * Generates a form control group.
  1157. * @param string $type the input type.
  1158. * @param string $name the input name.
  1159. * @param string $value the input value.
  1160. * @param array $htmlOptions additional HTML attributes.
  1161. * @param array $data data for multiple select inputs.
  1162. * @return string the generated control group.
  1163. */
  1164. public static function controlGroup($type, $name, $value, $htmlOptions = array(), $data = array())
  1165. {
  1166. $label = self::popOption('label', $htmlOptions, false);
  1167. $color = self::popOption('color', $htmlOptions);
  1168. $controlGroupOptions = self::popOption('groupOptions', $htmlOptions, array());
  1169. $labelOptions = self::popOption('labelOptions', $htmlOptions, array());
  1170. $controlOptions = self::popOption('controlOptions', $htmlOptions, array());
  1171. if (in_array($type, array(self::INPUT_TYPE_CHECKBOX, self::INPUT_TYPE_RADIOBUTTON)))
  1172. {
  1173. $htmlOptions['label'] = $label;
  1174. $htmlOptions['labelOptions'] = $labelOptions;
  1175. $label = false;
  1176. }
  1177. $help = self::popOption('help', $htmlOptions, '');
  1178. $helpOptions = self::popOption('helpOptions', $htmlOptions, array());
  1179. if (!empty($help))
  1180. $help = self::inputHelp($help, $helpOptions);
  1181. $input = static::createInput($type, $name, $value, $htmlOptions, $data);
  1182. $controlGroupOptions = self::addClassName('control-group', $controlGroupOptions);
  1183. if (!empty($color))
  1184. $controlGroupOptions = self::addClassName($color, $controlGroupOptions);
  1185. $labelOptions = self::addClassName('control-label', $labelOptions);
  1186. ob_start();
  1187. echo self::openTag('div', $controlGroupOptions);
  1188. if ($label !== false)
  1189. echo CHtml::label($label, $name, $labelOptions);
  1190. echo self::controls($input . $help, $controlOptions);
  1191. echo '</div>';
  1192. return ob_get_clean();
  1193. }
  1194. /**
  1195. * Creates a form input of the given type.
  1196. * @param string $type the input type.
  1197. * @param string $name the input name.
  1198. * @param string $value the input value.
  1199. * @param array $htmlOptions additional HTML attributes.
  1200. * @param array $data data for multiple select inputs.
  1201. * @return string the input.
  1202. * @throws CException if the input type is invalid.
  1203. */
  1204. protected static function createInput($type, $name, $value, $htmlOptions = array(), $data = array())
  1205. {
  1206. switch ($type)
  1207. {
  1208. case self::INPUT_TYPE_TEXT:
  1209. return self::textField($name, $value, $htmlOptions);
  1210. case self::INPUT_TYPE_PASSWORD:
  1211. return self::passwordField($name, $value, $htmlOptions);
  1212. case self::INPUT_TYPE_URL:
  1213. return self::urlField($name, $value, $htmlOptions);
  1214. case self::INPUT_TYPE_EMAIL:
  1215. return self::emailField($name, $value, $htmlOptions);
  1216. case self::INPUT_TYPE_NUMBER:
  1217. return self::numberField($name, $value, $htmlOptions);
  1218. case self::INPUT_TYPE_RANGE:
  1219. return self::rangeField($name, $value, $htmlOptions);
  1220. case self::INPUT_TYPE_DATE:
  1221. return self::dateField($name, $value, $htmlOptions);
  1222. case self::INPUT_TYPE_TEXTAREA:
  1223. return self::textArea($name, $value, $htmlOptions);
  1224. case self::INPUT_TYPE_FILE:
  1225. return self::fileField($name, $value, $htmlOptions);
  1226. case self::INPUT_TYPE_RADIOBUTTON:
  1227. return self::radioButton($name, $value, $htmlOptions);
  1228. case self::INPUT_TYPE_CHECKBOX:
  1229. return self::checkBox($name, $value, $htmlOptions);
  1230. case self::INPUT_TYPE_DROPDOWNLIST:
  1231. return self::dropDownList($name, $value, $data, $htmlOptions);
  1232. case self::INPUT_TYPE_LISTBOX:
  1233. return self::listBox($name, $value, $data, $htmlOptions);
  1234. case self::INPUT_TYPE_CHECKBOXLIST:
  1235. return self::checkBoxList($name, $value, $data, $htmlOptions);
  1236. case self::INPUT_TYPE_INLINECHECKBOXLIST:
  1237. return self::inlineCheckBoxList($name, $value, $data, $htmlOptions);
  1238. case self::INPUT_TYPE_RADIOBUTTONLIST:
  1239. return self::radioButtonList($name, $value, $data, $htmlOptions);
  1240. case self::INPUT_TYPE_INLINERADIOBUTTONLIST:
  1241. return self::inlineRadioButtonList($name, $value, $data, $htmlOptions);
  1242. case self::INPUT_TYPE_UNEDITABLE:
  1243. return self::uneditableField($value, $htmlOptions);
  1244. case self::INPUT_TYPE_SEARCH:
  1245. return self::searchField($name, $value, $htmlOptions);
  1246. default:
  1247. throw new CException('Invalid input type "' . $type . '".');
  1248. }
  1249. }
  1250. /**
  1251. * Generates an input HTML tag.
  1252. * This method generates an input HTML tag based on the given input name and value.
  1253. * @param string $type the input type.
  1254. * @param string $name the input name.
  1255. * @param string $value the input value.
  1256. * @param array $htmlOptions additional HTML attributes.
  1257. * @return string the generated input tag.
  1258. */
  1259. protected static function textInputField($type, $name, $value, $htmlOptions)
  1260. {
  1261. CHtml::clientChange('change', $htmlOptions);
  1262. $htmlOptions = self::normalizeInputOptions($htmlOptions);
  1263. $addOnClasses = self::getAddOnClasses($htmlOptions);
  1264. $addOnOptions = self::popOption('addOnOptions', $htmlOptions, array());
  1265. $addOnOptions = self::addClassName($addOnClasses, $addOnOptions);
  1266. $prepend = self::popOption('prepend', $htmlOptions, '');
  1267. $prependOptions = self::popOption('prependOptions', $htmlOptions, array());
  1268. if (!empty($prepend))
  1269. $prepend = self::inputAddOn($prepend, $prependOptions);
  1270. $append = self::popOption('append', $htmlOptions, '');
  1271. $appendOptions = self::popOption('appendOptions', $htmlOptions, array());
  1272. if (!empty($append))
  1273. $append = self::inputAddOn($append, $appendOptions);
  1274. ob_start();
  1275. if (!empty($addOnClasses))
  1276. echo self::openTag('div', $addOnOptions);
  1277. echo $prepend . CHtml::inputField($type, $name, $value, $htmlOptions) . $append;
  1278. if (!empty($addOnClasses))
  1279. echo '</div>';
  1280. return ob_get_clean();
  1281. }
  1282. /**
  1283. * Generates a text field input for a model attribute.
  1284. * @param CModel $model the data model.
  1285. * @param string $attribute the attribute.
  1286. * @param array $htmlOptions additional HTML attributes.
  1287. * @return string the generated input field.
  1288. * @see TbHtml::activeTextInputField
  1289. */
  1290. public static function activeTextField($model, $attribute, $htmlOptions = array())
  1291. {
  1292. return self::activeTextInputField('text', $model, $attribute, $htmlOptions);
  1293. }
  1294. /**
  1295. * Generates a password field input for a model attribute.
  1296. * @param CModel $model the data model.
  1297. * @param string $attribute the attribute.
  1298. * @param array $htmlOptions additional HTML attributes.
  1299. * @return string the generated input field.
  1300. * @see TbHtml::activeTextInputField
  1301. */
  1302. public static function activePasswordField($model, $attribute, $htmlOptions = array())
  1303. {
  1304. return self::activeTextInputField('password', $model, $attribute, $htmlOptions);
  1305. }
  1306. /**
  1307. * Generates an url field input for a model attribute.
  1308. * @param CModel $model the data model.
  1309. * @param string $attribute the attribute.
  1310. * @param array $htmlOptions additional HTML attributes.
  1311. * @return string the generated input field.
  1312. * @see TbHtml::activeTextInputField
  1313. */
  1314. public static function activeUrlField($model, $attribute, $htmlOptions = array())
  1315. {
  1316. return self::activeTextInputField('url', $model, $attribute, $htmlOptions);
  1317. }
  1318. /**
  1319. * Generates an email field input for a model attribute.
  1320. * @param CModel $model the data model.
  1321. * @param string $attribute the attribute.
  1322. * @param array $htmlOptions additional HTML attributes.
  1323. * @return string the generated input field.
  1324. * @see TbHtml::activeTextInputField
  1325. */
  1326. public static function activeEmailField($model, $attribute, $htmlOptions = array())
  1327. {
  1328. return self::activeTextInputField('email', $model, $attribute, $htmlOptions);
  1329. }
  1330. /**
  1331. * Generates a number field input for a model attribute.
  1332. * @param CModel $model the data model.
  1333. * @param string $attribute the attribute.
  1334. * @param array $htmlOptions additional HTML attributes.
  1335. * @return string the generated input field.
  1336. * @see TbHtml::activeTextInputField
  1337. */
  1338. public static function activeNumberField($model, $attribute, $htmlOptions = array())
  1339. {
  1340. return self::activeTextInputField('number', $model, $attribute, $htmlOptions);
  1341. }
  1342. /**
  1343. * Generates a range field input for a model attribute.
  1344. * @param CModel $model the data model.
  1345. * @param string $attribute the attribute.
  1346. * @param array $htmlOptions additional HTML attributes.
  1347. * @return string the generated input field.
  1348. * @see TbHtml::activeTextInputField
  1349. */
  1350. public static function activeRangeField($model, $attribute, $htmlOptions = array())
  1351. {
  1352. return self::activeTextInputField('range', $model, $attribute, $htmlOptions);
  1353. }
  1354. /**
  1355. * Generates a date field input for a model attribute.
  1356. * @param CModel $model the data model.
  1357. * @param string $attribute the attribute.
  1358. * @param array $htmlOptions additional HTML attributes.
  1359. * @return string the generated input field.
  1360. * @see TbHtml::activeTextInputField
  1361. */
  1362. public static function activeDateField($model, $attribute, $htmlOptions = array())
  1363. {
  1364. return self::activeTextInputField('date', $model, $attribute, $htmlOptions);
  1365. }
  1366. /**
  1367. * Generates a text area input for a model attribute.
  1368. * @param CModel $model the data model.
  1369. * @param string $attribute the attribute.
  1370. * @param array $htmlOptions additional HTML attributes.
  1371. * @return string the generated text area.
  1372. */
  1373. public static function activeTextArea($model, $attribute, $htmlOptions = array())
  1374. {
  1375. $htmlOptions = self::normalizeInputOptions($htmlOptions);
  1376. return CHtml::activeTextArea($model, $attribute, $htmlOptions);
  1377. }
  1378. /**
  1379. * Generates a radio button for a model attribute.
  1380. * @param CModel $model the data model.
  1381. * @param string $attribute the attribute.
  1382. * @param array $htmlOptions additional HTML attributes.
  1383. * @return string the generated radio button.
  1384. */
  1385. public static function activeRadioButton($model, $attribute, $htmlOptions = array())
  1386. {
  1387. $label = self::popOption('label', $htmlOptions, false);
  1388. $labelOptions = self::popOption('labelOptions', $htmlOptions, array());
  1389. $radioButton = CHtml::activeRadioButton($model, $attribute, $htmlOptions);
  1390. $labelOptions = self::addClassName('radio', $labelOptions);
  1391. return $label !== false ? self::tag('label', $labelOptions, $radioButton . $label) : $radioButton;
  1392. }
  1393. /**
  1394. * Generates a check box for a model attribute.
  1395. * @param CModel $model the data model.
  1396. * @param string $attribute the attribute.
  1397. * @param array $htmlOptions additional HTML attributes.
  1398. * @return string the generated check box.
  1399. */
  1400. public static function activeCheckBox($model, $attribute, $htmlOptions = array())
  1401. {
  1402. $label = self::popOption('label', $htmlOptions, false);
  1403. $labelOptions = self::popOption('labelOptions', $htmlOptions, array());
  1404. $radioButton = CHtml::activeCheckBox($model, $attribute, $htmlOptions);
  1405. $labelOptions = self::addClassName('checkbox', $labelOptions);
  1406. return $label !== false ? self::tag('label', $labelOptions, $radioButton . $label) : $radioButton;
  1407. }
  1408. /**
  1409. * Generates a drop down list for a model attribute.
  1410. * @param CModel $model the data model.
  1411. * @param string $attribute the attribute.
  1412. * @param array $data data for generating the list options (value=>display).
  1413. * @return string the generated drop down list.
  1414. */
  1415. public static function activeDropDownList($model, $attribute, $data, $htmlOptions = array())
  1416. {
  1417. $htmlOptions = self::normalizeInputOptions($htmlOptions);
  1418. return CHtml::activeDropDownList($model, $attribute, $data, $htmlOptions);
  1419. }
  1420. /**
  1421. * Generates a list box for a model attribute.
  1422. * @param CModel $model the data model.
  1423. * @param string $attribute the attribute.
  1424. * @param array $data data for generating the list options (value=>display).
  1425. * @param array $htmlOptions additional HTML attributes.
  1426. * @return string the generated list box
  1427. */
  1428. public static function activeListBox($model, $attribute, $data, $htmlOptions = array())
  1429. {
  1430. $htmlOptions = self::defaultOption('size', 4, $htmlOptions);
  1431. return self::activeDropDownList($model, $attribute, $data, $htmlOptions);
  1432. }
  1433. /**
  1434. * Generates a radio button list for a model attribute.
  1435. * @param CModel $model the data model.
  1436. * @param string $attribute the attribute.
  1437. * @param array $data $data value-label pairs used to generate the radio button list.
  1438. * @param array $htmlOptions additional HTML attributes.
  1439. * @return string the generated list.
  1440. */
  1441. public static function activeRadioButtonList($model, $attribute, $data, $htmlOptions = array())
  1442. {
  1443. CHtml::resolveNameID($model, $attribute, $htmlOptions);
  1444. $selection = CHtml::resolveValue($model, $attribute);
  1445. if ($model->hasErrors($attribute))
  1446. CHtml::addErrorCss($htmlOptions);
  1447. $name = self::popOption('name', $htmlOptions);
  1448. $unCheck = self::popOption('uncheckValue', $htmlOptions, '');
  1449. $hiddenOptions = isset($htmlOptions['id']) ? array('id' => CHtml::ID_PREFIX . $htmlOptions['id']) : array('id' => false);
  1450. $hidden = $unCheck !== null ? CHtml::hiddenField($name, $unCheck, $hiddenOptions) : '';
  1451. return $hidden . self::radioButtonList($name, $selection, $data, $htmlOptions);
  1452. }
  1453. /**
  1454. * Generates an inline radio button list for a model attribute.
  1455. * @param CModel $model the data model.
  1456. * @param string $attribute the attribute.
  1457. * @param array $data $data value-label pairs used to generate the radio button list.
  1458. * @param array $htmlOptions additional HTML attributes.
  1459. * @return string the generated list.
  1460. */
  1461. public static function activeInlineRadioButtonList($model, $attribute, $data, $htmlOptions = array())
  1462. {
  1463. $htmlOptions['inline'] = true;
  1464. return self::activeRadioButtonList($model, $attribute, $data, $htmlOptions);
  1465. }
  1466. /**
  1467. * Generates a check box list for a model attribute.
  1468. * @param CModel $model the data model.
  1469. * @param string $attribute the attribute.
  1470. * @param array $data $data value-label pairs used to generate the check box list.
  1471. * @param array $htmlOptions additional HTML attributes.
  1472. * @return string the generated list.
  1473. */
  1474. public static function activeCheckBoxList($model,$attribute,$data,$htmlOptions=array())
  1475. {
  1476. CHtml::resolveNameID($model, $attribute, $htmlOptions);
  1477. $selection = CHtml::resolveValue($model, $attribute);
  1478. if ($model->hasErrors($attribute))
  1479. CHtml::addErrorCss($htmlOptions);
  1480. $name = self::popOption('name', $htmlOptions);
  1481. $unCheck = self::popOption('uncheckValue', $htmlOptions, '');
  1482. $hiddenOptions = isset($htmlOptions['id']) ? array('id' => CHtml::ID_PREFIX . $htmlOptions['id']) : array('id' => false);
  1483. $hidden = $unCheck !== null ? CHtml::hiddenField($name, $unCheck, $hiddenOptions) : '';
  1484. return $hidden . self::checkBoxList($name, $selection, $data, $htmlOptions);
  1485. }
  1486. /**
  1487. * Generates an inline check box list for a model attribute.
  1488. * @param CModel $model the data model.
  1489. * @param string $attribute the attribute.
  1490. * @param array $data $data value-label pairs used to generate the check box list.
  1491. * @param array $htmlOptions additional HTML attributes.
  1492. * @return string the generated list.
  1493. */
  1494. public static function activeInlineCheckBoxList($model, $attribute, $data, $htmlOptions = array())
  1495. {
  1496. $htmlOptions['inline'] = true;
  1497. return self::activeCheckBoxList($model, $attribute, $data, $htmlOptions);
  1498. }
  1499. /**
  1500. * Generates an uneditable input for a model attribute.
  1501. * @param CModel $model the data model.
  1502. * @param string $attribute the attribute.
  1503. * @param array $htmlOptions additional HTML attributes.
  1504. * @return string the generated input.
  1505. */
  1506. public static function activeUneditableField($model, $attribute, $htmlOptions = array())
  1507. {
  1508. CHtml::resolveNameID($model, $attribute, $htmlOptions);
  1509. $value = CHtml::resolveValue($model, $attribute);
  1510. return self::uneditableField($value, $htmlOptions);
  1511. }
  1512. /**
  1513. * Generates a search query input for a model attribute.
  1514. * @param CModel $model the data model.
  1515. * @param string $attribute the attribute.
  1516. * @param array $htmlOptions additional HTML attributes.
  1517. * @return string the generated input.
  1518. */
  1519. public static function activeSearchField($model, $attribute, $htmlOptions = array())
  1520. {
  1521. $htmlOptions = self::addClassName('search-query', $htmlOptions);
  1522. return self::activeTextField($model, $attribute, $htmlOptions);
  1523. }
  1524. /**
  1525. * Generates a control group with a text field for a model attribute.
  1526. * @param CModel $model the data model.
  1527. * @param string $attribute the attribute.
  1528. * @param array $htmlOptions additional HTML attributes.
  1529. * @return string the generated control group.
  1530. * @see TbHtml::activeControlGroup
  1531. */
  1532. public static function activeTextFieldControlGroup($model, $attribute, $htmlOptions = array())
  1533. {
  1534. return self::activeControlGroup(self::INPUT_TYPE_TEXT, $model, $attribute, $htmlOptions);
  1535. }
  1536. /**
  1537. * Generates a control group with a password field for a model attribute.
  1538. * @param CModel $model the data model.
  1539. * @param string $attribute the attribute.
  1540. * @param array $htmlOptions additional HTML attributes.
  1541. * @return string the generated control group.
  1542. * @see TbHtml::activeControlGroup
  1543. */
  1544. public static function activePasswordFieldControlGroup($model, $attribute, $htmlOptions = array())
  1545. {
  1546. return self::activeControlGroup(self::INPUT_TYPE_PASSWORD, $model, $attribute, $htmlOptions);
  1547. }
  1548. /**
  1549. * Generates a control group with a url field for a model attribute.
  1550. * @param CModel $model the data model.
  1551. * @param string $attribute the attribute.
  1552. * @param array $htmlOptions additional HTML attributes.
  1553. * @return string the generated control group.
  1554. * @see TbHtml::activeControlGroup
  1555. */
  1556. public static function activeUrlFieldControlGroup($model, $attribute, $htmlOptions = array())
  1557. {
  1558. return self::activeControlGroup(self::INPUT_TYPE_URL, $model, $attribute, $htmlOptions);
  1559. }
  1560. /**
  1561. * Generates a control group with a email field for a model attribute.
  1562. * @param CModel $model the data model.
  1563. * @param string $attribute the attribute.
  1564. * @param array $htmlOptions additional HTML attributes.
  1565. * @return string the generated control group.
  1566. * @see TbHtml::activeControlGroup
  1567. */
  1568. public static function activeEmailFieldControlGroup($name, $value = '', $htmlOptions = array())
  1569. {
  1570. return self::activeControlGroup(self::INPUT_TYPE_EMAIL, $name, $value, $htmlOptions);
  1571. }
  1572. /**
  1573. * Generates a control group with a number field for a model attribute.
  1574. * @param CModel $model the data model.
  1575. * @param string $attribute the attribute.
  1576. * @param array $htmlOptions additional HTML attributes.
  1577. * @return string the generated control group.
  1578. * @see TbHtml::activeControlGroup
  1579. */
  1580. public static function activeNumberFieldControlGroup($model, $attribute, $htmlOptions = array())
  1581. {
  1582. return self::activeControlGroup(self::INPUT_TYPE_NUMBER, $model, $attribute, $htmlOptions);
  1583. }
  1584. /**
  1585. * Generates a control group with a range field for a model attribute.
  1586. * @param CModel $model the data model.
  1587. * @param string $attribute the attribute.
  1588. * @param array $htmlOptions additional HTML attributes.
  1589. * @return string the generated control group.
  1590. * @see TbHtml::activeControlGroup
  1591. */
  1592. public static function activeRangeFieldControlGroup($name, $value = '', $htmlOptions = array())
  1593. {
  1594. return self::controlGroup(self::INPUT_TYPE_RANGE, $name, $value, $htmlOptions);
  1595. }
  1596. /**
  1597. * Generates a control group with a date field for a model attribute.
  1598. * @param CModel $model the data model.
  1599. * @param string $attribute the attribute.
  1600. * @param array $htmlOptions additional HTML attributes.
  1601. * @return string the generated control group.
  1602. * @see TbHtml::activeControlGroup
  1603. */
  1604. public static function activeDateFieldControlGroup($name, $value = '', $htmlOptions = array())
  1605. {
  1606. return self::activeControlGroup(self::INPUT_TYPE_DATE, $name, $value, $htmlOptions);
  1607. }
  1608. /**
  1609. * Generates a control group with a text area for a model attribute.
  1610. * @param CModel $model the data model.
  1611. * @param string $attribute the attribute.
  1612. * @param array $htmlOptions additional HTML attributes.
  1613. * @return string the generated control group.
  1614. * @see TbHtml::activeControlGroup
  1615. */
  1616. public static function activeTextAreaControlGroup($model, $attribute, $htmlOptions = array())
  1617. {
  1618. return self::activeControlGroup(self::INPUT_TYPE_TEXTAREA, $model, $attribute, $htmlOptions);
  1619. }
  1620. /**
  1621. * Generates a control group with a file field for a model attribute.
  1622. * @param CModel $model the data model.
  1623. * @param string $attribute the attribute.
  1624. * @param array $htmlOptions additional HTML attributes.
  1625. * @return string the generated control group.
  1626. * @see TbHtml::activeControlGroup
  1627. */
  1628. public static function activeFileFieldControlGroup($model, $attribute, $htmlOptions = array())
  1629. {
  1630. return self::activeControlGroup(self::INPUT_TYPE_FILE, $model, $attribute, $htmlOptions);
  1631. }
  1632. /**
  1633. * Generates a control group with a radio button for a model attribute.
  1634. * @param CModel $model the data model.
  1635. * @param string $attribute the attribute.
  1636. * @param array $htmlOptions additional HTML attributes.
  1637. * @return string the generated control group.
  1638. * @see TbHtml::activeControlGroup
  1639. */
  1640. public static function activeRadioButtonControlGroup($model, $attribute, $htmlOptions = array())
  1641. {
  1642. return self::activeControlGroup(self::INPUT_TYPE_RADIOBUTTON, $model, $attribute, $htmlOptions);
  1643. }
  1644. /**
  1645. * Generates a control group with a check box for a model attribute.
  1646. * @param string $name the input name.
  1647. * @param string $checked whether the check box is checked.
  1648. * @param array $htmlOptions additional HTML attributes.
  1649. * @return string the generated control group.
  1650. * @see TbHtml::activeControlGroup
  1651. */
  1652. public static function activeCheckBoxControlGroup($model, $attribute, $htmlOptions = array())
  1653. {
  1654. return self::activeControlGroup(self::INPUT_TYPE_CHECKBOX, $model, $attribute, $htmlOptions);
  1655. }
  1656. /**
  1657. * Generates a control group with a drop down list for a model attribute.
  1658. * @param CModel $model the data model.
  1659. * @param string $attribute the attribute.
  1660. * @param array $data data for generating the list options (value=>display).
  1661. * @param array $htmlOptions additional HTML attributes.
  1662. * @return string the generated control group.
  1663. * @see TbHtml::activeControlGroup
  1664. */
  1665. public static function activeDropDownListControlGroup($model, $attribute, $data = array(), $htmlOptions = array())
  1666. {
  1667. return self::activeControlGroup(self::INPUT_TYPE_DROPDOWNLIST, $model, $attribute, $htmlOptions, $data);
  1668. }
  1669. /**
  1670. * Generates a control group with a list box for a model attribute.
  1671. * @param string $name the input name.
  1672. * @param string $select the selected value.
  1673. * @param array $data data for generating the list options (value=>display).
  1674. * @param array $htmlOptions additional HTML attributes.
  1675. * @return string the generated control group.
  1676. * @see TbHtml::activeControlGroup
  1677. */
  1678. public static function activeListBoxControlGroup($model, $attribute, $data = array(), $htmlOptions = array())
  1679. {
  1680. return self::activeControlGroup(self::INPUT_TYPE_LISTBOX, $model, $attribute, $htmlOptions, $data);
  1681. }
  1682. /**
  1683. * Generates a control group with a radio button list for a model attribute.
  1684. * @param CModel $model the data model.
  1685. * @param string $attribute the attribute.
  1686. * @param array $data data for generating the list options (value=>display).
  1687. * @param array $htmlOptions additional HTML attributes.
  1688. * @return string the generated control group.
  1689. * @see TbHtml::activeControlGroup
  1690. */
  1691. public static function activeRadioButtonListControlGroup($model, $attribute, $data = array(), $htmlOptions = array())
  1692. {
  1693. return self::activeControlGroup(self::INPUT_TYPE_RADIOBUTTONLIST, $model, $attribute, $htmlOptions, $data);
  1694. }
  1695. /**
  1696. * Generates a control group with an inline radio button list for a model attribute.
  1697. * @param string $name the input name.
  1698. * @param string $select the selected value.
  1699. * @param array $data data for generating the list options (value=>display).
  1700. * @param array $htmlOptions additional HTML attributes.
  1701. * @return string the generated control group.
  1702. * @see TbHtml::activeControlGroup
  1703. */
  1704. public static function activeInlineRadioButtonListControlGroup($model, $attribute, $data = array(), $htmlOptions = array())
  1705. {
  1706. return self::activeControlGroup(self::INPUT_TYPE_INLINERADIOBUTTONLIST, $model, $attribute, $htmlOptions, $data);
  1707. }
  1708. /**
  1709. * Generates a control group with a check box list for a model attribute.
  1710. * @param CModel $model the data model.
  1711. * @param string $attribute the attribute.
  1712. * @param array $data data for generating the list options (value=>display).
  1713. * @param array $htmlOptions additional HTML attributes.
  1714. * @return string the generated control group.
  1715. * @see TbHtml::activeControlGroup
  1716. */
  1717. public static function activeCheckBoxListControlGroup($model, $attribute, $data = array(), $htmlOptions = array())
  1718. {
  1719. return self::activeControlGroup(self::INPUT_TYPE_CHECKBOXLIST, $model, $attribute, $htmlOptions, $data);
  1720. }
  1721. /**
  1722. * Generates a control group with an inline check box list for a model attribute.
  1723. * @param CModel $model the data model.
  1724. * @param string $attribute the attribute.
  1725. * @param array $data data for generating the list options (value=>display).
  1726. * @param array $htmlOptions additional HTML attributes.
  1727. * @return string the generated control group.
  1728. * @see TbHtml::activeControlGroup
  1729. */
  1730. public static function activeInlineCheckBoxListControlGroup($model, $attribute, $data = array(), $htmlOptions = array())
  1731. {
  1732. return self::activeControlGroup(self::INPUT_TYPE_INLINECHECKBOXLIST, $model, $attribute, $htmlOptions, $data);
  1733. }
  1734. /**
  1735. * Generates a control group with a uneditable field for a model attribute.
  1736. * @param CModel $model the data model.
  1737. * @param string $attribute the attribute.
  1738. * @param array $htmlOptions additional HTML attributes.
  1739. * @return string the generated control group.
  1740. * @see TbHtml::activeControlGroup
  1741. */
  1742. public static function activeUneditableFieldControlGroup($model, $attribute, $htmlOptions = array())
  1743. {
  1744. return self::activeControlGroup(self::INPUT_TYPE_UNEDITABLE, $model, $attribute, $htmlOptions);
  1745. }
  1746. /**
  1747. * Generates a control group with a search field for a model attribute.
  1748. * @param CModel $model the data model.
  1749. * @param string $attribute the attribute.
  1750. * @param array $htmlOptions additional HTML attributes.
  1751. * @return string the generated control group.
  1752. * @see TbHtml::activeControlGroup
  1753. */
  1754. public static function activeSearchFieldControlGroup($model, $attribute, $htmlOptions = array())
  1755. {
  1756. return self::activeControlGroup(self::INPUT_TYPE_SEARCH, $model, $attribute, $htmlOptions);
  1757. }
  1758. /**
  1759. * Generates an active form row.
  1760. * @param string $type the input type.
  1761. * @param CModel $model the data model.
  1762. * @param string $attribute the attribute.
  1763. * @param array $htmlOptions additional HTML attributes.
  1764. * @param array $data data for multiple select inputs.
  1765. * @return string the generated control group.
  1766. */
  1767. public static function activeControlGroup($type, $model, $attribute, $htmlOptions = array(), $data = array())
  1768. {
  1769. $label = self::popOption('label', $htmlOptions);
  1770. $color = self::popOption('color', $htmlOptions);
  1771. $controlGroupOptions = self::popOption('groupOptions', $htmlOptions, array());
  1772. $labelOptions = self::popOption('labelOptions', $htmlOptions, array());
  1773. $controlOptions = self::popOption('controlOptions', $htmlOptions, array());
  1774. if (in_array($type, array(self::INPUT_TYPE_CHECKBOX, self::INPUT_TYPE_RADIOBUTTON)))
  1775. {
  1776. $htmlOptions = self::defaultOption('label', $model->getAttributeLabel($attribute), $htmlOptions);
  1777. $htmlOptions['labelOptions'] = $labelOptions;
  1778. $label = false;
  1779. }
  1780. $help = self::popOption('help', $htmlOptions, '');
  1781. $helpOptions = self::popOption('helpOptions', $htmlOptions, array());
  1782. if (!empty($help))
  1783. $help = self::inputHelp($help, $helpOptions);
  1784. $error = self::popOption('error', $htmlOptions, '');
  1785. $input = self::createActiveInput($type, $model, $attribute, $htmlOptions, $data);
  1786. $controlGroupOptions = self::addClassName('control-group', $controlGroupOptions);
  1787. if (!empty($color))
  1788. $controlGroupOptions = self::addClassName($color, $controlGroupOptions);
  1789. $labelOptions = self::addClassName('control-label', $labelOptions);
  1790. ob_start();
  1791. echo self::openTag('div', $controlGroupOptions);
  1792. if ($label !== false)
  1793. echo CHtml::activeLabelEx($model, $attribute, $labelOptions);
  1794. echo self::controls($input . $error . $help, $controlOptions);
  1795. echo '</div>';
  1796. return ob_get_clean();
  1797. }
  1798. /**
  1799. * Creates an active form input of the given type.
  1800. * @param string $type the input type.
  1801. * @param CModel $model the model instance.
  1802. * @param string $attribute the attribute name.
  1803. * @param array $htmlOptions additional HTML attributes.
  1804. * @param array $data data for multiple select inputs.
  1805. * @return string the input.
  1806. * @throws CException if the input type is invalid.
  1807. */
  1808. protected static function createActiveInput($type, $model, $attribute, $htmlOptions = array(), $data = array())
  1809. {
  1810. switch ($type)
  1811. {
  1812. case self::INPUT_TYPE_TEXT:
  1813. return self::activeTextField($model, $attribute, $htmlOptions);
  1814. case self::INPUT_TYPE_PASSWORD:
  1815. return self::activePasswordField($model, $attribute, $htmlOptions);
  1816. case self::INPUT_TYPE_URL:
  1817. return self::activeUrlField($model, $attribute, $htmlOptions);
  1818. case self::INPUT_TYPE_EMAIL:
  1819. return self::activeEmailField($model, $attribute, $htmlOptions);
  1820. case self::INPUT_TYPE_NUMBER:
  1821. return self::activeNumberField($model, $attribute, $htmlOptions);
  1822. case self::INPUT_TYPE_RANGE:
  1823. return self::activeRangeField($model, $attribute, $htmlOptions);
  1824. case self::INPUT_TYPE_DATE:
  1825. return self::activeDateField($model, $attribute, $htmlOptions);
  1826. case self::INPUT_TYPE_TEXTAREA:
  1827. return self::activeTextArea($model, $attribute, $htmlOptions);
  1828. case self::INPUT_TYPE_FILE:
  1829. return self::activeFileField($model, $attribute, $htmlOptions);
  1830. case self::INPUT_TYPE_RADIOBUTTON:
  1831. return self::activeRadioButton($model, $attribute, $htmlOptions);
  1832. case self::INPUT_TYPE_CHECKBOX:
  1833. return self::activeCheckBox($model, $attribute, $htmlOptions);
  1834. case self::INPUT_TYPE_DROPDOWNLIST:
  1835. return self::activeDropDownList($model, $attribute, $data, $htmlOptions);
  1836. case self::INPUT_TYPE_LISTBOX:
  1837. return self::activeListBox($model, $attribute, $data, $htmlOptions);
  1838. case self::INPUT_TYPE_CHECKBOXLIST:
  1839. return self::activeCheckBoxList($model, $attribute, $data, $htmlOptions);
  1840. case self::INPUT_TYPE_INLINECHECKBOXLIST:
  1841. return self::activeInlineCheckBoxList($model, $attribute, $data, $htmlOptions);
  1842. case self::INPUT_TYPE_RADIOBUTTONLIST:
  1843. return self::activeRadioButtonList($model, $attribute, $data, $htmlOptions);
  1844. case self::INPUT_TYPE_INLINERADIOBUTTONLIST:
  1845. return self::activeInlineRadioButtonList($model, $attribute, $data, $htmlOptions);
  1846. case self::INPUT_TYPE_UNEDITABLE:
  1847. return self::activeUneditableField($model, $attribute, $htmlOptions);
  1848. case self::INPUT_TYPE_SEARCH:
  1849. return self::activeSearchField($model, $attribute, $htmlOptions);
  1850. default:
  1851. throw new CException('Invalid input type "' . $type . '".');
  1852. }
  1853. }
  1854. /**
  1855. * Displays a summary of validation errors for one or several models.
  1856. * @param mixed $model the models whose input errors are to be displayed.
  1857. * @param string $header a piece of HTML code that appears in front of the errors.
  1858. * @param string $footer a piece of HTML code that appears at the end of the errors.
  1859. * @param array $htmlOptions additional HTML attributes to be rendered in the container div tag.
  1860. * @return string the error summary. Empty if no errors are found.
  1861. */
  1862. public static function errorSummary($model, $header = null, $footer = null, $htmlOptions = array())
  1863. {
  1864. // kind of a quick fix but it will do for now.
  1865. $htmlOptions = self::addClassName('alert alert-block alert-error', $htmlOptions);
  1866. return CHtml::errorSummary($model, $header, $footer, $htmlOptions);
  1867. }
  1868. /**
  1869. * Displays the first validation error for a model attribute.
  1870. * @param CModel $model the data model.
  1871. * @param string $attribute the attribute name.
  1872. * @param array $htmlOptions additional HTML attributes to be rendered in the container tag.
  1873. * @return string the error display. Empty if no errors are found.
  1874. */
  1875. public static function error($model, $attribute, $htmlOptions = array())
  1876. {
  1877. CHtml::resolveName($model, $attribute); // turn [a][b]attr into attr
  1878. $error = $model->getError($attribute);
  1879. return !empty($error) ? self::help($error, $htmlOptions) : '';
  1880. }
  1881. /**
  1882. * Generates an input HTML tag for a model attribute.
  1883. * This method generates an input HTML tag based on the given input name and value.
  1884. * @param string $type the input type.
  1885. * @param CModel $model the data model.
  1886. * @param string $attribute the attribute.
  1887. * @param array $htmlOptions additional HTML attributes.
  1888. * @return string the generated input tag.
  1889. */
  1890. protected static function activeTextInputField($type, $model, $attribute, $htmlOptions)
  1891. {
  1892. CHtml::resolveNameID($model, $attribute, $htmlOptions);
  1893. CHtml::clientChange('change', $htmlOptions);
  1894. $htmlOptions = self::normalizeInputOptions($htmlOptions);
  1895. $addOnClasses = self::getAddOnClasses($htmlOptions);
  1896. $addOnOptions = self::popOption('addOnOptions', $htmlOptions, array());
  1897. $addOnOptions = self::addClassName($addOnClasses, $addOnOptions);
  1898. $prepend = self::popOption('prepend', $htmlOptions, '');
  1899. $prependOptions = self::popOption('prependOptions', $htmlOptions, array());
  1900. if (!empty($prepend))
  1901. $prepend = self::inputAddOn($prepend, $prependOptions);
  1902. $append = self::popOption('append', $htmlOptions, '');
  1903. $appendOptions = self::popOption('appendOptions', $htmlOptions, array());
  1904. if (!empty($append))
  1905. $append = self::inputAddOn($append, $appendOptions);
  1906. ob_start();
  1907. if (!empty($addOnClasses))
  1908. echo self::openTag('div', $addOnOptions);
  1909. echo $prepend . CHtml::activeInputField($type, $model, $attribute, $htmlOptions) . $append;
  1910. if (!empty($addOnClasses))
  1911. echo '</div>';
  1912. return ob_get_clean();
  1913. }
  1914. /**
  1915. * Returns the add-on classes based on the given options.
  1916. * @param array $htmlOptions the options.
  1917. * @return string the classes.
  1918. */
  1919. protected static function getAddOnClasses($htmlOptions)
  1920. {
  1921. $classes = array();
  1922. if (self::getOption('append', $htmlOptions))
  1923. $classes[] = 'input-append';
  1924. if (self::getOption('prepend', $htmlOptions))
  1925. $classes[] = 'input-prepend';
  1926. return !empty($classes) ? implode(' ', $classes) : $classes;
  1927. }
  1928. /**
  1929. * Generates an add-on for an input field.
  1930. * @param string $addOn the add-on.
  1931. * @param array $htmlOptions additional HTML attributes.
  1932. * @return string the generated add-on.
  1933. */
  1934. protected static function inputAddOn($addOn, $htmlOptions)
  1935. {
  1936. $addOnOptions = self::popOption('addOnOptions', $htmlOptions, array());
  1937. $addOnOptions = self::addClassName('add-on', $addOnOptions);
  1938. return strpos($addOn, 'btn') === false // buttons should not be wrapped in a span
  1939. ? self::tag('span', $addOnOptions, $addOn)
  1940. : $addOn;
  1941. }
  1942. /**
  1943. * Generates a help text for an input field.
  1944. * @param string $help the help text.
  1945. * @param array $htmlOptions additional HTML attributes.
  1946. * @return string the generated help text.
  1947. */
  1948. protected static function inputHelp($help, $htmlOptions)
  1949. {
  1950. $type = self::popOption('type', $htmlOptions, self::HELP_TYPE_INLINE);
  1951. return $type === self::HELP_TYPE_INLINE
  1952. ? self::help($help, $htmlOptions)
  1953. : self::helpBlock($help, $htmlOptions);
  1954. }
  1955. /**
  1956. * Normalizes input options.
  1957. * @param array $options the options.
  1958. * @return array the normalized options.
  1959. */
  1960. protected static function normalizeInputOptions($options)
  1961. {
  1962. self::addSpanClass($options); // must be called here as CHtml renders inputs
  1963. $block = self::popOption('block', $options, false);
  1964. $size = self::popOption('size', $options);
  1965. if ($block)
  1966. $options = self::addClassName('input-block-level', $options);
  1967. else if (!empty($size))
  1968. $options = self::addClassName('input-' . $size, $options);
  1969. return $options;
  1970. }
  1971. /**
  1972. * Generates form controls.
  1973. * @param mixed $controls the controls.
  1974. * @param array $htmlOptions additional HTML attributes.
  1975. * @return string the generated controls.
  1976. */
  1977. public static function controls($controls, $htmlOptions = array())
  1978. {
  1979. $htmlOptions = self::addClassName('controls', $htmlOptions);
  1980. $row = self::popOption('row', $htmlOptions, false);
  1981. if ($row)
  1982. $htmlOptions = self::addClassName('controls-row', $htmlOptions);
  1983. $before = self::popOption('before', $htmlOptions, '');
  1984. $after = self::popOption('after', $htmlOptions, '');
  1985. if (is_array($controls))
  1986. $controls = implode(' ', $controls);
  1987. ob_start();
  1988. echo self::openTag('div', $htmlOptions);
  1989. echo $before . $controls . $after;
  1990. echo '</div>';
  1991. return ob_get_clean();
  1992. }
  1993. /**
  1994. * Generates form controls row.
  1995. * @param mixed $controls the controls.
  1996. * @param array $htmlOptions additional HTML attributes.
  1997. * @return string the generated controls.
  1998. */
  1999. public static function controlsRow($controls, $htmlOptions = array())
  2000. {
  2001. $htmlOptions['row'] = true;
  2002. return self::controls($controls, $htmlOptions);
  2003. }
  2004. /**
  2005. * Generates form actions.
  2006. * @param mixed $actions the actions.
  2007. * @param array $htmlOptions additional HTML attributes.
  2008. * @return string the generated actions.
  2009. */
  2010. public static function formActions($actions, $htmlOptions = array())
  2011. {
  2012. $htmlOptions = self::addClassName('form-actions', $htmlOptions);
  2013. if (is_array($actions))
  2014. $actions = implode(' ', $actions);
  2015. ob_start();
  2016. echo self::openTag('div', $htmlOptions);
  2017. echo $actions;
  2018. echo '</div>';
  2019. return ob_get_clean();
  2020. }
  2021. /**
  2022. * Generates a search form.
  2023. * @param mixed $action the form action URL.
  2024. * @param string $method form method (e.g. post, get).
  2025. * @param array $htmlOptions additional HTML options.
  2026. * @return string the generated form.
  2027. */
  2028. public static function searchForm($action, $method = 'post', $htmlOptions = array())
  2029. {
  2030. $htmlOptions = self::addClassName('form-search', $htmlOptions);
  2031. $inputOptions = self::popOption('inputOptions', $htmlOptions, array());
  2032. $inputOptions = self::mergeOptions(array('type' => 'text', 'placeholder' => 'Search'), $inputOptions);
  2033. $name = self::popOption('name', $inputOptions, 'search');
  2034. $value = self::popOption('value', $inputOptions, '');
  2035. ob_start();
  2036. echo self::beginFormTb(self::FORM_LAYOUT_SEARCH, $action, $method, $htmlOptions);
  2037. echo self::searchField($name, $value, $inputOptions);
  2038. echo CHtml::endForm();
  2039. return ob_get_clean();
  2040. }
  2041. /**
  2042. * Generates a navbar form.
  2043. * @param mixed $action the form action URL.
  2044. * @param string $method form method (e.g. post, get).
  2045. * @param array $htmlOptions additional HTML attributes
  2046. * @return string the generated form.
  2047. */
  2048. public static function navbarForm($action, $method = 'post', $htmlOptions = array())
  2049. {
  2050. $htmlOptions = self::addClassName('navbar-form', $htmlOptions);
  2051. return CHtml::form($action, $method, $htmlOptions);
  2052. }
  2053. /**
  2054. * Generates a navbar search form.
  2055. * @param mixed $action the form action URL.
  2056. * @param string $method form method (e.g. post, get).
  2057. * @param array $htmlOptions additional HTML attributes
  2058. * @return string the generated form.
  2059. */
  2060. public static function navbarSearchForm($action, $method = 'post', $htmlOptions = array())
  2061. {
  2062. $htmlOptions = self::addClassName('navbar-search', $htmlOptions);
  2063. return self::searchForm($action, $method, $htmlOptions);
  2064. }
  2065. // Buttons
  2066. // http://twitter.github.com/bootstrap/base-css.html#buttons
  2067. // --------------------------------------------------
  2068. /**
  2069. * Generates a hyperlink tag.
  2070. * @param string $text link body. It will NOT be HTML-encoded.
  2071. * @param mixed $url a URL or an action route that can be used to create a URL.
  2072. * @param array $htmlOptions additional HTML attributes.
  2073. * @return string the generated hyperlink
  2074. */
  2075. public static function link($text, $url = '#', $htmlOptions = array())
  2076. {
  2077. $htmlOptions = self::defaultOption('href', CHtml::normalizeUrl($url), $htmlOptions);
  2078. self::clientChange('click', $htmlOptions);
  2079. return self::tag('a', $htmlOptions, $text);
  2080. }
  2081. /**
  2082. * Generates an button.
  2083. * @param string $label the button label text.
  2084. * @param array $htmlOptions additional HTML attributes.
  2085. * @return string the generated button.
  2086. */
  2087. public static function button($label = 'Button', $htmlOptions = array())
  2088. {
  2089. return self::htmlButton($label, $htmlOptions);
  2090. }
  2091. /**
  2092. * Generates an image submit button.
  2093. * @param string $src the image URL
  2094. * @param array $htmlOptions additional HTML attributes.
  2095. * @return string the generated button.
  2096. */
  2097. public static function htmlButton($label = 'Button', $htmlOptions = array())
  2098. {
  2099. return self::btn(self::BUTTON_TYPE_HTML, $label, $htmlOptions);
  2100. }
  2101. /**
  2102. * Generates a submit button.
  2103. * @param string $label the button label
  2104. * @param array $htmlOptions additional HTML attributes.
  2105. * @return string the generated button.
  2106. */
  2107. public static function submitButton($label = 'Submit', $htmlOptions = array())
  2108. {
  2109. return self::btn(self::BUTTON_TYPE_SUBMIT, $label, $htmlOptions);
  2110. }
  2111. /**
  2112. * Generates a reset button.
  2113. * @param string $label the button label
  2114. * @param array $htmlOptions additional HTML attributes.
  2115. * @return string the generated button.
  2116. */
  2117. public static function resetButton($label = 'Reset', $htmlOptions = array())
  2118. {
  2119. return self::btn(self::BUTTON_TYPE_RESET, $label, $htmlOptions);
  2120. }
  2121. /**
  2122. * Generates an image submit button.
  2123. * @param string $src the image URL
  2124. * @param array $htmlOptions additional HTML attributes.
  2125. * @return string the generated button.
  2126. */
  2127. public static function imageButton($src, $htmlOptions = array())
  2128. {
  2129. $htmlOptions['src'] = $src;
  2130. return self::btn(self::BUTTON_TYPE_IMAGE, 'Submit', $htmlOptions);
  2131. }
  2132. /**
  2133. * Generates a link submit button.
  2134. * @param string $label the button label.
  2135. * @param array $htmlOptions additional HTML attributes.
  2136. * @return string the generated button tag.
  2137. */
  2138. public static function linkButton($label = 'Submit', $htmlOptions = array())
  2139. {
  2140. return self::btn(self::BUTTON_TYPE_LINK, $label, $htmlOptions);
  2141. }
  2142. /**
  2143. * Generates a link that can initiate AJAX requests.
  2144. * @param string $text the link body (it will NOT be HTML-encoded.)
  2145. * @param mixed $url the URL for the AJAX request.
  2146. * @param array $ajaxOptions AJAX options.
  2147. * @param array $htmlOptions additional HTML attributes.
  2148. * @return string the generated link.
  2149. */
  2150. public static function ajaxLink($text, $url, $ajaxOptions = array(), $htmlOptions = array())
  2151. {
  2152. $htmlOptions['url'] = $url;
  2153. $htmlOptions['ajaxOptions'] = $ajaxOptions;
  2154. return self::btn(self::BUTTON_TYPE_AJAXLINK, $text, $htmlOptions);
  2155. }
  2156. /**
  2157. * Generates a push button that can initiate AJAX requests.
  2158. * @param string $label the button label.
  2159. * @param mixed $url the URL for the AJAX request.
  2160. * @param array $ajaxOptions AJAX options.
  2161. * @param array $htmlOptions additional HTML attributes.
  2162. * @return string the generated button.
  2163. */
  2164. public static function ajaxButton($label, $url, $ajaxOptions = array(), $htmlOptions = array())
  2165. {
  2166. $ajaxOptions['url'] = $url;
  2167. $htmlOptions['ajax'] = $ajaxOptions;
  2168. return self::btn(self::BUTTON_TYPE_AJAXBUTTON, $label, $htmlOptions);
  2169. }
  2170. /**
  2171. * Generates a push button that can submit the current form in POST method.
  2172. * @param string $label the button label
  2173. * @param mixed $url the URL for the AJAX request.
  2174. * @param array $ajaxOptions AJAX options.
  2175. * @param array $htmlOptions additional HTML attributes.
  2176. * @return string the generated button.
  2177. */
  2178. public static function ajaxSubmitButton($label, $url, $ajaxOptions = array(), $htmlOptions = array())
  2179. {
  2180. $ajaxOptions['type'] = 'POST';
  2181. $htmlOptions['type'] = 'submit';
  2182. return self::ajaxButton($label, $url, $ajaxOptions, $htmlOptions);
  2183. }
  2184. /**
  2185. * Generates a button.
  2186. * @param string $type the button type.
  2187. * @param string $label the button label text.
  2188. * @param array $htmlOptions additional HTML attributes.
  2189. * @return string the generated button.
  2190. */
  2191. public static function btn($type, $label, $htmlOptions = array())
  2192. {
  2193. $htmlOptions = self::addClassName('btn', $htmlOptions);
  2194. $color = self::popOption('color', $htmlOptions);
  2195. if (!empty($color))
  2196. $htmlOptions = self::addClassName('btn-' . $color, $htmlOptions);
  2197. $size = self::popOption('size', $htmlOptions);
  2198. if (!empty($size))
  2199. $htmlOptions = self::addClassName('btn-' . $size, $htmlOptions);
  2200. if (self::popOption('block', $htmlOptions, false))
  2201. $htmlOptions = self::addClassName('btn-block', $htmlOptions);
  2202. if (self::popOption('disabled', $htmlOptions, false))
  2203. $htmlOptions = self::addClassName('disabled', $htmlOptions);
  2204. $loading = self::popOption('loading', $htmlOptions);
  2205. if (!empty($loading))
  2206. $htmlOptions['data-loading-text'] = $loading;
  2207. if (self::popOption('toggle', $htmlOptions, false))
  2208. $htmlOptions['data-toggle'] = 'button';
  2209. $items = strpos($type, 'input') === false ? self::popOption('items', $htmlOptions, array()) : array();
  2210. $icon = self::popOption('icon', $htmlOptions);
  2211. if (!empty($icon) && strpos($type, 'input') === false) // inputs cannot have icons
  2212. $label = self::icon($icon) . '&nbsp;' . $label;
  2213. $dropdownOptions = $htmlOptions;
  2214. self::removeOptions($htmlOptions, array('groupOptions', 'menuOptions', 'dropup'));
  2215. self::addSpanClass($htmlOptions); // must be called here as CHtml renders buttons
  2216. return count($items) > 0
  2217. ? self::btnDropdown($type, $label, $items, $dropdownOptions)
  2218. : self::createButton($type, $label, $htmlOptions);
  2219. }
  2220. /**
  2221. * Generates a button dropdown.
  2222. * $type the button type.
  2223. * @param string $label the button label text.
  2224. * @param array $items the menu items.
  2225. * @param array $htmlOptions additional HTML attributes.
  2226. * @return string the generated button.
  2227. */
  2228. protected static function btnDropdown($type, $label, $items, $htmlOptions)
  2229. {
  2230. $menuOptions = self::popOption('menuOptions', $htmlOptions, array());
  2231. $groupOptions = self::popOption('groupOptions', $htmlOptions, array());
  2232. $groupOptions = self::addClassName('btn-group', $groupOptions);
  2233. if (self::popOption('dropup', $htmlOptions, false))
  2234. $groupOptions = self::addClassName('dropup', $groupOptions);
  2235. ob_start();
  2236. echo self::openTag('div', $groupOptions);
  2237. if (self::popOption('split', $htmlOptions, false))
  2238. {
  2239. echo self::createButton($type, $label, $htmlOptions);
  2240. echo self::dropdownToggleButton('', $htmlOptions);
  2241. }
  2242. else
  2243. echo self::dropdownToggleLink($label, $htmlOptions);
  2244. echo self::dropdown($items, $menuOptions);
  2245. echo '</div>';
  2246. return ob_get_clean();
  2247. }
  2248. /**
  2249. * Creates a button the of given type.
  2250. * @param string $type the button type.
  2251. * @param string $label the button label.
  2252. * @param array $htmlOptions additional HTML attributes.
  2253. * @return string the button.
  2254. */
  2255. protected static function createButton($type, $label, $htmlOptions)
  2256. {
  2257. $url = self::popOption('url', $htmlOptions, '#');
  2258. $ajaxOptions = self::popOption('ajaxOptions', $htmlOptions, array());
  2259. switch ($type)
  2260. {
  2261. case self::BUTTON_TYPE_HTML:
  2262. return CHtml::htmlButton($label, $htmlOptions);
  2263. case self::BUTTON_TYPE_SUBMIT:
  2264. $htmlOptions['type'] = 'submit';
  2265. return CHtml::htmlButton($label, $htmlOptions);
  2266. case self::BUTTON_TYPE_RESET:
  2267. $htmlOptions['type'] = 'reset';
  2268. return CHtml::htmlButton($label, $htmlOptions);
  2269. case self::BUTTON_TYPE_IMAGE:
  2270. $htmlOptions['type'] = 'image';
  2271. return CHtml::htmlButton($label, $htmlOptions);
  2272. case self::BUTTON_TYPE_LINKBUTTON:
  2273. return CHtml::linkButton($label, $htmlOptions);
  2274. case self::BUTTON_TYPE_AJAXLINK:
  2275. return CHtml::ajaxLink($label, $url, $ajaxOptions, $htmlOptions);
  2276. case self::BUTTON_TYPE_AJAXBUTTON:
  2277. $ajaxOptions['url'] = $url;
  2278. $htmlOptions['ajax'] = $ajaxOptions;
  2279. return CHtml::htmlButton($label, $htmlOptions);
  2280. case self::BUTTON_TYPE_INPUTBUTTON:
  2281. return CHtml::button($label, $htmlOptions);
  2282. case self::BUTTON_TYPE_INPUTSUBMIT:
  2283. $htmlOptions['type'] = 'submit';
  2284. return CHtml::button($label, $htmlOptions);
  2285. case self::BUTTON_TYPE_LINK:
  2286. return self::link($label, $url, $htmlOptions);
  2287. default:
  2288. throw new CException('Invalid button type "' . $type . '".');
  2289. }
  2290. }
  2291. // Images
  2292. // http://twitter.github.com/bootstrap/base-css.html#images
  2293. // --------------------------------------------------
  2294. /**
  2295. * Generates an image tag with rounded corners.
  2296. * @param string $src the image URL.
  2297. * @param string $alt the alternative text display.
  2298. * @param array $htmlOptions additional HTML attributes.
  2299. * @return string the generated image tag.
  2300. */
  2301. public static function imageRounded($src, $alt = '', $htmlOptions = array())
  2302. {
  2303. $htmlOptions['type'] = self::IMAGE_TYPE_ROUNDED;
  2304. return self::image($src, $alt, $htmlOptions);
  2305. }
  2306. /**
  2307. * Generates an image tag with circle.
  2308. * @param string $src the image URL.
  2309. * @param string $alt the alternative text display.
  2310. * @param array $htmlOptions additional HTML attributes.
  2311. * @return string the generated image tag.
  2312. */
  2313. public static function imageCircle($src, $alt = '', $htmlOptions = array())
  2314. {
  2315. $htmlOptions['type'] = self::IMAGE_TYPE_CIRCLE;
  2316. return self::image($src, $alt, $htmlOptions);
  2317. }
  2318. /**
  2319. * Generates an image tag within polaroid frame.
  2320. * @param string $src the image URL.
  2321. * @param string $alt the alternative text display.
  2322. * @param array $htmlOptions additional HTML attributes.
  2323. * @return string the generated image tag.
  2324. */
  2325. public static function imagePolaroid($src, $alt = '', $htmlOptions = array())
  2326. {
  2327. $htmlOptions['type'] = self::IMAGE_TYPE_POLAROID;
  2328. return self::image($src, $alt, $htmlOptions);
  2329. }
  2330. /**
  2331. * Generates an image tag.
  2332. * @param string $src the image URL.
  2333. * @param string $alt the alternative text display.
  2334. * @param array $htmlOptions additional HTML attributes.
  2335. * @return string the generated image tag.
  2336. */
  2337. public static function image($src, $alt = '', $htmlOptions = array())
  2338. {
  2339. $type = self::popOption('type', $htmlOptions);
  2340. if (!empty($type))
  2341. $htmlOptions = self::addClassName('img-' . $type, $htmlOptions);
  2342. return CHtml::image($src, $alt, $htmlOptions);
  2343. }
  2344. // Icons by Glyphicons
  2345. // http://twitter.github.com/bootstrap/base-css.html#icons
  2346. // --------------------------------------------------
  2347. /**
  2348. * Generates an icon.
  2349. * @param string $icon the icon type.
  2350. * @param array $htmlOptions additional HTML attributes.
  2351. * @param string $tagName the icon HTML tag.
  2352. * @return string the generated icon.
  2353. */
  2354. public static function icon($icon, $htmlOptions = array(), $tagName = 'i')
  2355. {
  2356. if (is_string($icon))
  2357. {
  2358. if (strpos($icon, 'icon') === false)
  2359. $icon = 'icon-' . implode(' icon-', explode(' ', $icon));
  2360. $htmlOptions = self::addClassName($icon, $htmlOptions);
  2361. return self::openTag($tagName, $htmlOptions) . CHtml::closeTag($tagName); // tag won't work in this case
  2362. }
  2363. return '';
  2364. }
  2365. //
  2366. // COMPONENTS
  2367. // --------------------------------------------------
  2368. // Dropdowns
  2369. // http://twitter.github.com/bootstrap/components.html#dropdowns
  2370. // --------------------------------------------------
  2371. /**
  2372. * Generates a dropdown menu.
  2373. * @param array $items the menu items.
  2374. * @param array $htmlOptions additional HTML attributes.
  2375. * @return string the generated menu.
  2376. */
  2377. public static function dropdown($items, $htmlOptions = array())
  2378. {
  2379. // todo: think about how to apply this, now it applies to all depths while it should only apply for the first.
  2380. //$htmlOptions = self::setDefaultValue('role', 'menu', $htmlOptions);
  2381. $htmlOptions = self::addClassName('dropdown-menu', $htmlOptions);
  2382. ob_start();
  2383. echo self::menu($items, $htmlOptions);
  2384. return ob_get_clean();
  2385. }
  2386. /**
  2387. * Generates a dropdown toggle link.
  2388. * @param string $label the link label text.
  2389. * @param array $htmlOptions additional HTML attributes.
  2390. * @return string the generated link.
  2391. */
  2392. public static function dropdownToggleLink($label, $htmlOptions = array())
  2393. {
  2394. return self::dropdownToggle(self::BUTTON_TYPE_LINK, $label, $htmlOptions);
  2395. }
  2396. /**
  2397. * Generates a dropdown toggle button.
  2398. * @param string $label the button label text.
  2399. * @param array $htmlOptions additional HTML attributes.
  2400. * @return string the generated button.
  2401. */
  2402. public static function dropdownToggleButton($label = '', $htmlOptions = array())
  2403. {
  2404. return self::dropdownToggle(self::BUTTON_TYPE_HTML, $label, $htmlOptions);
  2405. }
  2406. /**
  2407. * Generates a dropdown toggle element.
  2408. * @param string $tag the HTML tag.
  2409. * @param string $label the element text.
  2410. * @param array $htmlOptions additional HTML attributes.
  2411. * @return string the generated element.
  2412. */
  2413. public static function dropdownToggle($type, $label, $htmlOptions)
  2414. {
  2415. $htmlOptions = self::addClassName('dropdown-toggle', $htmlOptions);
  2416. $htmlOptions = self::defaultOption('data-toggle', 'dropdown', $htmlOptions);
  2417. $label .= ' <b class="caret"></b>';
  2418. return self::btn($type, $label, $htmlOptions);
  2419. }
  2420. /**
  2421. * Generates a dropdown toggle menu item.
  2422. * @param string $label the menu item text.
  2423. * @param array $htmlOptions additional HTML attributes.
  2424. * @return string the generated menu item.
  2425. */
  2426. public static function dropdownToggleMenuLink($label, $htmlOptions = array())
  2427. {
  2428. $htmlOptions = self::addClassName('dropdown-toggle', $htmlOptions);
  2429. $htmlOptions = self::defaultOption('data-toggle', 'dropdown', $htmlOptions);
  2430. $label .= ' <b class="caret"></b>';
  2431. return self::link($label, '#', $htmlOptions);
  2432. }
  2433. // Button groups
  2434. // http://twitter.github.com/bootstrap/components.html#buttonGroups
  2435. // --------------------------------------------------
  2436. /**
  2437. * Generates a button group.
  2438. * @param array $buttons the button configurations.
  2439. * @param array $htmlOptions additional HTML options.
  2440. * @return string the generated button group.
  2441. */
  2442. public static function buttonGroup($buttons, $htmlOptions = array())
  2443. {
  2444. if (is_array($buttons) && !empty($buttons))
  2445. {
  2446. $htmlOptions = self::addClassName('btn-group', $htmlOptions);
  2447. if (self::popOption('vertical', $htmlOptions, false))
  2448. $htmlOptions = self::addClassName('btn-group-vertical', $htmlOptions);
  2449. $toggle = self::popOption('toggle', $htmlOptions);
  2450. if (!empty($toggle))
  2451. $htmlOptions['data-toggle'] = 'buttons-' . $toggle;
  2452. $parentOptions = array(
  2453. 'color' => self::popOption('color', $htmlOptions),
  2454. 'size' => self::popOption('size', $htmlOptions),
  2455. 'disabled' => self::popOption('disabled', $htmlOptions)
  2456. );
  2457. ob_start();
  2458. echo self::openTag('div', $htmlOptions);
  2459. foreach ($buttons as $buttonOptions)
  2460. {
  2461. $options = self::popOption('htmlOptions', $buttonOptions, array());
  2462. if (!empty($options))
  2463. $buttonOptions = self::mergeOptions($options, $buttonOptions);
  2464. $buttonLabel = self::popOption('label', $buttonOptions, '');
  2465. $buttonOptions = self::copyOptions(array('color', 'size', 'disabled'), $parentOptions, $buttonOptions);
  2466. $items = self::popOption('items', $buttonOptions, array());
  2467. if (!empty($items))
  2468. echo self::buttonDropdown($buttonLabel, $items, $buttonOptions);
  2469. else
  2470. echo self::linkButton($buttonLabel, $buttonOptions);
  2471. }
  2472. echo '</div>';
  2473. return ob_get_clean();
  2474. }
  2475. return '';
  2476. }
  2477. /**
  2478. * Generates a button toolbar.
  2479. * @param array $groups the button group configurations.
  2480. * @param array $htmlOptions additional HTML options.
  2481. * @return string the generated button toolbar.
  2482. */
  2483. public static function buttonToolbar($groups, $htmlOptions = array())
  2484. {
  2485. if (is_array($groups) && !empty($groups))
  2486. {
  2487. $htmlOptions = self::addClassName('btn-toolbar', $htmlOptions);
  2488. $parentOptions = array(
  2489. 'color' => self::popOption('color', $htmlOptions),
  2490. 'size' => self::popOption('size', $htmlOptions),
  2491. 'disabled' => self::popOption('disabled', $htmlOptions)
  2492. );
  2493. ob_start();
  2494. echo self::openTag('div', $htmlOptions);
  2495. foreach ($groups as $groupOptions)
  2496. {
  2497. $items = self::popOption('items', $groupOptions, array());
  2498. if (empty($items))
  2499. continue;
  2500. $options = self::popOption('htmlOptions', $groupOptions, array());
  2501. if (!empty($options))
  2502. $groupOptions = self::mergeOptions($options, $groupOptions);
  2503. $groupOptions = self::copyOptions(array('color', 'size', 'disabled'), $parentOptions, $groupOptions);
  2504. echo self::buttonGroup($items, $groupOptions);
  2505. }
  2506. echo '</div>';
  2507. return ob_get_clean();
  2508. }
  2509. return '';
  2510. }
  2511. // Button dropdowns
  2512. // http://twitter.github.com/bootstrap/components.html#buttonDropdowns
  2513. // --------------------------------------------------
  2514. /**
  2515. * Generates a button with a dropdown menu.
  2516. * @param string $label the button label text.
  2517. * @param array $items the menu items.
  2518. * @param array $htmlOptions additional HTML attributes.
  2519. * @return string the generated button.
  2520. */
  2521. public static function buttonDropdown($label, $items, $htmlOptions = array())
  2522. {
  2523. $htmlOptions['items'] = $items;
  2524. $type = self::popOption('type', $htmlOptions, self::BUTTON_TYPE_LINKBUTTON);
  2525. return self::btn($type, $label, $htmlOptions);
  2526. }
  2527. /**
  2528. * Generates a button with a split dropdown menu.
  2529. * @param string $label the button label text.
  2530. * @param array $items the menu items.
  2531. * @param array $htmlOptions additional HTML attributes.
  2532. * @return string the generated button.
  2533. */
  2534. public static function splitButtonDropdown($label, $items, $htmlOptions = array())
  2535. {
  2536. $htmlOptions['split'] = true;
  2537. return self::buttonDropdown($label, $items, $htmlOptions);
  2538. }
  2539. // Navs
  2540. // http://twitter.github.com/bootstrap/components.html#navs
  2541. // --------------------------------------------------
  2542. /**
  2543. * Generates a tab navigation.
  2544. * @param array $items the menu items.
  2545. * @param array $htmlOptions additional HTML attributes.
  2546. * @return string the generated menu.
  2547. */
  2548. public static function tabs($items, $htmlOptions = array())
  2549. {
  2550. return self::nav(self::NAV_TYPE_TABS, $items, $htmlOptions);
  2551. }
  2552. /**
  2553. * Generates a stacked tab navigation.
  2554. * @param array $items the menu items.
  2555. * @param array $htmlOptions additional HTML attributes.
  2556. * @return string the generated menu.
  2557. */
  2558. public static function stackedTabs($items, $htmlOptions = array())
  2559. {
  2560. $htmlOptions['stacked'] = true;
  2561. return self::tabs($items, $htmlOptions);
  2562. }
  2563. /**
  2564. * Generates a pills navigation.
  2565. * @param array $items the menu items.
  2566. * @param array $htmlOptions additional HTML attributes.
  2567. * @return string the generated menu.
  2568. */
  2569. public static function pills($items, $htmlOptions = array())
  2570. {
  2571. return self::nav(self::NAV_TYPE_PILLS, $items, $htmlOptions);
  2572. }
  2573. /**
  2574. * Generates a stacked pills navigation.
  2575. * @param array $items the menu items.
  2576. * @param array $htmlOptions additional HTML attributes.
  2577. * @return string the generated menu.
  2578. */
  2579. public static function stackedPills($items, $htmlOptions = array())
  2580. {
  2581. $htmlOptions['stacked'] = true;
  2582. return self::tabs($items, $htmlOptions);
  2583. }
  2584. /**
  2585. * Generates a list navigation.
  2586. * @param array $items the menu items.
  2587. * @param array $htmlOptions additional HTML attributes.
  2588. * @return string the generated menu.
  2589. */
  2590. public static function navList($items, $htmlOptions = array())
  2591. {
  2592. return self::nav(self::NAV_TYPE_LIST, $items, $htmlOptions);
  2593. }
  2594. /**
  2595. * Generates a navigation menu.
  2596. * @param string $type the menu type.
  2597. * @param array $items the menu items.
  2598. * @param array $htmlOptions additional HTML attributes.
  2599. * @return string the generated menu.
  2600. */
  2601. public static function nav($type, $items, $htmlOptions = array())
  2602. {
  2603. $htmlOptions = self::addClassName('nav', $htmlOptions);
  2604. $htmlOptions = self::addClassName('nav-' . $type, $htmlOptions);
  2605. if ($type !== self::NAV_TYPE_LIST && self::popOption('stacked', $htmlOptions, false))
  2606. $htmlOptions = self::addClassName('nav-stacked', $htmlOptions);
  2607. ob_start();
  2608. echo self::menu($items, $htmlOptions);
  2609. return ob_get_clean();
  2610. }
  2611. /**
  2612. * Generates a menu.
  2613. * @param array $items the menu items.
  2614. * @param array $htmlOptions additional HTML attributes.
  2615. * @return string the generated menu.
  2616. */
  2617. public static function menu($items, $htmlOptions = array())
  2618. {
  2619. ob_start();
  2620. echo self::openTag('ul', $htmlOptions);
  2621. foreach ($items as $itemOptions)
  2622. {
  2623. if (is_string($itemOptions))
  2624. echo $itemOptions;
  2625. else
  2626. {
  2627. $options = self::popOption('itemOptions', $itemOptions, array());
  2628. if (!empty($options))
  2629. $itemOptions = self::mergeOptions($options, $itemOptions);
  2630. // todo: I'm not quite happy with the logic below but it will have to do for now.
  2631. $label = self::popOption('label', $itemOptions, '');
  2632. if (self::popOption('active', $itemOptions, false))
  2633. $itemOptions = self::addClassName('active', $itemOptions);
  2634. if (self::popOption('disabled', $itemOptions, false))
  2635. $itemOptions = self::addClassName('disabled', $itemOptions);
  2636. if (self::popOption('header', $itemOptions, false))
  2637. echo self::menuHeader($label, $itemOptions);
  2638. else
  2639. {
  2640. $itemOptions['linkOptions'] = self::getOption('linkOptions', $itemOptions, array());
  2641. $icon = self::popOption('icon', $itemOptions);
  2642. if (!empty($icon))
  2643. $label = self::icon($icon) . ' ' . $label;
  2644. $items = self::popOption('items', $itemOptions, array());
  2645. if (empty($items))
  2646. {
  2647. $url = self::popOption('url', $itemOptions, false);
  2648. echo self::menuLink($label, $url, $itemOptions);
  2649. }
  2650. else
  2651. echo self::menuDropdown($label, $items, $itemOptions);
  2652. }
  2653. }
  2654. }
  2655. echo '</ul>';
  2656. return ob_get_clean();
  2657. }
  2658. /**
  2659. * Generates a menu link.
  2660. * @param string $label the link label.
  2661. * @param array $url the link url.
  2662. * @param array $htmlOptions additional HTML attributes.
  2663. * @return string the generated menu item.
  2664. */
  2665. public static function menuLink($label, $url, $htmlOptions = array())
  2666. {
  2667. $linkOptions = self::popOption('linkOptions', $htmlOptions, array());
  2668. ob_start();
  2669. echo self::openTag('li', $htmlOptions);
  2670. echo self::link($label, $url, $linkOptions);
  2671. echo '</li>';
  2672. return ob_get_clean();
  2673. }
  2674. /**
  2675. * Generates a menu dropdown.
  2676. * @param string $label the link label.
  2677. * @param array $items the menu configuration.
  2678. * @param array $htmlOptions additional HTML attributes.
  2679. * @return string the generated dropdown.
  2680. */
  2681. public static function menuDropdown($label, $items, $htmlOptions)
  2682. {
  2683. $htmlOptions = self::addClassName('dropdown', $htmlOptions);
  2684. $linkOptions = self::popOption('linkOptions', $htmlOptions, array());
  2685. $menuOptions = self::popOption('menuOptions', $htmlOptions, array());
  2686. $menuOptions = self::addClassName('dropdown-menu', $menuOptions);
  2687. if (self::popOption('active', $htmlOptions, false))
  2688. $htmlOptions = self::addClassName('active', $htmlOptions);
  2689. ob_start();
  2690. echo self::openTag('li', $htmlOptions);
  2691. echo self::dropdownToggleMenuLink($label, $linkOptions);
  2692. echo self::menu($items, $menuOptions);
  2693. echo '</li>';
  2694. return ob_get_clean();
  2695. }
  2696. /**
  2697. * Generates a menu header.
  2698. * @param string $label the header text.
  2699. * @param array $htmlOptions additional HTML options.
  2700. * @return string the generated header.
  2701. */
  2702. public static function menuHeader($label, $htmlOptions = array())
  2703. {
  2704. $htmlOptions = self::addClassName('nav-header', $htmlOptions);
  2705. return self::tag('li', $htmlOptions, $label);
  2706. }
  2707. /**
  2708. * Generates a menu divider.
  2709. * @param array $htmlOptions additional HTML attributes.
  2710. * @return string the generated menu item.
  2711. */
  2712. public static function menuDivider($htmlOptions = array())
  2713. {
  2714. $htmlOptions = self::addClassName('divider', $htmlOptions);
  2715. return self::tag('li', $htmlOptions);
  2716. }
  2717. /**
  2718. * Generates a tabbable menu.
  2719. * @param array $tabs the tab configurations.
  2720. * @param array $htmlOptions additional HTML attributes.
  2721. * @return string the generated menu.
  2722. */
  2723. public static function tabbable($tabs, $htmlOptions = array())
  2724. {
  2725. $htmlOptions = self::addClassName('tabbable', $htmlOptions);
  2726. $placement = self::popOption('placement', $htmlOptions);
  2727. if (!empty($placement))
  2728. $htmlOptions = self::addClassName('tabs-' . $placement, $htmlOptions);
  2729. $menuOptions = self::popOption('menuOptions', $htmlOptions, array());
  2730. $contentOptions = self::popOption('contentOptions', $htmlOptions, array());
  2731. $contentOptions = self::addClassName('tab-content', $contentOptions);
  2732. $menuItems = array();
  2733. foreach ($tabs as $i => &$tabOptions)
  2734. {
  2735. $icon = self::popOption('icon', $tabOptions);
  2736. $label = self::popOption('label', $tabOptions, '');
  2737. $id = $tabOptions['id'] = self::popOption('id', $tabOptions, 'tab_' . ($i + 1));
  2738. $active = self::getOption('active', $tabOptions, false);
  2739. $disabled = self::popOption('disabled', $tabOptions, false);
  2740. $linkOptions = self::popOption('linkOptions', $tabOptions, array());
  2741. $linkOptions['data-toggle'] = 'tab';
  2742. $itemOptions = self::popOption('itemOptions', $tabOptions, array());
  2743. $items = self::popOption('items', $tabOptions, array());
  2744. $menuItem = array(
  2745. 'icon' => $icon,
  2746. 'label' => $label,
  2747. 'url' => '#' . $id,
  2748. 'active' => $active,
  2749. 'disabled' => $disabled,
  2750. 'itemOptions' => $itemOptions,
  2751. 'linkOptions' => $linkOptions,
  2752. 'items' => $items,
  2753. );
  2754. $menuItems[] = $menuItem;
  2755. }
  2756. ob_start();
  2757. echo TbHtml::openTag('div', $htmlOptions);
  2758. echo TbHtml::tabs($menuItems, $menuOptions);
  2759. echo TbHtml::openTag('div', $contentOptions);
  2760. foreach ($tabs as &$tabOptions)
  2761. {
  2762. if (self::popOption('active', $tabOptions, false))
  2763. $tabOptions = self::addClassName('active', $tabOptions);
  2764. $tabContent = self::popOption('content', $tabOptions, '');
  2765. $tabOptions = self::addClassName('tab-pane', $tabOptions);
  2766. echo TbHtml::tag('div', $tabOptions, $tabContent);
  2767. }
  2768. echo '</div></div>';
  2769. return ob_get_clean();
  2770. }
  2771. // Navbar
  2772. // http://twitter.github.com/bootstrap/components.html#navbar
  2773. // --------------------------------------------------
  2774. /**
  2775. * Generates a navbar.
  2776. * @param string $content the navbar content.
  2777. * @param array $htmlOptions additional HTML attributes.
  2778. * @return string the generated navbar.
  2779. */
  2780. public static function navbar($content, $htmlOptions = array())
  2781. {
  2782. $htmlOptions = self::addClassName('navbar', $htmlOptions);
  2783. $display = self::popOption('display', $htmlOptions);
  2784. if (!empty($display) )
  2785. $htmlOptions = self::addClassName('navbar-' . $display, $htmlOptions);
  2786. $color = self::popOption('color', $htmlOptions);
  2787. if (!empty($color))
  2788. $htmlOptions = self::addClassName('navbar-' . $color, $htmlOptions);
  2789. $innerOptions = self::popOption('innerOptions', $htmlOptions, array());
  2790. $innerOptions = self::addClassName('navbar-inner', $innerOptions);
  2791. ob_start();
  2792. echo self::openTag('div', $htmlOptions);
  2793. echo self::tag('div', $innerOptions, $content);
  2794. echo '</div>';
  2795. return ob_get_clean();
  2796. }
  2797. /**
  2798. * Generates a brand link for the navbar.
  2799. * @param string $label the link label text.
  2800. * @param string $url the link url.
  2801. * @param array $htmlOptions additional HTML attributes.
  2802. * @return string the generated link.
  2803. */
  2804. public static function navbarBrandLink($label, $url, $htmlOptions = array())
  2805. {
  2806. $htmlOptions = self::addClassName('brand', $htmlOptions);
  2807. return self::link($label, $url, $htmlOptions);
  2808. }
  2809. /**
  2810. * Generates a text for the navbar.
  2811. * @param string $text the text.
  2812. * @param array $htmlOptions additional HTML attributes.
  2813. * @param string $tag the HTML tag.
  2814. * @return string the generated text block.
  2815. */
  2816. public static function navbarText($text, $htmlOptions = array(), $tag = 'p')
  2817. {
  2818. $htmlOptions = self::addClassName('navbar-text', $htmlOptions);
  2819. return self::tag($tag, $htmlOptions, $text);
  2820. }
  2821. /**
  2822. * Generates a menu divider for the navbar.
  2823. * @param array $htmlOptions additional HTML attributes.
  2824. * @return string the generated divider.
  2825. */
  2826. public static function navbarMenuDivider($htmlOptions = array())
  2827. {
  2828. $htmlOptions = self::addClassName('divider-vertical', $htmlOptions);
  2829. return self::tag('li', $htmlOptions);
  2830. }
  2831. // Breadcrumbs
  2832. // http://twitter.github.com/bootstrap/components.html#breadcrumbs
  2833. // --------------------------------------------------
  2834. /**
  2835. * Generates a breadcrumb menu.
  2836. * @param array $links the breadcrumb links.
  2837. * @param array $htmlOptions additional HTML attributes.
  2838. * @return string the generated breadcrumb.
  2839. */
  2840. public static function breadcrumbs($links, $htmlOptions = array())
  2841. {
  2842. $divider = self::popOption('divider', $htmlOptions, '/');
  2843. $htmlOptions = self::addClassName('breadcrumb', $htmlOptions);
  2844. ob_start();
  2845. echo self::openTag('ul', $htmlOptions);
  2846. foreach ($links as $label => $url)
  2847. {
  2848. if (is_string($label))
  2849. {
  2850. echo self::openTag('li');
  2851. echo self::link($label, $url);
  2852. echo self::tag('span', array('class' => 'divider'), $divider);
  2853. echo '</li>';
  2854. }
  2855. else
  2856. echo self::tag('li', array('class' => 'active'), $url);
  2857. }
  2858. echo '</ul>';
  2859. return ob_get_clean();
  2860. }
  2861. // Pagination
  2862. // http://twitter.github.com/bootstrap/components.html#pagination
  2863. // --------------------------------------------------
  2864. /**
  2865. * Generates a pagination.
  2866. * @param array $links the pagination buttons.
  2867. * @param array $htmlOptions additional HTML attributes.
  2868. * @return string the generated pagination.
  2869. */
  2870. public static function pagination($links, $htmlOptions = array())
  2871. {
  2872. if (is_array($links) && !empty($links))
  2873. {
  2874. $htmlOptions = self::addClassName('pagination', $htmlOptions);
  2875. $size = self::popOption('size', $htmlOptions);
  2876. if (!empty($size))
  2877. $htmlOptions = self::addClassName('pagination-' . $size, $htmlOptions);
  2878. $align = self::popOption('align', $htmlOptions);
  2879. if (!empty($align))
  2880. $htmlOptions = self::addClassName('pagination-' . $align, $htmlOptions);
  2881. $listOptions = self::popOption('listOptions', $htmlOptions, array());
  2882. ob_start();
  2883. echo self::openTag('div', $htmlOptions);
  2884. echo self::openTag('ul', $listOptions);
  2885. foreach ($links as $itemOptions)
  2886. {
  2887. $options = self::popOption('htmlOptions', $itemOptions, array());
  2888. if (!empty($options))
  2889. $itemOptions = self::mergeOptions($options, $itemOptions);
  2890. $label = self::popOption('label', $itemOptions, '');
  2891. $url = self::popOption('url', $itemOptions, false);
  2892. echo self::paginationLink($label, $url, $itemOptions);
  2893. }
  2894. echo '</ul>' . '</div>';
  2895. return ob_get_clean();
  2896. }
  2897. return '';
  2898. }
  2899. /**
  2900. * Generates a pagination link.
  2901. * @param string $label the link label text.
  2902. * @param mixed $url the link url.
  2903. * @param array $htmlOptions additional HTML attributes.
  2904. * @return string the generated link.
  2905. */
  2906. public static function paginationLink($label, $url, $htmlOptions = array())
  2907. {
  2908. $active = self::popOption('active', $htmlOptions);
  2909. $disabled = self::popOption('disabled', $htmlOptions);
  2910. if ($active)
  2911. $htmlOptions = self::addClassName('active', $htmlOptions);
  2912. else if ($disabled)
  2913. $htmlOptions = self::addClassName('disabled', $htmlOptions);
  2914. $linkOptions = self::popOption('linkOptions', $itemOptions, array());
  2915. ob_start();
  2916. echo self::openTag('li', $htmlOptions);
  2917. echo self::link($label, $url, $linkOptions);
  2918. echo '</li>';
  2919. return ob_get_clean();
  2920. }
  2921. /**
  2922. * Generates a pager.
  2923. * @param array $links the pager buttons.
  2924. * @param array $htmlOptions additional HTML attributes.
  2925. * @return string the generated pager.
  2926. */
  2927. public static function pager($links, $htmlOptions = array())
  2928. {
  2929. if (is_array($links) && !empty($links))
  2930. {
  2931. $htmlOptions = self::addClassName('pager', $htmlOptions);
  2932. ob_start();
  2933. echo self::openTag('ul', $htmlOptions);
  2934. foreach ($links as $itemOptions)
  2935. {
  2936. $options = self::popOption('htmlOptions', $itemOptions, array());
  2937. if (!empty($options))
  2938. $itemOptions = self::mergeOptions($options, $itemOptions);
  2939. $label = self::popOption('label', $itemOptions, '');
  2940. $url = self::popOption('url', $itemOptions, false);
  2941. echo self::pagerLink($label, $url, $itemOptions);
  2942. }
  2943. echo '</ul>';
  2944. return ob_get_clean();
  2945. }
  2946. return '';
  2947. }
  2948. /**
  2949. * Generates a pager link.
  2950. * @param string $label the link label text.
  2951. * @param mixed $url the link url.
  2952. * @param array $htmlOptions additional HTML attributes.
  2953. * @return string the generated link.
  2954. */
  2955. public static function pagerLink($label, $url, $htmlOptions = array())
  2956. {
  2957. $previous = self::popOption('previous', $htmlOptions);
  2958. $next = self::popOption('next', $htmlOptions);
  2959. if ($previous)
  2960. $htmlOptions = self::addClassName('previous', $htmlOptions);
  2961. else if ($next)
  2962. $htmlOptions = self::addClassName('next', $htmlOptions);
  2963. if (self::popOption('disabled', $htmlOptions, false))
  2964. $htmlOptions = self::addClassName('disabled', $htmlOptions);
  2965. $linkOptions = self::popOption('linkOptions', $itemOptions, array());
  2966. ob_start();
  2967. echo self::openTag('li', $htmlOptions);
  2968. echo self::link($label, $url, $linkOptions);
  2969. echo '</li>';
  2970. return ob_get_clean();
  2971. }
  2972. // Labels and badges
  2973. // http://twitter.github.com/bootstrap/components.html#labels-badges
  2974. // --------------------------------------------------
  2975. /**
  2976. * Generates a label span.
  2977. * @param string $label the label text.
  2978. * @param array $htmlOptions additional HTML attributes.
  2979. * @return string the generated span.
  2980. */
  2981. public static function labelTb($label, $htmlOptions = array())
  2982. {
  2983. $htmlOptions = self::addClassName('label', $htmlOptions);
  2984. $color = self::popOption('color', $htmlOptions);
  2985. if (!empty($color))
  2986. $htmlOptions = self::addClassName('label-' . $color, $htmlOptions);
  2987. return self::tag('span', $htmlOptions, $label);
  2988. }
  2989. /**
  2990. * Generates a badge span.
  2991. * @param string $label the badge text.
  2992. * @param array $htmlOptions additional HTML attributes.
  2993. * @return string the generated span.
  2994. */
  2995. public static function badge($label, $htmlOptions = array())
  2996. {
  2997. $htmlOptions = self::addClassName('badge', $htmlOptions);
  2998. $color = self::popOption('color', $htmlOptions);
  2999. if (!empty($color))
  3000. $htmlOptions = self::addClassName('badge-' . $color, $htmlOptions);
  3001. return self::tag('span', $htmlOptions, $label);
  3002. }
  3003. // Typography
  3004. // http://twitter.github.com/bootstrap/components.html#typography
  3005. // --------------------------------------------------
  3006. /**
  3007. * Generates a hero unit.
  3008. * @param string $heading the heading text.
  3009. * @param string $content the content text.
  3010. * @param array $htmlOptions additional HTML attributes.
  3011. * @return string the generated hero unit.
  3012. */
  3013. public static function heroUnit($heading, $content, $htmlOptions = array())
  3014. {
  3015. $htmlOptions = self::addClassName('hero-unit', $htmlOptions);
  3016. $headingOptions = self::popOption('headingOptions', $htmlOptions, array());
  3017. ob_start();
  3018. echo self::tag('div', $htmlOptions);
  3019. echo self::tag('h1', $headingOptions, $heading);
  3020. echo $content;
  3021. echo '</div>';
  3022. return ob_get_clean();
  3023. }
  3024. /**
  3025. * Generates a pager header.
  3026. * @param string $heading the heading text.
  3027. * @param string $subtext the subtext.
  3028. * @param array $htmlOptions additional HTML attributes.
  3029. * @return string the generated pager header.
  3030. */
  3031. public static function pageHeader($heading, $subtext, $htmlOptions = array())
  3032. {
  3033. // todo: we may have to set an empty array() as default value
  3034. $htmlOptions = self::addClassName('page-header', $htmlOptions);
  3035. $headerOptions = self::popOption('headerOptions', $htmlOptions, array());
  3036. $subtextOptions = self::popOption('subtextOptions', $htmlOptions, array());
  3037. ob_start();
  3038. echo self::openTag('div', $htmlOptions);
  3039. echo self::openTag('h1', $headerOptions);
  3040. echo CHtml::encode($heading) . ' ' . self::tag('small', $subtextOptions, $subtext);
  3041. echo '</h1>';
  3042. echo '</div>';
  3043. return ob_get_clean();
  3044. }
  3045. // Thumbnails
  3046. // http://twitter.github.com/bootstrap/components.html#thumbnails
  3047. // --------------------------------------------------
  3048. /**
  3049. * Generates a list of thumbnails.
  3050. * @param array $thumbnails the list configuration.
  3051. * @param array $htmlOptions additional HTML attributes.
  3052. * @return string the generated thumbnails.
  3053. */
  3054. public static function thumbnails($thumbnails, $htmlOptions = array())
  3055. {
  3056. if (is_array($thumbnails) && !empty($thumbnails))
  3057. {
  3058. /* todo: we may have to set an empty array() as default value */
  3059. $htmlOptions = self::addClassName('thumbnails', $htmlOptions);
  3060. $defaultSpan = self::popOption('span', $htmlOptions, 3);
  3061. ob_start();
  3062. echo self::openTag('ul', $htmlOptions);
  3063. foreach ($thumbnails as $thumbnailOptions)
  3064. {
  3065. $options = self::popOption('htmlOptions', $thumbnailOptions, array());
  3066. if (!empty($options))
  3067. $thumbnailOptions = self::mergeOptions($options, $thumbnailOptions);
  3068. $thumbnailOptions['itemOptions']['span'] = self::popOption('span', $thumbnailOptions, $defaultSpan);
  3069. $caption = self::popOption('caption', $thumbnailOptions, '');
  3070. $captionOptions = self::popOption('captionOptions', $thumbnailOptions, array());
  3071. $captionOptions = self::addClassName('caption', $captionOptions);
  3072. $label = self::popOption('label', $thumbnailOptions);
  3073. $labelOptions = self::popOption('labelOptions', $thumbnailOptions, array());
  3074. if (!empty($label))
  3075. $caption = self::tag('h3', $labelOptions, $label) . $caption;
  3076. $content = !empty($caption) ? self::tag('div', $captionOptions, $caption) : '';
  3077. $image = self::popOption('image', $thumbnailOptions);
  3078. $imageOptions = self::popOption('imageOptions', $thumbnailOptions, array());
  3079. $imageAlt = self::popOption('alt', $imageOptions, '');
  3080. if (!empty($image))
  3081. $content = CHtml::image($image, $imageAlt, $imageOptions) . $content;
  3082. $url = self::popOption('url', $thumbnailOptions, false);
  3083. echo $url !== false
  3084. ? self::thumbnailLink($content, $url, $thumbnailOptions)
  3085. : self::thumbnail($content, $thumbnailOptions);
  3086. }
  3087. echo '</ul>';
  3088. return ob_get_clean();
  3089. }
  3090. return '';
  3091. }
  3092. /**
  3093. * Generates a thumbnail.
  3094. * @param string $content the thumbnail content.
  3095. * @param array $htmlOptions additional HTML attributes.
  3096. * @return string the generated thumbnail.
  3097. */
  3098. public static function thumbnail($content, $htmlOptions = array())
  3099. {
  3100. $itemOptions = self::popOption('itemOptions', $htmlOptions, array());
  3101. $htmlOptions = self::addClassName('thumbnail', $htmlOptions);
  3102. ob_start();
  3103. echo self::openTag('li', $itemOptions);
  3104. echo self::openTag('div', $htmlOptions);
  3105. echo $content;
  3106. echo '</div>';
  3107. echo '</li>';
  3108. return ob_get_clean();
  3109. }
  3110. /**
  3111. * Generates a link thumbnail.
  3112. * @param string $content the thumbnail content.
  3113. * @param mixed $url the url that the thumbnail links to.
  3114. * @param array $htmlOptions additional HTML attributes.
  3115. * @return string the generated thumbnail.
  3116. */
  3117. public static function thumbnailLink($content, $url, $htmlOptions = array())
  3118. {
  3119. $itemOptions = self::popOption('itemOptions', $htmlOptions, array());
  3120. $htmlOptions = self::addClassName('thumbnail', $htmlOptions);
  3121. ob_start();
  3122. echo self::openTag('li', $itemOptions);
  3123. echo self::link($content, $url, $htmlOptions);
  3124. echo '</li>';
  3125. return ob_get_clean();
  3126. }
  3127. // Alerts
  3128. // http://twitter.github.com/bootstrap/components.html#alerts
  3129. // --------------------------------------------------
  3130. /**
  3131. * Generates an alert.
  3132. * @param string $color the color of the alert.
  3133. * @param string $message the message to display.
  3134. * @param array $htmlOptions additional HTML options.
  3135. * @return string the generated alert.
  3136. */
  3137. public static function alert($color, $message, $htmlOptions = array())
  3138. {
  3139. $htmlOptions = self::addClassName('alert', $htmlOptions);
  3140. if (!empty($color))
  3141. $htmlOptions = self::addClassName('alert-' . $color, $htmlOptions);
  3142. if (self::popOption('in', $htmlOptions, true))
  3143. $htmlOptions = self::addClassName('in', $htmlOptions);
  3144. if (self::popOption('block', $htmlOptions, false))
  3145. $htmlOptions = self::addClassName('alert-block', $htmlOptions);
  3146. if (self::popOption('fade', $htmlOptions, true))
  3147. $htmlOptions = self::addClassName('fade', $htmlOptions);
  3148. $closeText = self::popOption('closeText', $htmlOptions, self::CLOSE_TEXT);
  3149. $closeOptions = self::popOption('closeOptions', $htmlOptions, array());
  3150. ob_start();
  3151. echo self::openTag('div', $htmlOptions);
  3152. echo $closeText !== false ? self::closeLink($closeText, $closeOptions) : '';
  3153. echo $message;
  3154. echo '</div>';
  3155. return ob_get_clean();
  3156. }
  3157. /**
  3158. * Generates an alert block.
  3159. * @param string $color the color of the alert.
  3160. * @param string $message the message to display.
  3161. * @param array $htmlOptions additional HTML options.
  3162. * @return string the generated alert.
  3163. */
  3164. public static function blockAlert($color, $message, $htmlOptions = array())
  3165. {
  3166. $htmlOptions['block'] = true;
  3167. return self::alert($color, $message, $htmlOptions);
  3168. }
  3169. // Progress bars
  3170. // http://twitter.github.com/bootstrap/components.html#progress
  3171. // --------------------------------------------------
  3172. /**
  3173. * Generates a progress bar.
  3174. * @param integer $width the progress in percent.
  3175. * @param array $htmlOptions additional HTML attributes.
  3176. * @return string the generated progress bar.
  3177. */
  3178. public static function progressBar($width = 0, $htmlOptions = array())
  3179. {
  3180. $htmlOptions = self::addClassName('progress', $htmlOptions);
  3181. $color = self::popOption('color', $htmlOptions);
  3182. if (!empty($color))
  3183. $htmlOptions = self::addClassName('progress-' . $color, $htmlOptions);
  3184. if (self::popOption('striped', $htmlOptions, false))
  3185. {
  3186. $htmlOptions = self::addClassName('progress-striped', $htmlOptions);
  3187. if (self::popOption('animated', $htmlOptions, false))
  3188. $htmlOptions = self::addClassName('active', $htmlOptions);
  3189. }
  3190. $barOptions = self::popOption('barOptions', $htmlOptions, array());
  3191. $content = self::popOption('content', $htmlOptions, '');
  3192. $barOptions = self::defaultOption('content', $content, $barOptions);
  3193. ob_start();
  3194. echo self::openTag('div', $htmlOptions);
  3195. echo self::bar($width, $barOptions);
  3196. echo '</div>';
  3197. return ob_get_clean();
  3198. }
  3199. /**
  3200. * Generates a striped progress bar.
  3201. * @param integer $width the progress in percent.
  3202. * @param array $htmlOptions additional HTML attributes.
  3203. * @return string the generated progress bar.
  3204. */
  3205. public static function stripedProgressBar($width = 0, $htmlOptions = array())
  3206. {
  3207. $htmlOptions['striped'] = true;
  3208. return self::progressBar($width, $htmlOptions);
  3209. }
  3210. /**
  3211. * Generates an animated progress bar.
  3212. * @param integer $width the progress in percent.
  3213. * @param array $htmlOptions additional HTML attributes.
  3214. * @return string the generated progress bar.
  3215. */
  3216. public static function animatedProgressBar($width = 0, $htmlOptions = array())
  3217. {
  3218. $htmlOptions['animated'] = true;
  3219. return self::stripedProgressBar($width, $htmlOptions);
  3220. }
  3221. /**
  3222. * Generates a stacked progress bar.
  3223. * @param array $bars the bar configurations.
  3224. * @param array $htmlOptions additional HTML attributes.
  3225. * @return string the generated progress bar.
  3226. */
  3227. public static function stackedProgressBar($bars, $htmlOptions = array())
  3228. {
  3229. if (is_array($bars) && !empty($bars))
  3230. {
  3231. $htmlOptions = self::addClassName('progress', $htmlOptions);
  3232. ob_start();
  3233. echo self::openTag('div', $htmlOptions);
  3234. foreach ($bars as $barOptions)
  3235. {
  3236. $options = self::popOption('htmlOptions', $barOptions, array());
  3237. if (!empty($options))
  3238. $barOptions = self::mergeOptions($options, $barOptions);
  3239. $width = self::popOption('width', $barOptions, 0);
  3240. echo self::bar($width, $barOptions);
  3241. }
  3242. echo '</div>';
  3243. return ob_get_clean();
  3244. }
  3245. return '';
  3246. }
  3247. /**
  3248. * Generates a progress bar.
  3249. * @param integer $width the progress in percent.
  3250. * @param array $htmlOptions additional HTML attributes.
  3251. * @return string the generated bar.
  3252. */
  3253. public static function bar($width = 0, $htmlOptions = array())
  3254. {
  3255. $htmlOptions = self::addClassName('bar', $htmlOptions);
  3256. $color = self::popOption('color', $htmlOptions);
  3257. if (!empty($color))
  3258. $htmlOptions = self::addClassName('bar-' . $color, $htmlOptions);
  3259. if ($width < 0)
  3260. $width = 0;
  3261. if ($width > 100)
  3262. $width = 100;
  3263. $htmlOptions = self::addStyles("width: {$width}%;", $htmlOptions);
  3264. $content = self::popOption('content', $htmlOptions, '');
  3265. return self::tag('div', $htmlOptions, $content);
  3266. }
  3267. // Media objects
  3268. // http://twitter.github.com/bootstrap/components.html#media
  3269. // --------------------------------------------------
  3270. /**
  3271. * Generates a list of media objects.
  3272. * @param array $mediaObjects media object configurations.
  3273. * @return string generated list.
  3274. */
  3275. public static function mediaObjects($mediaObjects)
  3276. {
  3277. if (is_array($mediaObjects) && !empty($mediaObjects))
  3278. {
  3279. ob_start();
  3280. foreach ($mediaObjects as $mediaObjectOptions)
  3281. {
  3282. $image = self::getOption('image', $mediaObjectOptions);
  3283. $heading = self::getOption('heading', $mediaObjectOptions, '');
  3284. $content = self::getOption('content', $mediaObjectOptions, '');
  3285. $itemOptions = self::getOption('htmlOptions', $mediaObjectOptions, array());
  3286. $itemOptions['items'] = self::popOption('items', $mediaObjectOptions, array());
  3287. echo self::mediaObject($image, $heading, $content, $itemOptions);
  3288. }
  3289. return ob_get_clean();
  3290. }
  3291. return '';
  3292. }
  3293. /**
  3294. * Generates a single media object.
  3295. * @param string $image the image url.
  3296. * @param string $title the title text.
  3297. * @param string $content the content text.
  3298. * @param array $htmlOptions additional HTML attributes.
  3299. * @return string the media object.
  3300. */
  3301. public static function mediaObject($image, $heading, $content, $htmlOptions = array())
  3302. {
  3303. $htmlOptions = self::addClassName('media', $htmlOptions);
  3304. $linkOptions = self::popOption('linkOptions', $htmlOptions, array());
  3305. $linkOptions = self::defaultOption('pull', self::PULL_LEFT, $linkOptions);
  3306. $imageOptions = self::popOption('imageOptions', $htmlOptions, array());
  3307. $imageOptions = self::addClassName('media-object', $imageOptions);
  3308. $contentOptions = self::popOption('contentOptions', $htmlOptions, array());
  3309. $contentOptions = self::addClassName('media-body', $contentOptions);
  3310. $headingOptions = self::popOption('headingOptions', $htmlOptions, array());
  3311. $headingOptions = self::addClassName('media-heading', $headingOptions);
  3312. $items = self::popOption('items', $htmlOptions);
  3313. ob_start();
  3314. echo self::openTag('div', $htmlOptions);
  3315. $alt = self::popOption('alt', $imageOptions, '');
  3316. $href = self::popOption('href', $linkOptions, '#');
  3317. if (!empty($image))
  3318. echo self::link(CHtml::image($image, $alt, $imageOptions), $href, $linkOptions);
  3319. echo self::openTag('div', $contentOptions);
  3320. echo self::tag('h4', $headingOptions, $heading);
  3321. echo $content;
  3322. if (!empty($items))
  3323. echo self::mediaObjects($items);
  3324. echo '</div></div>';
  3325. return ob_get_clean();
  3326. }
  3327. // Misc
  3328. // http://twitter.github.com/bootstrap/components.html#misc
  3329. // --------------------------------------------------
  3330. /**
  3331. * Generates a well element.
  3332. * @param string $content the well content.
  3333. * @param array $htmlOptions additional HTML attributes.
  3334. * @return string the generated well.
  3335. */
  3336. public static function well($content, $htmlOptions = array())
  3337. {
  3338. $htmlOptions = self::addClassName('well', $htmlOptions);
  3339. $size = self::popOption('size', $htmlOptions);
  3340. if (!empty($size))
  3341. $htmlOptions = self::addClassName('well-' . $size, $htmlOptions);
  3342. ob_start();
  3343. echo self::tag('div', $htmlOptions, $content);
  3344. return ob_get_clean();
  3345. }
  3346. /**
  3347. * Generates a close link.
  3348. * @param string $label the link label text.
  3349. * @param array $htmlOptions additional HTML attributes.
  3350. * @return string the generated link.
  3351. */
  3352. public static function closeLink($label = self::CLOSE_TEXT, $htmlOptions = array())
  3353. {
  3354. $htmlOptions = self::defaultOption('href', '#', $htmlOptions);
  3355. return self::closeIcon('a', $label, $htmlOptions);
  3356. }
  3357. /**
  3358. * Generates a close button.
  3359. * @param string $label the button label text.
  3360. * @param array $htmlOptions the HTML options for the button.
  3361. * @return string the generated button.
  3362. */
  3363. public static function closeButton($label = self::CLOSE_TEXT, $htmlOptions = array())
  3364. {
  3365. return self::closeIcon('button', $label, $htmlOptions);
  3366. }
  3367. /**
  3368. * Generates a close element.
  3369. * @param string $label the element label text.
  3370. * @param array $htmlOptions additional HTML attributes.
  3371. * @return string the generated element.
  3372. */
  3373. public static function closeIcon($tag, $label, $htmlOptions = array())
  3374. {
  3375. $htmlOptions = self::addClassName('close', $htmlOptions);
  3376. $htmlOptions = self::defaultOption('data-dismiss', 'alert', $htmlOptions);
  3377. return self::tag($tag, $htmlOptions, $label);
  3378. }
  3379. /**
  3380. * Generates a collapse link.
  3381. * @param string $label the link label.
  3382. * @param string $target the CSS selector.
  3383. * @param array $htmlOptions additional HTML attributes.
  3384. * @return string the generated link.
  3385. */
  3386. public static function collapseLink($label, $target, $htmlOptions = array())
  3387. {
  3388. $htmlOptions['data-toggle'] = 'collapse';
  3389. return self::link($label, $target, $htmlOptions);
  3390. }
  3391. /**
  3392. * Generates a collapse icon.
  3393. * @param string $target the CSS selector for the target element.
  3394. * @param array $htmlOptions additional HTML attributes.
  3395. * @return string the generated icon.
  3396. */
  3397. public static function collapseIcon($target, $htmlOptions = array())
  3398. {
  3399. $htmlOptions = self::addClassName('btn btn-navbar', $htmlOptions);
  3400. $htmlOptions = self::defaultOptions($htmlOptions, array(
  3401. 'data-toggle' => 'collapse',
  3402. 'data-target' => $target,
  3403. ));
  3404. ob_start();
  3405. echo self::openTag('a', $htmlOptions);
  3406. echo '<span class="icon-bar"></span><span class="icon-bar"></span><span class="icon-bar"></span>';
  3407. echo '</a>';
  3408. return ob_get_clean();
  3409. }
  3410. //
  3411. // JAVASCRIPT
  3412. // --------------------------------------------------
  3413. // Tooltips and Popovers
  3414. // http://twitter.github.com/bootstrap/javascript.html#tooltips
  3415. // http://twitter.github.com/bootstrap/javascript.html#popovers
  3416. // --------------------------------------------------
  3417. /**
  3418. * Generates a tooltip.
  3419. * @param string $label the tooltip link label text.
  3420. * @param mixed $url the link url.
  3421. * @param string $content the tooltip content text.
  3422. * @param array $htmlOptions additional HTML attributes.
  3423. * @return string the generated tooltip.
  3424. */
  3425. public static function tooltip($label, $url, $content, $htmlOptions = array())
  3426. {
  3427. $htmlOptions['rel'] = 'tooltip';
  3428. return self::tooltipPopover($label, $url, $content, $htmlOptions);
  3429. }
  3430. /**
  3431. * Generates a popover.
  3432. * @param string $label the popover link label text.
  3433. * @param string $title the popover title text.
  3434. * @param string $content the popover content text.
  3435. * @param array $htmlOptions additional HTML attributes.
  3436. * @return string the generated popover.
  3437. */
  3438. public static function popover($label, $title, $content, $htmlOptions = array())
  3439. {
  3440. $htmlOptions['rel'] = 'popover';
  3441. $htmlOptions['data-content'] = $content;
  3442. $htmlOptions['data-toggle'] = 'popover';
  3443. return self::tooltipPopover($label, '#', $title, $htmlOptions);
  3444. }
  3445. /**
  3446. * Generates a base tooltip.
  3447. * @param string $label the tooltip link label text.
  3448. * @param mixed $url the link url.
  3449. * @param string $title the tooltip title text.
  3450. * @param array $htmlOptions additional HTML attributes.
  3451. * @return string the generated tooltip.
  3452. */
  3453. protected static function tooltipPopover($label, $url, $title, $htmlOptions)
  3454. {
  3455. $htmlOptions = self::defaultOption('title', $title, $htmlOptions);
  3456. if (self::popOption('animation', $htmlOptions))
  3457. $htmlOptions = self::defaultOption('data-animation', true, $htmlOptions);
  3458. if (self::popOption('html', $htmlOptions))
  3459. $htmlOptions = self::defaultOption('data-html', true, $htmlOptions);
  3460. $placement = self::popOption('placement', $htmlOptions);
  3461. if (!empty($placement))
  3462. $htmlOptions = self::defaultOption('data-placement', $placement, $htmlOptions);
  3463. if (self::popOption('selector', $htmlOptions))
  3464. $htmlOptions = self::defaultOption('data-selector', true, $htmlOptions);
  3465. $trigger = self::popOption('trigger', $htmlOptions);
  3466. if (!empty($trigger))
  3467. $htmlOptions = self::defaultOption('data-trigger', $trigger, $htmlOptions);
  3468. if (($delay = self::popOption('delay', $htmlOptions)) !== null)
  3469. $htmlOptions = self::defaultOption('data-delay', $delay, $htmlOptions);
  3470. return self::link($label, $url, $htmlOptions);
  3471. }
  3472. // Carousel
  3473. // http://twitter.github.com/bootstrap/javascript.html#carousel
  3474. // --------------------------------------------------
  3475. /**
  3476. * Generates an image carousel.
  3477. * @param array $items the item configurations.
  3478. * @param array $htmlOptions additional HTML attributes.
  3479. * @return string the generated carousel.
  3480. */
  3481. public static function carousel($items, $htmlOptions = array())
  3482. {
  3483. if (is_array($items) && !empty($items))
  3484. {
  3485. $id = self::getOption('id', $htmlOptions, CHtml::ID_PREFIX . CHtml::$count++);
  3486. $htmlOptions = self::defaultOption('id', $id, $htmlOptions);
  3487. $selector = '#' . $id;
  3488. $htmlOptions = self::addClassName('carousel', $htmlOptions);
  3489. if (self::popOption('slide', $htmlOptions, true))
  3490. $htmlOptions = self::addClassName('slide', $htmlOptions);
  3491. $interval = self::popOption('data-interval', $htmlOptions);
  3492. if ($interval)
  3493. $htmlOptions = self::defaultOption('data-interval', $interval, $htmlOptions);
  3494. $pause = self::popOption('data-interval', $htmlOptions);
  3495. if ($pause) // todo: add attribute validation if seen necessary.
  3496. $htmlOptions = self::defaultOption('data-pause', $pause, $htmlOptions);
  3497. $indicatorOptions = self::popOption('indicatorOptions', $htmlOptions, array());
  3498. $innerOptions = self::popOption('innerOptions', $htmlOptions, array());
  3499. $innerOptions = self::addClassName('carousel-inner', $innerOptions);
  3500. $prevOptions = self::popOption('prevOptions', $htmlOptions, array());
  3501. $prevLabel = self::popOption('label', $prevOptions, '&lsaquo;');
  3502. $nextOptions = self::popOption('nextOptions', $htmlOptions, array());
  3503. $nextLabel = self::popOption('label', $nextOptions, '&rsaquo;');
  3504. $hidePrevAndNext = self::popOption('hidePrevAndNext', $htmlOptions, false);
  3505. ob_start();
  3506. echo self::openTag('div', $htmlOptions);
  3507. echo self::carouselIndicators($selector, count($items), $indicatorOptions);
  3508. echo self::openTag('div', $innerOptions);
  3509. foreach ($items as $i => $itemOptions)
  3510. {
  3511. $itemOptions = self::addClassName('item', $itemOptions);
  3512. if ($i === 0) // first item should be active
  3513. $itemOptions = self::addClassName('active', $itemOptions);
  3514. $content = self::popOption('content', $itemOptions, '');
  3515. $image = self::popOption('image', $itemOptions, '');
  3516. $imageAlt = self::popOption('alt', $itemOptions, '');
  3517. $imageOptions = self::popOption('imageOptions', $itemOptions, array());
  3518. if (!empty($image))
  3519. $content = CHtml::image($image, $imageAlt, $imageOptions);
  3520. $label = self::popOption('label', $itemOptions);
  3521. $caption = self::popOption('caption', $itemOptions);
  3522. echo self::carouselItem($content, $label, $caption, $itemOptions);
  3523. }
  3524. echo '</div>';
  3525. if (!$hidePrevAndNext)
  3526. {
  3527. echo self::carouselPrevLink($prevLabel, $selector, $prevOptions);
  3528. echo self::carouselNextLink($nextLabel, $selector, $nextOptions);
  3529. }
  3530. echo '</div>';
  3531. return ob_get_clean();
  3532. }
  3533. return '';
  3534. }
  3535. /**
  3536. * Generates a carousel item.
  3537. * @param string $content the content.
  3538. * @param string $label the item label text.
  3539. * @param string $caption the item caption text.
  3540. * @param array $htmlOptions additional HTML attributes.
  3541. * @return string the generated item.
  3542. */
  3543. public static function carouselItem($content, $label, $caption, $htmlOptions = array())
  3544. {
  3545. $overlayOptions = self::popOption('overlayOptions', $htmlOptions, array());
  3546. $overlayOptions = self::addClassName('carousel-caption', $overlayOptions);
  3547. $labelOptions = self::popOption('labelOptions', $htmlOptions, array());
  3548. $captionOptions = self::popOption('captionOptions', $htmlOptions, array());
  3549. ob_start();
  3550. echo self::openTag('div', $htmlOptions);
  3551. echo $content;
  3552. if (isset($label) || isset($caption))
  3553. {
  3554. echo self::openTag('div', $overlayOptions);
  3555. if ($label)
  3556. echo self::tag('h4', $labelOptions, $label);
  3557. if ($caption)
  3558. echo self::tag('p', $captionOptions, $caption);
  3559. echo '</div>';
  3560. }
  3561. echo '</div>';
  3562. return ob_get_clean();
  3563. }
  3564. /**
  3565. * Generates a previous link for the carousel.
  3566. * @param string $label the link label text.
  3567. * @param mixed $url the link url.
  3568. * @param array $htmlOptions additional HTML attributes.
  3569. * @return string the generated link.
  3570. */
  3571. public static function carouselPrevLink($label, $url, $htmlOptions = array())
  3572. {
  3573. $htmlOptions['data-slide'] = 'prev';
  3574. $htmlOptions = self::addClassName('carousel-control left', $htmlOptions);
  3575. return self::link($label, $url, $htmlOptions);
  3576. }
  3577. /**
  3578. * Generates a next link for the carousel.
  3579. * @param string $label the link label text.
  3580. * @param mixed $url the link url.
  3581. * @param array $htmlOptions additional HTML attributes.
  3582. * @return string the generated link.
  3583. */
  3584. public static function carouselNextLink($label, $url, $htmlOptions = array())
  3585. {
  3586. $htmlOptions['data-slide'] = 'next';
  3587. $htmlOptions = self::addClassName('carousel-control right', $htmlOptions);
  3588. return self::link($label, $url, $htmlOptions);
  3589. }
  3590. /**
  3591. * Generates an indicator for the carousel.
  3592. * @param string $target the CSS selector for the target element.
  3593. * @param integer $numSlides the number of slides.
  3594. * @param array $htmlOptions additional HTML attributes.
  3595. * @return string the generated indicators.
  3596. */
  3597. public static function carouselIndicators($target, $numSlides, $htmlOptions = array())
  3598. {
  3599. $htmlOptions = self::addClassName('carousel-indicators', $htmlOptions);
  3600. ob_start();
  3601. echo self::openTag('ol', $htmlOptions);
  3602. for ($i = 0; $i < $numSlides; $i++)
  3603. {
  3604. $itemOptions = array('data-target' => $target, 'data-slide-to' => $i);
  3605. if ($i === 0)
  3606. $itemOptions['class'] = 'active';
  3607. echo self::tag('li', $itemOptions);
  3608. }
  3609. echo '</ol>';
  3610. return ob_get_clean();
  3611. }
  3612. // UTILITIES
  3613. // --------------------------------------------------
  3614. /**
  3615. * Appends new class names to the named index "class" at the `$htmlOptions` parameter.
  3616. * @param mixed $className the class(es) to append to `$htmlOptions`
  3617. * @param array $htmlOptions the HTML tag attributes to modify
  3618. * @return array the options.
  3619. */
  3620. public static function addClassName($className, $htmlOptions)
  3621. {
  3622. if (is_array($className))
  3623. $className = implode(' ', $className);
  3624. $htmlOptions['class'] = isset($htmlOptions['class']) ? $htmlOptions['class'] . ' ' . $className : $className;
  3625. return $htmlOptions;
  3626. }
  3627. /**
  3628. * Appends a CSS style string to the given options.
  3629. * @param string $styles the CSS style string.
  3630. * @param array $htmlOptions the options.
  3631. * @return array the options.
  3632. */
  3633. public static function addStyles($styles, $htmlOptions)
  3634. {
  3635. $htmlOptions['style'] = isset($htmlOptions['style']) ? $htmlOptions['style'] . ' ' . $styles : $styles;
  3636. return $htmlOptions;
  3637. }
  3638. /**
  3639. * Copies the option values from one option array to another.
  3640. * @param array $names the option names to copy.
  3641. * @param array $fromOptions the options to copy from.
  3642. * @param array $options the options to copy to.
  3643. * @return array the options.
  3644. */
  3645. public static function copyOptions($names, $fromOptions, $options)
  3646. {
  3647. if (is_array($fromOptions) && is_array($options))
  3648. {
  3649. foreach ($names as $key)
  3650. {
  3651. if (isset($fromOptions[$key]) && !isset($options[$key]))
  3652. $options[$key] = self::getOption($key, $fromOptions);
  3653. }
  3654. }
  3655. return $options;
  3656. }
  3657. /**
  3658. * Moves the option values from one option array to another.
  3659. * @param array $names the option names to move.
  3660. * @param array $fromOptions the options to move from.
  3661. * @param array $options the options to move to.
  3662. * @return array the options.
  3663. */
  3664. public static function moveOptions($names, $fromOptions, $options)
  3665. {
  3666. if (is_array($fromOptions) && is_array($options))
  3667. {
  3668. foreach ($names as $key)
  3669. {
  3670. if (isset($fromOptions[$key]) && !isset($options[$key]))
  3671. $options[$key] = self::popOption($key, $fromOptions);
  3672. }
  3673. }
  3674. return $options;
  3675. }
  3676. /**
  3677. * Sets multiple default options for the given options array.
  3678. * @param array $options the options to set defaults for.
  3679. * @param array $defaults the default options.
  3680. * @return array the options with default values.
  3681. */
  3682. public static function defaultOptions($options, $defaults)
  3683. {
  3684. if (is_array($defaults) && is_array($options))
  3685. {
  3686. foreach ($defaults as $name => $value)
  3687. $options = self::defaultOption($name, $value, $options);
  3688. }
  3689. return $options;
  3690. }
  3691. /**
  3692. * Merges two options arrays.
  3693. * @param array $a options to be merged to
  3694. * @param array $b options to be merged from
  3695. * @return array the merged options.
  3696. */
  3697. public static function mergeOptions($a, $b)
  3698. {
  3699. return CMap::mergeArray($a, $b); // yeah I know but we might want to change this to be something else later
  3700. }
  3701. /**
  3702. * Returns an item from the given options or the default value if it's not set.
  3703. * @param string $name the name of the item.
  3704. * @param array $options the options to get from.
  3705. * @param mixed $defaultValue the default value.
  3706. * @return mixed the value.
  3707. */
  3708. public static function getOption($name, $options, $defaultValue = null)
  3709. {
  3710. return (is_array($options) && isset($options[$name])) ? $options[$name] : $defaultValue;
  3711. }
  3712. /**
  3713. * Removes an item from the given options and returns the value.
  3714. * @param string $name the name of the item.
  3715. * @param array $options the options to remove the item from.
  3716. * @param mixed $defaultValue the default value.
  3717. * @return mixed the value.
  3718. */
  3719. public static function popOption($name, &$options, $defaultValue = null)
  3720. {
  3721. if (is_array($options))
  3722. {
  3723. $value = self::getOption($name, $options, $defaultValue);
  3724. unset($options[$name]);
  3725. return $value;
  3726. }
  3727. else
  3728. return $defaultValue;
  3729. }
  3730. /**
  3731. * Sets the default value for an item in the given options.
  3732. * @param string $name the name of the item.
  3733. * @param mixed $value the default value.
  3734. * @param array $options the options.
  3735. * @return mixed
  3736. */
  3737. public static function defaultOption($name, $value, $options)
  3738. {
  3739. if (is_array($options) && !isset($options[$name]))
  3740. $options[$name] = $value;
  3741. return $options;
  3742. }
  3743. /**
  3744. * Removes the option values from the given options.
  3745. * @param array $options the options to remove from.
  3746. * @param array $names names to remove from the options.
  3747. * @return array the options.
  3748. */
  3749. public static function removeOptions($options, $names)
  3750. {
  3751. return array_diff_key($options, array_flip($names));
  3752. }
  3753. /**
  3754. * Adds the grid span class to the given options is applicable.
  3755. * @param array $htmlOptions the HTML attributes.
  3756. * @return boolean whether the span class was added.
  3757. */
  3758. protected static function addSpanClass(&$htmlOptions)
  3759. {
  3760. $span = self::popOption('span', $htmlOptions);
  3761. if (!empty($span))
  3762. $htmlOptions = self::addClassName('span' . $span, $htmlOptions);
  3763. }
  3764. }