代码拉取完成,页面将自动刷新
/*
* 旨在消灭项目中重复的JS代码;
核心思想是:约定优于配置.
即在元素上做特别的约定(标识)就可以实现通用的功能,而不需要额外的通过js代码去实现这些功能.
文件划分:
utf8mb4_general_ci.js 文件: 理应做为做基本的文件,实现最通用的功能,理应每个项目都可以无缝引入的功能,理应放在head中引入
utf8mb4_general_ci-module-moduleName.js 文件: 主要为某一些项目某些某块特定处理的功能,分多文件,按需引入
@author Vic.xu
@since terrason
*/
(function (windom, $) {
/*
* 在nojs.init执行之前执行的函数 在模块加载前运行代码 不要放在ready中 使用方式: ($nojs.after同理)
* $nojs.before(function(context){ this; //表示nojs全局对象,等同于$nojs.
* this.test.enable=false; //禁用test模块 this.chosen.enable=false; //禁用chosen模块
* //do something else });
*
*/
var before = [];
var after = [];
window.base_url = windom.base_url || "";
windom.storage = windom.storage || {
get: function () {
}
};
windom.project_prefix = windom.project_prefix || "/";
var $nojs = function (context) {
// 在初始化nojs的各个模块之前执行的方法
for (var i in before) {
if ($.isFunction(before[i])) {
if (before[i].call($nojs, context) === false) {
return;
}
}
}
// 针对模块的优先级进行一次排序操作 priority 越小 越先执行
var modules = [];
var priorityDefault = 99; // 默认的优先级
for (var name in $nojs) {
var app = $nojs[name];
if (!app.priority && 0 != app.priority) {
app.priority = priorityDefault;
}
app.name = name;
modules.push(app);
}
modules.sort(function (p1, p2) {
return p1.priority - p2.priority;
}).forEach(function (app) {
if ($.isFunction(app.enable) ? app.enable() : app.enable === true) {
if ($nojs.debug) {
console.debug(app.name + " ->" + app.priority)
}
app.init(context);
}
});
// 在初始化nojs的各个模块之后执行的方法
for (var i in after) {
$.isFunction(after[i]) && after[i].call($nojs, context);
}
};
$nojs.before = function (fn) {
before.push(fn);
}
$nojs.after = function (fn) {
after.push(fn);
}
$nojs.debug = false;
/*
* 000. 测试 所有约定的写法遵照此格式写法
*/
$nojs.test = {
priority: 100,
// 1-是否启用此约定,可以根据依赖模块判断或直接返回 boolean
enable: function (context) {
return true;
},
// 2-选择器,对哪些元素做一些操作
selector: ".test",
// 3-对元素做哪些具体的操作
init: function (context) {
$(this.selector, context).each(function (i, t) {
$(t).append("<h1>这是一个测试</h1>")
});
}
};
/*
* 001. select值绑定 自动选择下拉框的值, 需要在下拉框上绑定当前值 data-value="value"
*/
$nojs.selectValueInitialization = {
enable: true,
selector: "select[data-value]",
priority: 98,// 保证比select2之类的先初始化
event: "$nojs-select-initialize",
init: function (context) {
$(this.selector, context).on(
this.event,
function (event) {
var $select = $(this);
var value = $select.data("value");
if (value !== undefined) { // 把相应的值选中
$select.children("option:selected").prop("selected", false);
if (value !== '') {
if (!$select[0].hasAttribute("multiple")) {
$select.children('option[value="' + value + '"]').prop("selected", true);
} else {// 如果是多选则把value用英文逗号分隔后匹配选择
value.toString().split(",").forEach(function (item) {
$select.children('option[value="' + item + '"]').prop("selected", true);
});
}
}
}
$select.trigger("change");
}).trigger(this.event);
}
};
/*
* 002. 日历控件 把datetime样式的元素初始化成bootstrap的日期控件
*/
$nojs.datetimepicker = {
enable: function () {
return !!$.fn.datetimepicker;
},
options: {
autoclose: true,
todayBtn: true,
language: "zh-CN"
},
selector: ".datetime",
initRange: function (option, $input, context) {
function _bindDateTarget(opt) {
var method = {
"startDateTarget": "setStartDate",
"endDateTarget": "setEndDate"
};
if (option[opt] === 'now') {
$input.datetimepicker(method[opt], new Date());
return;
}
var $target = $(option[opt], context);
if (!$target.length) {
$target = $("[name=" + option[opt] + "]", context);
}
$target.on("changeDate", function (ev) {
$input.datetimepicker(method[opt], this.value);
});
}
if (!option.startDateTarget && !option.endDateTarget) {
return;
}
var $form = $input.closest("form");
if ($form.length) {
context = $form;
}
if (option.startDateTarget) {
_bindDateTarget("startDateTarget");
}
if (option.endDateTarget) {
_bindDateTarget("endDateTarget");
}
},
init: function (context) {
var module = this;
$(this.selector, context).each(function (i, dt) {
var $input = $(dt);
var option = $.extend({}, module.options, $input.data());
$input.datetimepicker(option);
module.initRange(option, $input, context);
if (option.value) {
$input.val(option.value);
}
$input.next("span").click(function () {
$input.focus();
});
});
}
};
/*
* 004. 日历 把calendar样式的div元素初始化成bootstrap的日期控件
*/
$nojs.timeCalendar = $.extend(true, {}, $nojs.datetimepicker, {
selector: "div.calendar"
});
/*
* 005. CheckBox 和全选/取消 和相关批量操作按钮 的关系建立 1-全选按钮data-member="subName" 和
* name="subName" 的元素关联起来 2-操作按钮 data-checkbox-required="subName"
* 是否可以操作(是否选择name="subName" 子元素)
*/
$nojs.checkboxBinding = {
enable: true,
selector: "[data-member]",
$member: function ($leader, context) { // 获取成员
var memberName = $leader.data("member"); // 成员name
// return $("input:checkbox[name=" + memberName +
// "]:not(:disabled)", context);
return $("input:checkbox[data-leader=" + memberName + "]:not(:disabled)", context);
},
$relate: function ($leader, $member, context) { // 相关操作按钮是否可操作
var memberName = $leader.data("member"); // 成员name
var $relate = $("[data-checkbox-required=" + memberName + "]",
context)
if ($relate.length !== 0) {
$relate.prop("disabled",
$member.filter(":checked").length === 0);
}
},
init: function (context) {
var module = this;
$(this.selector, context).each(function () {
var $leader = $(this);
var $member = module.$member($leader, context);
$leader.change(function () { // 点击全选或者取消
$member.prop("checked", $leader.prop("checked"));
module.$relate($leader, $member, context);
});
$member.change(function () { // 点击成员 若全选则全选checkbox选中
$leader.prop("checked", $member.length == $member
.filter(":checked").length);
module.$relate($leader, $member, context);
});
module.$relate($leader, $member, context);
});
}
};
/*
* 006.chosen 下拉框初始化
*/
$nojs.chosen = {
enable: function () {
return !!$.fn.chosen;
},
selector: "select.chosen",
option: {
no_results_text: "没有找到", // 找不到结果时候显示的内容
allow_single_deselect: true, // 是否允许取消选择
max_selected_options: 12
// 当select为多选时,最多选择个数
},
init: function (context) {
var module = this;
$(module.selector, context).each(function () {
var $select = $(this);
var opts = $.extend(module.option, $select.data());
$select.chosen(opts);
});
}
};
/*
* 007. 发送短信验证码 data-smscode 的按钮点击产生倒计时效果
*/
$nojs.smscode = {
enable: function () {
return !!$.timer;
},
selector: "button[data-smscode],a[data-smscode]",
init: function (context) {
var thisModule = this;
// 短信验证码
$(document).on("click", thisModule.selector, function () {
var $this = $(this);
var originalCaption = $this.text();
var $caption = $("<span></span>");
var remain = 60;
var $remain = $("<span></span>").text(remain);
$caption.append($remain).append(" 秒后才可重新获取");
$this.html($caption);
var timer = $.timer(function () {
if (remain > 0) {
$remain.text(--remain);
} else {
timer.stop();
$(thisModule.selector, context).prop(
"disabled", false);
$this.text(originalCaption);
}
}, 1000, true);
$(thisModule.selector, context).prop("disabled", true);
});
}
};
/**
* 008.icon-picker初始化
*/
$nojs.iconPicker = {
enable: function () {
return !!$.fn.iconPicker;
},
selector: 'input.icon-picker',
init: function (context) {
$(this.selector, context).iconPicker();
}
};
/**
* 009. 异步构建一棵树 通过ztree url: data-url="" 数据加载的url setting :
* data-setting='{"k1":"v1", "k2":"v2"}' 用data绑定json数据: 外部单引号 内部双引号;
* 也可以是一个变量(不加引号) after:tree初始化后执行的方法,参数为当前树data-after="fnName"
* checked:绑定当前应该选中的节点 data-checked="idValue"
* http://www.treejs.cn/v3/api.php
*/
$nojs.buildZtree = {
enable: function () {
return !!$.fn.zTree;
},
selector: 'ul.ztree:not(.self)',
defaultZtreeSetting: { // 默认的ztree设置
view: {
showLine: true,
selectedMulti: false
},
data: {
simpleData: {
enable: true,
idKey: "id",
pIdKey: "pid",
rootPId: "0"
},
key: {
url: "_url" // 把url设置成一个不存在的key
}
}
},
// 把setting中的一些方法对应的字符串解析成function
settingString2Fn: function (opts) {
var callback = opts.callback;
// 把callback中的字符串解析成函数
if (callback) {
for (var k in callback) {
callback[k] = eval(callback[k]);
}
}
// 把callviewback中的字符串解析成函数 因为只有部分是function,因此用-fn作为后缀的才表示是函数
var view = opts.view;
if (view) {
for (var k in view) {
if (k.indexOf('-fn') > -1) {
var v = view[k];
var index = k.indexOf('-fn');
var newK = k.substring(0, index);
view[newK] = eval(v); // 加入新的key
delete view[k]; // 删除老的key
}
callback[k] = eval(callback[k]);
}
}
},
init: function (context) {
var module = this;
$(module.selector, context).each(function () {
var $ul = $(this);
var url = $ul.data("url");
if (!url) return;
var setting = eval($ul.data("setting")) || {};
module.settingString2Fn(setting);
var afterFn = $ul.data("after");
var checked = $ul.data("checked");
$request.get(url, {}, function (result) {
setting = $.extend(true, module.defaultZtreeSetting, setting);
var zTreeObj = $.fn.zTree.init($ul, setting, result.data);
$ul.data("ztree", zTreeObj);
if (checked) { // 把需要选中的节点选中
zTreeObj.selectNode(zTreeObj.getNodeByParam("id", curId, null));
}
if (afterFn) { // 初始化完成执行 的函数
common.callFunction(afterFn, zTreeObj);
}
});
});
}
};
/**
* 010. select2 初始化 https://select2.org/
*/
$nojs.select2 = {
enable: function () {
return !!$.fn.select2;
},
selector: 'select.select2',
options: {
allowClear: true,
language: 'zh-CN'
},
init: function (context) {
var module = this;
$(module.selector, context).each(function () {
var $select = $(this);
var opts = $.extend(true, {}, module.options, $select.data());
$select.select2(opts);
if ($select.closest("form.validate").size() === 1) {
$select.change(function () {
console.info("change");
$(this).valid();
});
}
});
}
};
/**
* 011. 滑块 尽量使用data绑定参数
* http://ionden.com/a/plugins/ion.rangeSlider/start.html
*/
$nojs.slider = {
enable: function () {
return !!$.fn.ionRangeSlider;
},
selector: "input.slider",
init: function (context) {
$(this.selector, context).each(function () {
var $input = $(this);
$input.ionRangeSlider();
});
}
};
/**
* 012. bootstrap-select https://www.bootstrapselect.cn/index.htm
* selectpicker
*/
$nojs.selectpicker = {
enable: function () {
return !!$.fn.selectpicker;
},
selector: "select.selectpicker", // 加此样式 会被插件本身初始化, 但是由于一些数据的加载顺序
// 此处重新初始化一次
init: function (context) {
$(this.selector, context).each(function () {
$(this).selectpicker();
});
}
};
/*
* 013. wangEditor 编辑器初始化 把textarea 隐藏,然后初始化一个wangEditor编辑器,并监听编辑器
* 把编辑器的内容同步到textarea
*/
$nojs.wangEditor = {
enable: function () {
return !!window.wangEditor;
},
selector: "textarea.wangEditor-textarea",
template: {
toolbar: '<div class="wangEditor-toolbar">',// toolbar
editor: '</div><div class="wangEditor-text">'// 编辑区
},
customConfig: { // wangEditor的一些其他配置 此处主要配置 文件上传相关 其他一般走默认
pasteFilterStyle: true, // 粘贴样式的过滤 默认 true
pasteIgnoreImg: false, // 忽略粘贴内容中的图片 默认是false
pasteTextHandle: function () {
}, // 自定义处理粘贴的文本内容
uploadImgShowBase64: false, // 使用 base64 保存图片
uploadImgServer: base_url + '/attachment/upfiles', // 上传图片到服务器
uploadFileName: 'upfiles', // 上传文件的name属性
uploadImgParams: { // 额外参数
module: 'wangEditor'
},
uploadImgHeaders: { // header token 检验
token: storage.get("token")
},
uploadImgHooks: { // 钩子函数
// 当服务器返回格式非 {errno:0, data: [...]}
customInsert: function (insertImg, result, editor) {
// 图片上传并返回结果,自定义插入图片的事件(而不是编辑器自动插入图片!!!)
// insertImg 是插入图片的函数,editor 是编辑器对象,result 是服务器端返回的结果
console.info(result);
if (result.code != 0) {
$.alert(result.msg, "上传出错了");
return;
}
if (result.data) {
result.data.forEach(function (item) {
insertImg(item.url);
});
}
}
}
},
init: function (context) {
var module = this;
$(this.selector, context).each(function (i, t) {
var $textarea = $(this);
var $toolbar = $(module.template.toolbar).attr("id", "wang-toolbar-" + i);
var $editor = $(module.template.editor).attr("id", "wang-editor-" + i);
$textarea.after($editor).after($toolbar).hide();
// $textarea 上携带的一些自定义参数
var dataOpt = $textarea.data();
var opt = $.extend({}, module.customConfig, dataOpt);
var E = window.wangEditor;
var editor = new E($toolbar[0], $editor[0])
editor.customConfig = opt;
editor.customConfig.onchange = function (html) {
// 监控变化,同步更新到 textarea
$textarea.val(html);
}
editor.create();
// 设置初始值 为$textarea中的值
editor.txt.html($textarea.val());
//绑定到原始textarea上
$textarea.data("nojsWangEditor", editor)
//初始化全屏预览和预览 两者在一个js中
if (E.fullscreen) {
E.fullscreen.init(module.selector);
E.preview.init(module.selector);
E.source.init(module.selector);
}
});
}
};
/**
* 014. editor.md markdown编辑器初始化 把一个div.editormd 初始化位一个markdown编辑器,
* 这个div中必须包含一个且只能是一个textarea 这个div 可通过data绑定一些editor.md的配置, 初始化成功后把editormd
* 绑定到这个div上, 方便后续使用
*/
$nojs.editormd = {
enable: function () {
return !!window.editormd;
},
selector: "div.editormd",
config: {
width: "100%",
height: 640,
autoHeight: false,
watch: true,
toolbarAutoFixed: true,
tocm: true,
emoji: true,
path: project_prefix + "/lib/editor.md-master/lib/",
saveHTMLToTextarea: false, // 保存 HTML 到 Textarea
imageUpload: true,
imageFormats: ["jpg", "jpeg", "gif", "png", "bmp", "webp"],
imageUploadURL: base_url + "/attachment/mdload",
/*
* toolbarIcons : function() { // Or return
* editormd.toolbarModes[name]; // full, simple, mini // Using "||"
* set icons align right. return ["undo", "redo", "bold","del",
* "italic", "quote", "uppercase", "h1", "h2","h3","h4","h5","h6",
* "list-ul", "list-ol","hr", "link", "reference-link", "image",
* "code", "preformatted-text", "code-block", "table",
* "datetime","emoji","html-entities", "pagebreak","goto-line",
* "watch" ,"unwatch", "preview", "search", "fullscreen",
* "clear","help","info" ]; },
*/
},
init: function (context) {
var module = this;
$(this.selector, context).each(function (i) {
var $div = $(this);
if ($("textarea", $div).size() != 1) {
return true; // continue
}
var id = $div.attr("id") || "editormd-" + i;
$div.attr("id", id);
console.info($.extend({}, module.config, $div.data()));
var editor = editormd(id, $.extend({}, module.config, $div.data()));
$div.data("editormd", editor);
});
}
};
/**
* 015. editor.md markdown 转html
*/
$nojs.mdToHtml = {
enable: function () {
return !!window.editormd;
},
selector: "div.showmd",
config: {
markdown: '',// markdown 内容
tocContainer: "#toc", // 自定义 ToC 容器层
// htmlDecode : true, // 开启 HTML 标签解析,为了安全性,默认不开启
htmlDecode: "style,script,iframe", // you can filter tags decode
// toc : false,
tocm: true, // Using [TOCM]
path: "lib/editor.md-master/lib/lib/",
// gfm : false,
// tocDropdown : true,
// markdownSourceCode : true, // 是否保留 Markdown 源码,即是否删除保存源码的
// Textarea 标签
emoji: true,
taskList: true,
tex: true, // 默认不解析
flowChart: true, // 默认不解析
sequenceDiagram: true, // 默认不解析
},
// 目录的html
tocHtml:
`<div class="panel panel-default md-toc">
<div class="panel-heading">
<h3 class="panel-title">
<span>目录</span><a id="closeToc"><i class="glyphicon glyphicon-remove pull-right text-small" ></i></a>
</h3>
</div>
<div class="panel-body" id="toc">
我是内容
</div>
</div>`,
// 固定在右下角的 切换目录按钮
tocToolbar: `<div class="bottom-toolbar">
<a class="btn btn-lg btn-link" data-toggle="tooltip"
data-placement="top" title="目录">
<i class="glyphicon glyphicon-th-list"></i>
</a>
</div>`,
// 切换显示目录的按钮
tocToggle: function ($toc) {
$(this.tocToolbar).clone().appendTo($("body")).find(".btn").tooltip({"placement": "top"}).on("click", function () {
$($toc).toggle("slow");
});
$("#closeToc", $toc).on("click", function () {
$($toc).toggle("fast");
});
},
init: function (context) {
var module = this;
var generatorToc = !!$.ui;
$(this.selector, context).each(function (i) {
var $div = $(this);
if ($("textarea", $div).size() != 1) {
return true; // continue
}
var config = $.extend({}, module.config, $div.data())
// 生成id 以及目录的id
var id = $div.attr("id") || "editormd-" + i;
$div.attr("id", id);
config.markdown = $("textarea", $div).val();
var $toc;
if (generatorToc) {
var tocId = id + '-toc';
$toc = $(module.tocHtml).clone().find("div.panel-body").attr("id", tocId).end();
$("body").after($toc);
config.tocContainer = "#" + tocId;
}
var editor = editormd.markdownToHTML(id, config);
$div.data("editormd", editor);
if (generatorToc) {
$toc.css("height", $toc.outerHeight()).css("width", $toc.outerWidth());
module.tocToggle($toc);
$toc.draggable({});
}
});
}
};
/* 016 初始化页码 */
$nojs.pagination = {
enable: function () {
return !!$.fn.pager;
},
selector: "form ul.pagination",
init: function (context) {
$(this.selector, context).pager();
}
};
/**
* 017 为一个标签绑(一般为a或者btn)定url请求,一般为异步操作 1. 附加参数 包含在这 标签内部的 标签:<i
* class="action-param" data-key="key" data-value="val" ></i> 2. 可指定为非异步请求
* data-asyn="false" 3. 请求前的提示 data-confirm="some message" 4. 请求后的回调
* data-after="fnName" 5. 支持未来元素 6. 请求url: data-url="url"
*/
$nojs.actions = {
enable: true,
options: {
asyn: false,// 默认是非异步请求
url: "",
type: "get",
confirm: "",// 提示信息
after: $.noop()
},
paramSelector: ".action-param",// 绑定参数的元素
// 发起请求的方法
request: function (type, $e) {
var module = this;
var options = $.extend(module.options, {type: type}, $e.data());
if (!options.url) {
$.alert("需包含正确的url", "提示");
return false;
}
// 如果有提示信息,则先提示 此处使用jquery.confirm
if (options.confirm) {
common.confirm(options.confirm, commit, {});
return false;
} else {
commit();
}
// 开始提交请求
function commit() {
var data = getParams();
// 异步提交
if (options.asyn) {
$request.get(options.url, {
type: options.type,
data: data,
confirm: true
}, options.after);
} else {
// 同步提交 通过构建表单的形式
var $form = $('<form></form>').appendTo($("body"));
$form.attr("method", options.type).attr("action", options.url);
var $input = $("<input type=\"hidden\" class=\"help\"/>");
for (var k in data) {
var $param = $input.clone().attr("name", k).val(data[k]);
$form.append($param);
}
$form.submit();
$form.remove();
}
}
// 获得参数
function getParams() {
var data = {};
$(module.paramSelector, $e).each(function () {
var k = $(this).data("key");
var v = $(this).data("value");
data[k] = v;
});
return data;
}
},
init: function (context) {
for (var name in this) {
var module = this[name];
if (module && module.init) {
module.init(context);
}
}
},
// get 请求
get: {
selector: ".action-get",
init: function (context) {
$(document).on("click", this.selector, function () {
$nojs.actions.request("get", $(this));
});
}
},
post: {
selector: ".action-post",
init: function (context) {
$(document).on("click", this.selector, function () {
$nojs.actions.request("post", $(this));
});
}
},
back: {// 返回请求操作 只返回 不刷新
selector: ".action-back",
init: function (context) {
$(this.selector, context).click(function () {
windom.history.back();// 返回
// window.history.go(-1);//返回+刷新
});
}
}
};
/*
* 018 多级联动
* 使用方法:
* 父select新增如下属性:
* data-linkage="true" 表示开启多级联动
* data-linkage-url="/test/children" 表示选取子select的相对url , 后台参数为pid,返回的结果为BaseResponse List<BaseSelectModel>
* data-linkage-target="#childrenId" 表示子select选择器
*/
$nojs.linkage = {
enable: true,
selector: "[data-linkage=true]",
init: function (context) {
$(this.selector, context).each(function () {
var $parentSelect = $(this);
var url = $parentSelect.data("linkageUrl");
var target = $parentSelect.data("linkageTarget")
if (url && target && $(target, context).size() > 0) {
var $target = $(target, context);
var $first = $("option", $target);
$parentSelect.on("change", function () {
var pId = $parentSelect.val();
$target.html($first);
if (!pId) {
return;
}
$request.post(url, {data: {pid: pId}}, function (result) {
if (result && result.code == 0) {
var data = result.data;
var html;
for (var i = 0; i < data.length; i++) {
html += '<option value="'
+ data[i].code
+ '">'
+ data[i].text
+ '</option>';
}
$target.append(html);
$target.trigger("$nojs-select-initialize");// 触发目标子类的选择
}
});
}).trigger("change");
}
});
}
};
// lookup 表单的重置
$nojs.lookupReset = {
enable: true,
selector: {
form: "form.lookup",// 要重置的表单
reset: "button.reset",// 触发的按钮
control: ":input"// 要重置的对象
},
init: function (context) {
var module = this;
var $form = $(module.selector.form, context);
$(module.selector.reset, $form).on("click", function () {
$(module.selector.control, $form).val("");
$form.submit();
});
}
};
$nojs.cleanInputGroup = {
enable: true,
selector: "div.input-group .clean",
init: function (context) {
$(this.selector, context).each(function () {
$(this).on("click", function (event) {
$(this).siblings(":input").val("");
event.stopPropagation();
});
})
}
};
windom.$nojs = $nojs;
})(window, jQuery);
$(document).ready(function () {
window.$nojs(document);
});
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。