新增插件配置分组功能

新增插件配置分组功能
新增插件配置可见条件
新增常规管理系统配置可见条件功能
新增表单可见条件组件
pull/377/head
Karson 2022-01-16 18:37:33 +08:00
parent d785d321f7
commit 65073c30b9
7 changed files with 256 additions and 129 deletions

View File

@ -323,6 +323,7 @@ CREATE TABLE `fa_config` (
`title` varchar(100) DEFAULT '' COMMENT '变量标题',
`tip` varchar(100) DEFAULT '' COMMENT '变量描述',
`type` varchar(30) DEFAULT '' COMMENT '类型:string,text,int,bool,array,datetime,date,file',
`visible` varchar(255) DEFAULT '' COMMENT '可见条件',
`value` text COMMENT '变量值',
`content` text COMMENT '变量字典数据',
`rule` varchar(100) DEFAULT '' COMMENT '验证规则',
@ -336,24 +337,24 @@ CREATE TABLE `fa_config` (
-- Records of fa_config
-- ----------------------------
BEGIN;
INSERT INTO `fa_config` VALUES (1, 'name', 'basic', 'Site name', '请填写站点名称', 'string', '我的网站', '', 'required', '', '');
INSERT INTO `fa_config` VALUES (2, 'beian', 'basic', 'Beian', '粤ICP备15000000号-1', 'string', '', '', '', '', '');
INSERT INTO `fa_config` VALUES (3, 'cdnurl', 'basic', 'Cdn url', '如果全站静态资源使用第三方云储存请配置该值', 'string', '', '', '', '', '');
INSERT INTO `fa_config` VALUES (4, 'version', 'basic', 'Version', '如果静态资源有变动请重新配置该值', 'string', '1.0.1', '', 'required', '', '');
INSERT INTO `fa_config` VALUES (5, 'timezone', 'basic', 'Timezone', '', 'string', 'Asia/Shanghai', '', 'required', '', '');
INSERT INTO `fa_config` VALUES (6, 'forbiddenip', 'basic', 'Forbidden ip', '一行一条记录', 'text', '', '', '', '', '');
INSERT INTO `fa_config` VALUES (7, 'languages', 'basic', 'Languages', '', 'array', '{\"backend\":\"zh-cn\",\"frontend\":\"zh-cn\"}', '', 'required', '', '');
INSERT INTO `fa_config` VALUES (8, 'fixedpage', 'basic', 'Fixed page', '请尽量输入左侧菜单栏存在的链接', 'string', 'dashboard', '', 'required', '', '');
INSERT INTO `fa_config` VALUES (9, 'categorytype', 'dictionary', 'Category type', '', 'array', '{\"default\":\"Default\",\"page\":\"Page\",\"article\":\"Article\",\"test\":\"Test\"}', '', '', '', '');
INSERT INTO `fa_config` VALUES (10, 'configgroup', 'dictionary', 'Config group', '', 'array', '{\"basic\":\"Basic\",\"email\":\"Email\",\"dictionary\":\"Dictionary\",\"user\":\"User\",\"example\":\"Example\"}', '', '', '', '');
INSERT INTO `fa_config` VALUES (11, 'mail_type', 'email', 'Mail type', '选择邮件发送方式', 'select', '1', '[\"请选择\",\"SMTP\"]', '', '', '');
INSERT INTO `fa_config` VALUES (12, 'mail_smtp_host', 'email', 'Mail smtp host', '错误的配置发送邮件会导致服务器超时', 'string', 'smtp.qq.com', '', '', '', '');
INSERT INTO `fa_config` VALUES (13, 'mail_smtp_port', 'email', 'Mail smtp port', '(不加密默认25,SSL默认465,TLS默认587)', 'string', '465', '', '', '', '');
INSERT INTO `fa_config` VALUES (14, 'mail_smtp_user', 'email', 'Mail smtp user', '(填写完整用户名)', 'string', '10000', '', '', '', '');
INSERT INTO `fa_config` VALUES (15, 'mail_smtp_pass', 'email', 'Mail smtp password', '(填写您的密码或授权码)', 'string', 'password', '', '', '', '');
INSERT INTO `fa_config` VALUES (16, 'mail_verify_type', 'email', 'Mail vertify type', 'SMTP验证方式[推荐SSL]', 'select', '2', '[\"无\",\"TLS\",\"SSL\"]', '', '', '');
INSERT INTO `fa_config` VALUES (17, 'mail_from', 'email', 'Mail from', '', 'string', '10000@qq.com', '', '', '', '');
INSERT INTO `fa_config` VALUES (18, 'attachmentcategory', 'dictionary', 'Attachment category', '', 'array', '{\"category1\":\"Category1\",\"category2\":\"Category2\",\"custom\":\"Custom\"}', '', '', '', '');
INSERT INTO `fa_config` VALUES (1, 'name', 'basic', 'Site name', '请填写站点名称', 'string', '', '我的网站', '', 'required', '', '');
INSERT INTO `fa_config` VALUES (2, 'beian', 'basic', 'Beian', '粤ICP备15000000号-1', 'string', '', '', '', '', '', '');
INSERT INTO `fa_config` VALUES (3, 'cdnurl', 'basic', 'Cdn url', '如果全站静态资源使用第三方云储存请配置该值', 'string', '', '', '', '', '', '');
INSERT INTO `fa_config` VALUES (4, 'version', 'basic', 'Version', '如果静态资源有变动请重新配置该值', 'string', '', '1.0.1', '', 'required', '', '');
INSERT INTO `fa_config` VALUES (5, 'timezone', 'basic', 'Timezone', '', 'string', '', 'Asia/Shanghai', '', 'required', '', '');
INSERT INTO `fa_config` VALUES (6, 'forbiddenip', 'basic', 'Forbidden ip', '一行一条记录', 'text', '', '', '', '', '', '');
INSERT INTO `fa_config` VALUES (7, 'languages', 'basic', 'Languages', '', 'array', '', '{\"backend\":\"zh-cn\",\"frontend\":\"zh-cn\"}', '', 'required', '', '');
INSERT INTO `fa_config` VALUES (8, 'fixedpage', 'basic', 'Fixed page', '请尽量输入左侧菜单栏存在的链接', 'string', '', 'dashboard', '', 'required', '', '');
INSERT INTO `fa_config` VALUES (9, 'categorytype', 'dictionary', 'Category type', '', 'array', '', '{\"default\":\"Default\",\"page\":\"Page\",\"article\":\"Article\",\"test\":\"Test\"}', '', '', '', '');
INSERT INTO `fa_config` VALUES (10, 'configgroup', 'dictionary', 'Config group', '', 'array', '', '{\"basic\":\"Basic\",\"email\":\"Email\",\"dictionary\":\"Dictionary\",\"user\":\"User\",\"example\":\"Example\"}', '', '', '', '');
INSERT INTO `fa_config` VALUES (11, 'mail_type', 'email', 'Mail type', '选择邮件发送方式', 'select', '', '1', '[\"请选择\",\"SMTP\"]', '', '', '');
INSERT INTO `fa_config` VALUES (12, 'mail_smtp_host', 'email', 'Mail smtp host', '错误的配置发送邮件会导致服务器超时', 'string', '', 'smtp.qq.com', '', '', '', '');
INSERT INTO `fa_config` VALUES (13, 'mail_smtp_port', 'email', 'Mail smtp port', '(不加密默认25,SSL默认465,TLS默认587)', 'string', '', '465', '', '', '', '');
INSERT INTO `fa_config` VALUES (14, 'mail_smtp_user', 'email', 'Mail smtp user', '(填写完整用户名)', 'string', '', '10000', '', '', '', '');
INSERT INTO `fa_config` VALUES (15, 'mail_smtp_pass', 'email', 'Mail smtp password', '(填写您的密码或授权码)', 'string', '', 'password', '', '', '', '');
INSERT INTO `fa_config` VALUES (16, 'mail_verify_type', 'email', 'Mail vertify type', 'SMTP验证方式[推荐SSL]', 'select', '', '2', '[\"无\",\"TLS\",\"SSL\"]', '', '', '');
INSERT INTO `fa_config` VALUES (17, 'mail_from', 'email', 'Mail from', '', 'string', '', '10000@qq.com', '', '', '', '');
INSERT INTO `fa_config` VALUES (18, 'attachmentcategory', 'dictionary', 'Attachment category', '', 'array', '', '{\"category1\":\"Category1\",\"category2\":\"Category2\",\"custom\":\"Custom\"}', '', '', '', '');
COMMIT;
-- ----------------------------

View File

@ -94,12 +94,16 @@ class Addon extends Backend
$this->error(__('Parameter %s can not be empty', ''));
}
$tips = [];
$groupList = [];
foreach ($config as $index => &$item) {
if ($item['name'] == '__tips__') {
$groupList = $item['content'] ? $item['content'] : [];
$tips = $item;
unset($config[$index]);
}
}
$groupList['other'] = '其它';
$this->view->assign("groupList", $groupList);
$this->view->assign("addon", ['info' => $info, 'config' => $config, 'tips' => $tips]);
$configFile = ADDON_PATH . $name . DS . 'config.html';
$viewFile = is_file($configFile) ? $configFile : '';

View File

@ -48,6 +48,7 @@ return [
'Field value' => '字段值',
'Content' => '数据列表',
'Rule' => '校验规则',
'Visible condition' => '可见条件',
'Site name' => '站点名称',
'Beian' => '备案号',
'Cdn url' => 'CDN地址',

View File

@ -1,118 +1,134 @@
<form id="config-form" class="edit-form form-horizontal" role="form" data-toggle="validator" method="POST" action="">
{if $addon.tips}
{if $addon.tips && $addon.tips.value}
<div class="alert {$addon.tips.extend|default='alert-info-light'}" style="margin-bottom:10px;">
{if $addon.tips.title}
<b>{$addon.tips.title}</b><br>
{/if}
{$addon.tips.value}
</div>
{/if}
<table class="table table-striped">
<thead>
<tr>
<th width="15%">{:__('Title')}</th>
<th width="85%">{:__('Value')}</th>
</tr>
</thead>
<tbody>
{foreach $addon.config as $item}
<tr>
<td>{$item.title}</td>
<td>
<div class="row">
<div class="col-sm-8 col-xs-12">
{switch $item.type}
{case string}
<input {$item.extend} type="text" name="row[{$item.name}]" value="{$item.value|htmlentities}" class="form-control" data-rule="{$item.rule}" data-tip="{$item.tip}"/>
{/case}
{case password}
<input {$item.extend} type="password" name="row[{$item.name}]" value="{$item.value|htmlentities}" class="form-control" data-rule="{$item.rule}" data-tip="{$item.tip}"/>
{/case}
{case text}
<textarea {$item.extend} name="row[{$item.name}]" class="form-control" data-rule="{$item.rule}" rows="5" data-tip="{$item.tip}">{$item.value|htmlentities}</textarea>
{/case}
{case array}
<dl class="fieldlist" data-name="row[{$item.name}]">
<dd>
<ins>{:__('Array key')}</ins>
<ins>{:__('Array value')}</ins>
</dd>
<dd><a href="javascript:;" class="btn btn-sm btn-success btn-append"><i class="fa fa-plus"></i> {:__('Append')}</a></dd>
<textarea name="row[{$item.name}]" cols="30" rows="5" class="hide">{$item.value|json_encode|htmlentities}</textarea>
</dl>
{/case}
{case date}
<input {$item.extend} type="text" name="row[{$item.name}]" value="{$item.value|htmlentities}" class="form-control datetimepicker" data-date-format="YYYY-MM-DD" data-tip="{$item.tip}" data-rule="{$item.rule}"/>
{/case}
{case time}
<input {$item.extend} type="text" name="row[{$item.name}]" value="{$item.value|htmlentities}" class="form-control datetimepicker" data-date-format="HH:mm:ss" data-tip="{$item.tip}" data-rule="{$item.rule}"/>
{/case}
{case datetime}
<input {$item.extend} type="text" name="row[{$item.name}]" value="{$item.value|htmlentities}" class="form-control datetimepicker" data-date-format="YYYY-MM-DD HH:mm:ss" data-tip="{$item.tip}" data-rule="{$item.rule}"/>
{/case}
{case number}
<input {$item.extend} type="number" name="row[{$item.name}]" value="{$item.value|htmlentities}" class="form-control" data-tip="{$item.tip}" data-rule="{$item.rule}"/>
{/case}
{case checkbox}
{foreach name="item.content" item="vo"}
<label for="row[{$item.name}][]-{$key}"><input id="row[{$item.name}][]-{$key}" name="row[{$item.name}][]" type="checkbox" value="{$key}" data-tip="{$item.tip}" {in name="key" value="$item.value" }checked{/in} /> {$vo}</label>
{/foreach}
{/case}
{case radio}
{foreach name="item.content" item="vo"}
<label for="row[{$item.name}]-{$key}"><input id="row[{$item.name}]-{$key}" name="row[{$item.name}]" type="radio" value="{$key}" data-tip="{$item.tip}" {in name="key" value="$item.value" }checked{/in} /> {$vo}</label>
{/foreach}
{/case}
{case value="select" break="0"}{/case}
{case value="selects"}
<select {$item.extend} name="row[{$item.name}]{$item.type=='selects'?'[]':''}" class="form-control selectpicker" data-tip="{$item.tip}" {$item.type=='selects'?'multiple':''}>
{foreach name="item.content" item="vo"}
<option value="{$key}" {in name="key" value="$item.value" }selected{/in}>{$vo}</option>
{/foreach}
</select>
{/case}
{case value="image" break="0"}{/case}
{case value="images"}
<div class="input-group">
<input {$item.extend} id="c-{$item.name}" class="form-control" size="50" name="row[{$item.name}]" type="text" value="{$item.value|htmlentities}" data-tip="{$item.tip}" data-rule="{$item.rule}">
<div class="input-group-addon no-border no-padding">
<span><button type="button" id="faupload-{$item.name}" class="btn btn-danger faupload" data-input-id="c-{$item.name}" data-mimetype="image/*" data-multiple="{$item.type=='image'?'false':'true'}" data-preview-id="p-{$item.name}"><i class="fa fa-upload"></i> {:__('Upload')}</button></span>
<span><button type="button" id="fachoose-{$item.name}" class="btn btn-primary fachoose" data-input-id="c-{$item.name}" data-mimetype="image/*" data-multiple="{$item.type=='image'?'false':'true'}"><i class="fa fa-list"></i> {:__('Choose')}</button></span>
</div>
<span class="msg-box n-right" for="c-{$item.name}"></span>
</div>
<ul class="row list-inline faupload-preview" id="p-{$item.name}"></ul>
{/case}
{case value="file" break="0"}{/case}
{case value="files"}
<div class="input-group">
<input {$item.extend} id="c-{$item.name}" class="form-control" size="50" name="row[{$item.name}]" type="text" value="{$item.value|htmlentities}" data-tip="{$item.tip}" data-rule="{$item.rule}">
<div class="input-group-addon no-border no-padding">
<span><button type="button" id="faupload-{$item.name}" class="btn btn-danger faupload" data-input-id="c-{$item.name}" data-multiple="{$item.type=='file'?'false':'true'}" data-preview-id="p-{$item.name}"><i class="fa fa-upload"></i> {:__('Upload')}</button></span>
<span><button type="button" id="fachoose-{$item.name}" class="btn btn-primary fachoose" data-input-id="c-{$item.name}" data-multiple="{$item.type=='file'?'false':'true'}"><i class="fa fa-list"></i> {:__('Choose')}</button></span>
</div>
<span class="msg-box n-right" for="c-{$item.name}"></span>
</div>
<ul class="row list-inline faupload-preview" id="p-{$item.name}"></ul>
{/case}
{case bool}
<label for="row[{$item.name}]-yes"><input id="row[{$item.name}]-yes" name="row[{$item.name}]" type="radio" value="1" {$item.value?'checked':''} data-tip="{$item.tip}" /> {:__('Yes')}</label>
<label for="row[{$item.name}]-no"><input id="row[{$item.name}]-no" name="row[{$item.name}]" type="radio" value="0" {$item.value?'':'checked'} data-tip="{$item.tip}" /> {:__('No')}</label>
{/case}
{default /}{$item.value}
{/switch}
</div>
<div class="col-sm-4"></div>
</div>
</td>
</tr>
{/foreach}
</tbody>
</table>
<div class="form-group layer-footer">
<label class="control-label col-xs-12 col-sm-2"></label>
<div class="col-xs-12 col-sm-8">
<button type="submit" class="btn btn-primary btn-embossed disabled">{:__('OK')}</button>
<button type="reset" class="btn btn-default btn-embossed">{:__('Reset')}</button>
<div class="panel panel-default panel-intro">
{if $groupList}
<div class="panel-heading">
<ul class="nav nav-tabs nav-group">
<li class="active"><a href="#all" data-toggle="tab">全部</a></li>
{foreach name="groupList" id="tab"}
<li><a href="#tab-{$key}" title="{$tab}" data-toggle="tab">{$tab}</a></li>
{/foreach}
</ul>
</div>
{/if}
<div class="panel-body {if !$groupList}no-padding{/if}">
<div id="myTabContent" class="tab-content">
{foreach name="groupList" id="group" key="groupName"}
<div class="tab-pane fade active in" id="tab-{$groupName}">
<table class="table table-striped table-config">
<tbody>
{foreach name="$addon.config" id="item"}
{if ((!isset($item['group']) || $item['group']=='') && $key=='other') || (isset($item['group']) && $item['group']==$groupName)}
<tr data-favisible="{$item.visible|default=''|htmlentities}" data-name="{$item.name}">
<td width="15%">{$item.title}</td>
<td>
<div class="row">
<div class="col-sm-8 col-xs-12">
{switch $item.type}
{case string}
<input {$item.extend} type="text" name="row[{$item.name}]" value="{$item.value|htmlentities}" class="form-control" data-rule="{$item.rule}" data-tip="{$item.tip}"/>
{/case}
{case password}
<input {$item.extend} type="password" name="row[{$item.name}]" value="{$item.value|htmlentities}" class="form-control" data-rule="{$item.rule}" data-tip="{$item.tip}"/>
{/case}
{case text}
<textarea {$item.extend} name="row[{$item.name}]" class="form-control" data-rule="{$item.rule}" rows="5" data-tip="{$item.tip}">{$item.value|htmlentities}</textarea>
{/case}
{case array}
<dl class="fieldlist" data-name="row[{$item.name}]">
<dd>
<ins>{:__('Array key')}</ins>
<ins>{:__('Array value')}</ins>
</dd>
<dd><a href="javascript:;" class="btn btn-sm btn-success btn-append"><i class="fa fa-plus"></i> {:__('Append')}</a></dd>
<textarea name="row[{$item.name}]" cols="30" rows="5" class="hide">{$item.value|json_encode|htmlentities}</textarea>
</dl>
{/case}
{case date}
<input {$item.extend} type="text" name="row[{$item.name}]" value="{$item.value|htmlentities}" class="form-control datetimepicker" data-date-format="YYYY-MM-DD" data-tip="{$item.tip}" data-rule="{$item.rule}"/>
{/case}
{case time}
<input {$item.extend} type="text" name="row[{$item.name}]" value="{$item.value|htmlentities}" class="form-control datetimepicker" data-date-format="HH:mm:ss" data-tip="{$item.tip}" data-rule="{$item.rule}"/>
{/case}
{case datetime}
<input {$item.extend} type="text" name="row[{$item.name}]" value="{$item.value|htmlentities}" class="form-control datetimepicker" data-date-format="YYYY-MM-DD HH:mm:ss" data-tip="{$item.tip}" data-rule="{$item.rule}"/>
{/case}
{case number}
<input {$item.extend} type="number" name="row[{$item.name}]" value="{$item.value|htmlentities}" class="form-control" data-tip="{$item.tip}" data-rule="{$item.rule}"/>
{/case}
{case checkbox}
{foreach name="item.content" item="vo"}
<label for="row[{$item.name}][]-{$key}"><input id="row[{$item.name}][]-{$key}" name="row[{$item.name}][]" type="checkbox" value="{$key}" data-tip="{$item.tip}" {in name="key" value="$item.value" }checked{/in} /> {$vo}</label>
{/foreach}
<span class="msg-box n-right" for="c-{$item.name}"></span>
{/case}
{case radio}
{foreach name="item.content" item="vo"}
<label for="row[{$item.name}]-{$key}"><input id="row[{$item.name}]-{$key}" name="row[{$item.name}]" type="radio" value="{$key}" data-tip="{$item.tip}" {in name="key" value="$item.value" }checked{/in} /> {$vo}</label>
{/foreach}
<span class="msg-box n-right" for="c-{$item.name}"></span>
{/case}
{case value="select" break="0"}{/case}
{case value="selects"}
<select {$item.extend} name="row[{$item.name}]{$item.type=='selects'?'[]':''}" class="form-control selectpicker" data-tip="{$item.tip}" {$item.type=='selects'?'multiple':''}>
{foreach name="item.content" item="vo"}
<option value="{$key}" {in name="key" value="$item.value" }selected{/in}>{$vo}</option>
{/foreach}
</select>
{/case}
{case value="image" break="0"}{/case}
{case value="images"}
<div class="form-inline">
<input id="c-{$item.name}" class="form-control" size="35" name="row[{$item.name}]" type="text" value="{$item.value|htmlentities}" data-tip="{$item.tip}">
<span><button type="button" id="plupload-{$item.name}" class="btn btn-danger plupload" data-input-id="c-{$item.name}" data-mimetype="image/*" data-multiple="{$item.type=='image'?'false':'true'}" data-preview-id="p-{$item.name}"><i class="fa fa-upload"></i> {:__('Upload')}</button></span>
<span><button type="button" id="fachoose-{$item.name}" class="btn btn-primary fachoose" data-input-id="c-{$item.name}" data-mimetype="image/*" data-multiple="{$item.type=='image'?'false':'true'}"><i class="fa fa-list"></i> {:__('Choose')}</button></span>
<ul class="row list-inline plupload-preview" id="p-{$item.name}"></ul>
</div>
{/case}
{case value="file" break="0"}{/case}
{case value="files"}
<div class="form-inline">
<input id="c-{$item.name}" class="form-control" size="35" name="row[{$item.name}]" type="text" value="{$item.value|htmlentities}" data-tip="{$item.tip}">
<span><button type="button" id="plupload-{$item.name}" class="btn btn-danger plupload" data-input-id="c-{$item.name}" data-multiple="{$item.type=='file'?'false':'true'}"><i class="fa fa-upload"></i> {:__('Upload')}</button></span>
<span><button type="button" id="fachoose-{$item.name}" class="btn btn-primary fachoose" data-input-id="c-{$item.name}" data-multiple="{$item.type=='file'?'false':'true'}"><i class="fa fa-list"></i> {:__('Choose')}</button></span>
</div>
{/case}
{case bool}
<label for="row[{$item.name}]-yes"><input id="row[{$item.name}]-yes" name="row[{$item.name}]" type="radio" value="1" {$item.value?'checked':''} data-tip="{$item.tip}" /> {:__('Yes')}</label>
<label for="row[{$item.name}]-no"><input id="row[{$item.name}]-no" name="row[{$item.name}]" type="radio" value="0" {$item.value?'':'checked'} data-tip="{$item.tip}" /> {:__('No')}</label>
{/case}
{default /}{$item.value}
{/switch}
</div>
<div class="col-sm-4"></div>
</div>
</td>
</tr>
{/if}
{/foreach}
</tbody>
</table>
</div>
{/foreach}
<div class="form-group layer-footer">
<label class="control-label col-xs-12 col-sm-2" style="width:15%;"></label>
<div class="col-xs-12 col-sm-8">
<button type="submit" class="btn btn-primary btn-embossed disabled">{:__('OK')}</button>
<button type="reset" class="btn btn-default btn-embossed">{:__('Reset')}</button>
</div>
</div>
</div>
</div>
</div>
</form>

View File

@ -36,7 +36,7 @@
{:build_heading(null, false)}
<ul class="nav nav-tabs">
{foreach $siteList as $index=>$vo}
<li class="{$vo.active?'active':''}"><a href="#{$vo.name}" data-toggle="tab">{:__($vo.title)}</a></li>
<li class="{$vo.active?'active':''}"><a href="#tab-{$vo.name}" data-toggle="tab">{:__($vo.title)}</a></li>
{/foreach}
{if $Think.config.app_debug}
<li data-toggle="tooltip" title="{:__('Add new config')}">
@ -50,7 +50,7 @@
<div id="myTabContent" class="tab-content">
<!--@formatter:off-->
{foreach $siteList as $index=>$vo}
<div class="tab-pane fade {$vo.active ? 'active in' : ''}" id="{$vo.name}">
<div class="tab-pane fade {$vo.active ? 'active in' : ''}" id="tab-{$vo.name}">
<div class="widget-body no-padding">
<form id="{$vo.name}-form" class="edit-form form-horizontal" role="form" data-toggle="validator" method="POST" action="{:url('general.config/edit')}">
{:token()}
@ -67,7 +67,7 @@
</thead>
<tbody>
{foreach $vo.list as $item}
<tr>
<tr data-favisible="{$item.visible|default=''|htmlentities}" data-name="{$item.name}">
<td>{$item.title}</td>
<td>
<div class="row">
@ -323,6 +323,12 @@ value2|title2</textarea>
<span class="msg-box n-right" for="rule"></span>
</div>
</div>
<div class="form-group">
<label for="visible" class="control-label col-xs-12 col-sm-2">{:__('Visible condition')}:</label>
<div class="col-xs-12 col-sm-4">
<input type="text" class="form-control" id="visible" name="row[visible]" value="" data-rule=""/>
</div>
</div>
<div class="form-group">
<label for="extend" class="control-label col-xs-12 col-sm-2">{:__('Extend')}:</label>
<div class="col-xs-12 col-sm-4">

View File

@ -678,6 +678,20 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function
Controller.api.bindevent();
},
config: function () {
$(document).on("click", ".nav-group li a[data-toggle='tab']", function () {
if ($(this).attr("href") == "#all") {
$(".tab-pane").addClass("active in");
}
return;
var type = $(this).attr("href").substring(1);
if (type == 'all') {
$(".table-config tr").show();
} else {
$(".table-config tr").hide();
$(".table-config tr[data-group='" + type + "']").show();
}
});
Controller.api.bindevent();
},
api: {

View File

@ -484,6 +484,89 @@ define(['jquery', 'bootstrap', 'upload', 'validator', 'validator-lang'], functio
$("[data-role='autocomplete']").autocomplete();
});
}
},
favisible: function (form) {
if ($("[data-favisible]", form).length == 0) {
return;
}
var checkCondition = function (condition) {
var conditionArr = condition.split(/&&/);
var success = 0;
var baseregex = /^([a-z0-9\_]+)([>|<|=|\!]=?)(.*)$/i, strregex = /^('|")(.*)('|")$/, regregex = /^regex:(.*)$/;
<!--@formatter:off-->
var operator_result = {
'>': function(a, b) { return a > b; },
'>=': function(a, b) { return a >= b; },
'<': function(a, b) { return a < b; },
'<=': function(a, b) { return a <= b; },
'==': function(a, b) { return a == b; },
'!=': function(a, b) { return a != b; },
'in': function(a, b) { return b.split(/\,/).indexOf(a) > -1; },
'regex': function(a, b) {
var regParts = b.match(/^\/(.*?)\/([gim]*)$/);
var regexp = regParts ? new RegExp(regParts[1], regParts[2]) : new RegExp(b);
return regexp.test(a);
}
};
<!--@formatter:on-->
var dataArr = form.serializeArray(), dataObj = {};
$(dataArr).each(function (i, field) {
dataObj[field.name] = field.value;
});
$.each(conditionArr, function (i, item) {
var basematches = baseregex.exec(item);
if (basematches) {
var name = basematches[1], operator = basematches[2], value = basematches[3].toString();
if (operator === '=') {
var strmatches = strregex.exec(value);
operator = strmatches ? '==' : 'in';
value = strmatches ? strmatches[2] : value;
}
var regmatches = regregex.exec(value);
if (regmatches) {
operator = 'regex';
value = regmatches[1];
}
var chkname = "row[" + name + "]";
if (typeof dataObj[chkname] === 'undefined') {
return false;
}
var objvalue = dataObj[chkname];
if (['>', '>=', '<', '<='].indexOf(operator) > -1) {
objvalue = parseFloat(objvalue);
value = parseFloat(value);
}
var result = operator_result[operator](objvalue, value);
success += (result ? 1 : 0);
}
});
return success === conditionArr.length;
};
form.on("keyup change click configchange", "input,select", function () {
$("[data-favisible][data-favisible!='']", form).each(function () {
var visible = $(this).data("favisible");
var groupArr = visible.split(/\|\|/);
var success = 0;
$.each(groupArr, function (i, j) {
if (checkCondition(j)) {
success++;
}
});
if (success > 0) {
$(this).removeClass("hidden");
} else {
$(this).addClass("hidden");
}
});
});
//追加上忽略元素
setTimeout(function () {
form.data('validator').options.ignore += ((form.data('validator').options.ignore ? ',' : '') + '[data-favisible] :hidden');
}, 0);
$("input,select", form).trigger("configchange");
}
},
api: {
@ -590,6 +673,8 @@ define(['jquery', 'bootstrap', 'upload', 'validator', 'validator-lang'], functio
events.tagsinput(form);
events.autocomplete(form);
events.favisible(form);
},
custom: {}
},