PageRenderTime 55ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 1ms

/e107_handlers/form_handler.php

https://github.com/CasperGemini/e107
PHP | 4384 lines | 2656 code | 795 blank | 933 comment | 486 complexity | 36b2a064186e9964bdf6e858e9dac778 MD5 | raw file
Possible License(s): GPL-2.0

Large files files are truncated, but you can click here to view the full file

  1. <?php
  2. /*
  3. * e107 website system
  4. *
  5. * Copyright (C) 2008-2012 e107 Inc (e107.org)
  6. * Released under the terms and conditions of the
  7. * GNU General Public License (http://www.gnu.org/licenses/gpl.txt)
  8. *
  9. * Form Handler
  10. *
  11. * $URL$
  12. * $Id$
  13. *
  14. */
  15. if (!defined('e107_INIT')) { exit; }
  16. /**
  17. *
  18. * @package e107
  19. * @subpackage e107_handlers
  20. * @version $Id$
  21. * @todo hardcoded text
  22. *
  23. * Automate Form fields creation. Produced markup is following e107 CSS/XHTML standards
  24. * If options argument is omitted, default values will be used (which OK most of the time)
  25. * Options are intended to handle some very special cases.
  26. *
  27. * Overall field options format (array or GET string like this one: var1=val1&var2=val2...):
  28. *
  29. * - id => (mixed) custom id attribute value
  30. * if numeric value is passed it'll be just appended to the name e.g. {filed-name}-{value}
  31. * if false is passed id will be not created
  32. * if empty string is passed (or no 'id' option is found)
  33. * in all other cases the value will be used as field id
  34. * default: empty string
  35. *
  36. * - class => (string) field class(es)
  37. * Example: 'tbox select class1 class2 class3'
  38. * NOTE: this will override core classes, so you have to explicit include them!
  39. * default: empty string
  40. *
  41. * - size => (int) size attribute value (used when needed)
  42. * default: 40
  43. *
  44. * - title (string) title attribute
  45. * default: empty string (omitted)
  46. *
  47. * - readonly => (bool) readonly attribute
  48. * default: false
  49. *
  50. * - selected => (bool) selected attribute (used when needed)
  51. * default: false
  52. *
  53. * checked => (bool) checked attribute (used when needed)
  54. * default: false
  55. * - disabled => (bool) disabled attribute
  56. * default: false
  57. *
  58. * - tabindex => (int) tabindex attribute value
  59. * default: inner tabindex counter
  60. *
  61. * - other => (string) additional data
  62. * Example: 'attribute1="value1" attribute2="value2"'
  63. * default: empty string
  64. */
  65. class e_form
  66. {
  67. protected $_tabindex_counter = 0;
  68. protected $_tabindex_enabled = true;
  69. protected $_cached_attributes = array();
  70. /**
  71. * @var user_class
  72. */
  73. protected $_uc;
  74. protected $_required_string;
  75. function __construct($enable_tabindex = false)
  76. {
  77. $this->_tabindex_enabled = $enable_tabindex;
  78. $this->_uc = e107::getUserClass();
  79. $this->setRequiredString('<span class="required">*&nbsp;</span>');
  80. }
  81. /**
  82. * Open a new form
  83. * @param string name
  84. * @param $method - post|get default is post
  85. * @param @target - e_REQUEST_URI by default
  86. * @param $other - unused at the moment.
  87. */
  88. public function open($name, $method=null, $target=null, $options=null)
  89. {
  90. if($target == null)
  91. {
  92. $target = e_REQUEST_URI;
  93. }
  94. if($method == null)
  95. {
  96. $method = "post";
  97. }
  98. $class = "";
  99. $autoComplete = "";
  100. parse_str($options,$options);
  101. $target = str_replace("&", "&amp;", $target);
  102. if(vartrue($options['class']))
  103. {
  104. $class = "class='".$options['class']."'";
  105. }
  106. if(isset($options['autocomplete'])) // leave as isset()
  107. {
  108. $autoComplete = " autocomplete='".($options['autocomplete'] ? 'on' : 'off')."'";
  109. }
  110. $text = "\n<form {$class} action='{$target}' id='".$this->name2id($name)."' method = '{$method}'{$autoComplete}>\n";
  111. if($method == 'get' && strpos($target,'='))
  112. {
  113. list($url,$qry) = explode("?",$target);
  114. parse_str($qry,$m);
  115. foreach($m as $k=>$v)
  116. {
  117. $text .= $this->hidden($k, $v);
  118. }
  119. }
  120. return $text;
  121. }
  122. /**
  123. * Close a Form
  124. */
  125. public function close()
  126. {
  127. return "</form>";
  128. }
  129. /**
  130. * Get required field markup string
  131. * @return string
  132. */
  133. public function getRequiredString()
  134. {
  135. return $this->_required_string;
  136. }
  137. /**
  138. * Set required field markup string
  139. * @param string $string
  140. * @return e_form
  141. */
  142. public function setRequiredString($string)
  143. {
  144. $this->_required_string = $string;
  145. return $this;
  146. }
  147. // For Comma separated keyword tags.
  148. function tags($name, $value, $maxlength = 200, $options = array())
  149. {
  150. if(is_string($options)) parse_str($options, $options);
  151. $options['class'] = 'tbox span1 e-tags';
  152. $options['size'] = 7;
  153. return $this->text($name, $value, $maxlength, $options);
  154. }
  155. /**
  156. * Text-Field Form Element
  157. * @param $name
  158. * @param $value
  159. * @param $maxlength
  160. * @param $options
  161. * - size: mini, small, medium, large, xlarge, xxlarge
  162. * - class:
  163. * - typeahead: 'users'
  164. *
  165. */
  166. function text($name, $value = '', $maxlength = 80, $options= array())
  167. {
  168. if(is_string($options))
  169. {
  170. parse_str($options,$options);
  171. }
  172. if(!vartrue($options['class']))
  173. {
  174. $options['class'] = "tbox";
  175. }
  176. if(deftrue('BOOTSTRAP') === 3)
  177. {
  178. $options['class'] .= ' form-control';
  179. }
  180. /*
  181. if(!vartrue($options['class']))
  182. {
  183. if($maxlength < 10)
  184. {
  185. $options['class'] = 'tbox input-text span3';
  186. }
  187. elseif($maxlength < 50)
  188. {
  189. $options['class'] = 'tbox input-text span7';
  190. }
  191. elseif($maxlength > 99)
  192. {
  193. $options['class'] = 'tbox input-text span7';
  194. }
  195. else
  196. {
  197. $options['class'] = 'tbox input-text';
  198. }
  199. }
  200. */
  201. if(vartrue($options['typeahead']))
  202. {
  203. if(vartrue($options['typeahead']) == 'users')
  204. {
  205. $options['data-source'] = e_BASE."user.php";
  206. $options['class'] .= " e-typeahead";
  207. }
  208. }
  209. if(vartrue($options['size']) && !is_numeric($options['size']))
  210. {
  211. $options['class'] .= " input-".$options['size'];
  212. unset($options['size']); // don't include in html 'size='.
  213. }
  214. $mlength = vartrue($maxlength) ? "maxlength=".$maxlength : "";
  215. $options = $this->format_options('text', $name, $options);
  216. //never allow id in format name-value for text fields
  217. return "<input type='text' name='{$name}' value='{$value}' {$mlength} ".$this->get_attributes($options, $name)." />";
  218. }
  219. function number($name, $value, $maxlength = 200, $options = array())
  220. {
  221. if(is_string($options)) parse_str($options, $options);
  222. if (vartrue($options['maxlength'])) $maxlength = $options['maxlength'];
  223. unset($options['maxlength']);
  224. if(!vartrue($options['size'])) $options['size'] = 15;
  225. if(!vartrue($options['class'])) $options['class'] = 'tbox number e-spinner input-small';
  226. if(!$value) $value = '0';
  227. return $this->text($name, $value, $maxlength, $options);
  228. }
  229. function email($name, $value, $maxlength = 200, $options = array())
  230. {
  231. $options = $this->format_options('text', $name, $options);
  232. //never allow id in format name-value for text fields
  233. return "<input type='email' name='{$name}' value='{$value}' maxlength='{$maxlength}'".$this->get_attributes($options, $name)." />
  234. ";
  235. }
  236. function iconpreview($id, $default, $width='', $height='') // FIXME
  237. {
  238. // XXX - $name ?!
  239. $parms = $name."|".$width."|".$height."|".$id;
  240. $sc_parameters .= 'mode=preview&default='.$default.'&id='.$id;
  241. return e107::getParser()->parseTemplate("{ICONPICKER=".$sc_parameters."}");
  242. }
  243. /**
  244. * @param $name
  245. * @param $default value
  246. * @param $label
  247. * @param $options - gylphs=1
  248. * @param $ajax
  249. */
  250. function iconpicker($name, $default, $label, $options = array(), $ajax = true)
  251. {
  252. $options['media'] = '_icon';
  253. return $this->imagepicker($name, $default, $label, $options);
  254. }
  255. /**
  256. * Internal Function used by imagepicker and filepicker
  257. */
  258. private function mediaUrl($category = '', $label = '', $tagid='', $extras=null)
  259. {
  260. $cat = ($category) ? '&amp;for='.$category : "";
  261. if(!$label) $label = ' Upload an image or file';
  262. if($tagid) $cat .= '&amp;tagid='.$tagid;
  263. if(is_string($extras))
  264. {
  265. parse_str($extras,$extras);
  266. }
  267. if(vartrue($extras['bbcode'])) $cat .= '&amp;bbcode=1';
  268. $mode = vartrue($extras['mode'],'main');
  269. $action = vartrue($extras['action'],'dialog');
  270. // $tabs // TODO - option to choose which tabs to display.
  271. //TODO Parse selection data back to parent form.
  272. $url = e_ADMIN_ABS."image.php?mode={$mode}&amp;action={$action}".$cat;
  273. $url .= "&amp;iframe=1";
  274. if(vartrue($extras['w']))
  275. {
  276. $url .= "&amp;w=".$extras['w'];
  277. }
  278. if(vartrue($extras['glyphs']))
  279. {
  280. $url .= "&amp;glyphs=1";
  281. }
  282. if(vartrue($extras['video']))
  283. {
  284. $url .= "&amp;video=1";
  285. }
  286. $title = "Media Manager : ".$category;
  287. // $ret = "<a title=\"{$title}\" rel='external' class='e-dialog' href='".$url."'>".$label."</a>"; // using colorXXXbox.
  288. $ret = "<a title=\"{$title}\" class='e-modal' data-modal-caption='Media Manager' data-cache='false' data-target='#uiModal' href='".$url."'>".$label."</a>"; // using bootstrap.
  289. // $footer = "<div style=\'padding:5px;text-align:center\' <a href=\'#\' >Save</a></div>";
  290. $footer = '';
  291. if(!e107::getRegistry('core/form/mediaurl'))
  292. {
  293. /*
  294. e107::js('core','core/admin.js','prototype');
  295. e107::js('core','core/dialog.js','prototype');
  296. e107::js('core','core/draggable.js','prototype');
  297. e107::css('core','core/dialog/dialog.css','prototype');
  298. e107::css('core','core/dialog/e107/e107.css','prototype');
  299. e107::js('footer-inline','
  300. $$("a.e-dialog").invoke("observe", "click", function(ev) {
  301. var element = ev.findElement("a");
  302. ev.stop();
  303. new e107Widgets.URLDialog(element.href, {
  304. id: element["id"] || "e-dialog",
  305. width: 890,
  306. height: 680
  307. }).center().setHeader("Media Manager : '.$category.'").setFooter('.$footer.').activate().show();
  308. });
  309. ','prototype');
  310. */
  311. e107::setRegistry('core/form/mediaurl', true);
  312. }
  313. return $ret;
  314. }
  315. /**
  316. * Avatar Picker
  317. * @param $name - form element name ie. value to be posted.
  318. * @param $curVal - current avatar value. ie. the image-file name or URL.
  319. */
  320. function avatarpicker($name,$curVal='',$options=array())
  321. {
  322. $tp = e107::getParser();
  323. $pref = e107::getPref();
  324. $attr = "aw=".$pref['im_width']."&ah=".$pref['im_height'];
  325. $tp->setThumbSize($pref['im_width'],$pref['im_height']);
  326. $blankImg = $tp->thumbUrl(e_IMAGE."generic/blank_avatar.jpg",$attr);
  327. $localonly = true; //TODO add a pref for allowing external or internal avatars or both.
  328. $idinput = $this->name2id($name);
  329. $previnput = $idinput."-preview";
  330. $optioni = $idinput."-options";
  331. $path = (substr($curVal,0,8) == '-upload-') ? '{e_AVATAR}upload/' : '{e_AVATAR}default/';
  332. $curVal = str_replace('-upload-','',$curVal);
  333. $img = (strpos($curVal,"://")!==false) ? $curVal : $tp->thumbUrl($path.$curVal);
  334. if(!$curVal)
  335. {
  336. $img = $blankImg;
  337. }
  338. if($localonly == true)
  339. {
  340. $text = "<input class='tbox' style='width:80%' id='{$idinput}' type='hidden' name='image' size='40' value='{$curVal}' maxlength='100' />";
  341. $text .= "<img src='".$img."' id='{$previnput}' class='img-rounded e-expandit e-tip avatar' style='cursor:pointer; width:".$pref['im_width']."px; height:".$pref['im_height']."px' title='Click on the avatar to change it'/>"; // TODO LAN
  342. }
  343. else
  344. {
  345. $text = "<input class='tbox' style='width:80%' id='{$idinput}' type='text' name='image' size='40' value='$curVal' maxlength='100' title=\"".LAN_SIGNUP_111."\" />";
  346. $text .= "<img src='".$img."' id='{$previnput}' style='display:none' />";
  347. $text .= "<input class='img-rounded btn btn-default button e-expandit' type ='button' style='cursor:pointer' size='30' value=\"Choose Avatar\" />"; //TODO Common LAN.
  348. }
  349. $avFiles = e107::getFile()->get_files(e_AVATAR_DEFAULT,".jpg|.png|.gif|.jpeg|.JPG|.GIF|.PNG");
  350. $text .= "\n<div id='{$optioni}' style='display:none;padding:10px' >\n"; //TODO unique id.
  351. if (vartrue($pref['avatar_upload']) && FILE_UPLOADS && vartrue($options['upload']))
  352. {
  353. $diz = LAN_USET_32.($pref['im_width'] || $pref['im_height'] ? "\n".str_replace(array('--WIDTH--','--HEIGHT--'), array($pref['im_width'], $pref['im_height']), LAN_USER_86) : "");
  354. $text .= "<div style='margin-bottom:10px'>".LAN_USET_26."
  355. <input class='tbox' name='file_userfile[avatar]' type='file' size='47' title=\"{$diz}\" />
  356. </div>
  357. <div class='divider'><span>OR</span></div>";
  358. }
  359. foreach($avFiles as $fi)
  360. {
  361. $img_path = $tp->thumbUrl(e_AVATAR_DEFAULT.$fi['fname']);
  362. $text .= "\n<a class='e-expandit' title='Choose this avatar' href='#{$optioni}'><img src='".$img_path."' alt='' onclick=\"insertext('".$fi['fname']."', '".$idinput."');document.getElementById('".$previnput."').src = this.src;\" /></a> ";
  363. //TODO javascript CSS selector
  364. }
  365. $text .= "<br />
  366. </div>";
  367. // Used by usersettings.php right now.
  368. return $text;
  369. //TODO discuss and FIXME
  370. // Intentionally disable uploadable avatar and photos at this stage
  371. if (false && $pref['avatar_upload'] && FILE_UPLOADS)
  372. {
  373. $text .= "<br /><span class='smalltext'>".LAN_SIGNUP_25."</span> <input class='tbox' name='file_userfile[]' type='file' size='40' />
  374. <br /><div class='smalltext'>".LAN_SIGNUP_34."</div>";
  375. }
  376. if (false && $pref['photo_upload'] && FILE_UPLOADS)
  377. {
  378. $text .= "<br /><span class='smalltext'>".LAN_SIGNUP_26."</span> <input class='tbox' name='file_userfile[]' type='file' size='40' />
  379. <br /><div class='smalltext'>".LAN_SIGNUP_34."</div>";
  380. }
  381. }
  382. /**
  383. * FIXME {IMAGESELECTOR} rewrite
  384. * @param string $name input name
  385. * @param string $default default value
  386. * @param string $label custom label
  387. * @param string $sc_parameters shortcode parameters
  388. * --- SC Parameter list ---
  389. * - media: if present - load from media category table
  390. * - w: preview width in pixels
  391. * - h: preview height in pixels
  392. * - help: tooltip
  393. * - video: when set to true, will enable the Youtube (video) tab.
  394. * @example $frm->imagepicker('banner_image', $_POST['banner_image'], '', 'banner'); // all images from category 'banner_image' + common images.
  395. * @example $frm->imagepicker('banner_image', $_POST['banner_image'], '', 'media=banner&w=600');
  396. * @return string html output
  397. */
  398. function imagepicker($name, $default, $label = '', $sc_parameters = '')
  399. {
  400. $tp = e107::getParser();
  401. $name_id = $this->name2id($name);
  402. $meta_id = $name_id."-meta";
  403. if(is_string($sc_parameters))
  404. {
  405. if(strpos($sc_parameters, '=') === false) $sc_parameters = 'media='.$sc_parameters;
  406. parse_str($sc_parameters, $sc_parameters);
  407. }
  408. // print_a($sc_parameters);
  409. if(empty($sc_parameters['media']))
  410. {
  411. $sc_parameters['media'] = '_common';
  412. }
  413. $default_thumb = $default;
  414. if($default)
  415. {
  416. if($video = $tp->toVideo($default, array('thumb'=>'src')))
  417. {
  418. $default_url = $video;
  419. }
  420. else
  421. {
  422. if('{' != $default[0])
  423. {
  424. // convert to sc path
  425. $default_thumb = $tp->createConstants($default, 'nice');
  426. $default = $tp->createConstants($default, 'mix');
  427. }
  428. $default_url = $tp->replaceConstants($default, 'abs');
  429. }
  430. $blank = FALSE;
  431. }
  432. else
  433. {
  434. //$default = $default_url = e_IMAGE_ABS."generic/blank.gif";
  435. $default_url = e_IMAGE_ABS."generic/nomedia.png";
  436. $blank = TRUE;
  437. }
  438. //$width = intval(vartrue($sc_parameters['width'], 150));
  439. $cat = $tp->toDB(vartrue($sc_parameters['media']));
  440. if($cat == '_icon') // ICONS
  441. {
  442. $ret = "<div class='imgselector-container' style='display:block;width:64px;min-height:64px'>";
  443. $thpath = isset($sc_parameters['nothumb']) || vartrue($hide) ? $default : $default_thumb;
  444. $label = "<div id='{$name_id}_prev' class='text-center well well-small image-selector' >";
  445. $label .= $tp->toIcon($default_url);
  446. $label .= "
  447. </div>";
  448. // $label = "<img id='{$name_id}_prev' src='{$default_url}' alt='{$default_url}' class='well well-small image-selector' style='{$style}' />";
  449. }
  450. else // Images
  451. {
  452. $title = (vartrue($sc_parameters['help'])) ? "title='".$sc_parameters['help']."'" : "";
  453. $width = vartrue($sc_parameters['w'], 120);
  454. $height = vartrue($sc_parameters['h'], 100);
  455. $ret = "<div class='imgselector-container e-tip' {$title} style='margin-right:25px; display:inline-block; width:".$width."px;min-height:".$height."px;'>";
  456. $att = 'aw='.$width."'&ah=".$height."'";
  457. $thpath = isset($sc_parameters['nothumb']) || vartrue($hide) ? $default : $tp->thumbUrl($default_thumb, $att, true);
  458. $label = "<img id='{$name_id}_prev' src='{$default_url}' alt='{$default_url}' class='well well-small image-selector' style='display:block;' />";
  459. if($cat != 'news' && $cat !='page' && $cat !='')
  460. {
  461. $cat = $cat . "_image";
  462. }
  463. }
  464. $ret .= $this->mediaUrl($cat, $label,$name_id,$sc_parameters);
  465. $ret .= "</div>\n";
  466. $ret .= "<input type='hidden' name='{$name}' id='{$name_id}' value='{$default}' />";
  467. $ret .= "<input type='hidden' name='mediameta_{$name}' id='{$meta_id}' value='' />";
  468. // $ret .= $this->text($name,$default); // to be hidden eventually.
  469. return $ret;
  470. // ----------------
  471. }
  472. function filepicker($name, $default, $label = '', $sc_parameters = '')
  473. {
  474. $tp = e107::getParser();
  475. $name_id = $this->name2id($name);
  476. if(is_string($sc_parameters))
  477. {
  478. if(strpos($sc_parameters, '=') === false) $sc_parameters = 'media='.$sc_parameters;
  479. parse_str($sc_parameters, $sc_parameters);
  480. }
  481. $cat = vartrue($sc_parameters['media']) ? $tp->toDB($sc_parameters['media']) : "_common_file";
  482. $default_label = ($default) ? $default : "Choose a file";
  483. $label = "<span id='{$name_id}_prev' class='btn btn-default btn-small'>".basename($default_label)."</span>";
  484. $sc_parameters['mode'] = 'main';
  485. $sc_parameters['action'] = 'dialog';
  486. // $ret .= $this->mediaUrl($cat, $label,$name_id,"mode=dialog&action=list");
  487. $ret .= $this->mediaUrl($cat, $label,$name_id,$sc_parameters);
  488. $ret .= "<input type='hidden' name='{$name}' id='{$name_id}' value='{$default}' style='width:400px' />";
  489. return $ret;
  490. }
  491. /**
  492. * Date field with popup calendar // NEW in 0.8/2.0
  493. *
  494. * @param string $name the name of the field
  495. * @param integer $datestamp UNIX timestamp - default value of the field
  496. * @param array or str
  497. * @example $frm->datepicker('my_field',time(),'type=date');
  498. * @example $frm->datepicker('my_field',time(),'type=datetime&inline=1');
  499. * @example $frm->datepicker('my_field',time(),'type=date&format=yyyy-mm-dd');
  500. * @example $frm->datepicker('my_field',time(),'type=datetime&format=MM, dd, yyyy hh:ii');
  501. *
  502. * @url http://trentrichardson.com/examples/timepicker/
  503. */
  504. function datepicker($name, $datestamp = false, $options = null)
  505. {
  506. if(vartrue($options) && is_string($options))
  507. {
  508. parse_str($options,$options);
  509. }
  510. $type = varset($options['type']) ? trim($options['type']) : "date"; // OR 'datetime'
  511. $dateFormat = varset($options['format']) ? trim($options['format']) :e107::getPref('inputdate', '%Y-%m-%d');
  512. $ampm = (preg_match("/%l|%I|%p|%P/",$dateFormat)) ? 'true' : 'false';
  513. if($type == 'datetime' && !varset($options['format']))
  514. {
  515. $dateFormat .= " ".e107::getPref('inputtime', '%H:%M:%S');
  516. }
  517. $dformat = e107::getDate()->toMask($dateFormat);
  518. $id = $this->name2id($name);
  519. $classes = array('date' => 'e-date', 'datetime' => 'e-datetime');
  520. if ($datestamp)
  521. {
  522. $value = is_numeric($datestamp) ? e107::getDate()->convert_date($datestamp, $dateFormat) : $datestamp; //date("d/m/Y H:i:s", $datestamp);
  523. }
  524. $text = "";
  525. // $text .= 'dformat='.$dformat.' defdisp='.$dateFormat;
  526. $class = (isset($classes[$type])) ? $classes[$type] : "tbox e-date";
  527. $size = vartrue($options['size']) ? intval($options['size']) : 40;
  528. $required = vartrue($options['required']) ? "required" : "";
  529. $firstDay = vartrue($options['firstDay']) ? $options['firstDay'] : 0;
  530. if(vartrue($options['inline']))
  531. {
  532. $text .= "<div class='{$class}' id='inline-{$id}' data-date-format='{$dformat}' data-date-ampm='{$ampm}' data-date-firstday='{$firstDay}' ></div>
  533. <input type='hidden' name='{$name}' id='{$id}' value='{$value}' data-date-format='{$dformat}' data-time-format='{$tformat}' data-date-ampm='{$ampm}' data-date-firstday='{$firstDay}' />
  534. ";
  535. }
  536. else
  537. {
  538. $text .= "<input class='{$class} input-xlarge' type='text' size='{$size}' name='{$name}' id='{$id}' value='{$value}' data-date-format='{$dformat}' data-date-ampm='{$ampm}' data-date-language='".e_LAN."' data-date-firstday='{$firstDay}' {$required} />";
  539. }
  540. // $text .= "ValueFormat: ".$dateFormat." Value: ".$value;
  541. // $text .= " ({$dformat}) type:".$dateFormat." ".$value;
  542. return $text;
  543. }
  544. /**
  545. * User auto-complete search
  546. *
  547. * @param string $name_fld field name for user name
  548. * @param string $id_fld field name for user id
  549. * @param string $default_name default user name value
  550. * @param integer $default_id default user id
  551. * @param array|string $options [optional] 'readonly' (make field read only), 'name' (db field name, default user_name)
  552. * @return string HTML text for display
  553. */
  554. function userpicker($name_fld, $id_fld, $default_name, $default_id, $options = array())
  555. {
  556. $tp = e107::getParser();
  557. if(!is_array($options)) parse_str($options, $options);
  558. $default_name = vartrue($default_name, '');
  559. $default_id = vartrue($default_id, 0);
  560. //TODO Auto-calculate $name_fld from $id_fld ie. append "_usersearch" here ?
  561. $fldid = $this->name2id($name_fld);
  562. $hidden_fldid = $this->name2id($id_fld);
  563. $ret = '<div class="input-append">';
  564. $ret .= $this->text($name_fld,$default_name,20, "class=e-tip&title=Type name of user&typeahead=users&readonly=".vartrue($options['readonly']))
  565. .$this->hidden($id_fld,$default_id, array('id' => $this->name2id($id_fld)))."<span class='add-on'>".$tp->toGlyph('fa-user')." <span id='{$fldid}-id'>".$default_id.'</span></span>';
  566. $ret .= "<a class='btn btn-inverse' href='#' id='{$fldid}-reset'>reset</a>
  567. </div>";
  568. e107::js('footer-inline', "
  569. \$('#{$fldid}').blur(function () {
  570. \$('#{$fldid}-id').html(\$('#{$hidden_fldid}').val());
  571. });
  572. \$('#{$fldid}-reset').click(function () {
  573. \$('#{$fldid}-id').html('0');
  574. \$('#{$hidden_fldid}').val(0);
  575. \$('#{$fldid}').val('');
  576. return false;
  577. });
  578. ");
  579. return $ret;
  580. /*
  581. $label_fld = str_replace('_', '-', $name_fld).'-upicker-lable';
  582. //'.$this->text($id_fld, $default_id, 10, array('id' => false, 'readonly'=>true, 'class'=>'tbox number')).'
  583. $ret = '
  584. <div class="e-autocomplete-c">
  585. '.$this->text($name_fld, $default_name, 150, array('id' => false, 'readonly' => vartrue($options['readonly']) ? true : false)).'
  586. <span id="'.$label_fld.'" class="'.($default_id ? 'success' : 'warning').'">Id #'.((int) $default_id).'</span>
  587. '.$this->hidden($id_fld, $default_id, array('id' => false)).'
  588. <span class="indicator" style="display: none;">
  589. <img src="'.e_IMAGE_ABS.'generic/loading_16.gif" class="icon action S16" alt="Loading..." />
  590. </span>
  591. <div class="e-autocomplete"></div>
  592. </div>
  593. ';
  594. e107::getJs()->requireCoreLib('scriptaculous/controls.js', 2);
  595. e107::getJs()->footerInline("
  596. //autocomplete fields
  597. \$\$('input[name={$name_fld}]').each(function(el) {
  598. if(el.readOnly) {
  599. el.observe('click', function(ev) { ev.stop(); var el1 = ev.findElement('input'); el1.blur(); } );
  600. el.next('span.indicator').hide();
  601. el.next('div.e-autocomplete').hide();
  602. return;
  603. }
  604. new Ajax.Autocompleter(el, el.next('div.e-autocomplete'), '".e_JS."e_ajax.php', {
  605. paramName: '{$name_fld}',
  606. minChars: 2,
  607. frequency: 0.5,
  608. afterUpdateElement: function(txt, li) {
  609. if(!\$(li)) return;
  610. var elnext = el.next('input[name={$id_fld}]'),
  611. ellab = \$('{$label_fld}');
  612. if(\$(li).id) {
  613. elnext.value = parseInt(\$(li).id);
  614. } else {
  615. elnext.value = 0
  616. }
  617. if(ellab)
  618. {
  619. ellab.removeClassName('warning').removeClassName('success');
  620. ellab.addClassName((elnext.value ? 'success' : 'warning')).update('Id #' + elnext.value);
  621. }
  622. },
  623. indicator: el.next('span.indicator'),
  624. parameters: 'ajax_used=1&ajax_sc=usersearch=".rawurlencode('searchfld='.str_replace('user_', '', vartrue($options['name'], 'user_name')).'--srcfld='.$name_fld)."'
  625. });
  626. });
  627. ");
  628. return $ret;
  629. */
  630. }
  631. /**
  632. * A Rating element
  633. * @var $text
  634. */
  635. function rate($table,$id,$options=null)
  636. {
  637. $table = preg_replace('/\W/', '', $table);
  638. $id = intval($id);
  639. return e107::getRate()->render($table, $id, $options);
  640. }
  641. function like($table,$id,$options=null)
  642. {
  643. $table = preg_replace('/\W/', '', $table);
  644. $id = intval($id);
  645. return e107::getRate()->renderLike($table,$id,$options);
  646. }
  647. function file($name, $options = array())
  648. {
  649. $options = $this->format_options('file', $name, $options);
  650. //never allow id in format name-value for text fields
  651. return "<input type='file' name='{$name}'".$this->get_attributes($options, $name)." />";
  652. }
  653. function upload($name, $options = array())
  654. {
  655. return 'Ready to use upload form fields, optional - file list view';
  656. }
  657. function password($name, $value = '', $maxlength = 50, $options = array())
  658. {
  659. if(is_string($options)) parse_str($options, $options);
  660. $addon = "";
  661. $gen = "";
  662. if(vartrue($options['generate']))
  663. {
  664. $gen = '&nbsp;<a href="#" class="btn btn-default btn-small e-tip" id="Spn_PasswordGenerator" title="Generate a password">Generate</a> <a class="btn btn-default btn-small e-tip" href="#" id="showPwd" title="Display the password">Show</a><br />';
  665. }
  666. if(vartrue($options['strength']))
  667. {
  668. $addon .= "<div style='margin-top:4px'><div id='pwdColor' class='progress' style='float:left;display:inline-block;width:218px'><div class='bar' id='pwdMeter' style='width:0%' ></div></div> <div id='pwdStatus' class='smalltext' style='float:left;display:inline-block;width:150px;margin-left:5px'></span></div>";
  669. }
  670. $options['pattern'] = vartrue($options['pattern'],'[\S]{4,}');
  671. $options['required'] = varset($options['required'], 1);
  672. $options['class'] = vartrue($options['class'],'e-password');
  673. if(deftrue('BOOTSTRAP') == 3)
  674. {
  675. $options['class'] .= ' form-control';
  676. }
  677. $options = $this->format_options('text', $name, $options);
  678. //never allow id in format name-value for text fields
  679. $text = "<input type='password' name='{$name}' value='{$value}' maxlength='{$maxlength}'".$this->get_attributes($options, $name)." />";
  680. return "<span class='form-inline'>".$text.$gen."</span>".vartrue($addon);
  681. }
  682. /**
  683. * Render a bootStrap ProgressBar.
  684. * @param string $name
  685. * @param number $value
  686. * @param array $options
  687. */
  688. public function progressBar($name,$value,$options=array())
  689. {
  690. if(!deftrue('BOOTSTRAP'))
  691. {
  692. return;
  693. }
  694. $class = vartrue($options['class'],'');
  695. return "<div class='progress ".$class."' id='".$this->name2id($name)."'>
  696. <div class='bar' style='width: ".number_format($value,1)."%'></div>
  697. </div>";
  698. }
  699. /**
  700. * Textarea Element
  701. * @param $name
  702. * @param $value
  703. * @param $rows
  704. * @param $cols
  705. * @param $options
  706. * @param $count
  707. */
  708. function textarea($name, $value, $rows = 10, $cols = 80, $options = array(), $counter = false)
  709. {
  710. if(is_string($options)) parse_str($options, $options);
  711. // auto-height support
  712. if(vartrue($options['size']) && !is_numeric($options['size']))
  713. {
  714. $options['class'] .= " input-".$options['size'];
  715. unset($options['size']); // don't include in html 'size='.
  716. }
  717. elseif(!vartrue($options['noresize']))
  718. {
  719. $options['class'] = (isset($options['class']) && $options['class']) ? $options['class'].' e-autoheight' : 'tbox span7 e-autoheight';
  720. }
  721. $options = $this->format_options('textarea', $name, $options);
  722. //never allow id in format name-value for text fields
  723. return "<textarea name='{$name}' rows='{$rows}' cols='{$cols}'".$this->get_attributes($options, $name).">{$value}</textarea>".(false !== $counter ? $this->hidden('__'.$name.'autoheight_opt', $counter) : '');
  724. }
  725. /**
  726. * Bbcode Area. Name, value, template, media-Cat, size, options array eg. counter
  727. * IMPORTANT: $$mediaCat is also used is the media-manager category identifier
  728. */
  729. function bbarea($name, $value, $template = '', $mediaCat='_common', $size = 'large', $options = array())
  730. {
  731. if(is_string($options)) parse_str($options, $options);
  732. //size - large|medium|small
  733. //width should be explicit set by current admin theme
  734. $size = 'input-large';
  735. switch($size)
  736. {
  737. case 'small':
  738. $rows = '7';
  739. $height = "style='height:250px'"; // inline required for wysiwyg
  740. break;
  741. case 'medium':
  742. $rows = '10';
  743. $height = "style='height:375px'"; // inline required for wysiwyg
  744. $size = "input-block-level";
  745. break;
  746. case 'large':
  747. default:
  748. $rows = '15';
  749. $size = 'large input-block-level';
  750. // $height = "style='height:500px;width:1025px'"; // inline required for wysiwyg
  751. break;
  752. }
  753. // auto-height support
  754. $options['class'] = 'tbox bbarea '.($size ? ' '.$size : '').' e-wysiwyg e-autoheight';
  755. $bbbar = '';
  756. $help_tagid = $this->name2id($name)."--preview";
  757. $options['other'] = "onselect='storeCaret(this);' onclick='storeCaret(this);' onkeyup='storeCaret(this);' {$height}";
  758. $counter = vartrue($options['counter'],false);
  759. $ret = "
  760. <div class='bbarea {$size}'>
  761. <div class='field-spacer'><!-- --></div>\n";
  762. $ret .= e107::getBB()->renderButtons($template,$help_tagid);
  763. $ret .= $this->textarea($name, $value, $rows, 70, $options, $counter); // higher thank 70 will break some layouts.
  764. $ret .= "</div>\n";
  765. $_SESSION['media_category'] = $mediaCat; // used by TinyMce.
  766. return $ret;
  767. // Quick fix - hide TinyMCE links if not installed, dups are handled by JS handler
  768. /*
  769. e107::getJs()->footerInline("
  770. if(typeof tinyMCE === 'undefined')
  771. {
  772. \$$('a.e-wysiwyg-switch').invoke('hide');
  773. }
  774. ");
  775. */
  776. }
  777. /**
  778. * Render a checkbox
  779. * @param string $name
  780. * @param mixed $value
  781. * @param boolean $checked
  782. * @param mixed $options query-string or array or string for a label. eg. label=Hello&foo=bar or array('label'=>Hello') or 'Hello'
  783. * @return void
  784. */
  785. function checkbox($name, $value, $checked = false, $options = array())
  786. {
  787. if(!is_array($options))
  788. {
  789. if(strpos($options,"=")!==false)
  790. {
  791. parse_str($options, $options);
  792. }
  793. else // Assume it's a label.
  794. {
  795. $options = array('label'=>$options);
  796. }
  797. }
  798. $options = $this->format_options('checkbox', $name, $options);
  799. $options['checked'] = $checked; //comes as separate argument just for convenience
  800. $text = "";
  801. $pre = (vartrue($options['label'])) ? "<label class='checkbox'>" : ""; // Bootstrap compatible markup
  802. $post = (vartrue($options['label'])) ? $options['label']."</label>" : "";
  803. unset($options['label']); // not to be used as attribute;
  804. $text .= "<input type='checkbox' name='{$name}' value='{$value}'".$this->get_attributes($options, $name, $value)." />";
  805. return $pre.$text.$post;
  806. }
  807. function checkbox_label($label_title, $name, $value, $checked = false, $options = array())
  808. {
  809. return $this->checkbox($name, $value, $checked, $options).$this->label($label_title, $name, $value);
  810. }
  811. function checkbox_switch($name, $value, $checked = false, $label = '')
  812. {
  813. return $this->checkbox($name, $value, $checked).$this->label($label ? $label : LAN_ENABLED, $name, $value);
  814. }
  815. function checkbox_toggle($name, $selector = 'multitoggle', $id = false, $label='')
  816. {
  817. $selector = 'jstarget:'.$selector;
  818. if($id) $id = $this->name2id($id);
  819. return $this->checkbox($name, $selector, false, array('id' => $id,'class' => 'checkbox toggle-all','label'=>$label));
  820. }
  821. function uc_checkbox($name, $current_value, $uc_options, $field_options = array())
  822. {
  823. if(!is_array($field_options)) parse_str($field_options, $field_options);
  824. return '
  825. <div class="check-block">
  826. '.$this->_uc->vetted_tree($name, array($this, '_uc_checkbox_cb'), $current_value, $uc_options, $field_options).'
  827. </div>
  828. ';
  829. }
  830. /**
  831. * Callback function used with $this->uc_checkbox
  832. *
  833. * @see user_class->select() for parameters
  834. */
  835. function _uc_checkbox_cb($treename, $classnum, $current_value, $nest_level, $field_options)
  836. {
  837. if($classnum == e_UC_BLANK)
  838. return '';
  839. if (!is_array($current_value))
  840. {
  841. $tmp = explode(',', $current_value);
  842. }
  843. $classIndex = abs($classnum); // Handle negative class values
  844. $classSign = (substr($classnum, 0, 1) == '-') ? '-' : '';
  845. $class = $style = '';
  846. if($nest_level == 0)
  847. {
  848. $class = " strong";
  849. }
  850. else
  851. {
  852. $style = " style='text-indent:" . (1.2 * $nest_level) . "em'";
  853. }
  854. $descr = varset($field_options['description']) ? ' <span class="smalltext">('.$this->_uc->uc_get_classdescription($classnum).')</span>' : '';
  855. return "<div class='field-spacer{$class}'{$style}>".$this->checkbox($treename.'[]', $classnum, in_array($classnum, $tmp), $field_options).$this->label($this->_uc->uc_get_classname($classIndex).$descr, $treename.'[]', $classnum)."</div>\n";
  856. }
  857. function uc_label($classnum)
  858. {
  859. return $this->_uc->uc_get_classname($classnum);
  860. }
  861. /**
  862. * A Radio Button Form Element
  863. * @param $name
  864. * @param @value array pair-values|string - auto-detected.
  865. * @param $checked boolean
  866. * @param $options
  867. */
  868. function radio($name, $value, $checked = false, $options = null)
  869. {
  870. if(!is_array($options)) parse_str($options, $options);
  871. if(is_array($value))
  872. {
  873. return $this->radio_multi($name, $value, $checked, $options);
  874. }
  875. $labelFound = vartrue($options['label']);
  876. unset($options['label']); // label attribute not valid in html5
  877. $options = $this->format_options('radio', $name, $options);
  878. $options['checked'] = $checked; //comes as separate argument just for convenience
  879. // $options['class'] = 'inline';
  880. $text = "";
  881. // return print_a($options,true);
  882. if($labelFound) // Bootstrap compatible markup
  883. {
  884. $text .= "<label class='radio inline'>";
  885. }
  886. $text .= "<input type='radio' name='{$name}' value='".$value."'".$this->get_attributes($options, $name, $value)." />";
  887. if(vartrue($options['help']))
  888. {
  889. $text .= "<div class='field-help'>".$options['help']."</div>";
  890. }
  891. if($labelFound)
  892. {
  893. $text .= $labelFound."</label>";
  894. }
  895. return $text;
  896. }
  897. /**
  898. * @param name
  899. * @param check_enabled
  900. * @param label_enabled
  901. * @param label_disabled
  902. * @param options
  903. */
  904. function radio_switch($name, $checked_enabled = false, $label_enabled = '', $label_disabled = '',$options=array())
  905. {
  906. if(!is_array($options)) parse_str($options, $options);
  907. $options_on = varset($options['enabled'],array());
  908. $options_off = varset($options['disabled'],array());
  909. if(vartrue($options['class']) == 'e-expandit' || vartrue($options['expandit'])) // See admin->prefs 'Single Login' for an example.
  910. {
  911. $options_on = array_merge($options, array('class' => 'e-expandit-on'));
  912. $options_off = array_merge($options, array('class' => 'e-expandit-off'));
  913. }
  914. $options_on['label'] = $label_enabled ? defset($label_enabled,$label_enabled) : LAN_ENABLED;
  915. $options_off['label'] = $label_disabled ? defset($label_disabled,$label_disabled) : LAN_DISABLED;
  916. if(vartrue($options['reverse'])) // reverse order.
  917. {
  918. unset($options['reverse']);
  919. return $this->radio($name, 0, !$checked_enabled, $options_off)." ".
  920. $this->radio($name, 1, $checked_enabled, $options_on);
  921. // return $this->radio($name, 0, !$checked_enabled, $options_off)."".$this->label($label_disabled ? $label_disabled : LAN_DISABLED, $name, 0)."&nbsp;&nbsp;".
  922. // $this->radio($name, 1, $checked_enabled, $options_on)."".$this->label($label_enabled ? $label_enabled : LAN_ENABLED, $name, 1);
  923. }
  924. // $helpLabel = (is_array($help)) ? vartrue($help[$value]) : $help;
  925. // Bootstrap Style Code - for use later.
  926. // ['help'] = $helpLabel;
  927. // $text[] = $this->radio($name, $value, (string) $checked === (string) $value, $options);
  928. return $this->radio($name, 1, $checked_enabled, $options_on)." ".$this->radio($name, 0, !$checked_enabled, $options_off);
  929. // return $this->radio($name, 1, $checked_enabled, $options_on)."".$this->label($label_enabled ? $label_enabled : LAN_ENABLED, $name, 1)."&nbsp;&nbsp;
  930. // ".$this->radio($name, 0, !$checked_enabled, $options_off)."".$this->label($label_disabled ? $label_disabled : LAN_DISABLED, $name, 0);
  931. }
  932. /**
  933. * XXX INTERNAL ONLY - Use radio() instead. array will automatically trigger this internal method.
  934. * @param string $name
  935. * @param array $elements = arrays value => label
  936. * @param string/integer $checked = current value
  937. * @param boolean $multi_line
  938. * @param mixed $help array of field help items or string of field-help (to show on all)
  939. */
  940. private function radio_multi($name, $elements, $checked, $options=array(), $help = null)
  941. {
  942. /* // Bootstrap Test.
  943. return' <label class="checkbox">
  944. <input type="checkbox" value="">
  945. Option one is this and that—be sure to include why its great
  946. </label>
  947. <label class="radio">
  948. <input type="radio" name="optionsRadios" id="optionsRadios1" value="option1" checked>
  949. Option one is this and that—be sure to include why its great
  950. </label>
  951. <label class="radio">
  952. <input type="radio" name="optionsRadios" id="optionsRadios2" value="option2">
  953. Option two can be something else and selecting it will deselect option one
  954. </label>';
  955. */
  956. $text = array();
  957. if(is_string($elements)) parse_str($elements, $elements);
  958. if(!is_array($options)) parse_str($options, $options);
  959. $help = '';
  960. if(vartrue($options['help']))
  961. {
  962. $help = "<div class='field-help'>".$options['help']."</div>";
  963. unset($options['help']);
  964. }
  965. foreach ($elements as $value => $label)
  966. {
  967. $label = defset($label, $label);
  968. $helpLabel = (is_array($help)) ? vartrue($help[$value]) : $help;
  969. // Bootstrap Style Code - for use later.
  970. $options['label'] = $label;
  971. $options['help'] = $helpLabel;
  972. $text[] = $this->radio($name, $value, (string) $checked === (string) $value, $options);
  973. // $text[] = $this->radio($name, $value, (string) $checked === (string) $value)."".$this->label($label, $name, $value).(isset($helpLabel) ? "<div class='field-help'>".$helpLabel."</div>" : '');
  974. }
  975. if($multi_line === false)
  976. {
  977. // return implode("&nbsp;&nbsp;", $text);
  978. }
  979. // support of UI owned 'newline' parameter
  980. if(!varset($options['sep']) && vartrue($options['newline'])) $options['sep'] = '<br />'; // TODO div class=separator?
  981. $separator = varset($options['sep']," ");
  982. // return print_a($text,true);
  983. return implode($separator, $text).$help;
  984. // return implode("\n", $text);
  985. //XXX Limiting markup.
  986. // return "<div class='field-spacer' style='width:50%;float:left'>".implode("</div><div class='field-spacer' style='width:50%;float:left'>", $text)."</div>";
  987. }
  988. /**
  989. * Just for BC - use the $options['label'] instead.
  990. */
  991. function label($text, $name = '', $value = '')
  992. {
  993. e107::getMessage()->addDebug("Deprecated \$frm->label() used");
  994. $for_id = $this->_format_id('', $name, $value, 'for');
  995. return "<label$for_id class='e-tip legacy'>{$text}</label>";
  996. }
  997. function help($text)
  998. {
  999. return !empty($text) ? '<div class="field-help">'.$text.'</div>' : '';
  1000. }
  1001. function select_open($name, $options = array())
  1002. {
  1003. $options = $this->format_options('select', $name, $options);
  1004. return "<select name='{$name}'".$this->get_attributes($options, $name).">";
  1005. }
  1006. /**
  1007. * @DEPRECATED - use select() instead.
  1008. */
  1009. function selectbox($name, $option_array, $selected = false, $options = array(), $defaultBlank= false)
  1010. {
  1011. return $this->select($name, $option_array, $selected, $options, $defaultBlank);
  1012. }
  1013. /**
  1014. *
  1015. * @param string $name
  1016. * @param array $option_array
  1017. * @param boolean $selected [optional]
  1018. * @param string|array $options [optional]
  1019. * @param boolean|string $defaultBlank [optional] set to TRUE if the first entry should be blank, or to a string to use it for the blank description.
  1020. * @return string HTML text for display
  1021. */
  1022. function select($name, $option_array, $selected = false, $options = array(), $defaultBlank= false)
  1023. {
  1024. if(!is_array($options)) parse_str($options, $options);
  1025. if($option_array === 'yesno')
  1026. {
  1027. $option_array = array(1 => LAN_YES, 0 => LAN_NO);
  1028. }
  1029. if(vartrue($options['multiple']))
  1030. {
  1031. $name = (strpos($name, '[') === false) ? $name.'[]' : $name;
  1032. if(!is_array($selected)) $selected = explode(",",$selected);
  1033. }
  1034. $text = $this->select_open($name, $options)."\n";
  1035. if(isset($options['default']))
  1036. {
  1037. $text .= $this->option($options['default'], varset($options['defaultValue']));
  1038. }
  1039. elseif($defaultBlank)
  1040. {
  1041. $diz = is_string($defaultBlank) ? $defaultBlank : '&nbsp;';
  1042. $text .= $this->option($diz, '');
  1043. }
  1044. if(varset($options['useValues'])) // use values as keys.
  1045. {
  1046. $new = array();
  1047. foreach($option_array as $v)
  1048. {
  1049. $new[$v] = $v;
  1050. }
  1051. $option_array = $new;
  1052. }
  1053. $text .= $this->option_multi($option_array, $selected)."\n".$this->select_close();
  1054. return $text;
  1055. }
  1056. //TODO
  1057. /**
  1058. * Universal Userclass selector - checkboxes, dropdown, everything.
  1059. * @param $name - form element name
  1060. * @param $curval - current userclass value(s) as array or comma separated.
  1061. * @param $type - 'checkbox', 'dropdown',
  1062. * @param options - query string or array. 'options=admin,mainadmin,classes&vetted=1&exclusions=0' etc.
  1063. * @return the userclass form element
  1064. */
  1065. function userclass($name, $curval, $type, $options)
  1066. {
  1067. }
  1068. /**
  1069. * Renders a generic search box. If $filter has values, a filter box will be included with the options provided.
  1070. *
  1071. */
  1072. function search($name, $searchVal, $submitName, $filterName='', $filterArray=false, $filterVal=false)
  1073. {
  1074. $tp = e107::getParser();
  1075. $text = '<span class="input-append e-search">'.$tp->toGlyph('fa-search').'
  1076. '.$this->text($name, $searchVal,20,'class=search-query').'
  1077. <button class="btn btn-primary" name="'.$submitName.'" type="submit">'.LAN_GO.'</button>
  1078. </span>';
  1079. if(is_array($filter))
  1080. {
  1081. $text .= $this->selectbox($$filterName, $filterArray, $filterVal);
  1082. }
  1083. // $text .= $this->admin_button($submitName,LAN_SEARCH,'search');
  1084. return $text;
  1085. /*
  1086. $text .=
  1087. <select style="display: none;" data-original-title="Filter the results below" name="filter_options" id="filter-options" class="e-tip tbox select filter" title="">
  1088. <option value="">Display All</option>
  1089. <option value="___reset___">Clear Filter</option>
  1090. <optgroup class="optgroup" label="Filter by&nbsp;Category">
  1091. <option value="faq_parent__1">General</option>
  1092. <option value="faq_parent__2">Misc</option>
  1093. <option value="faq_parent__4">Test 3</option>
  1094. </optgroup>
  1095. </select><div class="btn-group bootstrap-select e-tip tbox select filter"><button id="filter-options" class="btn dropdown-toggle clearfix" data-toggle="dropdown"><span class="filter-option pull-left">Display All</span>&nbsp;<span class="caret"></span></button><ul style="max-height: none; overflow-y: auto;" class="dropdown-menu" role="menu"><li rel="0"><a tabindex="-1" class="">Display All</a></li><li rel="1"><a tabindex="-1" class="">Clear Filter</a></li><li rel="2"><dt class="optgroup-div">Filter by&nbsp;Category</dt><a tabindex="-1" class="opt ">General</a></li><li rel="3"><a tabindex="-1" class="opt ">Misc</a></li><li rel="4"><a tabindex="-1" class="opt ">Test 3</a></li></ul></div>
  1096. <div class="e-autocomplete"></div>
  1097. <button type="submit" name="etrigger_filter" value="etrigger_filter" id="etrigger-filter" class="btn filter e-hide-if-js btn-primary"><span>Filter</span></button>
  1098. <span class="indicator" style="display: none;">
  1099. <img src="/e107_2.0/e107_images/generic/loading_16.gif" class="icon action S16" alt="Loading...">
  1100. </span>
  1101. */
  1102. }
  1103. function uc_select($name, $current_value, $uc_options, $select_options = array(), $opt_options = array())
  1104. {
  1105. return $this->select_open($name, $select_options)."\n".$this->_uc->vetted_tree($name, array($this, '_uc_select_cb'), $current_value, $uc_options, $opt_options)."\n".$this->select_close();
  1106. }
  1107. // Callback for vetted_tree - Creates the option list for a selection box
  1108. function _uc_select_cb($treename, $classnum, $current_value, $nest_level)
  1109. {
  1110. $classIndex = abs($classnum); // Handle negative class values
  1111. $classSign = (substr($classnum, 0, 1) == '-') ? '-' : '';
  1112. if($classnum == e_UC_BLANK)
  1113. return $this->option('&nbsp;', '');
  1114. $tmp = explode(',', $current_value);
  1115. if($nest_level == 0)
  1116. {
  1117. $prefix = '';
  1118. $style = "font-weight:bold; font-style: italic;";
  1119. }
  1120. elseif($nest_level == 1)
  1121. {
  1122. $prefix = '&nbsp;&nbsp;';
  1123. $style = "font-weight:bold";
  1124. }
  1125. else
  1126. {
  1127. $prefix = '&nbsp;&nbsp;'.str_repeat('--', $nest_level - 1).'&gt;';
  1128. $style = '';
  1129. }
  1130. return $this->option($prefix.$this->_uc->uc_get_classname($classnum), $classSign.$classIndex, ($current_value !== '' && in_array($classnum, $tmp)), array("style"=>"{$style}"))."\n";
  1131. }
  1132. function optgroup_open($label, $disabled = false)
  1133. {
  1134. return "<optgroup class='optgroup' label='{$label}'".($disabled ? " disabled='disabled'" : '').">";
  1135. }
  1136. /**
  1137. * <option> tag generation.
  1138. * @param $option_title
  1139. * @param $value
  1140. * @param $selected
  1141. * @param $options (eg. disabled=1)
  1142. */
  1143. function option($option_title, $value, $selected = false, $options = '')
  1144. {
  1145. if(is_string($options)) parse_str($options, $options);
  1146. if(false === $value) $value = '';
  1147. $options = $this->format_options('option', '', $options);
  1148. $options['selected'] = $selected; //comes as separate argument just for convenience
  1149. return "<option value='{$value}'".$this->get_attributes($options).">".defset($option_title, $option_title)."</option>";
  1150. }
  1151. /**
  1152. * Use selectbox() instead.
  1153. */
  1154. function option_multi($option_array, $selected = false, $options = array())
  1155. {
  1156. if(is_string($option_array)) parse_str($option_array, $option_array);
  1157. $text = '';
  1158. foreach ($option_array as $value => $label)
  1159. {
  1160. if(is_array($label))
  1161. {
  1162. $text .= $this->optgroup_open($value);
  1163. foreach($label as $val => $lab)
  1164. {
  1165. $text .= $this->option($lab, $val, (is_array($selected) ? in_array($val, $selected) : $selected == $val), $options)."\n";
  1166. }
  1167. $text .= $this->optgroup_close();
  1168. }
  1169. else
  1170. {
  1171. $text .= $this->option($label, $value, (is_array($selected) ? in_array($value, $selected) : $selected == $value), $options)."\n";
  1172. }
  1173. }
  1174. return $text;
  1175. }
  1176. function optgroup_close()
  1177. {
  1178. return "</optgroup>";
  1179. }
  1180. function select_close()
  1181. {
  1182. return "</select>";
  1183. }
  1184. function hidden($name, $value, $options = array())
  1185. {
  1186. $options = $this->format_options('hidden', $name, $options);
  1187. return "<input type='hidden' name='{$name}' value='{$value}'".$this->get_attributes($options, $name, $value)." />";
  1188. }
  1189. /**
  1190. * Generate hidden security field
  1191. * @return string
  1192. */
  1193. function token()
  1194. {
  1195. return "<input type='hidden' name='e-token' value='".defset('e_TOKEN', '')."' />";
  1196. }
  1197. function submit($name, $value, $options = array())
  1198. {
  1199. $options = $this->format_options('submit', $name, $options);
  1200. return "<input type='submit' name='{$name}' value='{$value}'".$this->get_attributes($options, $name, $value)." />";
  1201. }
  1202. function submit_image($name, $value, $image, $title='', $options = array())
  1203. {
  1204. $tp = e107::getParser();
  1205. $options = $this->format_options('submit_image', $name, $options);
  1206. switch ($image)
  1207. {
  1208. case 'edit':
  1209. $icon = "e-edit-32";
  1210. $options['class'] = $options['class'] == 'action' ? 'btn btn-default action edit' : $options['class'];
  1211. break;
  1212. case 'delete':
  1213. $icon = "e-delete-32";
  1214. $options['class'] = $options['class'] == 'action' ? 'btn btn-default action delete' : $options['class'];
  1215. $options['other'] = 'data-confirm="'.LAN_JSCONFIRM.'"';
  1216. break;
  1217. case 'execute':
  1218. $icon = "e-execute-32";
  1219. $options['class'] = $options['class'] == 'action' ? 'btn btn-default action execute' : $options['class'];
  1220. break;
  1221. case 'view':
  1222. $icon = "e-view-32";
  1223. $options['class'] = $options['class'] == 'action' ? 'btn btn-default action view' : $options['class'];
  1224. break;
  1225. }
  1226. $options['title'] = $title;//shorthand
  1227. return "<button type='submit' name='{$name}' data-placement='left' value='{$…

Large files files are truncated, but you can click here to view the full file