# 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
});
```