JS通用函数库
生成一个随机整数。如生成10到20间的随机整数:
var n = randInt(10, 20)
生成指定长度(cnt)的随机代码。不出现"0","1","o","l"这些易混淆字符。
示例:生成8位随机密码
var dyn_pwd = randAlphanum(8);
取名字的基础部分,如
var name = basename("/cc/ttt.asp"); // "ttt.asp"
var name2 = basename("c:\\aaa\\bbb/cc/ttt.asp", ".asp"); // "ttt"
解析url编码格式的查询字符串,返回对应的对象。
if (location.search) {
var queryStr = location.search.substr(1); // "?id=100&name=abc&val=3.14"去掉"?"号
var args = parseQuery(queryStr); // {id: 100, name: "abc", val: 3.14}
}
注意:
如果值为整数或小数,则会转成相应类型。如上例中 id为100,不是字符串"100".
将字符串转成boolean值。除"0", "1"外,还可以支持字符串 "on"/"off", "true"/"false"等。
重新加载当前页面,但不要#hash部分。
日期对象格式化字符串。
@param fmt 格式字符串。由以下组成:
yyyy - 四位年,如2008, 1999
yy - 两位年,如 08, 99
mm - 两位月,如 02, 12
dd - 两位日,如 01, 30
HH - 两位小时,如 00, 23
MM - 两位分钟,如 00, 59
SS - 两位秒,如 00, 59
支持这几种常用格式:
L - 标准日期时间,相当于 "yyyy-mm-dd HH:MM:SS"
D - 标准日期,相当于 "yyyy-mm-dd"
T - 标准时间,相当于 "HH:MM:SS"
示例:
var dt = new Date();
var dtStr1 = dt.format("D"); // "2009-10-20"
var dtStr2 = dt.format("yyyymmdd-HHMM"); // "20091020-2038"
将纯时间字符串生成一个日期对象。
var dt1 = parseTime("10:10:00");
var dt2 = parseTime("10:11");
将日期字符串转为日期时间格式。其效果相当于new Date(Date.parse(dateStr))
,但兼容性更好(例如在safari中很多常见的日期格式无法解析)
示例:
var dt1 = parseDate("2012-01-01");
var dt2 = parseDate("2012/01/01 20:00:09");
var dt3 = parseDate("2012.1.1 20:00");
为日期对象加几天/小时等。参数n为整数,可以为负数。
@param sInterval Enum. 间隔单位. d-天; m-月; y-年; h-小时; n-分; s-秒
示例:
var dt = new Date();
dt.add("d", 1); // 1天后
dt.add("m", 1); // 1个月后
dt.add("y", -1); // 1年前
dt.add("h", 3); // 3小时后
dt.add("n", 30); // 30分钟后
dt.add("s", 30); // 30秒后
@see Date.diff
计算日期到另一日期间的间隔,单位由sInterval指定(具体值列表参见Date.add).
var dt = new Date();
...
var dt2 = new Date();
var days = dt.diff("d", dt2); // 相隔多少天
@see Date.add
设置cookie值。如果只是为了客户端长时间保存值,一般建议使用 setStorage.
@see getCookie
@see delCookie
@see setStorage
取cookie值。
@see setCookie
@see delCookie
删除一个cookie项。
@see getCookie
@see setCookie
使用localStorage存储(或使用sessionStorage存储, 如果useSession=true)。
注意只能存储字符串,所以value不可以为数组,对象等,必须序列化后存储。
如果浏览器不支持Storage,则使用cookie实现.
示例:
setStorage("id", "100");
var id = getStorage("id");
delStorage("id");
示例2:对象需要序列化后存储:
var obj = {id:10, name:"Jason"};
setStorage("obj", JSON.stringify(obj));
var obj2 = getStorage("obj");
alert(obj2.name);
@see getStorage
@see delStorage
取storage中的一项。
默认使用localStorage存储,如果useSession=true,则使用sessionStorage存储。
如果浏览器不支持Storage,则使用cookie实现.
@see setStorage
@see delStorage
删除storage中的一项。
@see getStorage
@see setStorage
@param rs= {h=[header], d=[ @row ]} rs对象(RowSet)
@return arr=[ %obj ]
rs对象用于传递表格,包含表头与表内容。
函数用于将服务器发来的rs对象转成数组。
示例:
var rs = {
h: ["id", "name"],
d: [ [100, "Tom"], [101, "Jane"] ]
};
var arr = rs2Array(rs);
// 结果为
arr = [
{id: 100, name: "Tom"},
{id: 101, name: "Jane"}
];
@see rs2Hash
@see rs2MultiHash
@param rs= {h, d} rs对象(RowSet)
@return hash= {key => %obj}
示例:
var rs = {
h: ["id", "name"],
d: [ [100, "Tom"], [101, "Jane"] ]
};
var hash = rs2Hash(rs, "id");
// 结果为
hash = {
100: {id: 100, name: "Tom"},
101: {id: 101, name: "Jane"}
};
@see rs2Array
@param rs= {h, d} rs对象(RowSet)
@return hash= {key => [ %obj ]}
示例:
var rs = {
h: ["id", "name"],
d: [ [100, "Tom"], [101, "Jane"], [102, "Tom"] ]
};
var hash = rs2Hash(rs, "name");
// 结果为
hash = {
"Tom": [{id: 100, name: "Tom"}, {id: 102, name: "Tom"}],
"Jane": [{id: 101, name: "Jane"}]
};
@see rs2Hash
@see rs2Array
标识应用当前是否正在与服务端交互。一般用于自动化测试。
应用参数。
URL参数会自动加入该对象,例如URL为 http://{server}/{app}/index.html?orderId=10&dscr=上门洗车
,则该对象有以下值:
g_args.orderId=10; // 注意:如果参数是个数值,则自动转为数值类型,不再是字符串。
g_args.dscr="上门洗车"; // 对字符串会自动进行URL解码。
此外,框架会自动加一些参数:
@var g_args._app ?="user" 应用名称,由setApp({appName})指定。
@see parseQuery URL参数通过该函数获取。
应用全局共享数据。
在登录时,会自动设置userInfo属性为个人信息。所以可以通过 g_data.userInfo==null 来判断是否已登录。
@key g_data.userInfo
应用配置项。
设置应用的基本路径, 应以"/"结尾.
整数排序. 用于datagrid column sorter:
<th data-options="field:'id', sortable:true, sorter:intSort">编号</th>
小数排序. 用于datagrid column sorter:
<th data-options="field:'score', sortable:true, sorter:numberSort">评分</th>
取符合条件(fn)的对象,一般可使用$.closest替代
中止之后的调用, 直接返回.
和使用$.data()差不多,更好用一些. 例:
$(o).jdata().hello = 100;
$(o).jdata({hello:100, world:200});
取符合条件(expr)的对象,一般可使用$.closest替代
@return jquery tr对象
@param row {\@cols}, col: {useTh?=false, html?, \%css?, \%attr?, \%on?}
根据row结构构造jQuery tr对象。
筋斗云前端框架-Web应用桌面版
此框架实现与筋斗云服务端接口的无缝整合。在界面上以jquery-easyui库为基础展示列表、Tab页等。
参考应用 web/store.html - 商户管理端应用。
设计模式:列表页与详情页。
以订单对象Order为例:为订单对象增加“列表页”和“详情页”。
列表页应包含分页功能,默认只显示“未完成”订单。
点击列表中一项(一个订单),可显示详情页,即订单详情,并可进行查找、更新等功能。
@key #my-pages 包含所有页面、对话框定义的容器。
@key my-obj DOM属性,标识服务端对象
@key my-initfn DOM属性,标识页面或对话框的初始化函数,首次显示页面/对话框时调用。
列表页使用逻辑页面定义如下(放在div#my-pages之下),它最终展示为一个tab页:
<div id="my-pages" style="display:none">
...
<div class="pageOrder" title="订单管理" my-initfn="initPageOrder">
<table id="tblOrder" style="width:auto;height:auto">
<thead><tr>
<th data-options="field:'id', sortable:true, sorter:intSort">订单号</th>
<th data-options="field:'userPhone', sortable:true">用户联系方式</th>
<th data-options="field:'createTm', sortable:true">创建时间</th>
<th data-options="field:'status', formatter:OrderColumns.statusStr, styler:OrderColumns.statusStyler, sortable:true">状态</th>
<th data-options="field:'dscr', sortable:true">描述</th>
<th data-options="field:'cmt'">用户备注</th>
</tr></thead>
</table>
</div>
</div>
注意:
详情页展示为一个对话框,也将它也放在 div#my-pages 下。定义如下(此处为展示原理已简化):
<div id="dlgOrder" my-obj="Ordr" my-initfn="initDlgOrder" title="用户订单" style="width:520px;height:500px;">
<form method="POST">
订单号:<input name="id" disabled></td>
订单状态:
<select name="status" style="width:150px">
<option value=""> </option>
<option value="CR">未付款</option>
<option value="PA">待服务(已付款)</option>
<option value="ST">正在服务</option>
<option value="RE">已服务(待评价)</option>
<option value="RA">已评价</option>
<option value="CA">已取消</option>
</select>
用户备注:<textarea name="cmt" rows=3 cols=30></textarea>
</form>
<div>
注意:
@see WUI.showObjDlg
@see WUI.showDlg
以上定义了订单对象的列表页和详情页,围绕对象"Order", 按规范,我们定义了以下名字:
<a href="#pageOrder" class="easyui-linkbutton" icon="icon-ok">订单管理</a><br/><br/>
打开页面后,页面的生存周期如下:
@key pagecreate,pageshow,pagedestroy 页面事件
@key wui-pageName 属性:页面名
@key .wui-page 页面类
订单列表页的初始化,需要将列表页(代码中jpage)、列表(代码中jtbl)与详情页(代码中jdlg)关联起来,实现对话增删改查各项功能。
function initPageOrder()
{
var jpage = $(this);
var jtbl = jpage.find("#tblOrder");
var jdlg = $("#dlgOrder");
// 注意:此处定义显示哪些缺省操作按钮:
// r-refresh/刷新, f-find/查找, s-set/更新。参考 WUI.dg_toolbar.
// 如果不定义则所有操作按钮都展示。
jtbl.jdata().toolbar = "rfs";
// 当天订单
var query1 = {cond: "createTm between '" + new Date().format("D") + "' and '" + new Date().addDay(1).format("D") + "'"};
// 显示待服务/正在服务订单
var query2 = {cond: "status='CR' OR status='PA' OR status='ST'"};
function getTodoOrders()
{
WUI.reload(jtbl, null, query2);
}
function getTodayOrders()
{
WUI.reload(jtbl, null, query1);
}
var btn1 = {text: "今天订单", iconCls:'icon-search', handler: getTodayOrders};
var btn2 = {text: "所有未完成", iconCls:'icon-search', handler: getTodoOrders};
var dgOpt = {
// 设置查询接口
url: makeUrl(["Ordr", "query"], {res:"*,createTm,userPhone"}),
// 设置缺省查询条件
queryParams: query1,
// 设置工具栏上的按钮,并与对话框jdlg关联。
toolbar: WUI.dg_toolbar(jtbl, jdlg, "-", btn1, btn2),
// 双击一行,应展示详情页对话框
onDblClickRow: WUI.dg_dblclick(jtbl, jdlg)
};
jtbl.datagrid(dgOpt);
}
@see WUI.showPage
@see WUI.dg_toolbar
@see WUI.dg_dblclick
@see WUI.makeUrl
@key example-dialog
默认对话框中由于设定了底层对象(my-obj)及属性关联(form中带name属性的组件,已关联对象属性),因而可自动显示和提交数据。
特别地,某些属性不宜直接展示,例如属性“人物头像”,服务器存储的是图片id(picId),而展示时应显示为图片而不是一个数字;
或者如“权限列表”属性,服务器存储的是逗号分隔的一组权限比如"emp,mgr",而展示时需要为每项显示一个勾选框。
这类需求就需要编码控制。
相关事件:
@see beforeshow show 对话框中form显示前后
@see initdata loaddata 对话框中form加载数据前后
@see savedata retdata 对话框中form保存数据前后
对话框类名:
@see .wui-dialog
function initDlgOrder()
{
var jdlg = $(this);
var jfrm = jdlg.find("form");
jfrm.on("beforeshow", function(ev, formMode) {
jdlg.find(".forFind").toggle(formMode == FormMode.forFind);
jdlg.find(".notForFind").toggle(formMode != FormMode.forFind);
})
.on("loaddata", function (ev, data, formMode) {
// data是列表页中一行对应的数据,框架自动根据此数据将对应属性填上值。
// 如果界面上展示的字段无法与属性直接对应,可以在该事件回调中设置。
// hiddenToCheckbox(jfrm.find("#divPerms"));
})
.on("savedata", function (ev, formMode, initData) {
// 在form提交时,所有带name属性且不带disabled属性的对象值会被发往服务端。
// 此事件回调可以设置一些界面上无法与属性直接对应的内容。
// checkboxToHidden(jfrm.find("#divPerms"));
})
.on("retdata", function (ev, data, formMode) {
var formMode = jdlg.jdata().mode;
if (formMode == FormMode.forAdd) {
alert('返回ID: ' + data);
}
};
}
@see checkboxToHidden (有示例)
@see hiddenToCheckbox
@see imgToHidden
@see hiddenToImg (有示例)
框架中,对象列表通过easyui-datagrid来展现。
注意:由于历史原因,我们没有使用datagrid中的编辑功能。
参考:http://www.jeasyui.net/plugins/183.html
教程:http://www.jeasyui.net/tutorial/148.html
@key datagrid.formatter
@key datagrid.styler
示例一:显示名称及颜色
订单状态字段定义为:
status:: Enum. 订单状态。CR-新创建,RE-已服务,CA-已取消.
在显示时,要求显示其中文名称,且根据状态不同,显示不同的背景颜色。
在table中设置formatter与styler选项:
<div class="pageOrder" title="订单管理" my-initfn="initPageOrder">
<table id="tblOrder" style="width:auto;height:auto">
<thead><tr>
<th data-options="field:'id', sortable:true, sorter:intSort">订单号</th>
...
<th data-options="field:'status', formatter:OrderColumns.statusStr, styler:OrderColumns.statusStyler, sortable:true">状态</th>
</tr></thead>
</table>
</div>
formatter用于控制Cell中的HTML标签,styler用于控制Cell自己的CSS style.
在JS中定义函数:
var OrderColumns = {
statusStr: function (value, row) {
var OrderStatusStr = {
CR: "未付款",
RE: "已服务",
CA: "已取消"
};
return OrderStatusStr[value] || value;
},
statusStyler: function (value, row) {
var colors = {
CR: "#000",
RE: "#0f0",
CA: "#ccc"
};
var color = colors[value];
if (color)
return "background-color: " + color;
},
...
}
注意:
示例二:下面是一些通用的例子,特别是生成对象链接经常会用到。
var Formatter = {
// 显示数值
number: function (value)
{
return parseFloat(value);
},
// 显示一张或一组图片链接,点一个链接可以在新页面上显示原图片
pics: function (value) {
if (value == null)
return "(无图)";
return value.replace(/(\d+),?/g, function (ms, picId) {
var url = makeUrl("att", {thumbId: picId});
return "<a target='_black' href='" + url + "'>" + picId + "</a> ";
});
},
// 订单编号,显示为一个链接,点击就打开订单对话框该订单。
orderId: function (value) {
if (value != null)
{
return makeLinkTo("#dlgOrder", value, value);
}
}
};
@see makeLinkTo 生成对象链接,以便点击时打开该对象的详情对话框。
@key datagrid.sortable
@key datagrid.sorter
使用sortable:true指定该列可排序(可点击列头排序),用sorter指定排序算法(缺省是字符串排序),例如:
<th data-options="field:'name', sortable:true">姓名</th>
<th data-options="field:'id', sortable:true, sorter:intSort">编号</th>
<th data-options="field:'score', sortable:true, sorter:numberSort">评分</th>
框架提供了intSort,numberSort这些函数用于整数排序或小数排序。也可以自定义函数。示例:
function intSort(a, b)
{
return parseInt(a) - parseInt(b);
}
注意:
@see intSort numberSort
如果打开数据表就希望按某一列排序,可设置:
jtbl.datagrid({
...
sortName: 'id',
sortOrder: 'desc'
});
手工点击列标题栏排序,会自动修改这两个属性。
在添加数据时,如果当前sortOrder是倒序,则新数据显示在表格当前页的最前面,否则显示在最后。
框架对datagrid还做了以下缺省设置:
默认开启datagrid的分页功能。每页缺省显示20条数据。可通过datagrid选项自行重新定义,如:
jtbl.datagrid({
...
pageSize: 20,
pageList: [20,30,50] // 在分页栏中可以选择分页大小
});
如果需要禁用分页,可以设置:
jtbl.datagrid({
url: makeUrl("Ordr.query", {"_pagesz": 9999}), // 定义很大的pagesz, 一次取出所有
pagination: false, // 禁用分页组件
...
});
示例:下拉框中显示员工列表 (Choose-from-list / 关联选择框)
@see jQuery.fn.mycombobox
@see hiddenToImg (有示例)
@see imgToHidden
@see hiddenToCheckbox
@see checkboxToHidden (有示例)
例如设计有商品表Item, 每个商品属于特定的商户:
@Item: id, storeId, name
storeId:: Integer. 商品所属商户编号。
也就是说,商户包含商品。要展现商品,可将它放在商户层次之下。
可以这样设计用户操作:在商户列表上增加一个按钮“查看商品”,点击后打开一个新的列表页,显示该商户的商品列表。
定义两个列表页:
<div class="pageStore" title="商户列表" my-initfn="initPageStore">
</div>
<div class="pageItem" title="商户商品" my-initfn="initPageItem">
</div>
为这两个列表页定义初始化函数:
// 商户列表页
function initPageStore()
{
function showItemPage()
{
var row = jtbl.datagrid('getSelected');
if(row == null){
alert("您需要选择需要操作的行");
return;
}
// !!! 调用showPage显示新页 !!!
WUI.showPage("pageItem", "商户商品-" + row.name, [row.id]);
// 要使每个商户都打开一个商品页面而不是共享一个页面,必须保证第二个参数(页面标题)根据商户不同而不一样。
// 第三个参数是传给该页面初始化函数的参数列表,是一个数组。
}
var btn1 = {text: "查看商品", iconCls: "icon-search", handler: showPageCloseOrder};
...
jtbl.datagrid({
...
toolbar: WUI.dg_toolbar(jtbl, jdlg, btn1),
});
}
// 商品列表页,注意有一个参数storeId, 并在查询时使用到它。
function initPageItem(storeId)
{
jtbl.datagrid({
// 用参数storeId过滤
url: makeUrl("Item.query", {cond: "storeId=" + storeId}),
...
});
}
注意:
调用WUI.showPage时,除了指定页面名,还指定了页面标题(第二参数)和页面初始化参数(第三参数, 一定是一个数组):
WUI.showPage("pageItem", "商户商品-" + row.name, [row.id]);
显然,第二个参数随着商户名称不同而不同,这保证了不同商户打开的商品页面不会共用。
在商品页面初始化时,第三参数将传递给初始化函数:
function initPageItem(storeId) // storeId=row.id
@see WUI.showPage
以群发短信功能为例。
假定服务端已有以下接口:
sendSms(phone, content)
phone:: 手机号
content:: 发送内容
注意:每个带name属性的组件对应接口中的参数。
<div id="dlgSendSms" title="群发短信" style="width:500px;height:300px;">
<form method="POST">
手机号:<input name="phone" data-options="required:true">
发送内容: <textarea rows=5 cols=30 name="content"></textarea>
</form>
</div>
可以调用WUI.showDlg,写一个显示对话框的函数:
function showDlgSendSms()
{
var jdlg = $("#dlgSendSms");
WUI.showDlg(jdlg, {
url: makeUrl("sendSms"),
onOk: function (data) {
WUI.closeDlg(jdlg);
app_show('操作成功!');
}
});
}
在showDlg的选项url中指定了接口为"sendSms"。操作成功后,显示一个消息。
@see WUI.showDlg
@see app_show
除了直接调用该函数显示对话框外,还有一种更简单的通过a标签href属性指定打开对话框的做法,如:
<a href="?showDlgSendSms" class="easyui-linkbutton" icon="icon-ok">群发短信</a><br/><br/>
点击该按钮,即调用了showDlgSendSms函数打开对话框。
@alias enterWaiting ()
TODO: require #block
@alias leaveWaiting
@alias makeUrl
生成对后端调用的url.
var params = {id: 100};
var url = makeUrl("Ordr.set", params);
注意:调用该函数生成的url在结尾有标志字符串"zz=1", 如"../api.php/login?_app=user&zz=1"
@alias callSvr
@param ac String. action, 交互接口名. 也可以是URL(比如由makeUrl生成)
@param params Object. URL参数(或称HTTP GET参数)
@param postParams Object. POST参数. 如果有该参数, 则自动使用HTTP POST请求(postParams作为POST内容), 否则使用HTTP GET请求.
@param fn Function(data). 回调函数, data参考该接口的返回值定义。
@param userOptions 用户自定义参数, 会合并到$.ajax调用的options参数中.可在回调函数中用"this.参数名"引用.
@return XMLHttpRequest (XHR) 与$.ajax返回相同。
常用userOptions:
例:
callSvr("logout");
callSvr("logout", api_logout);
callSvr("login", {wantAll:1}, api_login);
callSvr("info/hotline.php", {q: '大众'}, api_hotline);
// 也兼容使用makeUrl的旧格式如:
callSvr(makeUrl("logout"), api_logout);
callSvr(makeUrl("logout", {a:1}), api_logout);
callSvr("User.get", function (data) {
if (data === false) { // 仅当设置noex且服务端返回错误时可返回false
return;
}
foo(data);
}, null, {noex:1});
callSvr支持FormData对象,可用于上传文件等场景。示例如下:
@key example-upload
HTML:
file: <input id="file1" type="file" multiple>
<button type="button" id="btn1">upload</button>
JS:
jpage.find("#btn1").on('click', function () {
var fd = new FormData();
$.each(jpage.find('#file1')[0].files, function (i, e) {
fd.append('file' + (i+1), e);
});
callSvr('upload', api_upload, fd);
function api_upload(data) { ... }
});
@alias callSvrSync
@return data 原型规定的返回数据
同步模式调用callSvr.
@see WUI.callSvr
@alias app_alert
@param type String. "i"|"e"|"w"
@param fn Function(). 用户点击确定后的回调。
使用jQuery easyui弹出提示对话框.
@alias app_confirm
@param fn Function(). 用户点击确定后的回调。
使用jQuery easyui弹出确认对话框.
@alias app_show
使用jQuery easyui弹出对话框.
@alias makeLinkTo
生成一个链接的html代码,点击该链接可以打开指定对象的对话框。
示例:根据订单号,生成一个链接,点击链接打开订单详情对话框。
var orderId = 101;
var html = makeLinkTo("#dlgOrder", orderId, "订单" + orderId);
@key .my-combobox 关联选择框
@var ListOptions 定义关联选择框的数据源
@param force ?=false 如果为true, 则调用时强制重新初始化。默认只初始化一次。
关联选择框组件。
用法:先定义select组件:
<select name="empId" class="my-combobox" data-options="valueField: 'id', ..."></select>
通过data-options可设置选项: { valueField, textField, url, formatter(row), loadFilter(data) }
初始化:
$(".my-combobox").mycombobox();
注意:使用WUI.showDlg显示的对话框中如果有.my-combobox组件,会在调用WUI.showDlg时自动初始化,无须再调用上述代码。
特性:
例如,在订单上设计有empId字段:
@Ordr: id, ... empId
empId:: Integer. 员工编号,关联Employee.id字段。
在显示订单详情对话框时,这列显示为“分派给员工”,是一个列出所有员工的下拉列表框,可以这样写:
<tr>
<td>分派给</td>
<td><select name="empId" class="my-combobox" data-options="valueField:'id',textField:'name',url:makeUrl('Employee.query', {wantArray:1})"></select></td>
</tr>
为了精确控制返回字段与显示格式,data-options可能更加复杂,一般建议写一个返回这些属性的函数,像这样:
<td><select name="empId" class="my-combobox" data-options="ListOptions.Emp()"></select></td>
习惯上,可以把函数统一放在ListOptions变量中:
var ListOptions = {
// ListOptions.Emp()
Emp: function () {
var opts = {
valueField: "id",
textField: "name",
url: makeUrl('Employee.query', {
res: 'id,name,uname',
cond: 'storeId=' + g_data.userInfo.storeId,
wantArray:1
}),
formatter: function (row) { return row.name + '(' + row.uname + ')'; }
};
return opts;
},
...
};
另一个例子:在返回列表后,可通过loadFilter修改列表,例如添加一项:
<select name="brandId" class="my-combobox" data-options="ListOptions.Brand()" ></select>
JS代码ListOptions.Brand:
var ListOptions = {
...
// ListOptions.Brand()
Brand: function () {
var opts = {
valueField: 'id',
textField:'name',
url:makeUrl('queryBrand', {wantArray:1}),
loadFilter: function(data) {
data.unshift({id:'0', name:'所有品牌'});
return data;
}
};
return opts;
}
};
临时reload一下,完事后恢复原url
@param rowData must be the original data from table row
@param pageName 由page上的class指定。
@param title ? 如果未指定,则使用page上的title属性.
@param paramArr ? 调用initfn时使用的参数,是一个数组。
新页面以title作为id。
注意:每个页面都是根据pages下相应pageName复制出来的,显示在一个新的tab页中。相同的title当作同一页面。
初始化函数由page上的my-initfn属性指定。
page定义示例:
<div id="my-pages" style="display:none">
<div class="pageHome" title="首页" my-initfn="initPageHome"></div>
</div>
page调用示例:
WUI.showPage("pageHome");
WUI.showPage("pageHome", "首页");
WUI.showPage("pageHome", "首页2");
@param opt ?={url, buttons, noCancel=false, okLabel="确定", cancelLabel="取消", modal=true, reset=true, validate=true, data, onOk, onSubmit, onAfterSubmit}
特殊class my-reset: 当执行form reset时会将内容清除. (适用于在forSet/forLink模式下添加显示内容, 而在forFind/forAdd模式下时清除内容)
<div class="my-reset">...</div>
hidden上的特殊property noReset: (TODO)
在dialog的form中将触发以下事件:
@key beforeshow Function(ev, formMode) form显示前事件.
@key show Function(ev, formMode) form显示事件.
@key initdata Function(ev, data, formMode) form加载数据前,可修改要加载的数据即data
@key loaddata Function(ev, data, formMode) form加载数据后,一般用于将服务端数据转为界面显示数据
@key savedata Function(ev, formMode, initData) form提交前事件,用于将界面数据转为提交数据. 返回false或调用ev.preventDefault()可阻止form提交。
@key retdata Function(ev, data, formMode) form提交后事件,用于处理返回数据
调用此函数后,对话框将加上以下CSS Class:
@key .wui-dialog 标识WUI对话框的类名。
@see example-dialog 在对话框中使用事件
@param kvList {key=>value}, 键值对,值中支持操作符及通配符。也支持格式 [ [key, value] ], 这时允许key有重复。
根据kvList生成BPQ协议定义的{obj}.query的cond参数。
例如:
var kvList = {phone: "13712345678", id: ">100", addr: "上海*", picId: "null"};
WUI.getQueryCond(kvList);
有多项时,每项之间以"AND"相连,以上定义将返回如下内容:
"phone='13712345678' AND id>100 AND addr LIKE '上海*' AND picId IS NULL"
示例二:
var kvList = [ ["phone", "13712345678"], ["id", ">100"], ["addr", "上海*"], ["picId", "null"] ];
WUI.getQueryCond(kvList); // 结果同上。
设置值时,支持以下格式:
支持简单的and/or查询,但不支持在其中使用括号:
在详情页对话框中,切换到查找模式,在任一输入框中均可支持以上格式。
根据键值对生成BQP协议中{obj}.query接口需要的cond参数.
示例:
WUI.getQueryParam({phone: '13712345678', id: '>100'})
返回
{cond: "phone='13712345678' AND id>100"}
@see WUI.getQueryCond
@param id String. mode=link时必设,set/del如缺省则从关联的jtbl中取, add/find时不需要
@param jdbl Datagrid. dialog/form关联的datagrid -- 如果dlg对应多个tbl, 必须每次打开都设置
事件参考:
@see WUI.showDlg
设置easyui-datagrid上toolbar上的按钮。缺省支持的按钮有r(refresh), f(find), a(add), s(set), d(del), 可通过以下设置方式修改:
// jtbl.jdata().toolbar 缺省值为 "rfasd"
jtbl.jdata().toolbar = "rfs"; // 没有a-添加,d-删除
如果要添加自定义按钮,可通过button_lists一一传递.
示例:添加两个自定义按钮查询“今天订单”和“所有未完成订单”。
function getTodayOrders()
{
var queryParams = WUI.getQueryParam({comeTm: new Date().format("D")});
WUI.reload(jtbl, null, queryParams);
}
// 显示待服务/正在服务订单
function getTodoOrders()
{
var queryParams = {cond: "status=" + OrderStatus.Paid + " or status=" + OrderStatus.Started};
WUI.reload(jtbl, null, queryParams);
}
var btn1 = {text: "今天订单", iconCls:'icon-search', handler: getTodayOrders};
var btn2 = {text: "所有未完成", iconCls:'icon-search', handler: getTodoOrders};
// 默认显示当天订单
var queryParams = WUI.getQueryParam({comeTm: new Date().format("D")});
var dgOpt = {
url: makeUrl(["Ordr", "query"]),
queryParams: queryParams,
pageList: ...
pageSize: ...
// "-" 表示按钮之间加分隔符
toolbar: WUI.dg_toolbar(jtbl, jdlg, btn1, "-", btn2),
onDblClickRow: WUI.dg_dblclick(jtbl, jdlg)
};
jtbl.datagrid(dgOpt);
设置双击datagrid行的回调,功能是打开相应的dialog
使用.easyui-linkbutton时,其中的a[href]字段会被框架特殊处理:
<a href="#pageHome" class="easyui-linkbutton" icon="icon-ok">首页</a>
<a href="?showDlgSendSms" class="easyui-linkbutton" icon="icon-ok">群发短信</a>
也可以使用 data-type="easyui-linkbutton", 如
<a href="#pageHome" data-type="easyui-linkbutton" icon="icon-ok">首页</a>
@param onHandleLogin Function(data). 调用后台login()成功后的回调函数(里面使用this为ajax options); 可以直接使用WUI.handleLogin
@param reuseCmd String. 当session存在时替代后台login()操作的API, 如"User.get", "Employee.get"等, 它们在已登录时返回与login相兼容的数据. 因为login操作比较重, 使用它们可减轻服务器压力.
@return Boolean. true=登录成功; false=登录失败.
该函数一般在页面加载完成后调用,如
function main()
{
WUI.setApp({
appName: APP_NAME,
title: APP_TITLE,
onShowLogin: showDlgLogin
});
WUI.tryAutoLogin(WUI.handleLogin, "whoami");
}
$(main);
@param data 调用API "login"成功后的返回数据.
处理login相关的操作, 如设置g_data.userInfo, 保存自动登录的token等等.
@param app= {appName?=user, title?="客户端", onShowLogin, pageHome?="pageHome"}
@param dontReload 如果非0, 则注销后不刷新页面.
注销当前登录, 成功后刷新页面(除非指定dontReload=1)
@param jp jquery结点
@param sep ?=',' 分隔符,默认为逗号
用于在对象详情对话框中,以一组复选框(checkbox)来对应一个逗号分隔式列表的字段。
例如对象Employee中有一个“权限列表”字段perms定义如下:
perms:: List(perm)。权限列表,可用值为: item-上架商户管理权限, emp-普通员工权限, mgr-经理权限。
现在以一组checkbox来在表达perms字段,希望字段中有几项就将相应的checkbox选中,例如值"emp,mgr"表示同时具有emp与mgr权限,显示时应选中这两项。
定义HTML如下:
<div id="dlgEmployee" my-obj="Employee" my-initfn="initDlgEmployee" title="商户员工">
...
<div id="divPerms">
<input type="hidden" name="perms">
<label><input type="checkbox" value="item">上架商品管理</label><br>
<label><input type="checkbox" value="emp" checked>员工:查看,操作订单(默认)</label><br>
<label><input type="checkbox" value="mgr">商户管理</label><br>
</div>
</div>
注意:
在JS中调用如下:
function initDlgEmployee()
{
var jdlg = $(this);
var jfrm = jdlg.find("form");
jfrm.on("loaddata", function (ev, data) {
// 显示时perms字段自动存在hidden对象中,通过调用 hiddenToCheckbox将相应的checkbox选中
hiddenToCheckbox(jfrm.find("#divPerms"));
})
.on("savedata", function (ev) {
// 保存时收集checkbox选中的内容,存储到hidden对象中。
checkboxToHidden(jfrm.find("#divPerms"));
});
}
@see hiddenToCheckbox
@param jp jquery结点
@param sep ?=',' 分隔符,默认为逗号
用于在对象详情对话框中,以一组复选框(checkbox)来对应一个逗号分隔式列表的字段。
@see checkboxToHidden (有示例)
用于在对象详情对话框中,展示关联图片字段。图片可以为单张或多张。
除显示图片外,也可以展示其它用户上传的文件,如视频、文本等。
以下是一个带图片的商户表设计,里面有两个字段picId与pics,一个显示单张图片,一个显示一组图片。
@Store: id, name, picId, pics
picId:: Integer. 商户头像。
pics:: List(Integer). 商户图片列表,格式如"101,102,103".
要显示单张图片,可编写HTML如下:
<div id="dlgStore" my-obj="Store" title="商户" my-initfn="initDlgStore">
...
<tr>
<td>商户头像</td>
<td id="divStorePicId">
<input name="picId" style="display:none">
<div class="imgs"></div>
<input type="file" accept="image/*" onchange="onChooseFile.apply(this)">
</td>
</tr>
</div>
注意:
如果不需要压缩缩略图,则可在jp上设置属性 wui-nothumb, 如
<td id="divStorePicId" wui-nothumb>
...
</td>
@key wui-nothumb
要显示多张图片,可编写HTML如下:
<tr>
<td>门店照片</td>
<td id="divStorePics">
<input name="pics" style="display:none">
<div class="imgs"></div>
<input type="file" accept="image/*" multiple onchange="onChooseFile.apply(this)">
<p>(图片上点右键,可以删除图片等操作)</p>
</td>
</tr>
为了可以做删除图片等操作,可以在对话框中再加个右键菜单,比如
<div id="mnuPics">
<div id="mnuDelPic">删除图片</div>
</div>
JS逻辑如下:
function initDlgStore()
{
var jdlg = $(this);
var jmenu = jdlg.find("#mnuPics");
var jfrm = jdlg.find("form");
jfrm.on("loaddata", function (ev, data) {
// 加载图片
hiddenToImg(jfrm.find("#divStorePics"));
hiddenToImg(jfrm.find("#divStorePicId"));
})
.on("savedata", function (ev) {
// 保存图片
imgToHidden(jfrm.find("#divStorePics"));
imgToHidden(jfrm.find("#divStorePicId"));
});
// 设置右键菜单,比如删除图片
var curImg;
jmenu.menu({
onClick: function (item) {
var jimg = $(curImg);
switch (item.id) {
case "mnuDelPic":
jimg.remove();
break;
}
}
});
jdlg.on("contextmenu", "img", function (ev) {
ev.preventDefault();
jmenu.menu('show', {left: ev.pageX, top: ev.pageY});
curImg = this;
});
}
@key wui-nopic
以上传视频文件为例,HTML代码如下:
<td>上传素材视频</td>
<td id="divVideoFile" wui-nopic>
<input name="attId" style="display:none">
<div class="imgs"></div>
<input class="videoFile" type="file">
</td>
通过添加属性"wui-nopic", 在.imgs区域内显示文件链接而非图片。其它JS代码与处理图片无异。
@see imgToHidden
@see onChooseFile
用于在对象详情对话框中,展示关联图片字段。图片可以为单张或多张。
会先调用upload(fmt=raw_b64)接口保存所有改动的图片,然后将picId存储到hidden字段中。
@see hiddenToImg 有示例
与hiddenToImg/imgToHidden合用,在对话框上显示一个图片字段。
在文件输入框中,选中一个文件后,调用此方法,可将图片压缩后显示到指定的img标签中(div.imgs)。
使用lrz组件进行图片压缩,最大宽高不超过1280px。然后以base64字串方式将图片显示到一个img组件中。
TODO: 添加图片压缩参数,图片框显示大小等。
@see hiddenToImg
在详情页对话框中,以某字段作为查询条件来查询。
@param o 当前对象。一般在onclick事件中调用时,直接填写this.
@param param 查询参数,如 {userPhone: "13712345678"},可以指定多个参数。
示例:在订单表中,显示用户手机号,边上再增加一个按钮“查询该手机所有订单”,点击就以当前显示的手机号查询所有订单:
<div id="dlgOrder" my-obj="Ordr" my-initfn="initDlgOrder" title="用户订单" style="padding:20px 40px 20px 40px;width:520px;height:500px;">
<form method="POST">
用户手机号 <input name="userPhone" class="easyui-validatebox" data-options="validType:'usercode'">
<input class="notForFind" type=button onClick="searchField(this, {userPhone: this.form.userPhone.value});" value="查询该手机所有订单">
</form>
</div>
@see WUI.getQueryCond 值支持比较运行符等多种格式,可参考这里定义。