# Husky **Repository Path**: tomatoSuper/Husky ## Basic Information - **Project Name**: Husky - **Description**: 一个轻量任性的自定义表单插件 - **Primary Language**: JavaScript - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2017-03-17 - **Last Updated**: 2020-12-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ### 初始化 在项目根目录下面执行命令 npm install ### 开发环境启动命令 在根目录下面执行 $ npm run start-dev-server dev $ npm run gulp-dev ### 正式环境 在根目录下面执行 npm run build 命令执行完毕之后会在根目录下面生成 `dist` 目录,`dist` 目录下的代码直接放入 服务器下可直接运行。 scp 部署测试环境 Mac/Liunx适用 需要输入密码 scp -r /`{WorkSpace}`/esheyi-system/dist/* root@192.168.1.158:/data/tomcat4040/webapps/esheyi ### 目录结构 |--- esheyi-system | |--- bin | |__ www.js | |--- dist 资源输出目录 | |--- node_modules nodejs模块文件 | |--- routes 里面所放的 全部都是 esheyi-system 后台运行的js文件、包括REST接口调用、URL请求路径处理 | |--- src | |__ img 图片目录 | | | |__ js 前台业务相关的js文件 | | | |__ plugins 所使用的插件目录(已经集成了 amazeui 2.6.2 、jquery) | | | | | |__ external.js 三方javascript库生成的文件,目前包含lodash和moment | | | | | |__ ...other plugins | | | |__ scss 页面业务相关的scss文件 | | | | | |__ components 自定的的SASS模块文件 | | | | | |__ helper 公共SASS函数 (@function) | | | | | |__ mixins 混合(mixin) | | | | | |__ service views里面的页面对应的css,一般跟页面一一对应 | | | | | |__ vendor | | | | | |__ variables.scss 一些 sass 定义的变量、基础数据 | | | | | |__ cat.scss 入口 | | | | | --- views 动态页面目录 | |--- .gitignore | |--- app.js esheyi-system 入口文件、里面有项目的初始化配置项 | |--- gulpfile.babel.js gulp工作流配置文件 | |--- package.json | |--- README.md # documentation ### dataTable css 外部引用 ``` ``` js外部引用 ``` ``` html ```html
订单列表
``` js ```javascript var settings = { /** 数据源 */ "sAjaxSource": "./order.json", "sScrollXInner": "100%", /** 列表字段显示 */ "aoColumns": [{ "mDataProp": "id", "sTitle": "id", "sDefaultContent": "" }, { "mDataProp": "orderNo", "sTitle": "orderNo", "sDefaultContent": "" }], /** 向服务器传额外的参数 */ "fnServerParams": function(aoData) { return common.getSearchData("form",aoData); } } var options = $.extend(true, {}, _dataTableSettings, settings); $(".dataTables-example").dataTable(options); ``` ### layer [ layer 官方示例 ](http://layer.layui.com/) [ layer 弹出层文档 ](http://www.layui.com/doc/modules/layer.html) js 外部资源引用 ``` ``` ```javascript /** * 单纯的alert提示框 * number 的取值范围:-1 ~ 7 */ layer.alert('Hi,你好! 点击确认更换图标', { icon: number, shadeClose: true, title: '更换图标' }, function() { //这里是点击确认之后的回调参数 }); /** 询问框 */ layer.confirm('您是如何看待前端开发?', { btn: ['重要','奇葩'] //按钮 }, function(){ layer.msg('的确很重要', {icon: 1}); }, function(){ layer.msg('也可以这样', { time: 20000, //20s后自动关闭 btn: ['明白了', '知道了'] }); }); /** 提示层 */ layer.msg('玩命提示中'); /** 墨绿深蓝风 */ layer.alert('墨绿风格,点击确认看深蓝', { skin: 'layui-layer-molv' //样式类名 ,closeBtn: 0 }, function(){ layer.alert('偶吧深蓝style', { skin: 'layui-layer-lan' ,closeBtn: 0 ,anim: 4 //动画类型 }); }); /** 捕获页 */ layer.open({ type: 1, shade: false, title: false, //不显示标题 content: $('.layer_notice'), //捕获的元素 cancel: function(){ layer.msg('捕获就是从页面已经存在的元素上,包裹layer的结构', {time: 5000, icon:6}); } }); /** 页面层 */ layer.open({ type: 1, skin: 'layui-layer-rim', //加上边框 area: ['420px', '240px'], //宽高 content: 'html内容' }); /** 自定页 */ layer.open({ type: 1, skin: 'layui-layer-demo', //样式类名 closeBtn: 0, //不显示关闭按钮 anim: 2, shadeClose: true, //开启遮罩关闭 content: '内容' }); /** tips层 */ layer.tips('Hi,我是tips', '吸附元素选择器,如#id'); /** iframe层 */ layer.open({ type: 2, title: 'layer mobile页', shadeClose: true, shade: 0.8, area: ['380px', '90%'], content: 'http://layer.layui.com/mobile/' //iframe的url }); /** iframe窗 */ layer.open({ type: 2, title: false, closeBtn: 0, //不显示关闭按钮 shade: [0], area: ['340px', '215px'], offset: 'rb', //右下角弹出 time: 2000, //2秒后自动关闭 anim: 2, content: ['test/guodu.html', 'no'], //iframe的url,no代表不显示滚动条 end: function(){ //此处用于演示 layer.open({ type: 2, title: '很多时候,我们想最大化看,比如像这个页面。', shadeClose: true, shade: false, maxmin: true, //开启最大化最小化按钮 area: ['893px', '600px'], content: 'http://fly.layui.com/' }); } }); /** 加载层 */ var index = layer.load(0, {shade: false}); //0代表加载的风格,支持0-2 /** loading层 */ var index = layer.load(1, { shade: [0.1,'#fff'] //0.1透明度的白色背景 }); /** 小tips */ layer.tips('我是另外一个tips,只不过我长得跟之前那位稍有些不一样。', '吸附元素选择器', { tips: [1, '#3595CC'], time: 4000 }); /** prompt层 */ layer.prompt({ title: '输入任何口令,并确认', formType: 1 //prompt风格,支持0-2 }, function(pass){ layer.prompt({title: '随便写点啥,并确认', formType: 2}, function(text){ layer.msg('演示完毕!您的口令:'+ pass +' 您最后写下了:'+ text); }); }); /** tab层 */ layer.tab({ area: ['600px', '300px'], tab: [{ title: 'TAB1', content: '内容1' }, { title: 'TAB2', content: '内容2' }, { title: 'TAB3', content: '内容3' }] }); /** 相册层 */ $.getJSON('test/photos.json?v='+new Date, function(json){ layer.photos({ photos: json //格式见API文档手册页 ,anim: 5 //0-6的选择,指定弹出图片动画类型,默认随机 }); }); ``` ### validate 外部资源引用 ```javascript ``` html ```html
完整验证表单
这里写点提示的内容
请再次输入您的密码
``` js ```javascript (function() { 'use strict'; $.validator.setDefaults({ highlight: function(e) { $(e).closest(".form-group").removeClass("has-success").addClass("has-error") }, success: function(e) { e.closest(".form-group").removeClass("has-error").addClass("has-success") }, errorElement: "span", errorPlacement: function(e, r) { e.appendTo(r.is(":radio") || r.is(":checkbox") ? r.parent().parent().parent() : r.parent()) }, errorClass: "help-block m-b-none", validClass: "help-block m-b-none" }); $(document).ready(function() { var e = " "; $("#signupForm").validate({ rules: { firstname: "required", lastname: "required", username: { required: !0, minlength: 2 }, password: { required: !0, minlength: 5 }, confirm_password: { required: !0, minlength: 5, equalTo: "#password" }, email: { required: !0, email: !0 }, topic: { required: "#newsletter:checked", minlength: 2 }, agree: "required" }, messages: { firstname: e + "请输入你的姓", lastname: e + "请输入您的名字", username: { required: e + "请输入您的用户名", minlength: e + "用户名必须两个字符以上" }, password: { required: e + "请输入您的密码", minlength: e + "密码必须5个字符以上" }, confirm_password: { required: e + "请再次输入密码", minlength: e + "密码必须5个字符以上", equalTo: e + "两次输入的密码不一致" }, email: e + "请输入您的E-mail", agree: { required: e + "必须同意协议后才能注册", element: "#agree-error" } }, submitHandler: function(form) { $(form).ajaxSubmit(function(d) { /*提交成功之后的返回函数,根据返回的数据处理不同的业务逻辑*/ }); } }) }); }).call(this) ``` ### 上传(dropzone) 外部引用资源 ```html ``` ```javascript /** * 上传方法 * @param {Object} options 上传选项 * @param {String} options.url 上传url * @param {String} [options.paramName=file] 上传文件的param名 * @param {Number} [options.maxFiles=100] 最大文件数 * @param {Number} [options.maxFileSize=10] 单文件最大容量,单位MB * @param {Function} [ok] 确定按钮后的callback * @param {Function} [cancel] 关闭按钮后的callback */ common.upload(options,function(){ //点击“上传”之后回调函数 },function(){ //点击“关闭”之后的回调函数 }) ``` ### 图库(gallery) 对于上传组件的二次封装(目前仅适用于已经存在的业务逻辑,并没有一般化) ```html ``` ```javascript var options={ url:"/saveFile.do", fileFolder:{folder:"house",id:"123456"} } /** * 基于fancybox,jQuery的简单图库插件 * @param {Boolean} [options.readOnly=false] 是否只读 * @param {String} [options.type=image] 相册类型,支持image/图片和file/文件 * @param {String} [options.title=文件上传] 标题 * @param {String} options.url 上传url * @param {String} [options.paramName=file] 文件上传的参数名 * @param {String} [options.returnPathName=filePath] 返回文件路径参数名 * @param {Object} options.fileFolder 前端路径 * @param {Number} [options.maxFiles=100] 最大文件数 * @param {Number} [options.maxFileSize=10] 单文件最大容量 * @param {String[]} [options.filePaths] 已存在文件名列表 * @param {Function} [options.uploadCallback] 上传完成后的回调函数 * @param {Function} [options.deleteCallback] 删除完成后的回调函数 */ $("#gallery").gallery(options){ } // get file paths from gallery $("#gallery").gallery.getFilePaths(); ``` ### 时间轴(timeline) 外部引用资源 ```html ``` ```javascript $("#timeline").timeline([ {title:"事项2",content:"时间轴测试2",date:new Date(),addInfo:"额外信息"}, {icon:"check",title:"事项1",content:"时间轴测试1",date:new Date()} ]) ``` ### common.openInsertDialog ```javascript /** * common.openInsertDialog 是一个公共的弹框。专门用户处理 "新增页面弹框"] * 公共方法,打开新增dialog * options 参数 * url : dialog 打开的页面路径 -- 必填 * title : 打开的弹框的标题 -- 必填 * area : 弹框的宽度、高度。默认:['800px', '500px'] * btn :弹框上面的操作按钮。默认:['保存', '取消'] * sAjaxSource : 选填,如果填写之后,会把弹出框里面form表单的数据自动提交 */ common.openInsertDialog({ 'url': './agency/insertAgency.html', 'title': '添加中介公司', 'sAjaxSource': window.globalHost+'/esheyi-bp/admin/agencyInfo/save.do' }); ``` ### 省市区、板块 四级联动 ##### 基于插件 ```html ``` ##### 实现 ``` /** * 省市区、板块 四级联动 * @param {[type]} level1 [description] * @param {[type]} level2 [description] * @param {[type]} level3 [description] * @param {[type]} level4 [description] */ FourLinkage: function(level1, level2, level3, level4, checkedData) { var self = this, selectorLevel1 = level1, selectorLevel2 = level2, selectorLevel3 = level3, selectorLevel4 = level4; /** * 和3级联动同一个数据源 * @param {[type]} !self.threeLinkageData [description] * @return {[type]} [description] */ if (!self.threeLinkageData) { self.post(window.globalHost + '/esheyi-bp/admin/zoneInfo/getZoneInfoOption.do', { status: 'AVAILABLE' }).done(function(data) { self.threeLinkageData = self.transformData(data)[0]['subZone']; lv1(self.threeLinkageData); }); } else { lv1(self.threeLinkageData); } /** * 省份 * @param {[type]} data [description] * @return {[type]} [description] */ function lv1(data) { var list = [''], level1Data = data, nextLevelData = []; $.each(data, function(i, I) { if (!!checkedData && checkedData.lv1 == I.id) { nextLevelData = level1Data[i]['subZone']; list.push(''); } else { list.push(''); } }); $(selectorLevel1).html(list.join("")); $(selectorLevel1).chosen({}).off('change').on('change', function(ev, obj) { var selectedIndex = ev.currentTarget.selectedIndex; /** * 下标需要减一,因为select初始化的时候最上面有个空的option标签 */ selectedIndex--; if (!!level1Data.length) { lv2(level1Data[selectedIndex]['subZone']); } else { lv2([]); } }); lv2(nextLevelData); } /** * 城市 * @param {[type]} data [description] * @return {[type]} [description] */ function lv2(data) { var list = [''], level2Data = data, nextLevelData = []; // $(selectorLevel2).chosen("destroy").html(""); if (!!$(selectorLevel2).data('chosen')) { $(selectorLevel2).data('chosen').destroy(); } $.each(data, function(i, I) { // list.push(''); if (!!checkedData && checkedData.lv2 == I.id) { nextLevelData = level2Data[i]['subZone']; list.push(''); } else { list.push(''); } }); $(selectorLevel2).html(list.join("")); $(selectorLevel2).chosen().off('change').on('change', function(ev, obj) { var selectedIndex = ev.currentTarget.selectedIndex; /** * 下标需要减一,因为select初始化的时候最上面有个空的option标签 */ selectedIndex--; /** * 区域渲染 */ if (!!level2Data.length) { lv3(level2Data[selectedIndex]['subZone']); } else { lv3([]); } }); lv3(nextLevelData); } /** * 区域 * @param {[type]} data [description] * @return {[type]} [description] */ function lv3(data) { var list = [''], level3Data = data, nextLevelData = []; // $(selectorLevel3).chosen("destroy").html(""); if (!!$(selectorLevel3).data('chosen')) { $(selectorLevel3).data('chosen').destroy(); } $.each(data, function(i, I) { // list.push(''); if (!!checkedData && checkedData.lv3 == I.id) { nextLevelData = level3Data[i]['subZone']; list.push(''); } else { list.push(''); } }); $(selectorLevel3).html(list.join("")); $(selectorLevel3).chosen().off('change').on('change', function(ev, obj) { var selectedIndex = ev.currentTarget.selectedIndex; /** * 下标需要减一,因为select初始化的时候最上面有个空的option标签 */ selectedIndex--; if (!!level3Data.length) { lv4(level3Data[selectedIndex]['subZone']); } else { lv3([]); } }); lv4(nextLevelData); } /** * 板块 * @param {[type]} data [description] * @return {[type]} [description] */ function lv4(data) { var list = [''], level4Data = data; if (!!$(selectorLevel4).data('chosen')) { $(selectorLevel4).data('chosen').destroy(); } $.each(data, function(i, I) { // list.push(''); if (!!checkedData && checkedData.lv4 == I.id) { list.push(''); } else { list.push(''); } }); $(selectorLevel4).html(list.join("")); $(selectorLevel4).chosen().off('change').on('change', function(ev, obj) { }); !!checkedData.callback && checkedData.callback(); } } ``` ### 使用方式 ```javascript /** * 省市区、板块 四级联动 * @param {[type]} level1 [省份 选择器] 必传 * @param {[type]} level2 [城市 选择器] 必传 * @param {[type]} level3 [区域 选择器] 必传 * @param {[type]} level4 [板块 选择器] 必传 * @param {[type]} checkedData [回填数据对象] 选填 */ common.FourLinkage("form .chosen-select-zoneId1", "form .chosen-select-zoneId2", "form .chosen-select-zoneId3", "form .chosen-select-zoneId4"); ``` ### 带checked 参数回填省市区、板块四级联动 ```javascript common.FourLinkage("form .chosen-select-zoneId1", "form .chosen-select-zoneId2", "form .chosen-select-zoneId3", "form .chosen-select-zoneId4", { lv1: detailInfo.zoneId1, lv2: detailInfo.zoneId2, lv3: detailInfo.zoneId3, lv4: detailInfo.zoneId4, callback: function() { /** * 省市区、板块 联动 初始化完成之后回调函数 */ } }); ``` ### 根据“name”获取地址栏中的参数 ```javascript /** * 根据“name”获取地址栏中的参数 * @param {[type]} name [description] * @return {[type]} [description] */ getQueryString: function(name) { var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"); var r = window.location.search.substr(1).match(reg); if (r != null) return unescape(r[2]); return null; } ``` ##### 使用方式 ```javascript common.getQueryString(name); ``` ### 基于枚举数据的下拉插件 ##### 基于插件 ```html ``` ##### 实现 ```javascript /** * 基于枚举数据的下拉插件 * @param {[type]} selector [选择器] * @param {[type]} data [数据源] * @param {[type]} checked [选中的key值] * @return {[type]} [null] */ buildNormalEnumSelect: function(selector, data, checked) { var list = ['']; $.each(data, function(i, I) { if (!!checked && checked == i) { list.push(''); } else { list.push(''); } }); $(selector).html(list.join("")); $(selector).chosen({}); } ``` ##### 使用方式 ```javascript /** * 枚举下拉列表函数,能够方便的初始化下拉方法 * 参数1:选择器 * 参数2:枚举数据源 * 参数3:回填参数的key值 */ common.buildNormalEnumSelect(".chosen-select-agencyStatus", enumObject.enumJsonData['agencyStatus'], 'COOPERATING'); ``` ### 基于 ajax 远程数据源的下拉插件 ##### 基于插件 ```html ``` ##### 实现 ```javascript /** * 基于ajax后台数据源的下拉插件 * @param {[type]} options [参数] * @return {[type]} [null] */ buildNormalAjaxSelect: function(options) { var self = this; $.post(options.url, options.data).success(function(data) { var data = self.transformData(data); var list = ['']; $.each(data, function(i, I) { if (!!options.checked && options.checked == I[options.key]) { list.push(''); } else { list.push(''); } }); $(options.selector).html(list.join("")); $(options.selector).chosen({}); }); }, ``` ##### 使用方式 ```javascript /** * 初始化 销售下拉列表 * selector:选择器 * url:请求获取数据的数据源 * data:请求数据接口参数 * key: 'id' 渲染下拉列表时放在 * value:'userName' * checked:回选参数是的值,checked传入的值 会 与 data['id'] 所返回的值做一个匹配,相同那么就认为一致。回选此选项 * @type {String} */ common.buildNormalAjaxSelect({ selector: "form .chosen-select", url: window.globalHost + '/esheyi-bp/admin/user/index.do', data: { status: 'AVAILABLE' }, key: 'id', value: 'userName', checked: detailInfo.saleId }); ```