(mixed) custom id attribute value
* if numeric value is passed it'll be just appended to the name e.g. {filed-name}-{value}
* if false is passed id will be not created
* if empty string is passed (or no 'id' option is found)
* in all other cases the value will be used as field id
* default: empty string
*
* - class => (string) field class(es)
* Example: 'tbox select class1 class2 class3'
* NOTE: this will override core classes, so you have to explicit include them!
* default: empty string
*
* - size => (int) size attribute value (used when needed)
* default: 40
*
* - title (string) title attribute
* default: empty string (omitted)
*
* - readonly => (bool) readonly attribute
* default: false
*
* - selected => (bool) selected attribute (used when needed)
* default: false
*
* checked => (bool) checked attribute (used when needed)
* default: false
* - disabled => (bool) disabled attribute
* default: false
*
* - tabindex => (int) tabindex attribute value
* default: inner tabindex counter
*
* - other => (string) additional data
* Example: 'attribute1="value1" attribute2="value2"'
* default: empty string
*/
class e_form
{
protected $_tabindex_counter = 0;
protected $_tabindex_enabled = true;
protected $_cached_attributes = array();
/**
* @var user_class
*/
protected $_uc;
protected $_required_string;
function __construct($enable_tabindex = false)
{
$this->_tabindex_enabled = $enable_tabindex;
$this->_uc = e107::getUserClass();
$this->setRequiredString('* ');
}
/**
* Open a new form
* @param string name
* @param $method - post|get default is post
* @param @target - e_REQUEST_URI by default
* @param $other - unused at the moment.
* @return string
*/
public function open($name, $method=null, $target=null, $options=null)
{
if($target == null)
{
$target = e_REQUEST_URI;
}
if($method == null)
{
$method = "post";
}
$class = "";
$autoComplete = "";
if(is_string($options))
{
parse_str($options, $options);
}
if(vartrue($options['class']))
{
$class = "class='".$options['class']."'";
}
else // default
{
$class= "class='form-horizontal'";
}
if(isset($options['autocomplete'])) // leave as isset()
{
$autoComplete = " autocomplete='".($options['autocomplete'] ? 'on' : 'off')."'";
}
if($method == 'get' && strpos($target,'='))
{
list($url,$qry) = explode("?",$target);
$text = "\n
";
$thpath = isset($sc_parameters['nothumb']) || vartrue($hide) ? $default : $default_thumb;
$label = "
";
$label .= $tp->toIcon($default_url);
$label .= "
";
// $label = "
";
}
else // Images
{
$title = (vartrue($sc_parameters['help'])) ? "title='".$sc_parameters['help']."'" : "";
$width = vartrue($sc_parameters['w'], 120);
$height = vartrue($sc_parameters['h'], 0);
$ret = "
";
$att = 'aw='.$width."'&ah=".$height."'";
$thpath = empty($default) || !empty($video) ? $default_url : $tp->thumbUrl($default_thumb, $att, true);
//isset($sc_parameters['nothumb']) || vartrue($hide) ?
$label = "
";
if($cat != 'news' && $cat !='page' && $cat !='' && strpos($cat,'_image')===false)
{
$cat = $cat . "_image";
}
}
if(!empty($previewURL))
{
$default_url = $previewURL;
}
$ret .= $this->mediaUrl($cat, $label,$name_id,$sc_parameters);
if($cat != '_icon' && $blank == false) // ICONS
{
$ret .= "
";
}
$ret .= "
\n";
$ret .= "
";
$ret .= "
";
// $ret .= $this->text($name,$default); // to be hidden eventually.
return $ret;
// ----------------
}
private function imagepickerDefault($path, $parms=array())
{
$tp = e107::getParser();
if(!empty($parms['legacyPath'])) // look in a specific path.
{
$legacyDefault = rtrim($parms['legacyPath'],'/')."/".$path;
$legacyRel = $tp->replaceConstants($legacyDefault);
if(is_readable($legacyRel))
{
return array($legacyDefault, $legacyDefault);
}
else
{
// e107::getDebug()->log("Legacy Default:".$legacyDefault);
// e107::getDebug()->log("wasnt found:".$legacyRel);
}
}
$path = str_replace('e_MEDIA_IMAGE/','{e_MEDIA_IMAGE}',$path);
$default_thumb = $tp->createConstants($path, 'nice');
$default = $tp->createConstants($path, 'mix');
return array($default_thumb, $default);
}
/**
* File Picker
* @param string name eg. 'myfield' or 'myfield[]'
* @param mixed default
* @param string label
* @param mixed sc_parameters
*/
function filepicker($name, $default, $label = '', $sc_parameters = '')
{
$tp = e107::getParser();
$name_id = $this->name2id($name);
if(is_string($sc_parameters))
{
if(strpos($sc_parameters, '=') === false) $sc_parameters = 'media='.$sc_parameters;
parse_str($sc_parameters, $sc_parameters);
}
$cat = vartrue($sc_parameters['media']) ? $tp->toDB($sc_parameters['media']) : "_common_file";
$ret = '';
if($sc_parameters['data'] === 'array')
{
// Do not use $this->hidden() method - as it will break 'id' value.
$ret .= "
";
$ret .= "
";
$ret .= "
";
$default = $default['path'];
}
else
{
$ret .= "
";
}
$default_label = ($default) ? $default : LAN_CHOOSE_FILE;
$label = "
".basename($default_label)." ";
$sc_parameters['mode'] = 'main';
$sc_parameters['action'] = 'dialog';
// $ret .= $this->mediaUrl($cat, $label,$name_id,"mode=dialog&action=list");
$ret .= $this->mediaUrl($cat, $label,$name_id,$sc_parameters);
return $ret;
}
/**
* Date field with popup calendar // NEW in 0.8/2.0
* on Submit returns unix timestamp or string value.
* @param string $name the name of the field
* @param integer $datestamp UNIX timestamp - default value of the field
* @param array or str
* @example $frm->datepicker('my_field',time(),'type=date');
* @example $frm->datepicker('my_field',time(),'type=datetime&inline=1');
* @example $frm->datepicker('my_field',time(),'type=date&format=yyyy-mm-dd');
* @example $frm->datepicker('my_field',time(),'type=datetime&format=MM, dd, yyyy hh:ii');
* @example $frm->datepicker('my_field',time(),'type=datetime&return=string');
*
* @url http://trentrichardson.com/examples/timepicker/
* @return string
*/
function datepicker($name, $datestamp = false, $options = null)
{
if(vartrue($options) && is_string($options))
{
parse_str($options,$options);
}
$type = varset($options['type']) ? trim($options['type']) : "date"; // OR 'datetime'
$dateFormat = varset($options['format']) ? trim($options['format']) :e107::getPref('inputdate', '%Y-%m-%d');
$ampm = (preg_match("/%l|%I|%p|%P/",$dateFormat)) ? 'true' : 'false';
$value = null;
$hiddenValue = null;
$useUnix = (isset($options['return']) && ($options['return'] === 'string')) ? 'false' : 'true';
$id = $this->name2id($name);
$classes = array('date' => 'e-date', 'datetime' => 'e-datetime');
if($type == 'datetime' && !varset($options['format']))
{
$dateFormat .= " ".e107::getPref('inputtime', '%H:%M:%S');
}
$dformat = e107::getDate()->toMask($dateFormat);
// If default value is set.
if ($datestamp && $datestamp !='0000-00-00') // date-field support.
{
if(!is_numeric($datestamp))
{
$datestamp = strtotime($datestamp);
}
// Convert date to proper (selected) format.
$hiddenValue = $value = e107::getDate()->convert_date($datestamp, $dformat);
if ($useUnix === 'true')
{
$hiddenValue = $datestamp;
}
}
$class = (isset($classes[$type])) ? $classes[$type] : "tbox e-date";
$size = vartrue($options['size']) ? intval($options['size']) : 40;
$required = vartrue($options['required']) ? "required" : "";
$firstDay = vartrue($options['firstDay']) ? $options['firstDay'] : 0;
$xsize = (vartrue($options['size']) && !is_numeric($options['size'])) ? $options['size'] : 'xlarge';
$disabled = vartrue($options['disabled']) ? "disabled" : "";
$text = "";
if(vartrue($options['inline']))
{
$text .= "
";
$text .= "
";
}
else
{
$text .= "
";
$ftype = (!empty($options['debug'])) ? 'text' : 'hidden';
$text .= "
";
}
// Load it in the footer.
// FIXME use Library Manager (e107::library()) instead?
e107::css('core', 'bootstrap-datetimepicker/css/bootstrap-datetimepicker.min.css', 'jquery');
e107::js('core', 'bootstrap-datetimepicker/js/bootstrap-datetimepicker.min.js', 'jquery', 2);
e107::js('core', 'bootstrap-datetimepicker/js/bootstrap-datetimepicker.init.js', 'jquery', 2);
if(e_LANGUAGE !== 'English')
{
e107::js('footer-inline', e107::getDate()->buildDateLocale());
}
return $text;
}
/**
* Render a simple user dropdown list.
* @param string $name - form field name
* @param null $val - current value
* @param array $options
* @param string $options['group'] if == 'class' then users will be sorted into userclass groups.
* @param string $options['fields']
* @param string $options['classes'] - single or comma-separated list of user-classes members to include.
* @param string $options['excludeSelf'] = exlude logged in user from list.
* @param string $options['return'] if == 'array' an array is returned.
* @param string $options['return'] if == 'sqlWhere' an sql query is returned.
* @return string select form element.
*/
public function userlist($name, $val=null, $options=array())
{
$fields = (!empty($options['fields'])) ? $options['fields'] : "user_id,user_name,user_class";
$class = (!empty($options['classes'])) ? $options['classes'] : e_UC_MEMBER ; // all users sharing the same class as the logged-in user.
$class = str_replace(" ","",$class);
switch ($class)
{
case e_UC_ADMIN:
$where = "user_admin = 1";
$classList = e_UC_ADMIN;
break;
case e_UC_MEMBER:
$where = "user_ban = 0";
$classList = e_UC_MEMBER;
break;
case e_UC_NOBODY:
return "";
break;
case 'matchclass':
$where = "user_class REGEXP '(^|,)(".str_replace(",","|", USERCLASS).")(,|$)'";
$classList = USERCLASS;
$clist = explode(",",USERCLASS);
if(count($clist) > 1 && !isset($options['group'])) // group classes by default if more than one found.
{
$options['group'] = 'class';
}
break;
default:
$where = "user_class REGEXP '(^|,)(".str_replace(",","|", $class).")(,|$)'";
$classList = $class;
break;
}
if(!empty($options['return']) && $options['return'] == 'sqlWhere') // can be used by user.php ajax method..
{
return $where;
}
$users = e107::getDb()->retrieve("user",$fields, "WHERE ".$where." ORDER BY user_name LIMIT 1000",true);
if(empty($users))
{
return "Unavailable";
}
$opt = array();
if(!empty($options['group']) && $options['group'] == 'class')
{
$classes = explode(',',$classList);
foreach($classes as $cls)
{
$cname = e107::getUserClass()->getName($cls);
$cname = str_replace('_',' ', trim($cname));
foreach($users as $u)
{
$uclass = explode(',',$u['user_class']);
if(($classList == e_UC_ADMIN) || ($classList == e_UC_MEMBER) || in_array($cls,$uclass))
{
$id = $u['user_id'];
if(!empty($options['excludeSelf']) && ($id == USERID))
{
continue;
}
$opt[$cname][$id] = $u['user_name'];
}
}
}
}
else
{
foreach($users as $u)
{
$id = $u['user_id'];
$opt[$id] = $u['user_name'];
}
}
ksort($opt);
if(!empty($options['return']) && $options['return'] == 'array') // can be used by user.php ajax method..
{
return $opt;
}
return $this->select($name,$opt,$val,$options, varset($options['default'],null));
}
/**
* User auto-complete search
* XXX EXPERIMENTAL - subject to change.
* @param string $name_fld field name for user name
* @param string $id_fld field name for user id
* @param string $default_name default user name value
* @param integer $default_id default user id
* @param array|string $options [optional] 'readonly' (make field read only), 'name' (db field name, default user_name)
* @return string HTML text for display
*/
/*
function userpicker($name_fld, $id_fld='', $default_name, $default_id, $options = array())
{
if(!is_array($options))
{
parse_str($options, $options);
}
$default_name = vartrue($default_name, '');
$default_id = vartrue($default_id, '');
$default_options = array();
if (!empty($default_name))
{
$default_options = array(
array(
'value' => $default_id,
'label' => $default_name,
),
);
}
$defaults['selectize'] = array(
'loadPath' => e_BASE . 'user.php',
'create' => false,
'maxItems' => 1,
'mode' => 'multi',
'options' => $default_options,
);
//TODO FIXME Filter by userclass. - see $frm->userlist().
$options = array_replace_recursive($defaults, $options);
$ret = $this->text($name_fld, $default_id, 20, $options);
return $ret;
}
*/
/**
* User Field - auto-complete search
* @param string $name form element name
* @param string|array $value comma separated list of user ids or array of userid=>username pairs.
* @param array|string $options [optional]
* @param int $options['limit'] Maximum number of users
* @param string $options['id'] Custom id
* @param string $options['inline'] Inline ID.
*
* @example $frm->userpicker('author', 1);
* @example $frm->userpicker('authors', "1,2,3");
* @example $frm->userpicker('author', array('user_id'=>1, 'user_name'=>'Admin');
* @example $frm->userpicker('authors', array(0=>array('user_id'=>1, 'user_name'=>'Admin', 1=>array('user_id'=>2, 'user_name'=>'John'));
*
* @todo $options['type'] = 'select' - dropdown selections box with data returned as array instead of comma-separated.
* @return string HTML text for display
*/
function userpicker($name, $value, $options = array())
{
if(!is_array($options))
{
parse_str($options, $options);
}
$defaultItems = array();
if(is_array($value))
{
if(isset($value[0]))// multiple users.
{
foreach($value as $val)
{
$defaultItems[] = array('value'=>$val['user_id'], 'label'=>$val['user_name']);
}
}
else // single user
{
$defaultItems[] = array('value'=>$value['user_id'], 'label'=>$value['user_name']);
}
}
elseif(!empty($value)) /// comma separated with user-id lookup.
{
$tmp = explode(",", $value);
foreach($tmp as $uid)
{
if($user = e107::user($uid))
{
$defaultItems[] = array('value'=>$user['user_id'], 'label'=>$user['user_name']);
}
}
}
$parms = array(
'selectize' => array(
'loadPath' => e_BASE . 'user.php',
'create' => false,
'maxItems' => 1,
'mode' => 'multi',
'options' => $defaultItems
)
);
if(!empty($options['limit']))
{
$parms['selectize']['maxItems'] = intval($options['limit']);
}
if(!empty($options['id']))
{
$parms['id'] = $options['id'];
}
if(!empty($options['inline']))
{
$parms['selectize']['e_editable'] = $options['inline'];
}
//TODO FIXME Filter by userclass. - see $frm->userlist().
$defValues = array();
foreach($defaultItems as $val)
{
$defValues[] = $val['value'];
}
$ret = $this->text($name, implode(",",$defValues), 100, $parms);
return $ret;
}
/**
* A Rating element
* @var $text
*/
function rate($table,$id,$options=null)
{
$table = preg_replace('/\W/', '', $table);
$id = intval($id);
return e107::getRate()->render($table, $id, $options);
}
function like($table,$id,$options=null)
{
$table = preg_replace('/\W/', '', $table);
$id = intval($id);
return e107::getRate()->renderLike($table,$id,$options);
}
/**
* File Upload form element.
* @param $name
* @param array $options (optional) array('multiple'=>1)
* @return string
*/
function file($name, $options = array())
{
$options = $this->format_options('file', $name, $options);
//never allow id in format name-value for text fields
return "
get_attributes($options, $name)." />";
}
function upload($name, $options = array())
{
return 'Ready to use upload form fields, optional - file list view';
}
function password($name, $value = '', $maxlength = 50, $options = array())
{
if(is_string($options)) parse_str($options, $options);
$addon = "";
$gen = "";
if(vartrue($options['generate']))
{
$gen = '
'.LAN_GENERATE.' ';
if(empty($options['nomask']))
{
$gen .= '
'.LAN_SHOW.' ';
}
}
if(vartrue($options['strength']))
{
$addon .= "
";
}
$options['pattern'] = vartrue($options['pattern'],'[\S]{4,}');
$options['required'] = varset($options['required'], 1);
$options['class'] = vartrue($options['class'],'e-password tbox');
e107::js('core', 'password/jquery.pwdMeter.js', 'jquery', 2);
e107::js('footer-inline', '
$(".e-password").pwdMeter({
minLength: 6,
displayGeneratePassword: true,
generatePassText: "Generate",
randomPassLength: 12
});
');
if(deftrue('BOOTSTRAP') == 3)
{
$options['class'] .= ' form-control';
}
if(vartrue($options['size']) && !is_numeric($options['size']))
{
$options['class'] .= " input-".$options['size'];
unset($options['size']); // don't include in html 'size='.
}
$type = empty($options['nomask']) ? 'password' : 'text';
$options = $this->format_options('text', $name, $options);
//never allow id in format name-value for text fields
$text = "
get_attributes($options, $name)." />";
if(empty($gen) && empty($addon))
{
return $text;
}
else
{
return "
".$text.$gen." ".vartrue($addon);
}
}
/**
* Render Pagination using 'nextprev' shortcode.
* @param string $url eg. e_REQUEST_SELF.'?from=[FROM]'
* @param int $total total records
* @param int $from value to replace [FROM] with in the URL
* @param int $perPage number of items per page
* @param array $options template, type, glyphs
* @return string
*/
public function pagination($url='', $total=0, $from=0, $perPage=10, $options=array())
{
if(!is_numeric($total))
{
return '';
}
require_once(e_CORE."shortcodes/single/nextprev.php");
$nextprev = array(
'tmpl_prefix' => varset($options['template'],'default'),
'total' => intval($total),
'amount' => intval($perPage),
'current' => intval($from),
'url' => urldecode($url),
'type' => varset($options['type'],'record'), // page|record
'glyphs' => vartrue($options['glyphs'],false) // 1|0
);
return nextprev_shortcode($nextprev);
}
/**
* Render a bootStrap ProgressBar.
* @param string $name
* @param number $value
* @param array $options
* @example Use
*/
public function progressBar($name,$value,$options=array())
{
if(!deftrue('BOOTSTRAP')) // Legacy ProgressBar.
{
$barl = (file_exists(THEME.'images/barl.png') ? THEME_ABS.'images/barl.png' : e_PLUGIN_ABS.'poll/images/barl.png');
$barr = (file_exists(THEME.'images/barr.png') ? THEME_ABS.'images/barr.png' : e_PLUGIN_ABS.'poll/images/barr.png');
$bar = (file_exists(THEME.'images/bar.png') ? THEME_ABS.'images/bar.png' : e_PLUGIN_ABS.'poll/images/bar.png');
return "
";
}
$class = vartrue($options['class'],'');
$target = $this->name2id($name);
$striped = (vartrue($options['btn-label'])) ? ' progress-striped active' : '';
$percVal = number_format($value,0).'%';
$text = "
";
$text .= $percVal;
$text .= "
";
$loading = vartrue($options['loading'],'Please wait...');
$buttonId = $target.'-start';
if(vartrue($options['btn-label']))
{
$interval = vartrue($options['interval'],1000);
$text .= '
'.$options['btn-label'].' ';
$text .= '
'.LAN_CANCEL.' ';
}
return $text;
}
/**
* Textarea Element
* @param $name
* @param $value
* @param $rows
* @param $cols
* @param $options
* @param $count
* @return string
*/
function textarea($name, $value, $rows = 10, $cols = 80, $options = array(), $counter = false)
{
if(is_string($options)) parse_str($options, $options);
// auto-height support
if(empty($options['class']))
{
$options['class'] = '';
}
if(vartrue($options['size']) && !is_numeric($options['size']))
{
$options['class'] .= " form-control input-".$options['size'];
unset($options['size']); // don't include in html 'size='.
}
elseif(!vartrue($options['noresize']))
{
$options['class'] = (isset($options['class']) && $options['class']) ? $options['class'].' e-autoheight' : 'tbox col-md-7 span7 e-autoheight form-control';
}
$options = $this->format_options('textarea', $name, $options);
// print_a($options);
//never allow id in format name-value for text fields
return "
".(false !== $counter ? $this->hidden('__'.$name.'autoheight_opt', $counter) : '');
}
/**
* Bbcode Area. Name, value, template, media-Cat, size, options array eg. counter
* IMPORTANT: $$mediaCat is also used is the media-manager category identifier
* @param $name
* @param $value
* @param $template
* @param $mediaCat _common
* @param $size : small | medium | large
* @param $options array();
*/
function bbarea($name, $value, $template = '', $mediaCat='_common', $size = 'large', $options = array())
{
if(is_string($options)) parse_str($options, $options);
//size - large|medium|small
//width should be explicit set by current admin theme
// $size = 'input-large';
$height = '';
$cols = 70;
switch($size)
{
case 'tiny':
$rows = '3';
$cols = 50;
// $height = "style='height:250px'"; // inline required for wysiwyg
break;
case 'small':
$rows = '7';
$height = "style='height:230px'"; // inline required for wysiwyg
$size = "input-block-level";
break;
case 'medium':
$rows = '10';
$height = "style='height:375px'"; // inline required for wysiwyg
$size = "input-block-level";
break;
case 'large':
default:
$rows = '15';
$size = 'large input-block-level';
// $height = "style='height:500px;width:1025px'"; // inline required for wysiwyg
break;
}
// auto-height support
$options['class'] = 'tbox bbarea '.($size ? ' '.$size : '').' e-wysiwyg e-autoheight form-control';
$bbbar = '';
$help_tagid = $this->name2id($name)."--preview";
if(e107::wysiwyg(true) === false) // bbarea loaded, so activate wysiwyg (if enabled in preferences)
{
$options['other'] = "onselect='storeCaret(this);' onclick='storeCaret(this);' onkeyup='storeCaret(this);' {$height}";
}
else
{
$options['other'] = " ".$height;
}
$counter = vartrue($options['counter'],false);
$ret = "
\n";
$ret .= e107::getBB()->renderButtons($template,$help_tagid);
$ret .= $this->textarea($name, $value, $rows, $cols, $options, $counter); // higher thank 70 will break some layouts.
$ret .= "
\n";
$_SESSION['media_category'] = $mediaCat; // used by TinyMce.
return $ret;
// Quick fix - hide TinyMCE links if not installed, dups are handled by JS handler
/*
e107::getJs()->footerInline("
if(typeof tinyMCE === 'undefined')
{
\$$('a.e-wysiwyg-switch').invoke('hide');
}
");
*/
}
/**
* Render a checkbox
* @param string $name
* @param mixed $value
* @param boolean $checked
* @param mixed $options query-string or array or string for a label. eg. label=Hello&foo=bar or array('label'=>Hello') or 'Hello'
* @return string
*/
function checkbox($name, $value, $checked = false, $options = array())
{
if(!is_array($options))
{
if(strpos($options,"=")!==false)
{
parse_str($options, $options);
}
elseif(is_array($options))
{
// do nothing.
}
else // Assume it's a label.
{
$options = array('label'=>$options);
}
}
$labelClass = (!empty($options['inline'])) ? 'checkbox-inline' : 'checkbox';
$labelTitle = '';
$options = $this->format_options('checkbox', $name, $options);
$options['checked'] = $checked; //comes as separate argument just for convenience
$text = "";
$active = ($checked === true) ? " active" : ""; // allow for styling if needed.
if(!empty($options['label'])) // add attributes to
{
if(!empty($options['title']))
{
$labelTitle = " title=\"".$options['title']."\"";
unset($options['title']);
}
if(!empty($options['class']))
{
$labelClass .= " ".$options['class'];
unset($options['class']);
}
}
$pre = (vartrue($options['label'])) ? "" : ""; // Bootstrap compatible markup
$post = (vartrue($options['label'])) ? $options['label']." " : "";
unset($options['label']); // not to be used as attribute;
$text .= " get_attributes($options, $name, $value)." />";
return $pre.$text.$post;
}
/**
* Render an array of checkboxes.
* @param string $name
* @param array $option_array
* @param mixed $checked
* @param array $options [optional useKeyValues]
*/
function checkboxes($name, $option_array, $checked, $options=array())
{
$name = (strpos($name, '[') === false) ? $name.'[]' : $name;
if(!is_array($checked)) $checked = explode(",",$checked);
$text = "";
$cname = $name;
foreach($option_array as $k=>$label)
{
if(!empty($options['useKeyValues'])) // ie. auto-generated
{
$key = $k;
$c = in_array($k, $checked) ? true : false;
}
elseif(!empty($options['useLabelValues']))
{
$key = $label;
//print_a($label);
$c = in_array($label, e107::getParser()->toDB($checked)) ? true : false;
}
else
{
$key = 1;
$cname = str_replace('[]','['.$k.']',$name);
$c = vartrue($checked[$k]);
}
$text .= $this->checkbox($cname, $key, $c, $label);
}
// return print_a($checked,true);
if(!empty($text))
{
return "".$text."
";
}
return $text;
}
function checkbox_label($label_title, $name, $value, $checked = false, $options = array())
{
return $this->checkbox($name, $value, $checked, $options).$this->label($label_title, $name, $value);
}
function checkbox_switch($name, $value, $checked = false, $label = '')
{
return $this->checkbox($name, $value, $checked).$this->label($label ? $label : LAN_ENABLED, $name, $value);
}
function checkbox_toggle($name, $selector = 'multitoggle', $id = false, $label='') //TODO Fixme - labels will break this. Don't use checkbox, use html.
{
$selector = 'jstarget:'.$selector;
if($id) $id = $this->name2id($id);
return $this->checkbox($name, $selector, false, array('id' => $id,'class' => 'checkbox checkbox-inline toggle-all','label'=>$label));
}
function uc_checkbox($name, $current_value, $uc_options, $field_options = array())
{
if(!is_array($field_options)) parse_str($field_options, $field_options);
return '
'.$this->_uc->vetted_tree($name, array($this, '_uc_checkbox_cb'), $current_value, $uc_options, $field_options).'
';
}
/**
* Callback function used with $this->uc_checkbox
*
* @see user_class->select() for parameters
*/
function _uc_checkbox_cb($treename, $classnum, $current_value, $nest_level, $field_options)
{
if($classnum == e_UC_BLANK)
return '';
if (!is_array($current_value))
{
$tmp = explode(',', $current_value);
}
$classIndex = abs($classnum); // Handle negative class values
$classSign = (substr($classnum, 0, 1) == '-') ? '-' : '';
$class = $style = '';
if($nest_level == 0)
{
$class = " strong";
}
else
{
$style = " style='text-indent:" . (1.2 * $nest_level) . "em'";
}
$descr = varset($field_options['description']) ? ' ('.$this->_uc->uc_get_classdescription($classnum).') ' : '';
return "".$this->checkbox($treename.'[]', $classnum, in_array($classnum, $tmp), $field_options).$this->label($this->_uc->uc_get_classname($classIndex).$descr, $treename.'[]', $classnum)."
\n";
}
function uc_label($classnum)
{
return $this->_uc->uc_get_classname($classnum);
}
/**
* A Radio Button Form Element
* @param $name
* @param @value array pair-values|string - auto-detected.
* @param $checked boolean
* @param $options
*/
function radio($name, $value, $checked = false, $options = null)
{
if(!is_array($options)) parse_str($options, $options);
if(is_array($value))
{
return $this->radio_multi($name, $value, $checked, $options);
}
$labelFound = vartrue($options['label']);
unset($options['label']); // label attribute not valid in html5
$options = $this->format_options('radio', $name, $options);
$options['checked'] = $checked; //comes as separate argument just for convenience
// $options['class'] = 'inline';
$text = "";
// return print_a($options,true);
if($labelFound) // Bootstrap compatible markup
{
$defaultClass = (deftrue('BOOTSTRAP') === 3) ? 'radio-inline' : 'radio inline';
$dis = (!empty($options['disabled'])) ? " disabled" : "";
$text .= "";
}
$text .= " get_attributes($options, $name, $value)." />";
if(vartrue($options['help']))
{
$text .= "".$options['help']."
";
}
if($labelFound)
{
$text .= "".$labelFound." ";
}
return $text;
}
/**
* Boolean Radio Buttons.
* @param name string
* @param check_enabled boolean
* @param label_enabled default is LAN_ENABLED
* @param label_disabled default is LAN_DISABLED
* @param options array - inverse=1 (invert values) or reverse=1 (switch display order)
*/
function radio_switch($name, $checked_enabled = false, $label_enabled = '', $label_disabled = '',$options=array())
{
if(!is_array($options)) parse_str($options, $options);
$options_on = varset($options['enabled'],array());
$options_off = varset($options['disabled'],array());
unset($options['enabled'],$options['disabled']);
$options_on = array_merge($options_on, $options);
$options_off = array_merge($options_off, $options);
if(vartrue($options['class']) == 'e-expandit' || vartrue($options['expandit'])) // See admin->prefs 'Single Login' for an example.
{
$options_on = array_merge($options, array('class' => 'e-expandit-on'));
$options_off = array_merge($options, array('class' => 'e-expandit-off'));
}
$options_on['label'] = $label_enabled ? defset($label_enabled,$label_enabled) : LAN_ENABLED;
$options_off['label'] = $label_disabled ? defset($label_disabled,$label_disabled) : LAN_DISABLED;
if(!empty($options['inverse'])) // Same as 'writeParms'=>'reverse=1&enabled=LAN_DISABLED&disabled=LAN_ENABLED'
{
$text = $this->radio($name, 0, !$checked_enabled, $options_on)." ".$this->radio($name, 1, $checked_enabled, $options_off);
}
elseif(!empty($options['reverse'])) // reverse display order.
{
$text = $this->radio($name, 0, !$checked_enabled, $options_off)." ".$this->radio($name, 1, $checked_enabled, $options_on);
}
else
{
$text = $this->radio($name, 1, $checked_enabled, $options_on)." ".$this->radio($name, 0, !$checked_enabled, $options_off);
}
return $text;
}
/**
* XXX INTERNAL ONLY - Use radio() instead. array will automatically trigger this internal method.
* @param string $name
* @param array $elements = arrays value => label
* @param string/integer $checked = current value
* @param boolean $multi_line
* @param mixed $help array of field help items or string of field-help (to show on all)
*/
private function radio_multi($name, $elements, $checked, $options=array(), $help = null)
{
/* // Bootstrap Test.
return'
Option one is this and that—be sure to include why its great
Option one is this and that—be sure to include why its great
Option two can be something else and selecting it will deselect option one
';
*/
$text = array();
if(is_string($elements)) parse_str($elements, $elements);
if(!is_array($options)) parse_str($options, $options);
$help = '';
if(vartrue($options['help']))
{
$help = "".$options['help']."
";
unset($options['help']);
}
foreach ($elements as $value => $label)
{
$label = defset($label, $label);
$helpLabel = (is_array($help)) ? vartrue($help[$value]) : $help;
// Bootstrap Style Code - for use later.
$options['label'] = $label;
$options['help'] = $helpLabel;
$text[] = $this->radio($name, $value, (string) $checked === (string) $value, $options);
// $text[] = $this->radio($name, $value, (string) $checked === (string) $value)."".$this->label($label, $name, $value).(isset($helpLabel) ? "".$helpLabel."
" : '');
}
// if($multi_line === false)
// {
// return implode(" ", $text);
// }
// support of UI owned 'newline' parameter
if(!varset($options['sep']) && vartrue($options['newline'])) $options['sep'] = ' '; // TODO div class=separator?
$separator = varset($options['sep']," ");
// return print_a($text,true);
return implode($separator, $text).$help;
// return implode("\n", $text);
//XXX Limiting markup.
// return "".implode("
", $text)."
";
}
/**
* Just for BC - use the $options['label'] instead.
*/
function label($text, $name = '', $value = '')
{
// $backtrack = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS,2);
// e107::getMessage()->addDebug("Deprecated \$frm->label() used in: ".print_a($backtrack,true));
$for_id = $this->_format_id('', $name, $value, 'for');
return "{$text} ";
}
function help($text)
{
return !empty($text) ? ''.$text.'
' : '';
}
function select_open($name, $options = array())
{
if(!is_array($options)) parse_str($options, $options);
if(vartrue($options['size']) && !is_numeric($options['size']))
{
if(!empty($options['class']))
{
$options['class'] .= " input-".$options['size'];
}
else
{
$options['class'] = "input-".$options['size'];
}
unset($options['size']); // don't include in html 'size='.
}
$options = $this->format_options('select', $name, $options);
return "get_attributes($options, $name).">";
}
/**
* @DEPRECATED - use select() instead.
*/
function selectbox($name, $option_array, $selected = false, $options = array(), $defaultBlank= false)
{
return $this->select($name, $option_array, $selected, $options, $defaultBlank);
}
/**
*
* @param string $name
* @param array $option_array
* @param boolean $selected [optional]
* @param string|array $options [optional]
* @param bool $options['useValues'] when true uses array values as the key.
* @param bool|string $defaultBlank [optional] set to TRUE if the first entry should be blank, or to a string to use it for the blank description.
* @return string HTML text for display
*/
function select($name, $option_array, $selected = false, $options = array(), $defaultBlank= false)
{
if(!is_array($options)) parse_str($options, $options);
if($option_array === 'yesno')
{
$option_array = array(1 => LAN_YES, 0 => LAN_NO);
}
if(vartrue($options['multiple']))
{
$name = (strpos($name, '[') === false) ? $name.'[]' : $name;
if(!is_array($selected)) $selected = explode(",",$selected);
}
$text = $this->select_open($name, $options)."\n";
if(isset($options['default']))
{
if($options['default'] === 'blank')
{
$options['default'] = ' ';
}
$text .= $this->option($options['default'], varset($options['defaultValue'],''));
}
elseif($defaultBlank)
{
$diz = is_string($defaultBlank) ? $defaultBlank : ' ';
$text .= $this->option($diz, '');
}
if(varset($options['useValues'])) // use values as keys.
{
$new = array();
foreach($option_array as $v)
{
$new[$v] = $v;
}
$option_array = $new;
}
$text .= $this->option_multi($option_array, $selected)."\n".$this->select_close();
return $text;
}
/**
* Universal Userclass selector - checkboxes, dropdown, everything.
* @param string $name - form element name
* @param int $curval - current userclass value(s) as array or comma separated.
* @param string $type - checkbox|dropdown default is dropdown.
* @param string|array $options - classlist or query string or key=value pair.
* @param string $options['options'] comma-separated list of display options. 'options=admin,mainadmin,classes&vetted=1&exclusions=0' etc.
*
* @example $frm->userclass('name', 0, 'dropdown', 'classes'); // display all userclasses
* @example $frm->userclass('name', 0, 'dropdown', 'classes,matchclass'); // display only classes to which the user belongs.
* @return string form element(s)
*/
function userclass($name, $curval=255, $type=null, $options=null)
{
if(!empty($options))
{
if(is_array($options))
{
$opt = $options;
}
elseif(strpos($options,'=')!==false)
{
parse_str($options,$opt);
}
else
{
$opt = array('options'=>$options);
}
}
else
{
$opt = array();
}
$optlist = vartrue($opt['options'],null);
switch ($type)
{
case 'checkbox':
return e107::getUserClass()->uc_checkboxes($name, $curval, $optlist, null,false);
break;
case 'dropdown':
default:
return e107::getUserClass()->uc_dropdown($name, $curval, $optlist, $opt);
break;
}
}
/**
* Renders a generic search box. If $filter has values, a filter box will be included with the options provided.
*
*/
function search($name, $searchVal, $submitName, $filterName='', $filterArray=false, $filterVal=false)
{
$tp = e107::getParser();
$text = '
'.$this->text($name, $searchVal,20,'class=search-query&placeholder=Search…').'
'.$tp->toGlyph('fa-search',' ').'
';
if(is_array($filter))
{
$text .= $this->selectbox($$filterName, $filterArray, $filterVal);
}
// $text .= $this->admin_button($submitName,LAN_SEARCH,'search');
return $text;
/*
$text .=
Display All
Clear Filter
General
Misc
Test 3
Display All
Filter
*/
}
function uc_select($name, $current_value, $uc_options, $select_options = array(), $opt_options = array())
{
if(!empty($select_options['multiple']) && substr($name,-1) != ']')
{
$name .= '[]';
}
if(empty($current_value) && !empty($uc_options)) // make the first in the opt list the default value.
{
$tmp = explode(",", $uc_options);
$current_value = e107::getUserClass()->getClassFromKey($tmp[0]);
}
if(!empty($current_value) && !is_numeric($current_value)) // convert name to id.
{
$current_value = $this->_uc->getID($current_value);
}
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();
}
// Callback for vetted_tree - Creates the option list for a selection box
function _uc_select_cb($treename, $classnum, $current_value, $nest_level)
{
$classIndex = abs($classnum); // Handle negative class values
$classSign = (substr($classnum, 0, 1) == '-') ? '-' : '';
if($classnum == e_UC_BLANK)
return $this->option(' ', '');
$tmp = explode(',', $current_value);
if($nest_level == 0)
{
$prefix = '';
$style = "font-weight:bold; font-style: italic;";
}
elseif($nest_level == 1)
{
$prefix = ' ';
$style = "font-weight:bold";
}
else
{
$prefix = ' '.str_repeat('--', $nest_level - 1).'>';
$style = '';
}
return $this->option($prefix.$this->_uc->uc_get_classname($classnum), $classSign.$classIndex, ($current_value !== '' && in_array($classnum, $tmp)), array("style"=>"{$style}"))."\n";
}
function optgroup_open($label, $disabled = false, $options = null)
{
return "\n";
}
/**
* tag generation.
* @param $option_title
* @param $value
* @param $selected
* @param $options (eg. disabled=1)
*/
function option($option_title, $value, $selected = false, $options = '')
{
if(is_string($options)) parse_str($options, $options);
if(false === $value) $value = '';
$options = $this->format_options('option', '', $options);
$options['selected'] = $selected; //comes as separate argument just for convenience
return " get_attributes($options).">".defset($option_title, $option_title)." ";
}
/**
* Use selectbox() instead.
*/
function option_multi($option_array, $selected = false, $options = array())
{
if(is_string($option_array)) parse_str($option_array, $option_array);
$text = '';
if(empty($option_array))
{
return $this->option('','');
}
foreach ($option_array as $value => $label)
{
if(is_array($label))
{
$text .= $this->optgroup($value,$label,$selected,$options, 0);
}
else
{
$text .= $this->option($label, $value, (is_array($selected) ? in_array($value, $selected) : $selected == $value), $options)."\n";
}
}
return $text;
}
/**
* No compliant, but it works.
* @param $value
* @param $label
* @param $selected
* @param $options
* @param int $level
* @return string
*/
private function optgroup($value, $label, $selected, $options, $level=1)
{
$level++;
$text = $this->optgroup_open($value, null, array('class'=>'level-'.$level));
foreach($label as $val => $lab)
{
if(is_array($lab))
{
$text .= $this->optgroup($val,$lab,$selected,$options,$level);
}
else
{
$text .= $this->option($lab, $val, (is_array($selected) ? in_array($val, $selected) : $selected == $val), $options)."\n";
}
}
$text .= $this->optgroup_close();
return $text;
}
function optgroup_close()
{
return " \n";
}
function select_close()
{
return " ";
}
function hidden($name, $value, $options = array())
{
$options = $this->format_options('hidden', $name, $options);
return " get_attributes($options, $name, $value)." />";
}
/**
* Generate hidden security field
* @return string
*/
function token()
{
return " ";
}
function submit($name, $value, $options = array())
{
$options = $this->format_options('submit', $name, $options);
return " get_attributes($options, $name, $value)." />";
}
function submit_image($name, $value, $image, $title='', $options = array())
{
$tp = e107::getParser();
$options = $this->format_options('submit_image', $name, $options);
switch ($image)
{
case 'edit':
$icon = "e-edit-32";
$options['class'] = $options['class'] == 'action' ? 'btn btn-default action edit' : $options['class'];
break;
case 'delete':
$icon = (e_ADMIN_AREA === true) ? "e-delete-32" : 'fa-trash.glyph';
$options['class'] = $options['class'] == 'action' ? 'btn btn-default action delete' : $options['class'];
$options['other'] = 'data-confirm="'.LAN_JSCONFIRM.'"';
break;
case 'execute':
$icon = "e-execute-32";
$options['class'] = $options['class'] == 'action' ? 'btn btn-default action execute' : $options['class'];
break;
case 'view':
$icon = "e-view-32";
$options['class'] = $options['class'] == 'action' ? 'btn btn-default action view' : $options['class'];
break;
}
$options['title'] = $title;//shorthand
return "get_attributes($options, $name, $value)." >".$tp->toIcon($icon)." ";
}
/**
* Alias of admin_button, adds the etrigger_ prefix required for UI triggers
* @see e_form::admin_button()
*/
function admin_trigger($name, $value, $action = 'submit', $label = '', $options = array())
{
return $this->admin_button('etrigger_'.$name, $value, $action, $label, $options);
}
/**
* Generic Button Element.
* @param string $name
* @param string $value
* @param string $action [optional] default is submit - use 'dropdown' for a bootstrap dropdown button.
* @param string $label [optional]
* @param string|array $options [optional]
* @return string
*/
public function button($name, $value, $action = 'submit', $label = '', $options = array())
{
if(deftrue('BOOTSTRAP') && $action == 'dropdown' && is_array($value))
{
// $options = $this->format_options('admin_button', $name, $options);
$options['class'] = vartrue($options['class']);
$align = vartrue($options['align'],'left');
$text = '';
return $text;
}
return $this->admin_button($name, $value, $action, $label, $options);
}
/**
* Render a Breadcrumb in Bootstrap format.
* @param $array
* @param $array[url]
* @param $array[text]
*/
function breadcrumb($array)
{
if(!is_array($array)){ return; }
$opt = array();
$homeIcon = e107::getParser()->toGlyph('icon-home.glyph',false);
$opt[] = "".$homeIcon." "; // Add Site-Pref to disable?
$text = '";
// return print_a($opt,true);
return $text;
}
/**
* Render a direct link admin-edit button on the frontend.
* @param $url
* @param string $perms
* @return string
*/
public function instantEditButton($url, $perms='0')
{
if(deftrue("BOOTSTRAP") && getperms($perms))
{
return "".e107::getParser()->toGlyph('fa-edit')." ";
}
return '';
}
/**
* Admin Button - for front-end, use button();
* @param string $name
* @param string $value
* @param string $action [optional] default is submit
* @param string $label [optional]
* @param string|array $options [optional]
* @return string
*/
function admin_button($name, $value, $action = 'submit', $label = '', $options = array())
{
$btype = 'submit';
if(strpos($action, 'action') === 0)
{
$btype = 'button';
}
if(isset($options['loading']) && ($options['loading'] == false))
{
unset($options['loading']);
$include = '';
}
else
{
$include = (deftrue("FONTAWESOME")) ? "data-loading-icon='fa-spinner' data-disable='true'" : "";
}
$options = $this->format_options('admin_button', $name, $options);
$options['class'] = vartrue($options['class']);
$options['class'] .= ' btn ' . $action;
if(empty($label))
{
$label = $value;
}
// Ability to use any kind of button class for the selected action.
if (!$this->defaultButtonClassExists($options['class']))
{
$options['class'] .= ' ' . $this->getDefaultButtonClassByAction($action);
}
switch ($action)
{
case 'checkall':
$options['class'] .= ' btn-mini btn-xs';
break;
case 'delete':
case 'danger':
$options['other'] = 'data-confirm="'.LAN_JSCONFIRM.'"';
break;
case 'batch':
case 'batch e-hide-if-js':
// FIXME hide-js shouldn't be here.
break;
case 'filter':
case 'filter e-hide-if-js':
// FIXME hide-js shouldn't be here.
break;
}
return "get_attributes($options, $name) . ">{$label} ";
}
/**
* Helper function to check if a (CSS) class already contains a button class?
*
* @param string $class
* The class we want to check.
*
* @return bool
* True if $class already contains a button class. Otherwise false.
*/
function defaultButtonClassExists($class = '')
{
// Bootstrap button classes.
// @see http://getbootstrap.com/css/#buttons-options
$btnClasses = array(
'btn-default',
'btn-primary',
'btn-success',
'btn-info',
'btn-warning',
'btn-danger',
'btn-link',
);
foreach($btnClasses as $btnClass) {
if(strpos($class, $btnClass, 0) !== false)
{
return true;
}
}
return false;
}
/**
* Helper function to get default button class by action.
*
* @param string $action
* Action for a button. See button().
*
* @return string $class
* Default button class.
*/
function getDefaultButtonClassByAction($action)
{
switch($action)
{
case 'update':
case 'create':
case 'import':
case 'submit':
case 'success':
$class = 'btn-success';
break;
case 'checkall':
$class = 'btn-default';
break;
case 'cancel':
$class = 'btn-default';
break;
case 'delete':
case 'danger':
$class = 'btn-danger';
break;
case 'execute':
$class = 'btn-success';
break;
case 'other':
case 'login':
case 'primary':
$class = 'btn-primary';
break;
case 'warning':
case 'confirm':
$class = 'btn-warning';
break;
case 'batch':
case 'batch e-hide-if-js':
$class = 'btn-primary';
break;
case 'filter':
case 'filter e-hide-if-js':
$class = 'btn-primary';
break;
case 'default':
default:
$class = 'btn-default';
break;
}
return $class;
}
function getNext()
{
if(!$this->_tabindex_enabled) return 0;
$this->_tabindex_counter += 1;
return $this->_tabindex_counter;
}
function getCurrent()
{
if(!$this->_tabindex_enabled) return 0;
return $this->_tabindex_counter;
}
function resetTabindex($reset = 0)
{
$this->_tabindex_counter = $reset;
}
function get_attributes($options, $name = '', $value = '')
{
$ret = '';
//
foreach ($options as $option => $optval)
{
$optval = trim($optval);
switch ($option)
{
case 'id':
$ret .= $this->_format_id($optval, $name, $value);
break;
case 'class':
if(!empty($optval)) $ret .= " class='{$optval}'";
break;
case 'size':
if($optval) $ret .= " size='{$optval}'";
break;
case 'title':
if($optval) $ret .= " title='{$optval}'";
break;
case 'label':
if($optval) $ret .= " label='{$optval}'";
break;
case 'tabindex':
if($optval) $ret .= " tabindex='{$optval}'";
elseif(false === $optval || !$this->_tabindex_enabled) break;
else
{
$this->_tabindex_counter += 1;
$ret .= " tabindex='".$this->_tabindex_counter."'";
}
break;
case 'readonly':
if($optval) $ret .= " readonly='readonly'";
break;
case 'multiple':
if($optval) $ret .= " multiple='multiple'";
break;
case 'selected':
if($optval) $ret .= " selected='selected'";
break;
case 'maxlength':
if($optval) $ret .= " maxlength='{$optval}'";
break;
case 'checked':
if($optval) $ret .= " checked='checked'";
break;
case 'disabled':
if($optval) $ret .= " disabled='disabled'";
break;
case 'required':
if($optval) $ret .= " required='required'";
break;
case 'autofocus':
if($optval) $ret .= " autofocus='autofocus'";
break;
case 'placeholder':
if($optval) {
$optval = deftrue($optval, $optval);
$ret .= " placeholder='{$optval}'";
}
break;
case 'wrap':
if($optval) $ret .= " wrap='{$optval}'";
break;
case 'autocomplete':
if($optval) $ret .= " autocomplete='{$optval}'";
break;
case 'pattern':
if($optval) $ret .= " pattern='{$optval}'";
break;
case 'other':
if($optval) $ret .= " $optval";
break;
}
if(substr($option,0,5) =='data-')
{
$ret .= " ".$option."='{$optval}'";
}
}
return $ret;
}
/**
* Auto-build field attribute id
*
* @param string $id_value value for attribute id passed with the option array
* @param string $name the name attribute passed to that field
* @param unknown_type $value the value attribute passed to that field
* @return string formatted id attribute
*/
function _format_id($id_value, $name, $value = '', $return_attribute = 'id')
{
if($id_value === false) return '';
//format data first
$name = trim($this->name2id($name), '-');
$value = trim(preg_replace('#[^a-zA-Z0-9\-]#','-', $value), '-');
//$value = trim(preg_replace('#[^a-z0-9\-]#/i','-', $value), '-'); // This should work - but didn't for me!
$value = trim(str_replace("/","-",$value), '-'); // Why?
if(!$id_value && is_numeric($value)) $id_value = $value;
// clean - do it better, this could lead to dups
$id_value = trim($id_value, '-');
if(empty($id_value) ) return " {$return_attribute}='{$name}".($value ? "-{$value}" : '')."'";// also useful when name is e.g. name='my_name[some_id]'
elseif(is_numeric($id_value) && $name) return " {$return_attribute}='{$name}-{$id_value}'";// also useful when name is e.g. name='my_name[]'
else return " {$return_attribute}='{$id_value}'";
}
function name2id($name)
{
$name = strtolower($name);
return rtrim(str_replace(array('[]', '[', ']', '_', '/', ' ','.', '(', ')', '::', ':'), array('-', '-', '', '-', '-', '-', '-','','','-',''), $name), '-');
}
/**
* Format options based on the field type,
* merge with default
*
* @param string $type
* @param string $name form name attribute value
* @param array|string $user_options
* @return array merged options
*/
function format_options($type, $name, $user_options=null)
{
if(is_string($user_options))
{
parse_str($user_options, $user_options);
}
$def_options = $this->_default_options($type);
if(is_array($user_options))
{
$user_options['name'] = $name; //required for some of the automated tasks
foreach (array_keys($user_options) as $key)
{
if(!isset($def_options[$key]) && substr($key,0,5)!='data-') unset($user_options[$key]); // data-xxxx exempt //remove it?
}
}
else
{
$user_options = array('name' => $name); //required for some of the automated tasks
}
return array_merge($def_options, $user_options);
}
/**
* Get default options array based on the field type
*
* @param string $type
* @return array default options
*/
function _default_options($type)
{
if(isset($this->_cached_attributes[$type])) return $this->_cached_attributes[$type];
$def_options = array(
'id' => '',
'class' => '',
'title' => '',
'size' => '',
'readonly' => false,
'selected' => false,
'checked' => false,
'disabled' => false,
'required' => false,
'autofocus' => false,
'tabindex' => 0,
'label' => '',
'placeholder' => '',
'pattern' => '',
'other' => '',
'autocomplete' => '',
'maxlength' => '',
'wrap' => '',
'multiple' => '',
// 'multiple' => false, - see case 'select'
);
$form_control = (deftrue('BOOTSTRAP') === 3) ? ' form-control' : '';
switch ($type) {
case 'hidden':
$def_options = array('id' => false, 'disabled' => false, 'other' => '');
break;
case 'text':
$def_options['class'] = 'tbox input-text'.$form_control;
unset($def_options['selected'], $def_options['checked']);
break;
case 'file':
$def_options['class'] = 'tbox file';
unset($def_options['selected'], $def_options['checked']);
break;
case 'textarea':
$def_options['class'] = 'tbox textarea'.$form_control;
unset($def_options['selected'], $def_options['checked'], $def_options['size']);
break;
case 'select':
$def_options['class'] = 'tbox select'.$form_control;
$def_options['multiple'] = false;
unset($def_options['checked']);
break;
case 'option':
$def_options = array('class' => '', 'selected' => false, 'other' => '', 'disabled' => false, 'label' => '');
break;
case 'radio':
//$def_options['class'] = ' ';
$def_options = array('class' => '');
unset($def_options['size'], $def_options['selected']);
break;
case 'checkbox':
unset($def_options['size'], $def_options['selected']);
break;
case 'submit':
$def_options['class'] = 'button btn btn-primary';
unset($def_options['checked'], $def_options['selected'], $def_options['readonly']);
break;
case 'submit_image':
$def_options['class'] = 'action';
unset($def_options['checked'], $def_options['selected'], $def_options['readonly']);
break;
case 'admin_button':
unset($def_options['checked'], $def_options['selected'], $def_options['readonly']);
break;
}
$this->_cached_attributes[$type] = $def_options;
return $def_options;
}
function columnSelector($columnsArray, $columnsDefault = '', $id = 'column_options')
{
$columnsArray = array_filter($columnsArray);
// navbar-header nav-header
// navbar-header nav-header
$text = '";
// $text .= " ";
$text .= "";
/*
$text = '