PageRenderTime 68ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

/helpers/TbHtml.php

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