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