API参考 - 筋斗云前端(桌面Web版)

最后更新:2016-12-14

Modules

common.js (module)

WUI (module)


Keywords

#my-pages (key)

$.getScriptWithCache (fn)

.easyui-linkbutton (key)

.my-combobox (key)

.wui-dialog (key)

.wui-page (key)

BASE_URL (var)

Date.add (fn)

Date.addDay (fn)

Date.addHours (fn)

Date.addMin (fn)

Date.addMonth (fn)

Date.diff (fn)

Date.format (fn)

IsBusy (var)

ListOptions (var)

Plugins (class)

Plugins.exists (fn)

Plugins.list (fn)

WUI (module)

WUI.app_alert (fn)

WUI.app_confirm (fn)

WUI.app_show (fn)

WUI.callSvr (fn)

WUI.callSvrSync (fn)

WUI.closeDlg (fn)

WUI.dg_dblclick (fn)

WUI.dg_toolbar (fn)

WUI.enterWaiting (fn)

WUI.getQueryCond (fn)

WUI.getQueryParam (fn)

WUI.handleLogin (fn)

WUI.initClient (fn)

WUI.leaveWaiting (fn)

WUI.logout (fn)

WUI.m_app (var)

WUI.makeLinkTo (fn)

WUI.makeUrl (fn)

WUI.reload (fn)

WUI.reloadRow (fn)

WUI.reloadTmp (fn)

WUI.setApp (fn)

WUI.showDlg (fn)

WUI.showObjDlg (fn)

WUI.showPage (fn)

WUI.tryAutoLogin (fn)

app_abort (fn)

app_alert (alias)

app_confirm (alias)

app_show (alias)

assert (fn)

basename (fn)

beforeshow (key)

callSvr (alias)

callSvrSync (alias)

checkboxToHidden (fn)

common.js (module)

datagrid.formatter (key)

datagrid.sortable (key)

datagrid.sorter (key)

datagrid.styler (key)

delCookie (fn)

delStorage (fn)

enterWaiting (alias)

example-dialog (key)

example-upload (key)

g_args (var)

g_args._app (var)

g_cfg (var)

g_data (var)

g_data.userInfo (key)

getAncestor (fn)

getCookie (fn)

getStorage (fn)

hiddenToCheckbox (fn)

hiddenToImg (fn)

imgToHidden (fn)

initdata (key)

intSort (fn)

jQuery.fn.getAncestor (fn)

jQuery.fn.jdata (fn)

jQuery.fn.mycombobox (fn)

leaveWaiting (alias)

loaddata (key)

makeLinkTo (alias)

makeUrl (alias)

my-initfn (key)

my-obj (key)

numberSort (fn)

onChooseFile (fn)

pagecreate,pageshow,pagedestroy (key)

parseDate (fn)

parseQuery (fn)

parseTime (fn)

randAlphanum (fn)

randInt (fn)

reloadSite (fn)

retdata (key)

row2tr (fn)

rs2Array (fn)

rs2Hash (fn)

rs2MultiHash (fn)

savedata (key)

searchField (fn)

setCookie (fn)

setStorage (fn)

show (key)

tobool (fn)

wui-nopic (key)

wui-nothumb (key)

wui-pageName (key)


@module common.js

JS通用函数库


@fn randInt(from, to)

生成一个随机整数。如生成10到20间的随机整数:

var n = randInt(10, 20)

@fn randAlphanum(cnt)

生成指定长度(cnt)的随机代码。不出现"0","1","o","l"这些易混淆字符。

示例:生成8位随机密码

var dyn_pwd = randAlphanum(8);

@fn basename(name, ext?)

取名字的基础部分,如

var name = basename("/cc/ttt.asp"); // "ttt.asp"
var name2 = basename("c:\\aaa\\bbb/cc/ttt.asp", ".asp"); // "ttt"

@fn assert(cond, dscr?)


@fn parseQuery(str)

解析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".


@fn tobool(v)

将字符串转成boolean值。除"0", "1"外,还可以支持字符串 "on"/"off", "true"/"false"等。


@fn reloadSite()

重新加载当前页面,但不要#hash部分。


@fn Date.format(fmt?=L)

日期对象格式化字符串。

@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"

@fn Date.addDay(n)


@fn Date.addHours(n)


@fn Date.addMin(n)


@fn Date.addMonth(n)


@fn parseTime(s)

将纯时间字符串生成一个日期对象。

var dt1 = parseTime("10:10:00");
var dt2 = parseTime("10:11");

@fn parseDate(dateStr)

将日期字符串转为日期时间格式。其效果相当于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");

@fn Date.add(sInterval, n)

为日期对象加几天/小时等。参数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


@fn Date.diff(sInterval, dtEnd)

计算日期到另一日期间的间隔,单位由sInterval指定(具体值列表参见Date.add).

var dt = new Date();
...
var dt2 = new Date();
var days = dt.diff("d", dt2); // 相隔多少天

@see Date.add


@fn setCookie(name, value, days?=30)

设置cookie值。如果只是为了客户端长时间保存值,一般建议使用 setStorage.

@see getCookie

@see delCookie

@see setStorage


@fn getCookie(name)

取cookie值。

@see setCookie

@see delCookie


@fn delCookie(name)

删除一个cookie项。

@see getCookie

@see setCookie


@fn setStorage(name, value, useSession?=false)

使用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


@fn getStorage(name, useSession?=false)

取storage中的一项。
默认使用localStorage存储,如果useSession=true,则使用sessionStorage存储。

如果浏览器不支持Storage,则使用cookie实现.

@see setStorage

@see delStorage


@fn delStorage(name)

删除storage中的一项。

@see getStorage

@see setStorage


@fn rs2Array(rs)

@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


@fn rs2Hash(rs, key)

@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


@fn rs2MultiHash(rs, key)

@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


@var IsBusy

标识应用当前是否正在与服务端交互。一般用于自动化测试。


@var g_args

应用参数。

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参数通过该函数获取。


@var g_data = {userInfo?}

应用全局共享数据。

在登录时,会自动设置userInfo属性为个人信息。所以可以通过 g_data.userInfo==null 来判断是否已登录。

@key g_data.userInfo


@var g_cfg

应用配置项。


@var BASE_URL

设置应用的基本路径, 应以"/"结尾.


@fn intSort(a, b)

整数排序. 用于datagrid column sorter:

<th data-options="field:'id', sortable:true, sorter:intSort">编号</th>

@fn numberSort(a, b)

小数排序. 用于datagrid column sorter:

<th data-options="field:'score', sortable:true, sorter:numberSort">评分</th>

@fn getAncestor(o, fn)

取符合条件(fn)的对象,一般可使用$.closest替代


@fn app_abort()

中止之后的调用, 直接返回.


@fn jQuery.fn.jdata(val?)

和使用$.data()差不多,更好用一些. 例:

$(o).jdata().hello = 100;
$(o).jdata({hello:100, world:200});

@fn jQuery.fn.getAncestor(expr)

取符合条件(expr)的对象,一般可使用$.closest替代


@fn row2tr(row)

@return jquery tr对象

@param row {\@cols}, col: {useTh?=false, html?, \%css?, \%attr?, \%on?}

根据row结构构造jQuery tr对象。


@fn $.getScriptWithCache(url, options?)


@module WUI

1 对象管理功能

1.1 定义列表页和详情页

1.2 添加入口按钮

1.3 定义页面初始化函数

1.4 定义对话框的初始化函数

1.5 列表页中的常见需求

1.5.1 列表页中的列,以特定格式展现

1.5.2 排序与分页

1.6 详情页对话框的常见需求

1.6.1 设计模式:关联选择框

1.6.2 picId字段显示图片

1.6.3 List字段显示为多个选项框

1.7 设计模式:展示层次对象

2 对话框功能

2.1 定义对话框

2.2 显示对话框

筋斗云前端框架-Web应用桌面版

此框架实现与筋斗云服务端接口的无缝整合。在界面上以jquery-easyui库为基础展示列表、Tab页等。
参考应用 web/store.html - 商户管理端应用。

1 对象管理功能

设计模式:列表页与详情页。

以订单对象Order为例:为订单对象增加“列表页”和“详情页”。

列表页应包含分页功能,默认只显示“未完成”订单。
点击列表中一项(一个订单),可显示详情页,即订单详情,并可进行查找、更新等功能。

1.1 定义列表页和详情页

@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="">&nbsp;</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", 按规范,我们定义了以下名字:

1.2 添加入口按钮
<a href="#pageOrder" class="easyui-linkbutton" icon="icon-ok">订单管理</a><br/><br/>
1.3 定义页面初始化函数

打开页面后,页面的生存周期如下:

@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

1.4 定义对话框的初始化函数

@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 (有示例)

1.5 列表页中的常见需求

框架中,对象列表通过easyui-datagrid来展现。
注意:由于历史原因,我们没有使用datagrid中的编辑功能。

参考:http://www.jeasyui.net/plugins/183.html
教程:http://www.jeasyui.net/tutorial/148.html

1.5.1 列表页中的列,以特定格式展现

@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>&nbsp;";
        });
    },
    // 订单编号,显示为一个链接,点击就打开订单对话框该订单。
    orderId: function (value) {
        if (value != null)
        {
            return makeLinkTo("#dlgOrder", value, value);
        }
    }
};

@see makeLinkTo 生成对象链接,以便点击时打开该对象的详情对话框。

1.5.2 排序与分页

@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还做了以下缺省设置:

如果需要禁用分页,可以设置:

jtbl.datagrid({
    url: makeUrl("Ordr.query", {"_pagesz": 9999}), // 定义很大的pagesz, 一次取出所有
    pagination: false, // 禁用分页组件
    ...
});
1.6 详情页对话框的常见需求
1.6.1 设计模式:关联选择框

示例:下拉框中显示员工列表 (Choose-from-list / 关联选择框)

@see jQuery.fn.mycombobox

1.6.2 picId字段显示图片

@see hiddenToImg (有示例)

@see imgToHidden

1.6.3 List字段显示为多个选项框

@see hiddenToCheckbox

@see checkboxToHidden  (有示例)

1.7 设计模式:展示层次对象

例如设计有商品表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

2 对话框功能

以群发短信功能为例。

假定服务端已有以下接口:

sendSms(phone, content)
phone:: 手机号
content:: 发送内容
2.1 定义对话框

注意:每个带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>
2.2 显示对话框

可以调用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函数打开对话框。


@var WUI.m_app


@fn WUI.enterWaiting()

@alias enterWaiting ()

TODO: require #block


@fn WUI.leaveWaiting()

@alias leaveWaiting


@fn WUI.makeUrl(action, params)

@alias makeUrl

生成对后端调用的url.

var params = {id: 100};
var url = makeUrl("Ordr.set", params);

注意:调用该函数生成的url在结尾有标志字符串"zz=1", 如"../api.php/login?_app=user&zz=1"


@fn WUI.callSvr(ac, [params?], fn?, postParams?, userOptions?)

1 文件上传支持(FormData)

@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});

1 文件上传支持(FormData)

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) { ... }
});

@fn WUI.callSvrSync(ac, [params?], fn?, postParams?, userOptions?)

@alias callSvrSync

@return data 原型规定的返回数据

同步模式调用callSvr.

@see WUI.callSvr


@fn WUI.app_alert(msg, type?=i, fn?)

@alias app_alert

@param type String. "i"|"e"|"w"

@param fn Function(). 用户点击确定后的回调。

使用jQuery easyui弹出提示对话框.


@fn WUI.app_confirm(msg, type?=i, fn?)

@alias app_confirm

@param fn Function(). 用户点击确定后的回调。

使用jQuery easyui弹出确认对话框.


@fn WUI.app_show(msg)

@alias app_show

使用jQuery easyui弹出对话框.


@fn WUI.makeLinkTo(dlg, id, text)

@alias makeLinkTo

生成一个链接的html代码,点击该链接可以打开指定对象的对话框。

示例:根据订单号,生成一个链接,点击链接打开订单详情对话框。

var orderId = 101;
var html = makeLinkTo("#dlgOrder", orderId, "订单" + orderId);

@fn jQuery.fn.mycombobox(force?=false)

@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;
    }
};

@fn WUI.reload(jtbl, url?, queryParams?)


@fn WUI.reloadTmp(jtbl, url?, queryParams?)

临时reload一下,完事后恢复原url


@fn WUI.reloadRow(jtbl, rowData)

@param rowData must be the original data from table row


@fn WUI.showPage(pageName, title?, paramArr?)

@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");

@fn WUI.closeDlg(jdlg)


@fn WUI.showDlg(jdlg, opt?)

@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 在对话框中使用事件


@fn WUI.getQueryCond(kvList)

@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查询,但不支持在其中使用括号:

在详情页对话框中,切换到查找模式,在任一输入框中均可支持以上格式。


@fn WUI.getQueryParam(kvList)

根据键值对生成BQP协议中{obj}.query接口需要的cond参数.

示例:

WUI.getQueryParam({phone: '13712345678', id: '>100'})
返回
{cond: "phone='13712345678' AND id>100"}

@see WUI.getQueryCond


@fn WUI.showObjDlg(jdlg, mode, id?)

@param id String. mode=link时必设,set/del如缺省则从关联的jtbl中取, add/find时不需要

@param jdbl Datagrid. dialog/form关联的datagrid -- 如果dlg对应多个tbl, 必须每次打开都设置

事件参考:

@see WUI.showDlg


@fn WUI.dg_toolbar(jtbl, jdlg, button_lists...)

设置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);

@fn WUI.dg_dblclick

设置双击datagrid行的回调,功能是打开相应的dialog


@key .easyui-linkbutton

使用.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>

@fn WUI.tryAutoLogin(onHandleLogin, reuseCmd?)

@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);

@fn WUI.handleLogin(data)

@param data 调用API "login"成功后的返回数据.

处理login相关的操作, 如设置g_data.userInfo, 保存自动登录的token等等.


@fn WUI.initClient()


@class Plugins


@fn Plugins.exists(pluginName)


@fn Plugins.list()


@fn WUI.setApp(app)

@param app= {appName?=user, title?="客户端", onShowLogin, pageHome?="pageHome"}


@fn WUI.logout(dontReload?=0)

@param dontReload 如果非0, 则注销后不刷新页面.

注销当前登录, 成功后刷新页面(除非指定dontReload=1)


@fn checkboxToHidden(jp, sep?=',')

@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


@fn hiddenToCheckbox(jp, sep?=",")

@param jp jquery结点

@param sep ?=',' 分隔符,默认为逗号

用于在对象详情对话框中,以一组复选框(checkbox)来对应一个逗号分隔式列表的字段。

@see checkboxToHidden (有示例)


@fn hiddenToImg(jp, sep?=",")

1 显示图片

2 显示多张图片

3 显示视频或其它文件

用于在对象详情对话框中,展示关联图片字段。图片可以为单张或多张。
除显示图片外,也可以展示其它用户上传的文件,如视频、文本等。

1 显示图片

以下是一个带图片的商户表设计,里面有两个字段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>

注意:

@key wui-nothumb

2 显示多张图片

要显示多张图片,可编写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;
    });
}

3 显示视频或其它文件

@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


@fn imgToHidden(jp, sep?=",")

用于在对象详情对话框中,展示关联图片字段。图片可以为单张或多张。

会先调用upload(fmt=raw_b64)接口保存所有改动的图片,然后将picId存储到hidden字段中。

@see hiddenToImg 有示例


@fn onChooseFile()

与hiddenToImg/imgToHidden合用,在对话框上显示一个图片字段。
在文件输入框中,选中一个文件后,调用此方法,可将图片压缩后显示到指定的img标签中(div.imgs)。

使用lrz组件进行图片压缩,最大宽高不超过1280px。然后以base64字串方式将图片显示到一个img组件中。

TODO: 添加图片压缩参数,图片框显示大小等。

@see hiddenToImg


@fn searchField(o, param)

在详情页对话框中,以某字段作为查询条件来查询。

@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 值支持比较运行符等多种格式,可参考这里定义。


Generated by jdcloud-gendoc @ 2016-12-14T17:10:13+08:00