open beetl <#form:xxx 控件

This commit is contained in:
thinkgem
2024-07-22 15:42:51 +08:00
parent 7ce1f84866
commit 7e3a55a578
15 changed files with 1795 additions and 0 deletions

View File

@@ -0,0 +1,95 @@
<%/* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
* No deletion without permission, or be held responsible to law. */
/**
* 表单控件:单选按钮
* @author ThinkGem
* @version 2017-3-5
*/
var p = {
// 标签参数
id: id!, // 元素ID如果不填写则与name相同
path: path!, // 绑定form上model中属性的值
name: name!, // 元素名称,不填写
value: value!, // 元素值
defaultValue: defaultValue!,// 默认值 v4.1.5
dictType: dictType!'', // 字典类型从字典里获取自动设置items、itemLabel、itemValue
items: items!([]), // 列表数据可接受对象集合List<DictData>
itemLabel: itemLabel!'', // 指定列表数据中的什么属性名作为option的标签名
itemValue: itemValue!'', // 指定列表数据中的什么属性名作为option的value值
label: label!, // 只有一个复选按钮的情况下设置(开关)
readonly: toBoolean(readonly!false), // 是否只读模式 v4.2.0
// 内置参数
thisTag: thisTag,
exclAttrs: ['id', 'path', 'name', 'value', 'defaultValue', 'dictType',
'items', 'itemLabel', 'itemValue', 'label']
};
// 编译绑定参数
form.path(p);
// 编译属性参数
form.attrs(p);
// 编译集合参数
form.items(p);
// 只有一个复选按钮的情况下
if (isNotBlank(p.label)){
p.items = [{label:p.label,value:'1'}];
p.itemLabel = 'label';
p.itemValue = 'value';
}
// 如果不是字符串,则转换为字符串
if (type.name(p.value) != 'String'){
p.value = @ObjectUtils.toString(p.value);
}
// 转换为字符串数组
if (type.name(p.value) == 'String'){
p.value = @StringUtils.split(p.value, ',');
}
// 如果只读模式则禁用并加默认值为value
if (p.readonly){
p.attrs = p.attrs + ' disabled="true"';
}
// 输出选项
var body = {
var checked,title;
for (var item in p.items){
checked = (@StringUtils.inString(item[p.itemValue], p.value) ? ' checked' : '');
if (type.name(item) == 'DictData' && isNotBlank(item['description'])){
title = ' title="' + item['description'] + '"';
}
%><label${title}><input type="checkbox" id="${p.id}${itemLP.index}" name="${p.name}"
value="${item[p.itemValue]}"${p.attrs}${checked}> ${item[p.itemLabel]}</label><%
}
/**
* 1.若复选框不被选中时,服务端将不能接受这个参数,也就得不到选择的状态。
* 2.如果有一个复选框参数前加“_”时这个不被选中的参数将被设置为null。
* 3.如果有一个复选框参数前加“!”时,这个不被选中的参数,将被设置为该值,作为默认值。
* 4.详见org.springframework.web.bind.WebDataBinder类的Prefix注释。
*/
if (isNotBlank(p.name)){
if (p.readonly){
for(var val in p.value){
%><input type="hidden" name="!${p.name}" value="${val}"/><%
}
}else{
%><input type="hidden" name="!${p.name}" value="${isNotBlank(p.label)?'0':''}"/><%
}
}
};
%>
<span id="${p.id}" class="icheck"${p.attrs}>
${body}</span>

View File

@@ -0,0 +1,254 @@
<%/* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
* No deletion without permission, or be held responsible to law. */
/**
* 表单控件:扩展控件组
* @author ThinkGem
* @version 2017-3-5
*/
var p = {
// 标签参数
collapsed: toBoolean(collapsed!true), // 初始状态是否折叠
title: text('扩展字段'), // 显示标题、折叠标题v4.2.3 版本以后版本生效
extendS1: extendS1!text('String 1'), // extendS1 及以下属性的标签名 v4.2.3 版本以后版本生效
extendS2: extendS2!text('String 2'),
extendS3: extendS3!text('String 3'),
extendS4: extendS4!text('String 4'),
extendS5: extendS5!text('String 5'),
extendS6: extendS6!text('String 6'),
extendS7: extendS7!text('String 7'),
extendS8: extendS8!text('String 8'),
extendI1: extendI1!text('Integer 1'),
extendI2: extendI2!text('Integer 2'),
extendI3: extendI3!text('Integer 3'),
extendI4: extendI4!text('Integer 4'),
extendF1: extendF1!text('Float 1'),
extendF2: extendF2!text('Float 2'),
extendF3: extendF3!text('Float 3'),
extendF4: extendF4!text('Float 4'),
extendD1: extendD1!text('Date 1'),
extendD2: extendD2!text('Date 2'),
extendD3: extendD3!text('Date 3'),
extendD4: extendD4!text('Date 4'),
pathPrefix: (isBlank(pathPrefix!) ? '' : pathPrefix + '.') + 'extend',
// 内置参数
thisTag: thisTag
};
%>
<div class="box-child ${p.collapsed ? 'collapsed-box' : ''}">
<div class="form-unit" data-widget="collapse-child">${p.title}
<span class="box-tools btn-box-tool"><i class="fa fa-plus"></i></span>
</div>
<div class="box-body">
<div class="row">
<div class="col-xs-6">
<div class="form-group">
<label class="control-label col-sm-4" title="">
<span class="required hide">*</span> ${p.extendS1}<i class="fa icon-question hide"></i></label>
<div class="col-sm-8">
<#form:input path="${p.pathPrefix}.extendS1" maxlength="500" class="form-control "/>
</div>
</div>
</div>
<div class="col-xs-6">
<div class="form-group">
<label class="control-label col-sm-4" title="">
<span class="required hide">*</span> ${p.extendS2}<i class="fa icon-question hide"></i></label>
<div class="col-sm-8">
<#form:input path="${p.pathPrefix}.extendS2" maxlength="500" class="form-control "/>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-6">
<div class="form-group">
<label class="control-label col-sm-4" title="">
<span class="required hide">*</span> ${p.extendS3}<i class="fa icon-question hide"></i></label>
<div class="col-sm-8">
<#form:input path="${p.pathPrefix}.extendS3" maxlength="500" class="form-control "/>
</div>
</div>
</div>
<div class="col-xs-6">
<div class="form-group">
<label class="control-label col-sm-4" title="">
<span class="required hide">*</span> ${p.extendS4}<i class="fa icon-question hide"></i></label>
<div class="col-sm-8">
<#form:input path="${p.pathPrefix}.extendS4" maxlength="500" class="form-control "/>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-6">
<div class="form-group">
<label class="control-label col-sm-4" title="">
<span class="required hide">*</span> ${p.extendS5}<i class="fa icon-question hide"></i></label>
<div class="col-sm-8">
<#form:input path="${p.pathPrefix}.extendS5" maxlength="500" class="form-control "/>
</div>
</div>
</div>
<div class="col-xs-6">
<div class="form-group">
<label class="control-label col-sm-4" title="">
<span class="required hide">*</span> ${p.extendS6}<i class="fa icon-question hide"></i></label>
<div class="col-sm-8">
<#form:input path="${p.pathPrefix}.extendS6" maxlength="500" class="form-control "/>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-6">
<div class="form-group">
<label class="control-label col-sm-4" title="">
<span class="required hide">*</span> ${p.extendS7}<i class="fa icon-question hide"></i></label>
<div class="col-sm-8">
<#form:input path="${p.pathPrefix}.extendS7" maxlength="500" class="form-control "/>
</div>
</div>
</div>
<div class="col-xs-6">
<div class="form-group">
<label class="control-label col-sm-4" title="">
<span class="required hide">*</span> ${p.extendS8}<i class="fa icon-question hide"></i></label>
<div class="col-sm-8">
<#form:input path="${p.pathPrefix}.extendS8" maxlength="500" class="form-control "/>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-6">
<div class="form-group">
<label class="control-label col-sm-4" title="">
<span class="required hide">*</span> ${p.extendI1}<i class="fa icon-question hide"></i></label>
<div class="col-sm-8">
<#form:input path="${p.pathPrefix}.extendI1" maxlength="19" class="form-control digits"/>
</div>
</div>
</div>
<div class="col-xs-6">
<div class="form-group">
<label class="control-label col-sm-4" title="">
<span class="required hide">*</span> ${p.extendI2}<i class="fa icon-question hide"></i></label>
<div class="col-sm-8">
<#form:input path="${p.pathPrefix}.extendI2" maxlength="19" class="form-control digits"/>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-6">
<div class="form-group">
<label class="control-label col-sm-4" title="">
<span class="required hide">*</span> ${p.extendI3}<i class="fa icon-question hide"></i></label>
<div class="col-sm-8">
<#form:input path="${p.pathPrefix}.extendI3" maxlength="19" class="form-control digits"/>
</div>
</div>
</div>
<div class="col-xs-6">
<div class="form-group">
<label class="control-label col-sm-4" title="">
<span class="required hide">*</span> ${p.extendI4}<i class="fa icon-question hide"></i></label>
<div class="col-sm-8">
<#form:input path="${p.pathPrefix}.extendI4" maxlength="19" class="form-control digits"/>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-6">
<div class="form-group">
<label class="control-label col-sm-4" title="">
<span class="required hide">*</span> ${p.extendF1}<i class="fa icon-question hide"></i></label>
<div class="col-sm-8">
<#form:input path="${p.pathPrefix}.extendF1" class="form-control number"/>
</div>
</div>
</div>
<div class="col-xs-6">
<div class="form-group">
<label class="control-label col-sm-4" title="">
<span class="required hide">*</span> ${p.extendF2}<i class="fa icon-question hide"></i></label>
<div class="col-sm-8">
<#form:input path="${p.pathPrefix}.extendF2" class="form-control number"/>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-6">
<div class="form-group">
<label class="control-label col-sm-4" title="">
<span class="required hide">*</span> ${p.extendF3}<i class="fa icon-question hide"></i></label>
<div class="col-sm-8">
<#form:input path="${p.pathPrefix}.extendF3" class="form-control number"/>
</div>
</div>
</div>
<div class="col-xs-6">
<div class="form-group">
<label class="control-label col-sm-4" title="">
<span class="required hide">*</span> ${p.extendF4}<i class="fa icon-question hide"></i></label>
<div class="col-sm-8">
<#form:input path="${p.pathPrefix}.extendF4" class="form-control number"/>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-6">
<div class="form-group">
<label class="control-label col-sm-4" title="">
<span class="required hide">*</span> ${p.extendD1}<i class="fa icon-question hide"></i></label>
<div class="col-sm-8">
<#form:input path="${p.pathPrefix}.extendD1" readonly="readonly" maxlength="20" class="form-control laydate "
dataFormat="date" data-type="date" data-format="yyyy-MM-dd"/>
</div>
</div>
</div>
<div class="col-xs-6">
<div class="form-group">
<label class="control-label col-sm-4" title="">
<span class="required hide">*</span> ${p.extendD2}<i class="fa icon-question hide"></i></label>
<div class="col-sm-8">
<#form:input path="${p.pathPrefix}.extendD2" readonly="readonly" maxlength="20" class="form-control laydate "
dataFormat="date" data-type="date" data-format="yyyy-MM-dd"/>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-6">
<div class="form-group">
<label class="control-label col-sm-4" title="">
<span class="required hide">*</span> ${p.extendD3}<i class="fa icon-question hide"></i></label>
<div class="col-sm-8">
<#form:input path="${p.pathPrefix}.extendD3" readonly="readonly" maxlength="20" class="form-control laydate "
dataFormat="datetime" data-type="datetime" data-format="yyyy-MM-dd HH:mm:ss"/>
</div>
</div>
</div>
<div class="col-xs-6">
<div class="form-group">
<label class="control-label col-sm-4" title="">
<span class="required hide">*</span> ${p.extendD4}<i class="fa icon-question hide"></i></label>
<div class="col-sm-8">
<#form:input path="${p.pathPrefix}.extendD4" readonly="readonly" maxlength="20" class="form-control laydate "
dataFormat="datetime" data-type="datetime" data-format="yyyy-MM-dd HH:mm:ss"/>
</div>
</div>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,205 @@
<%/* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
* No deletion without permission, or be held responsible to law. */
/**
* 表单控件:文件上传
* @author ThinkGem
* @version 2017-3-5
*/
var p = {
// 标签参数
id: id!, // 元素ID
bizKey: bizKey!, // 业务表的主键值(与附件关联的业务数据)
bizType: bizType!, // 业务表的上传类型全网唯一推荐格式实体名_上传类型例如文章图片article_photo
dataMap: toBoolean(dataMap!false), // 后台接受的 fileUploadIds 是否从 dataMap 中获取Cloud环境下使用
returnPath: toBoolean(returnPath!false), // 是否是返回文件路径到输入框默认false可将路径直接保存到某个字段里
filePathInputId: filePathInputId!, // 设置文件URL存放的输入框的ID当returnPath为true的时候返回文件URL到这个输入框
fileNameInputId: fileNameInputId!, // 设置文件名称存放的输入框的ID当returnPath为true的时候返回文件名称到这个输入框
uploadType: uploadType!'', // 上传文件类型all、file、image、media若不设置则自动根据上传文件后缀获取
class: class!'', // 标签框的CSS类名设置 required 加入必填验证
readonly: readonly!'false', // 是否只读模式,只读模式下为查看模式,只允许下载
dataMsgRequired: thisTag.attrs['data-msg-required'], // 必填错误提示信息 v4.2.1
allowSuffixes: allowSuffixes!'', // 允许上传的后缀前台的限制不能超越file.*AllowSuffixes的设置例如.jpg,.png,
maxFileSize: maxFileSize!'', // 当前控件的文件上传大小设置500*1024*1024单位字节不可超过配置文件设置的文件大小
maxUploadNum: @ObjectUtils.toInteger(maxUploadNum!300), // 多文件下允许最多上传几个默认300个设置-1代表不限制
cueWords: cueWords!'', // 提示语,默认:或将照片(文件)拖到这里,最多可选 maxUploadNum 张(个) v4.1.5
imageMaxWidth: imageMaxWidth!'', // 图片压缩最大宽度uploadType为image生效设置-1代表不做任何处理
imageMaxHeight: imageMaxHeight!'', // 图片压缩最大宽度uploadType为image生效设置-1代表不做任何处理
imageThumbName: imageThumbName!'', // 如果开启了图片缩略图这里可以指定缩略图名称例如150x150.jpg v5.4.2
serviceUpload: serviceUpload!(ctxAdmin+'/file/upload'), // 上传文件后台服务 v4.1.5
serviceDownload: serviceDownload!(ctxAdmin+'/file/download'), // 下载文件后台服务 v4.1.5
serviceFileList: serviceFileList!(ctxAdmin+'/file/fileList'), // 查询文件后台服务 v4.1.5
extendParams: extendParams!'', // 提交的上传扩展参数例如n1:'v1',n2:'v2'后台接受fileEntity.getFileUploadParams().getExtend() v4.1.3
isLazy: toBoolean(isLazy!false), // 设置为ture需要点击上传按钮才上传文件否则选择后就直接上传
isMini: toBoolean(isMini!false), // 是否是精简上传窗口,无边距,无边框
preview: preview!'', // 是否显示预览按钮接受参数v4.2.0 之前版本为 weboffice之后版本为 true可根据需要扩展预览引擎
callbackFuncName: callbackFuncName!'fileuploadCallback', // 可自定义回调方法的函数名 v4.2.0
// 内置参数
thisTag: thisTag
};
// 编译绑定参数
form.path(p);
// 标题自动生成
if (isBlank(p.dataMsgRequired)){
var title = text('文件');
if(p.uploadType=='file'){
title = text('文档');
}else if(p.uploadType=='image'){
title = text('图片');
}else if(p.uploadType=='media'){
title = text('音频或视频');
}
p.dataMsgRequired = text('请上传') + title;
}
// 生成参数名
p.name = p.bizType;
p.nameDel = p.bizType + '__del';
if (p.dataMap){
p.name = 'dataMap['+p.name+']';
p.nameDel = 'dataMap['+p.nameDel+']';
}
%>
<div id="${p.id}_wup" class="wup_container ${p.isMini?'mini':''}">
<% if(isNotBlank(p.bizType)){ %>
<input id="${p.id}" name="${p.name}" value="" class="wup_input ${p.uploadType} ${p.class}" data-msg-required="${p.dataMsgRequired}"/>
<input id="${p.id}__del" name="${p.nameDel}" value="" type="hidden"/>
<% } %>
<div class="area">
<% if(p.uploadType == 'image'){ %>
<div id="${p.id}Uploader" class="wup_img">
<div class="statusBar" style="display:none;">
<% if(!p.isMini){ %>
<div class="progress">
<span class="text">0%</span>
<span class="percentage"></span>
</div>
<div class="info"></div>
<% }
// 如果是mini界面并上传个数大于1则显示出来上传信息和继续上传按钮
else if(p.maxUploadNum > 1){ %>
<div class="info"></div>
<% } %>
<div class="btns">
<div id="${p.id}filePicker2" class="webuploader-container"></div>
<div class="uploadBtn state-pedding">${text('开始上传')}</div>
</div>
</div>
<div class="queueList">
<ul id="${p.id}fileLists" class="filelist"></ul>
<div id="${p.id}dndArea" class="placeholder">
<div id="${p.id}filePicker" class="webuploader-container"></div>
<% if(isNotBlank(p.cueWords)){ %>
<p>${p.cueWords}</p>
<% }else if(!p.isMini){ %>
<p>${text('或将照片拖到这里,最多可选 {0\} 张', p.maxUploadNum)}</p>
<% } %>
</div>
</div>
</div>
<% }else{ %>
<div id="${p.id}Uploader" class="wup_file">
<div class="statusBar" style="display:none;">
<div class="progress">
<span class="text">0%</span>
<span class="percentage"></span>
</div>
<div class="info"></div>
<div class="btns">
<div id="${p.id}filePicker2" class="webuploader-container"></div>
<div class="uploadBtn">${text('开始上传')}</div>
</div>
</div>
<div class="queueList">
<div class="table-responsive">
<table class="table table-striped filetable table-hover">
<tbody id="${p.id}fileLists"></tbody>
</table>
</div>
<div id="${p.id}dndArea" class="placeholder">
<div id="${p.id}filePicker" class="webuploader-container"></div>
<% if(isNotBlank(p.cueWords)){ %>
<p>${p.cueWords}</p>
<% }else{ %>
<p>${text('或将文件拖到这里,最多可选 {0\} 个', p.maxUploadNum)}</p>
<% } %>
</div>
</div>
</div>
<% } %>
</div>
</div>
<script type="text/javascript">
$(function() {
if ('${p.readonly}' == 'true'){
$("#${p.id}").addClass("disabled");
}
$('#${p.id}Uploader').webuploader({
id: '${p.id}',
bizKey: '${p.bizKey}',
bizType: '${p.bizType}',
readonly: $("#${p.id}").hasClass("disabled"),
returnPath: "#{p.returnPath}",
filePathInputId: '${p.filePathInputId}',
fileNameInputId: '${p.fileNameInputId}',
uploadType: '${p.uploadType}',
maxFileSize: "#{isNotBlank(p.maxFileSize)?p.maxFileSize:@Global.getConfig('file.maxFileSize', '500*1024*1024')}",
imageAllowSuffixes: '${isNotBlank(p.allowSuffixes)?p.allowSuffixes:@Global.getConfig("file.imageAllowSuffixes", ".gif,.bmp,.jpeg,.jpg,.ico,.png,.tif,.tiff,")}',
mediaAllowSuffixes: '${isNotBlank(p.allowSuffixes)?p.allowSuffixes:@Global.getConfig("file.mediaAllowSuffixes", ".flv,.swf,.mkv,webm,.mid,.mov,.mp3,.mp4,.m4v,.mpc,.mpeg,.mpg,.swf,.wav,.wma,.wmv,.avi,.rm,.rmi,.rmvb,.aiff,.asf,.ogg,.ogv,")}',
fileAllowSuffixes: '${isNotBlank(p.allowSuffixes)?p.allowSuffixes:@Global.getConfig("file.fileAllowSuffixes", ".doc,.docx,.rtf,.xls,.xlsx,.csv,.ppt,.pptx,.pdf,.vsd,.txt,.md,.xml,.rar,.zip,.7z,.tar,.tgz,.jar,.gz,.gzip,.bz2,.cab,.iso,")}',
chunked: "#{__info_type=='0'?false:@Global.getConfig('file.chunked', 'true')}",
chunkSize: "#{@Global.getConfigToInteger('file.chunkSize', '10*1024*1024')}",
threads: "#{@Global.getConfigToInteger('file.threads', '3')}",
maxUploadNum: "#{p.maxUploadNum}",
imageMaxWidth: '${p.imageMaxWidth}',
imageMaxHeight: '${p.imageMaxHeight}',
imageThumbName: '${p.imageThumbName}',
service: {
upload: '${p.serviceUpload}',
download: '${p.serviceDownload}',
fileList: '${p.serviceFileList}'
},
extendParams: {"#{p.extendParams}"},
isLazy: "#{p.isLazy}",
preview: "${__info_type=='0'?'':p.preview!=''?p.preview:@Global.getConfig('file.preview','true')}",
callback: function(id, act, $this, fileUploadId, fileUrl, fileName, fileUpload){
if(typeof "#{p.callbackFuncName}" == 'function'){
"#{p.callbackFuncName}"(id, act, $this, fileUploadId, fileUrl, fileName, fileUpload);
}
}
});
});
//# /*
/**
* 上传组件回调 v4.2.0
* @param id 标签的id
* @param act 动作事件create、ready、addFile、delFile
* @param $this webuploader 组件对象
* @param fileUpload 添加文件时的数据 v4.2.2
*/
function fileuploadCallback(id, act, $this, fileUploadId, fileUrl, fileName, fileUpload){
log(id + ' ' + act + ' ' + fileUploadId + ' ' + fileUrl + ' ' + fileName)
if (act == 'addFile') { log(fileUpload); }
log($this)
}
//# */
</script>

View File

@@ -0,0 +1,27 @@
<%/* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
* No deletion without permission, or be held responsible to law. */
/**
* 表单控件:表单标签
* @author ThinkGem
* @version 2017-3-5
*/
var p = {
// 标签参数
id: id!, // 表单ID
model: model!, // 绑定Model对象例如${user!}
action: action!, // 表单请求地址
method: method!, // 请求方法,默认 post
enctype: enctype!, // 发送之前进行数据编码上传文件时指定multipart/form-data
// 内置参数
thisTag: thisTag,
exclAttrs: ['id', 'model', 'action', 'method']
};
// 编译属性参数
form.attrs(p);
%><form id="${p.id}" action="${p.action}" method="${p.method}"${p.attrs}>
${tagBody}</form>

View File

@@ -0,0 +1,29 @@
<%/* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
* No deletion without permission, or be held responsible to law. */
/**
* 表单控件:隐藏域
* @author ThinkGem
* @version 2017-3-5
*/
var p = {
// 标签参数
id: id!, // 元素ID如果不填写则与name相同
path: path!, // 绑定form上model中属性的值
name: name!, // 元素名称,不填写
value: value!, // 元素值
defaultValue: defaultValue!,// 默认值 v4.1.5
// 内置参数
thisTag: thisTag,
exclAttrs: ['id', 'path', 'name', 'value', 'defaultValue', 'type']
};
// 编译绑定参数
form.path(p);
// 编译属性参数
form.attrs(p);
%><input type="hidden" id="${p.id}" name="${p.name}" value="${p.value}"${p.attrs}/>

View File

@@ -0,0 +1,63 @@
<%/* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
* No deletion without permission, or be held responsible to law. */
/**
* 表单控件:图标选择控件
* @author ThinkGem
* @version 2017-3-5
*/
var p = {
// 标签参数
id: id!, // 元素ID如果不填写则与name相同
path: path!, // 绑定form上model中属性的值
name: name!, // 元素名称,不填写
value: value!, // 元素值
defaultValue: defaultValue!,// 默认值 v4.1.5
class: class!'', // 隐藏域和标签框的CSS类名
// 内置参数
thisTag: thisTag
};
// 编译绑定参数
form.path(p);
%>
<div class="input-group">
<span class="input-group-addon"><i id="${p.id}Icon" class="${isNotBlank(p.value)?p.value:'fa fa-fw'}"></i></span>
<input id="${p.id}" name="${p.name}" type="text" value="${p.value}" class="form-control ${p.class}">
<span class="input-group-btn"><a id="${p.id}Button" href="javascript:" class="btn btn-default"
><i class="fa fa-search"></i></a></span>
</div>
<script>
$("#${p.id}Button").click(function(){
js.layer.open({
type: 2,
maxmin: true,
shadeClose: true,
title: '${text("图标选择")}',
area: [(js.layer.$(js.layer.window).width() - 100) + 'px',
(js.layer.$(js.layer.window).height() - 100) + 'px'],
content: '${ctxPath}/tags/iconselect?value='+$("#${p.id}").val(),
success: function(layero, index){
var info = '<font color="red" class="pull-left mt10">${text("提示:双击选择图标。")}</font>';
layero.find('.layui-layer-btn').append(info);
},
btn: ['<i class="fa fa-close"></i> ${text("关闭")}',
'<i class="fa fa-eraser"></i> ${text("清除")}'],
btn1: function(index, layero){
var win = layero.iframeWindow();
var icon = win.$("#icon").val();
$("#${p.id}Icon").attr("class", 'fa fa-fw ' + icon);
$("#${p.id}").val(icon).change();
try { $('#${p.id}').resetValid(); }catch(e){}
},
btn2: function(index, layero){
$("#${p.id}Icon").attr("class", "fa fa-fw");
$("#${p.id}").val("").change();
}
});
});
</script>

View File

@@ -0,0 +1,77 @@
<%/* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
* No deletion without permission, or be held responsible to law. */
/**
* 表单控件图片裁剪返回image/base64
* @author ThinkGem
* @version 2017-12-16
*/
var p = {
// 标签参数
id: id!, // 元素ID如果不填写则与name相同
path: path!, // 绑定form上model中属性的值
name: name!, // 元素名称,不填写
value: value!, // 元素值
defaultValue: defaultValue!,// 默认值 v4.1.5
class: class!'', // 隐藏域的CSS类名
btnText: btnText!text('选择图片'), // 按钮的名字
btnClass: btnClass!'', // 按钮的CSS类名
imageId: imageId!'', // 裁剪后base64返回到img的id
imageDefaultSrc: imageDefaultSrc!'', // 图片默认地址,清除后使用地址
ratio: ratio!'1/1', // 图片裁剪比例 v4.1.7
circle: circle!'false', // 是否圆形图片
maxWidth: maxWidth!'', // 裁剪图片后返回的最大宽度 v4.2.1
maxHeight: maxHeight!'', // 裁剪图片后返回的最大高度 v4.2.1
// 内置参数
thisTag: thisTag
};
// 编译绑定参数
form.path(p);
%>
<input id="${p.id}" name="${p.name}" type="hidden" value="${p.value}" class="${p.class}">
<a id="${p.id}Button" href="javascript:" class="btn btn-default ${p.btnClass}">${p.btnText}</a>
<script>
$("#${p.id}Button,#${p.imageId}").click(function(){
js.layer.open({
type: 2,
maxmin: true,
shadeClose: true,
title: '${text("图片裁剪")}',
area: [(js.layer.$(js.layer.window).width() - 150) + 'px',
(js.layer.$(js.layer.window).height() - 100) + 'px'],
content: '${ctxPath}/tags/imageclip',
contentFormData: {
ratio: '${p.ratio}',
circle: '${p.circle}',
maxWidth: '${p.maxWidth}',
maxHeight: '${p.maxHeight}',
imageSrc: $("#${p.imageId}").attr('src'),
imageDefaultSrc: '${p.imageDefaultSrc}'
},
btn: ['<i class="fa fa-check"></i> ${text("确定")}',
'<i class="fa fa-eraser"></i> ${text("清除")}',
'<i class="fa fa-close"></i> ${text("关闭")}'],
btn1: function(index, layero){
var win = layero.iframeWindow();
win.getImageBase64(win.$image, function(imageBase64){
$("#${p.imageId}").attr("src", imageBase64);
$("#${p.id}").val(imageBase64).change();
try { $('#${p.id}').resetValid(); }catch(e){}
});
},
btn2: function(index, layero){
$("#${p.imageId}").attr("src","${p.imageDefaultSrc}");
$("#${p.id}").val("EMPTY").change();
}
});
});
</script>

View File

@@ -0,0 +1,67 @@
<%/* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
* No deletion without permission, or be held responsible to law. */
/**
* 表单控件:输入框
* @author ThinkGem
* @version 2017-3-5
*/
var p = {
// 标签参数
id: id!, // 元素ID如果不填写则与name相同
path: path!, // 绑定form上model中属性的值
name: name!, // 元素名称,不填写
value: value!, // 元素值
defaultValue: defaultValue!,// 默认值 v4.1.5
type: type!'text', // 元素的类型默认text
dataFormat: dataFormat!'', // 数据格式化,支持如下值:
// date: 日期默认值设置defaultValue="${date()}"
// yyyy: 年默认值设置defaultValue="${date('2019','yyyy')}"
// yyyy-MM: 年月默认值设置defaultValue="${date('2019-11','yyyy-MM')}"
// datetime: 日期时间 yyyy-MM-dd HH:mm 格式化
// datetime2: 日期时间,带秒 yyyy-MM-dd HH:mm:ss 格式化
// 自定义日期 path 改为 name 加 value="${@DateUtils.formatDate(model.field,'yyyyMMdd')}}"
// number: 数值类型 #.## 格式化默认值设置defaultValue="${0}"
// number2: 数值类型 0.00 格式化默认值设置defaultValue="${0}" v4.1.8
// 自定义数值 path 改为 name 加 value="${@NumberUtils.formatNumber(model.field,'0.0')}}"
// 内置参数
thisTag: thisTag,
exclAttrs: ['id', 'path', 'name', 'value', 'defaultValue', 'type', 'dataFormat']
};
// 编译绑定参数
form.path(p);
var df = '';
// 日期类型格式化(后台实体属性必须是 Date 类型的属性)
if (p.dataFormat == 'date'){
df = {%> value="${p.value,dateFormat='yyyy-MM-dd'}"<%};
}else if (p.dataFormat == 'yyyy'){
df = {%> value="${p.value,dateFormat='yyyy'}"<%};
}else if (p.dataFormat == 'yyyy-MM'){
df = {%> value="${p.value,dateFormat='yyyy-MM'}"<%};
}else if (p.dataFormat == 'MM-dd'){
df = {%> value="${p.value,dateFormat='MM-dd'}"<%};
}else if (p.dataFormat == 'datetime'){
df = {%> value="${p.value,dateFormat='yyyy-MM-dd HH:mm'}"<%};
}else if (p.dataFormat == 'datetime2'){
df = {%> value="${p.value,dateFormat='yyyy-MM-dd HH:mm:ss'}"<%};
}
// 数值类型格式化(后台实体属性必须是 数值 类型的属性)
else if (p.dataFormat == 'number'){
df = {%> value="${p.value,numberFormat='#.##'}"<%};
}else if (p.dataFormat == 'number2'){
df = {%> value="${p.value,numberFormat='0.00'}"<%};
}else{
df = {%> value="${p.value}"<%};
}
p.attrs = p.attrs!'' + df;
// 编译属性参数
form.attrs(p);
%><input type="${p.type}" id="${p.id}" name="${p.name}"${p.attrs}/>

View File

@@ -0,0 +1,258 @@
<%/* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
* No deletion without permission, or be held responsible to law. */
/**
* 表单控件:列表选择组件
* @author ThinkGem
* @version 2017-3-5
*/
var p = {
// 标签参数
id: id!, // 元素ID
path: path!, // 绑定form上model中属性的值
name: name!, // 隐藏域名称
value: value!, // 隐藏域值
defaultValue: defaultValue!,// 隐藏域默认值 v4.1.5
labelPath: labelPath!, // 绑定form上model中属性的值
labelName: labelName!, // 标签框名称
labelValue: labelValue!, // 标签框值
defaultLabel: defaultLabel!,// 标签框默认值 v4.1.5
class: class!'', // 标签框的CSS类名
placeholder: placeholder!, // 标签框的预期值的提示信息
dataMsgRequired: thisTag.attrs['data-msg-required'], // 必填错误提示信息
btnClass: btnClass!, // 标签框后面的按钮CSS类名
title: title!text('选项选择'), // 对话框标题
boxWidth: boxWidth!'$(js.window).width() - 100', // 对话框宽度
boxHeight: boxHeight!'$(js.window).height() - 100', // 对话框高度
url: url!, // 列表地址参考EmpUserController的empUserSelect方法
readonly: readonly!'false', // 是否只读模式
allowInput: toBoolean(allowInput!false), // 是否允许label框输入
allowClear: toBoolean(allowClear!true), // 是否允许清空选择内容
checkbox: toBoolean(checkbox!false), // 是否显示复选框是否支持多选如果设置canSelectParent=true则返回父节点数据
itemCode: itemCode!, // 选择后结果集中的Code属性名返回到隐藏域的值
itemName: itemName!, // 选择后结果集中的Name属性名返回到输入框的值
getSelectDataFuncName: getSelectDataFuncName!'listselectGetSelectData', // 选择页面,获取已经选择的数据,回显到选择页面 v4.1.5
setSelectDataFuncName: setSelectDataFuncName!'listselectSetSelectData', // 选择之后,点击确定,将选择数据设置到业务表单 v4.2.0
openFuncName: openFuncName!'listselectOpen', // 可自定义弹窗前调用的函数名 v4.2.0
checkFuncName: checkFuncName!'listselectCheck', // 可自定义验证方法的函数名 v4.2.0
callbackFuncName: callbackFuncName!'listselectCallback', // 可自定义回调方法的函数名 v4.1.5
// 内置参数
thisTag: thisTag
};
// 编译绑定参数
form.path(p);
// 标签属性编译
p.labelAttrs = '';
if (!p.allowInput){
p.labelAttrs = p.labelAttrs + ' readonly="readonly"';
}
if (isNotBlank(p.dataMsgRequired)){
p.labelAttrs = p.labelAttrs + ' data-msg-required="' + p.dataMsgRequired + '"';
}
if (isNotBlank(p.placeholder)){
p.labelAttrs = p.labelAttrs + ' placeholder="' + p.placeholder + '"';
}
// 如果没有设置是否显示“清除”按钮开关则根据class判断是否为必须字段。
if (allowClear == null && @StringUtils.contains(p.class, 'required')){
allowClear = false;
}
%><div class="input-group treeselect" id="${p.id}Div" data-url="${p.url}">
<input id="${p.id}Name" type="text" name="${p.labelName}" value="${p.labelValue}"
class="form-control ${p.class} ${p.labelClass} isReset"${p.labelAttrs}
/><input id="${p.id}Code" type="hidden" name="${p.name}" value="${p.value}" class="isReset"
/><span class="input-group-btn"><a id="${p.id}Button" href="javascript:"
class="btn btn-default ${p.btnClass}"><i class="fa fa-search"></i></a>
</span>
</div>
<script>
if ('${p.readonly}' == 'true' || $("#${p.id}Name").hasClass("disabled")){
$("#${p.id}Button,#${p.id}Name").addClass("disabled");
}
$("#${p.id}Button${p.allowInput?'':',#'+p.id+'Name'}").click(function(){
if ($("#${p.id}Button").hasClass("disabled") || $("#${p.id}Name").hasClass("disabled")){
return true;
}
var selectData = {},
boxWidth = "#{p.boxWidth}",
boxHeight = "#{p.boxHeight}";
boxWidth = boxWidth < 350 ? 350 : boxWidth;
boxHeight = boxHeight < 250 ? 250 : boxHeight;
//# // 初始化页面,回显选择的数据
if(typeof "#{p.getSelectDataFuncName}" == 'function'){
selectData = "#{p.getSelectDataFuncName}"('${p.id}');
//# if (isNotBlank(p.itemCode) && isNotBlank(p.itemName)){
}else{
var codes = $('#${p.id}Code').val(), names = $('#${p.id}Name').val(),
keysToJsonPart = function(key, value){ var num = key.split('.').length - 1,
part = key.replace(/\./g, '":{"'); if (num >= 0){ part = '"' + part + '":"' + value + '"'; }
for (var i = 0; i < num; i++){ part = part + '}'; } return part; };
if(codes != null && codes != "" && names != null && names != ""){
var codesArr = codes.split(","), namesArr = names.split(",");
if (codesArr && namesArr && codesArr.length == namesArr.length){
for(var i=0; i<codesArr.length; i++) {
selectData[codesArr[i]] = JSON.parse('{' + keysToJsonPart('${p.itemCode}', codesArr[i])
+ ',' + keysToJsonPart('${p.itemName}', namesArr[i]) + '}');
}
}
}
//# }
}
var options = {
type: 2,
maxmin: true,
shadeClose: true,
title: '${p.title}',
area: [boxWidth+'px', boxHeight+'px'],
content: $('#${p.id}Div').attr('data-url'),
contentFormData: {
__layer: true,
checkbox: '${p.checkbox}',
selectData: js.encodeUrl(JSON.stringify(selectData))
},
success: function(layero, index){
if ($(js.layer.window).width() < boxWidth
|| $(js.layer.window).height() < boxHeight){
js.layer.full(index);
}
},
btn: ['<i class="fa fa-check"></i> ${text("确定")}'],
btn1: function(index, layero){
var win = layero.iframeWindow();
selectData = win.getSelectData();
//# // 自定义选择节点验证返回false代表验证失败
if(typeof "#{p.checkFuncName}" == 'function'){
if (!"#{p.checkFuncName}"('${p.id}', selectData)){
return false;
}
}
//# // 点击确定,获取用户选择数据
if(typeof "#{p.setSelectDataFuncName}" == 'function'){
"#{p.setSelectDataFuncName}"('${p.id}', selectData);
//# if (isNotBlank(p.itemCode) && isNotBlank(p.itemName)){
}else{
var codes = [], names = [];
$.each(selectData, function(key, value){
codes.push(js.val(value,'${p.itemCode}'));
names.push(js.val(value,'${p.itemName}'));
});
$('#${p.id}Code').val(codes.join(',')).change();
$('#${p.id}Name').val(names.join(',')).change();
//# }
}
try{$('#${p.id}Code,#${p.id}Name').resetValid();}catch(e){}
//# // 选择回调方法,选择成功后调用
if(typeof "#{p.callbackFuncName}" == 'function'){
"#{p.callbackFuncName}"('${p.id}', 'ok', index, layero, selectData);
}
}
};
//# if (p.allowClear){
options.btn.push('<i class="fa fa-eraser"></i> ${text("清除")}');
options['btn'+options.btn.length] = function(index, layero){
$("#${p.id}Code").val('').change();
$("#${p.id}Name").val('').change();
try{$('#${p.id}Code,#${p.id}Name').resetValid();}catch(e){}
//# // 选择回调方法,点击清空后调用
if(typeof "#{p.callbackFuncName}" == 'function'){
"#{p.callbackFuncName}"('${p.id}', 'clear', index, layero);
}
};
//# }
options.btn.push('<i class="fa fa-close"></i> ${text("关闭")}');
options['btn'+options.btn.length] = function(index, layero){
//# // 选择回调方法,点击取消调用
if(typeof "#{p.callbackFuncName}" == 'function'){
"#{p.callbackFuncName}"('${p.id}', 'cancel', index, layero);
}
};
//# // 弹出对话框前调用,返回 false 则不弹框,直接返回
if(typeof "#{p.openFuncName}" == 'function'){
if("#{p.openFuncName}"('${p.id}', options) === false){
return true;
}
}
js.layer.open(options);
});
//# /*
/**
* 选择前调用数据验证函数返回false代表验证失败
* @param id 标签的id
* @param selectData 当前选择列表的数据MAP
* @return true 验证成功false 验证失败
*/
function listselectCheck(id, selectData){
if (id == 'parent'){
log(selectData); // 选择的节点数据
}
return true;
}
/**
* 选择框回调方法
* @param id 标签的id
* @param act 动作事件ok、cloear、cancel
* @param index layer的索引号
* @param layero layer内容的jQuery对象
* @param selectData 当前选择列表的数据MAP
*/
function listselectCallback(id, act, index, layero, selectData){
if (id == 'parent' && (act == 'ok' || act == 'clear')){
var win = layero.iframeWindow();
log(win); // 选择框内容的window对象
log(act); // 回调活动事件ok、clear、cancel
log(index); // layer的index
log(layero); // layer实例对象
log(selectData); // 选择的节点数据
}
}
/**
* 弹出对话框,列表数据回显调用方法
* @param id 标签的id
* @return selectData 当前选择列表的数据MAP
*/
function listselectGetSelectData(id){
var selectData = {};
if (id == 'parent'){
selectData['主键字段值'] = {行数据};
}
return selectData;
}
/**
* 选择后,设置到业务表单调用方法 v4.2.0
* @param id 标签的id
* @param selectData 当前选择列表的数据MAP
*/
function listselectSetSelectData(id, selectData){
if (id == 'parent'){
log(selectData);
}
}
/**
* 弹出对话框前调用 v4.2.0
* @param id 标签的id
* @param options 弹窗选项
* @return 返回 false 则不弹框,直接返回
*/
function listselectOpen(id, options){
if (id == 'parent'){
log(options);
}
}
//# */
</script>

View File

@@ -0,0 +1,77 @@
<%/* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
* No deletion without permission, or be held responsible to law. */
/**
* 表单控件:单选按钮
* @author ThinkGem
* @version 2017-3-5
*/
var p = {
// 标签参数
id: id!, // 元素ID如果不填写则与name相同
path: path!, // 绑定form上model中属性的值
name: name!, // 元素名称,不填写
value: value!, // 元素值
defaultValue: defaultValue!,// 默认值 v4.1.5
dictType: dictType!, // 字典类型从字典里获取自动设置items、itemLabel、itemValue
items: items!([]), // 列表数据可接受对象集合List<DictData>
itemLabel: itemLabel!'', // 指定列表数据中的什么属性名作为option的标签名
itemValue: itemValue!'', // 指定列表数据中的什么属性名作为option的value值
readonly: toBoolean(readonly!false), // 是否只读模式 v4.2.0
blankOption: toBoolean(blankOption!false), // 是否默认有个空白选择项目 v4.2.0
blankOptionValue: blankOptionValue!'', // 给空白选择项目设置一个值,默认:空字符串 v4.2.0
blankOptionLabel: blankOptionLabel!'全部', // 给空白选择项目设置一个标签,如:请选择、全部 v4.2.0
// 内置参数
thisTag: thisTag,
exclAttrs: ['id', 'path', 'name', 'value', 'defaultValue', 'dictType',
'items', 'itemLabel', 'itemValue']
};
// 编译绑定参数
form.path(p);
// 编译属性参数
form.attrs(p);
// 编译集合参数
form.items(p);
// 如果只读模式则禁用并加默认值为value
if (p.readonly){
p.attrs = p.attrs + ' disabled="true"';
%><input type="hidden" name="!${p.name}" value="${p.value}"/><%
}else{
%><input type="hidden" name="!${p.name}" value=""/><%
}
// 输出选项
var body = {
if (p.blankOption){
%><label><input type="radio" id="${p.id}_" name="${p.name}"
value="${p.blankOptionValue}"${p.attrs} checked> ${p.blankOptionLabel}</label><%
}
var checked, title;
for (var item in p.items){
checked = (@ObjectUtils.toString(p.value) == item[p.itemValue] ? ' checked' : '');
if (type.name(item) == 'DictData'){
if (!item['isRoot']) {
continue;
}
if (isNotBlank(item['description'])){
title = ' title="' + item['description'] + '"';
}
}
%><label${title}><input type="radio" id="${p.id}${itemLP.index}" name="${p.name}"
value="${item[p.itemValue]}"${p.attrs}${checked}> ${item[p.itemLabel]}</label><%
}
};
%>
<span id="${p.id}" class="icheck">
${body}</span>

View File

@@ -0,0 +1,124 @@
<%/* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
* No deletion without permission, or be held responsible to law. */
/**
* 表单控件:下拉选择框
* @author ThinkGem
* @version 2017-3-5
*/
var p = {
// 标签参数
id: id!, // 元素ID如果不填写则与name相同
path: path!, // 绑定form上model中属性的值
name: name!, // 元素名称,不填写
value: value!, // 元素值
defaultValue: defaultValue!,// 默认值 v4.1.5
dictType: dictType!, // 字典类型从字典里获取自动设置items、itemLabel、itemValue
// 字典类型加 __all双下划线+all 后缀,则显示停用的字典 v4.2.0
dictIcon: toBoolean(dictIcon!true), // 是否加载字典里设置的样式默认true v4.3.3
dictStyle: toBoolean(dictStyle!false), // 是否加载字典里设置的样式默认false v4.3.3
items: items![], // 列表数据可接受对象集合List<DictData>
itemLabel: itemLabel!'', // 指定列表数据中的什么属性名作为option的标签名
itemValue: itemValue!'', // 指定列表数据中的什么属性名作为option的value值
itemStatus: itemStatus!'', // option 的 disabled如果是字符串类型0正常,!0禁用v4.2.0
multiple: multiple!'false', // 是否为多选框
readonly: toBoolean(readonly!false), // 是否只读模式 v4.1.7
blankOption: toBoolean(blankOption!false), // 是否默认有个空白选择项目
blankOptionValue: blankOptionValue!'', // 给空白选择项目设置一个值,默认:空字符串 v4.2.0
blankOptionLabel: blankOptionLabel!'&nbsp;', // 给空白选择项目设置一个标签,如:请选择、全部
// data-placeholder: '请选择人员信息', // 下拉选择框的提示信息
// 内置参数
thisTag: thisTag,
exclAttrs: ['id', 'path', 'name', 'value', 'defaultValue', 'dictType',
'items', 'itemLabel', 'itemValue', 'multiple', 'blankOption']
};
// 编译绑定参数
form.path(p);
// 编译属性参数
form.attrs(p);
// 编译集合参数
form.items(p);
// 是否是多选下拉框
if (toBoolean(p.multiple)){
p.attrs = p.attrs + ' multiple="true" data-close-on-select="false"';
}
// 转换为字符串数组
if (p.multiple == 'true' && type.name(p.value) == 'String'){
// p.value = @ObjectUtils.toString(p.value); 一定是字符串,无需转换
p.value = @StringUtils.split(p.value, ',');
}
// 加一个 type="hidden" 当不选择任何东西的时候使用该默认值否则发送null则不会被执行update
if (p.multiple == 'true' || p.readonly){
// 如果只读模式则禁用并加默认值为value
if (p.readonly){
p.attrs = p.attrs + ' disabled="true"';
if (p.multiple == 'true'){
for (var val in p.value!){
%><input type="hidden" name="!${p.name}" value="${val}"/><%
}elsefor{
%><input type="hidden" name="!${p.name}" value=""/><%
}
}else{
%><input type="hidden" name="!${p.name}" value="${p.value}"/><%
}
}else{
%><input type="hidden" name="!${p.name}" value=""/><%
}
}
// 输出下拉选项
var body = {
if (p.blankOption && p.multiple != 'true'){
%><option value="${p.blankOptionValue}">${p.blankOptionLabel}</option><%
}
for (var item in p.items){
var iv = @ObjectUtils.toString(@ReflectUtils.invokeGetter(item, p.itemValue));
var il = @ObjectUtils.toString(@ReflectUtils.invokeGetter(item, p.itemLabel));
var attr = '';
if (p.multiple == 'true'){
attr = attr + (@StringUtils.inString(iv, p.value) ? ' selected' : '');
}else{
attr = attr + (@ObjectUtils.toString(p.value) == iv ? ' selected' : '');
}
if (type.name(item) == 'DictData'){
if (!item['isRoot']) {
continue;
}
if (isNotBlank(item['description'])){
attr = attr + ' title="' + item['description'] + '"';
}
if (p.dictIcon && isNotBlank(item['dictIcon'])){
attr = attr + ' data-icon="' + item.dictIcon + '"';
}
if (p.dictStyle && isNotBlank(item['cssStyle'])){
attr = attr + ' style="' + item.cssStyle + '"';
}
if (p.dictStyle && isNotBlank(item['cssClass'])){
attr = attr + ' class="' + item.cssClass + '"';
}
if (isBlank(p.itemStatus)){
p.itemStatus = 'status';
}
}
if (isNotBlank(p.itemStatus) && isNotBlank(item[p.itemStatus])){
attr = attr + (@ObjectUtils.toString(item[p.itemStatus]) != '0' ? ' disabled' : '');
}
%><option value="${iv}"${attr}>${il}</option><%
}
};
%>
<select id="${p.id}" name="${p.name}"${p.attrs}>
${body}</select>

View File

@@ -0,0 +1,29 @@
<%/* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
* No deletion without permission, or be held responsible to law. */
/**
* 表单控件:文本域
* @author ThinkGem
* @version 2017-3-5
*/
var p = {
// 标签参数
id: id!, // 元素ID如果不填写则与name相同
path: path!, // 绑定form上model中属性的值
name: name!, // 元素名称,不填写
value: value!, // 元素值
defaultValue: defaultValue!,// 默认值 v4.1.5
// 内置参数
thisTag: thisTag,
exclAttrs: ['id', 'path', 'name', 'value', 'defaultValue', 'type']
};
// 编译绑定参数
form.path(p);
// 编译属性参数
form.attrs(p);
%><textarea id="${p.id}" name="${p.name}"${p.attrs}>${p.value}</textarea>

View File

@@ -0,0 +1,250 @@
<%/* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
* No deletion without permission, or be held responsible to law. */
/**
* 表单控件:树结构选择框
* @author ThinkGem
* @version 2017-3-5
*/
var p = {
// 标签参数
id: id!, // 元素ID
path: path!, // 绑定form上model中属性的值
name: name!, // 隐藏域名称
value: value!, // 隐藏域值
defaultValue: defaultValue!,// 隐藏域默认值 v4.1.5
labelPath: labelPath!, // 绑定form上model中属性的值
labelName: labelName!, // 标签框名称
labelValue: labelValue!, // 标签框值
defaultLabel: defaultLabel!,// 标签框默认值 v4.1.5
class: class!'', // 标签框的CSS类名
placeholder: placeholder!, // 标签框的预期值的提示信息
dataMsgRequired: thisTag.attrs['data-msg-required'], // 必填错误提示信息
btnClass: btnClass!, // 标签框后面的按钮CSS类名
title: title!text('选项选择'), // 对话框标题
boxWidth: boxWidth!300, // 对话框宽度默认300像素
boxHeight: boxHeight!400, // 对话框高度默认400像素
url: url!, // 树结构,数据源地址 [{id, pid, name}]
readonly: readonly!'false', // 是否只读模式
allowInput: toBoolean(allowInput!false), // 是否允许label框输入
allowClear: toBoolean(allowClear!true), // 是否允许清空选择内容
checkbox: toBoolean(checkbox!false), // 是否显示复选框是否支持多选如果设置canSelectParent=true则返回父节点数据
chkboxType: chkboxType!'', // 复选框级联选择规则 v4.0.6,默认:{'Y':'ps','N':'ps'}
expandLevel: @ObjectUtils.toInteger(expandLevel!(-1)), // 默认展开层次级别(默认:如果有1个根节点则展开一级节点否则不展开
canSelectRoot: toBoolean(canSelectRoot!false), // 可以选择跟节点
canSelectParent: toBoolean(canSelectParent!false), // 可以选择父级节点
isReturnValue: isReturnValue!'false', // 是否返回树结构的value值而不是返回id默认id
returnFullName: toBoolean(returnFullName!false), // 是否返回全路径,包含所有上级信息,以 returnFullNameSplit 参数分隔
returnFullNameSplit: returnFullNameSplit!'/', // 是否返回全路径,的分隔符,默认“/”
fastSearch: toBoolean(allowClear!true), // 快速查询,查询框输入后接着进行查询,关闭后,点击查询按钮或回车再查询 v4.5.0 v5.0.2
openFuncName: openFuncName!'treeselectOpen', // 可自定义弹窗前调用的函数名 v4.2.0
checkFuncName: checkFuncName!'treeselectCheck', // 可自定义验证方法的函数名 v4.1.5
callbackFuncName: callbackFuncName!'treeselectCallback', // 可自定义回调方法的函数名 v4.1.0
// 内置参数
thisTag: thisTag
};
// 编译绑定参数
form.path(p);
// 标签属性编译
p.labelAttrs = '';
if (!p.allowInput){
p.labelAttrs = p.labelAttrs + ' readonly="readonly"';
}
if (isNotBlank(p.dataMsgRequired)){
p.labelAttrs = p.labelAttrs + ' data-msg-required="' + p.dataMsgRequired + '"';
}
if (isNotBlank(p.placeholder)){
p.labelAttrs = p.labelAttrs + ' placeholder="' + p.placeholder + '"';
}
// 如果没有设置是否显示“清除”按钮开关则根据class判断是否为必须字段。
if (allowClear! == null && @StringUtils.contains(p.class, 'required')){
p.allowClear = false;
}
%><div class="input-group treeselect" id="${p.id}Div" data-url="${p.url}">
<input id="${p.id}Name" type="text" name="${p.labelName}" value="${p.labelValue}"
class="form-control ${p.class} ${p.labelClass} isReset"${p.labelAttrs}
/><input id="${p.id}Code" type="hidden" name="${p.name}" value="${p.value}" class="isReset"
/><span class="input-group-btn"><a id="${p.id}Button" href="javascript:"
class="btn btn-default ${p.btnClass}"><i class="fa fa-search"></i></a>
</span>
</div>
<script>
if ('${p.readonly}' == 'true' || $("#${p.id}Name").hasClass("disabled")){
$("#${p.id}Button,#${p.id}Name").addClass("disabled");
}
$("#${p.id}Button${p.allowInput?'':',#'+p.id+'Name'}").click(function(){
if ($("#${p.id}Button").hasClass("disabled") || $("#${p.id}Name").hasClass("disabled")){
return true;
}
var options = {
type: 2,
maxmin: true,
shadeClose: true,
title: '${p.title}',
area: ['${p.boxWidth}px', '${p.boxHeight}px'],
content: '${ctxPath}/tags/treeselect',
contentFormData: {
url: $('#${p.id}Div').attr('data-url'),
checkbox: '${p.checkbox}',
chkboxType: "${p.chkboxType}",
expandLevel: '${p.expandLevel}',
selectCodes: $("#${p.id}Code").val(),
isReturnValue: '${p.isReturnValue}',
fastSearch: '${p.fastSearch}',
},
success: function(layero, index){
if ($(js.layer.window).width() < "#{p.boxWidth}"
|| $(js.layer.window).height() < "#{p.boxHeight}"){
js.layer.full(index);
}
},
btn: ['<i class="fa fa-check"></i> ${text("确定")}'],
btn1: function(index, layero){
var win = layero.iframeWindow();
win.$('#keyword').val('').change();
var codes = [], names = [], nodes;
if ("${p.checkbox}" == "true"){
nodes = win.tree.getCheckedNodes(true);
}else{
nodes = win.tree.getSelectedNodes();
}
for(var i=0; i<nodes.length; i++) {
//# // 如果为复选框选择,则过滤掉父节点
//# if (p.checkbox && !p.canSelectParent){
if (nodes[i].isParent){
continue;
}
//# } // 不允许选择跟节点
//# if (!p.canSelectRoot){
if (nodes[i].level == 0 && nodes[i].isParent){
js.showMessage("${text('不能选择根节点')}"+nodes[i].name+"${text('请重新选择')}。");
return false;
}
//# } // 不允许选择父节点
//# if (!p.canSelectParent){
if (nodes[i].isParent){
js.showMessage("${text('不能选择父节点')}"+nodes[i].name+"${text('请重新选择')}。");
return false;
}
//# }
var code = nodes[i]['${p.isReturnValue!}'=='true'?'value':'id'], name = nodes[i]['name'];
//# // 如果是返回全部路径的名称,则读取名称路径
//# if (p.returnFullName){
var pNode = nodes[i].getParentNode();
while(!!pNode) {
name = pNode.name + '${p.returnFullNameSplit}' + name;
pNode = pNode.getParentNode();
}
//# }
codes.push(String(code).replace(/^u_/g,''));
names.push(String(name)/* .replace(/\([0-9]*\)/g,'') */);
//# // 如果不是复选框选择,则返回只第一个选择节点就可以了
//# if (!p.checkbox){
break;
//# }
}
//# // 自定义选择节点验证返回false代表验证失败
if(typeof "#{p.checkFuncName}" == 'function'){
if (!"#{p.checkFuncName}"('${p.id}', nodes)){
return false;
}
}
$("#${p.id}Code").val(codes.join(',')).change();
$("#${p.id}Name").val(names.join(',')).change();
//# // 选择回调方法,选择成功后调用
if(typeof "#{p.callbackFuncName}" == 'function'){
"#{p.callbackFuncName}"('${p.id}', 'ok', index, layero, nodes);
}
try{$('#${p.id}Code,#${p.id}Name').resetValid();}catch(e){}
}
};
//# if (p.allowClear){
options.btn.push('<i class="fa fa-eraser"></i> ${text("清除")}');
options['btn'+options.btn.length] = function(index, layero){
$("#${p.id}Code").val('').change();
$("#${p.id}Name").val('').change();
try{$('#${p.id}Code,#${p.id}Name').resetValid();}catch(e){}
//# // 选择回调方法,点击清空后调用
if(typeof "#{p.callbackFuncName}" == 'function'){
"#{p.callbackFuncName}"('${p.id}', 'clear', index, layero);
}
};
//# }
options.btn.push('<i class="fa fa-close"></i> ${text("关闭")}');
options['btn'+options.btn.length] = function(index, layero){
//# // 选择回调方法,点击取消调用
if(typeof "#{p.callbackFuncName}" == 'function'){
"#{p.callbackFuncName}"('${p.id}', 'cancel', index, layero);
}
};
//# // 弹出对话框前调用,返回 false 则不弹框,直接返回
if(typeof "#{p.openFuncName}" == 'function'){
if("#{p.openFuncName}"('${p.id}', options) === false){
return true;
}
}
js.layer.open(options);
});
//# /*
/**
* 选择前调用数据验证函数返回false代表验证失败
* @param id 标签的id
* @param node 验证的数据
* @return true 验证成功false 验证失败
*/
function treeselectCheck(id, nodes){
if (id == 'parent'){
log(nodes); // 选择的节点数据
}
return true;
}
/**
* 选择回调方法
* @param id 标签的id
* @param act 动作事件ok、clear、cancel
* @param index layer的索引号
* @param layero layer内容的jQuery对象
* @param nodes 当前选择的树节点数组
*/
function treeselectCallback(id, act, index, layero, nodes){
if (id == 'parent' && (act == 'ok' || act == 'clear')){
var win = layero.iframeWindow();
log(win); // 选择框内容的window对象
log(act); // 回调活动事件ok、clear、cancel
log(index); // layer的index
log(layero); // layer实例对象
log(nodes); // 选择的节点数据
}
}
/**
* 弹出对话框前调用 v4.2.0
* @param id 标签的id
* @param options 弹窗选项
* @return 返回 false 则不弹框,直接返回
*/
function treeselectOpen(id, options){
if (id == 'parent'){
log(options);
}
}
//# */
</script>

View File

@@ -0,0 +1,174 @@
<%/* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
* No deletion without permission, or be held responsible to law. */
/**
* 表单控件:输入框
* @author ThinkGem
* @version 2017-3-5
*/
var p = {
// 标签参数
id: id!, // 元素ID如果不填写则与name相同
path: path!, // 绑定form上model中属性的值
name: name!, // 元素名称,不填写
value: value!, // 元素值
defaultValue: defaultValue!,// 默认值 v4.1.5
class: class!'', // 标签框的CSS类名设置 required 加入必填验证
maxlength: maxlength!'', // 编辑器最大输入字数,为空代表无限制
height: height!'200', // 编辑器的高度默认200
maxHeight: maxHeight!, // 编辑器的最大高度
simpleToolbars: toBoolean(simpleToolbars!false), // 是否是简单的工具条
readonly: toBoolean(readonly!false), // 是否只读模式
outline: toBoolean(outline!false), // 大纲视图
options: options!'', // UE附加选项逗号隔开。
// 内置参数
thisTag: thisTag
};
// 编译绑定参数
form.path(p);
%>
<% if(p.outline){ %>
<div class="row edui-outline" id="${p.id}outline">
<div class="col-xs-9 left">
<textarea id="${p.id}" name="${p.name}" rows="4" class="edui-textarea form-control ${p.class}"></textarea>
<script id="${p.id}UE" type="text/plain" style="width:100%;height:${p.height}px;">${p.value}</script>
</div>
<div id="${p.id}OpenClose" class="open-close toc-close">&nbsp;</div>
<div class="col-xs-3 right">
<div class="wrapper" id="${p.id}Wrapper">
<div class="wrapperTitle">${text('目录标题')}</div>
<div class="wrapperContainer" id="${p.id}Container"></div>
<div class="clearfix"></div>
</div>
</div>
</div>
<% }else{ %>
<textarea id="${p.id}" name="${p.name}" rows="4" class="edui-textarea form-control ${p.class}"></textarea>
<script id="${p.id}UE" type="text/plain" style="width:100%;height:${p.height}px;">${p.value}</script>
<% } %>
<script type="text/javascript">
var ${p.id}UE;
$(function() {
${p.id}UE = UE.getEditor('${p.id}UE', {
<% if(isNotBlank(p.maxlength)){ %>maximumWords: ${p.maxlength}, <% } %>
<% if(p.simpleToolbars){ %>toolbars: window.UEDITOR_CONFIG.simpleToolbars, <% } %>
${p.options} readonly: ${p.readonly}, initialFrameHeight: ${p.height},
});
// 更新编辑器内容 ${p.id}UE.updateContent();
${p.id}UE.updateContent = function(){
if (!${p.id}UE.hasContents()){
$('#${p.id}').val("").change();
}else{
var html = ${p.id}UE.getContent().replace('<!--HTML-->','');
$('#${p.id}').val("<!--HTML-->" + html).change();
}
if (typeof window.webuploaderRefresh == 'function'){
window.webuploaderRefresh();
}
};
<% if(p.outline){ %>
// 刷新目录表题树 ${p.id}UE.refreshDirectiontion();
${p.id}UE.refreshDirection = function(){
var dirmap = {}, dir = ${p.id}UE.execCommand('getsections');
// 更新目录树
$('#${p.id}Container').html(traversal(dir) || '${text("暂无大纲标题")}.');
// 点击章节触发
$('#${p.id}Container .sectionItem').click(function(e){
var $target = $(this), address = $target.attr('data-address');
${p.id}UE.execCommand('selectsection', dirmap[address], true);
});
// 生成更新目录树
function traversal(section) {
var $list, $item, $itemContent, child, childList;
if(section.children.length) {
$list = $('<ul>');
for(var i = 0; i< section.children.length; i++) {
child = section.children[i];
//设置目录节点内容标签
$itemContent = $('<span class="sectionItem">' + child['title'] + '</span>');
$itemContent.attr('data-address', child['startAddress'].join(','));
dirmap[child['startAddress'].join(',')] = child;
//设置目录节点容器标签
$item = $('<li>');
$item.append($itemContent);
//继续遍历子节点
if($item.children.length) {
childList = traversal(child);
childList && $item.append(childList);
}
$list.append($item);
}
}
return $list;
}
// 重设大纲视图宽度
$('#${p.id}Wrapper').css('width', $('#${p.id}outline .right').width()+'px');
};
// 页面网上滚动时,让目录固定在顶部
$(window).scroll(function(e) {
var scrollTop = (document.body.scrollTop||document.documentElement.scrollTop), leftTop = $('.left').offset().top,
wrapperHeight = ($('#${p.id}Wrapper').height()), wrapperHeight = (wrapperHeight > 0 ? wrapperHeight : 200);
if(leftTop < scrollTop && leftTop + $('.left').height() - scrollTop - wrapperHeight > 0) {
$('#${p.id}Wrapper').addClass('fixTop');
$('#${p.id}OpenClose').addClass('fixTop');
} else {
$('#${p.id}Wrapper').removeClass('fixTop');
$('#${p.id}OpenClose').removeClass('fixTop')
}
// 重设大纲视图宽度
$('#${p.id}Wrapper').css('width', $('#${p.id}outline .right').width()+'px');
}).resize(function(){
// 重设大纲视图宽度
$('#${p.id}Wrapper').css('width', $('#${p.id}outline .right').width()+'px');
});
// 显示或隐藏目录树
$('#${p.id}OpenClose').click(function(){
if($(this).hasClass("toc-close")){
$(this).removeClass("toc-close");
$(this).addClass("toc-open");
$("#${p.id}outline .right").hide();
$("#${p.id}outline .left").removeClass('col-xs-9');
$("#${p.id}outline .left").addClass('col-xs-12');
}else{
$(this).addClass("toc-close");
$(this).removeClass("toc-open");
$("#${p.id}outline .right").show();
$("#${p.id}outline .left").removeClass('col-xs-12');
$("#${p.id}outline .left").addClass('col-xs-9');
}
${p.id}UE.fireEvent('keydown', 0); // 重置工具栏大小
});
<% } %>
// 编辑器加载完成事件
${p.id}UE.ready(function(){
<% if (isNotBlank(p.maxHeight)){ %>
${p.id}UE.setHeight(${p.maxHeight});
<% } %>
${p.id}UE.addListener('contentchange', function(){
${p.id}UE.updateContent();
});
<% if(p.outline){ %>
${p.id}UE.addListener('updateSections', function(){
${p.id}UE.refreshDirection();
});
${p.id}UE.refreshDirection();
<% } %>
if (typeof window.webuploaderRefresh == 'function'){
window.webuploaderRefresh();
}
});
});
$('#${p.id}').parents('form').submit(function(){
${p.id}UE.updateContent();
});
</script>

View File

@@ -0,0 +1,66 @@
<%/* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
* No deletion without permission, or be held responsible to law. */
/**
* 表单控件:验证码输入框
* @author ThinkGem
* @version 2017-3-5
*/
var p = {
id: id!name, // 验证码输入框ID
name: name!, // 验证码输入框名称(必填)
isRequired: toBoolean(isRequired!true), // 是否必填,默认必填
dataMsgRequired: thisTag.attrs['data-msg-required'], // 必填错误提示信息
isRemote: toBoolean(isRemote!true), // 是否支持实时远程验证
dataMsgRemote: thisTag.attrs['data-msg-remote'], // 必填错误提示信息
isLazy: toBoolean(isLazy!false), // 是否懒加载验证码图片原noRefresh参数
label: label!text('验证码'), // 控件的标签V4.2.2
isShowLabel: toBoolean(isShowLabel!true), // 是否显示“验证码”标签默认trueV4.0.5
// 内置参数
thisTag: thisTag
};
// 必填属性HTML
var require = {
if (p.isRequired){
%> required="true" data-msg-required="${p.dataMsgRequired!text('请填写验证码')}"<%
}
};
// 远程验证HTML
var remote = {
if (p.isRemote){
%> remote="${ctxPath}/validCode" data-msg-remote="${p.dataMsgRemote!text('验证码不正确.')}"<%
}
};
%>
<div class="input-group">
<% if (p.isShowLabel){ %><span class="input-group-addon">${p.label}</span><% } %>
<input type="text" id="${p.id}" name="${p.name}" class="form-control"${require}${remote} autocomplete="off"/>
<span class="input-group-addon p0">
<img id="${p.id}Img" class="${p.id}Img" title="${text('看不清,点击图片刷新')}" src="" alt="${text('验证码')}" style="width:100px;"/>
<button id="${p.id}Refresh" class="hide" type="button"></button>
</span>
</div>
<script>
$('#${p.id}Refresh').click(function(){
var src = '${ctxPath}/validCode?'+new Date().getTime();
$('#${p.id}Img').attr('src', src).removeClass('hide');
})<% if (!p.isLazy){ %>.click()<% } %>;
$('#${p.id}Img').click(function(){
$('#${p.id}Refresh').click();
$('#${p.id}').focus().val('');
});
$('#${p.id}').focus(function(){
if($('#${p.id}Img').attr('src') == ''){
$('#${p.id}Refresh').click();
}
});
</script>