PageSourceSearch

https://yqdz.nanhaibank.com:480/dopUnify/redirect/SunAOS/static/js/plugin/B-JUI/js/bjui-all.js

js nanhaibank.com collected 2026-09-25 05:09:49 UTC 756,068 bytes, 19,092 lines download raw bytes

1/*!
2 * B-JUI  V1.31 (http://b-jui.com)
3 * Git@OSC (http://git.oschina.net/xknaan/B-JUI)
4 * Copyright 2014 K'naan.
5 * Licensed under Apache (http://www.apache.org/licenses/LICENSE-2.0)
6 */
7/* ========================================================================
8 * B-JUI: bjui-core.js  V1.31
9 * @author K'naan
10 * -- Modified from dwz.core.js (author:[email protected])
11 * http://git.oschina.net/xknaan/B-JUI/blob/master/BJUI/js/bjui-core.js
12 * ========================================================================
13 * Copyright 2014 K'naan.
14 * Licensed under Apache (http://www.apache.org/licenses/LICENSE-2.0)
15 * ======================================================================== */
16/**
17 * 修改说明:
18 * 1、1110行:兼容IE11中 ztree 下拉时重叠问题 --2019-09-20
19 * 2、cellsTitle:7743行、10682行、15253行,单元格增加 title 提示,true 为显示title,false为不显示 --2019-10-9
20 * 3、closeAll:3878行 //关闭所有打开的弹出框  调用方法:BJUI.dialog('closeAll') 2020-05-26
21 * 4、cellsHeight:7744行、10695行、15287行,表格行高配置,true:固定行高30px,超出隐藏,false(默认),行高根据内容多少自行换行显示 2020-06-10
22 * 5、getEditData:11510行,取新增、修改编辑行的值 --2020-08-17
23 * 6、getDelData:11519行,取删除行的值 --2020-08-17
24 * 7、openTab:2906行,选项卡增加name属性-options.name -2020-08-17
25 * 8、Theme.prototype.init:换肤设置 ---- 2020-10-09
26 * 9、Datagrid.prototype.inlineEdit:select.change -- 2020-10-20
27 * 10、afterChange: 7105行,date不为空,移除验证 2020-11-02
28 * 11、表格列拖动配置:12838行,配置列拖动时的宽度 2020-11-02
29 * 12、日历显示调整 年+月、月显示配置: 6805行 2020-11-13
30 * 13、表格:右键菜单配置 contextMenuSys、contextMenuList(7945) 2020-12-01
31 * 14、表格:双击行方法配置 dblClickSys 2021-01-04
32 * 15、spinner: 数据递增递减,当readonly时,不允许操作按钮(15803行) 2021-01
33 * 16、Datagrid.prototype.initEvents:11237行,表格树复选操作 2021-02-18
34 * 17、10910-10912未设置表头宽度时,根据表头文字设置宽度 2021-04-07
35 * */
36
37+function ($) {
38    'use strict';
39
40    var BJUI = {
41        JSPATH     : 'BJUI/',
42        PLUGINPATH : 'BJUI/plugins/',
43        IS_DEBUG   : false,
44        KeyPressed : { //key press state
45            ctrl  : false,
46            shift : false
47        },
48        keyCode: {
49            ENTER : 13, ESC  : 27, END : 35, HOME : 36,
50            SHIFT : 16, CTRL : 17, TAB : 9,
51            LEFT  : 37, RIGHT: 39, UP  : 38, DOWN : 40,
52            DELETE: 46, BACKSPACE: 8
53        },
54        eventType: {
55            initUI         : 'bjui.initUI',         // When document load completed or ajax load completed, B-JUI && Plugins init
56            beforeInitUI   : 'bjui.beforeInitUI',   // If your DOM do not init [add to DOM attribute 'data-noinit="true"']
57            afterInitUI    : 'bjui.afterInitUI',    //
58            ajaxStatus     : 'bjui.ajaxStatus',     // When performing ajax request, display or hidden progress bar
59            resizeGrid     : 'bjui.resizeGrid',     // When the window or dialog resize completed
60            beforeAjaxLoad : 'bjui.beforeAjaxLoad', // When perform '$.fn.ajaxUrl', to do something...
61
62            beforeLoadNavtab  : 'bjui.beforeLoadNavtab',
63            beforeLoadDialog  : 'bjui.beforeLoadDialog',
64            afterLoadNavtab   : 'bjui.afterLoadNavtab',
65            afterLoadDialog   : 'bjui.afterLoadDialog',
66            beforeCloseNavtab : 'bjui.beforeCloseNavtab',
67            beforeCloseDialog : 'bjui.beforeCloseDialog',
68            afterCloseNavtab  : 'bjui.afterCloseNavtab',
69            afterCloseDialog  : 'bjui.afterCloseDialog'
70        },
71        formColWidth: {L:900, M:680, S:360, SS:240},
72        pageInfo: {pageCurrent:'pageCurrent', pageSize:'pageSize', orderField:'orderField', orderDirection:'orderDirection'},
73        alertMsg: {displayPosition:'topcenter', alertTimeout: 6000}, //alertmsg display position && close timeout
74        ajaxTimeout: 30000,
75        statusCode: {ok:200, error:300, timeout:301},
76        keys: {statusCode:'statusCode', message:'message'},
77        ui: {
78            windowWidth      : 0,
79            showSideWidth    : 990,
80            sidenavWidth     : 260,
81            offsetWidth      : 15,
82            displayFirst     : true,
83            showSlidebar     : true,      // After the B-JUI initialization, display slidebar
84            clientPaging     : true,      // Response paging and sorting information on the client
85            overwriteHomeTab : false      // When open an undefined id of navtab, whether overwrite the home navtab
86        },
87        debug: function(msg) {
88            if (this.IS_DEBUG) {
89                if (typeof(console) != 'undefined') console.log(msg)
90                else alert(msg)
91            }
92        },
93        loginInfo: {
94            url    : 'login.html',
95            title  : 'Login',
96            width  : 420,
97            height : 260,
98            mask   : true
99        },
100        loadLogin: function() {
101            var login = this.loginInfo
102
103            BJUI.dialog({id:'bjui-login', url:login.url, title:login.title, width:login.width, height:login.height, mask:login.mask})
104        },
105        init: function(options) {
106            var op = $.extend({}, options)
107
108            $.extend(BJUI.keys, op.keys)
109            $.extend(BJUI.statusCode, op.statusCode)
110            $.extend(BJUI.pageInfo, op.pageInfo)
111            $.extend(BJUI.formColWidth, op.formColWidth)
112            $.extend(BJUI.alertMsg, op.alertMsg)
113            $.extend(BJUI.loginInfo, op.loginInfo)
114            $.extend(BJUI.ui, op.ui)
115
116            if (op.JSPATH) this.JSPATH = op.JSPATH
117            if (op.PLUGINPATH) this.PLUGINPATH = op.PLUGINPATH
118            if (op.ajaxTimeout) this.ajaxTimeout = op.ajaxTimeout
119
120            this.IS_DEBUG = op.debug || false
121            this.initEnv()
122
123            if ((!$.cookie || !$.cookie('bjui_theme')) && op.theme) $(this).theme('setTheme', op.theme)
124        },
125        initEnv: function() {
126            $(window).resize(function() {
127                BJUI.initLayout()
128
129                setTimeout(function() {$(this).trigger(BJUI.eventType.resizeGrid)}, 30)
130            })
131
132            setTimeout(function() {
133                $(document).initui()
134
135                var $collapse = $('#bjui-navbar-collapse'), left = $collapse.prev().width()
136
137                $collapse.css('left', left).data('position.left', left)
138
139                BJUI.initLayout()
140
141                $('#bjui-top-collapse').on('click.theme', '.dropdown-toggle', function() {
142                    var $dropdown = $(this).next(), $topcollapse = $('#bjui-top-collapse')
143
144                    if (!$topcollapse.hasClass('navbar-show')) {
145                        $topcollapse.attr('style', $dropdown.is(':visible') ? '' : 'overflow:visible !important;')
146                    }
147                })
148
149                $('[data-toggle="collapsenavbar"]').click(function() {
150                    var $this = $(this), $target = $($this.data('target')), $parent = $this.closest('.navbar-header')
151
152                    if ($target.length) {
153                        $target.toggleClass('navbar-show')
154                        $parent.toggleClass('navbar-show')
155
156                        $(document).on('click', function(e) {
157                            if(!($target.has(e.target).length) && !($parent.has(e.target).length)) {
158                                $target.removeClass('navbar-show')
159                                $parent.removeClass('navbar-show')
160                            }
161                        })
162                    }
163                })
164            }, 10)
165        },
166        initLayout: function() {
167            var ww = $(window).width(), hh = $(window).height(),
168                $top = $('#bjui-top'), $navbar = $('#bjui-navbar'), $collapse = $('#bjui-top-collapse, #bjui-navbar-collapse'),
169                th = $top.height(), nh = parseInt($navbar.css('min-height'), 10),
170                eventName = 'click.bjui.sidenav.hide', opts = {},
171                $navtab  = $('#bjui-navtab'), $sidenav = $('#bjui-sidenav'), $sidenavcol = $('#bjui-sidenav-col'),
172                $sidenavarrow = $('#bjui-sidenav-arrow'), $sidenavbtn = $('#bjui-sidenav-btn'), $sidenavbox = $('#bjui-sidenav-box'),
173                tnh = $sidenavbtn.outerHeight() - 2
174            // $("#jquery-accordion-menu").height($("#indexMenu").height());
175            $('#bjui-navtab .tabsPageContent').height(hh - $('#bjui-navbar').height()-$(" #bjui-navtab  .tabsPageHeader .tabsPageHeaderContent").height()-7);
176
177
178            //  $('#bjui-navtab .tabsPageContent').height(hh -76);
179
180            /*alert(hh);
181            alert($('#bjui-navbar').height());
182            alert($('#indexMenu .navtabPage .bjui-pageFooter').height());
183            alert($(" #bjui-navtab  .tabsPageHeader .tabsPageHeaderContent").height());
184            alert($("#indexMenu").height());*/
185
186
187            //$("#main-nav>div>ul").height($("#indexMenu").height());
188            //$("#main-nav>div>ul>li>ul").height($("#indexMenu").height());
189
190            $sidenav.height(hh - th - nh - 1)
191            $sidenavcol.width(BJUI.ui.sidenavWidth)
192
193            $collapse.scrollTop(5).eq(0).removeAttr('style')
194            $collapse.each(function() {
195                var $this = $(this), $collapsebtn = $this.prev().find('.navbar-toggle'), isCollapse = ($this.scrollTop() == 5 || $this.hasClass('navbar-show'))
196
197                isCollapse && $this.scrollTop(0)
198
199                $this.toggleClass('position', isCollapse)
200                $collapsebtn.toggleClass('position', isCollapse)
201
202                if ($this.data('position.left') && (ww / 2) < $this.data('position.left')) {
203                    $this.prev().find('> .navbar-brand').hide()
204                    $this.css('left', 0)
205                } else {
206                    $this.prev().find('> .navbar-brand').show()
207                    $this.css('left', $this.data('position.left'))
208                }
209            })
210
211            if (ww < BJUI.ui.showSideWidth) {
212                //$sidenavcol.css('left', -(BJUI.ui.sidenavWidth + BJUI.ui.offsetWidth)).addClass('autohide')
213                $sidenavcol.css('left', 0).addClass('autohide')
214
215                $navtab.css('margin-left', 0)
216                $sidenavbtn.show()
217            } else {
218                $sidenavcol.css('left', 0).removeClass('autohide')
219                // $navtab.css('margin-left', (BJUI.ui.sidenavWidth + BJUI.ui.offsetWidth))
220                $navtab.css('margin-left', 0)
221                $sidenavbtn.hide()
222            }
223
224            $sidenavarrow.off(eventName).on(eventName, function() {
225                $sidenavcol
226                    .stop()
227                    .animate({
228                        left: -(BJUI.ui.sidenavWidth + BJUI.ui.offsetWidth)
229                    }, 'fast', function() {
230                        $sidenavbtn.show()
231
232                        $(window).trigger(BJUI.eventType.resizeGrid)
233                    })
234
235                $navtab
236                    .stop()
237                    .animate({
238                        'margin-left': 0
239                    }, 'fast')
240            })
241
242            $sidenavbtn.off(eventName).on(eventName, function() {
243                $sidenavbtn.hide()
244
245                $sidenavcol
246                    .stop()
247                    .animate({
248                        left: 0
249                    }, 'fast', function() {
250                        $(window).trigger(BJUI.eventType.resizeGrid)
251                    })
252
253                opts['margin-left'] = (BJUI.ui.sidenavWidth + BJUI.ui.offsetWidth)
254                if (ww < BJUI.ui.showSideWidth)
255                    opts['margin-left'] = 0
256
257                $navtab
258                    .stop()
259                    .animate(opts, 'fast')
260            })
261
262            /* fixed pageFooter */
263            /*setTimeout(function() {
264                $('#bjui-navtab > .tabsPageContent > .navtabPage').resizePageH()
265                $('#bjui-navtab > .tabsPageContent > .navtabPage').find('.bjui-layout').resizePageH()
266            }, 10)*/
267        },
268        regional: {},
269        setRegional: function(key, value) {
270            BJUI.regional[key] = value
271        },
272        getRegional : function(key) {
273            if (String(key).indexOf('.') >= 0) {
274                var msg, arr = String(key).split('.')
275
276                for (var i = 0; i < arr.length; i++) {
277                    if (!msg) msg = BJUI.regional[arr[i]]
278                    else msg = msg[arr[i]]
279                }
280
281                return msg
282            } else {
283                return BJUI.regional[key]
284            }
285        },
286        doRegional: function(frag, regional) {
287            $.each(regional, function(k, v) {
288                frag = frag.replaceAll('#'+ k +'#', v)
289            })
290
291            return frag
292        },
293        // is ie browser
294        isIE: function(ver) {
295            var b = document.createElement('b')
296            b.innerHTML = '<!--[if IE '+ ver +']><i></i><![endif]-->'
297
298            return b.getElementsByTagName('i').length === 1
299        },
300        StrBuilder: function() {
301            return new StrBuilder()
302        }
303    }
304
305    function StrBuilder() {
306        this.datas = new Array()
307    }
308
309    StrBuilder.prototype.add = function(str) {
310        if (typeof str !== 'undefined') this.datas.push(str)
311        return this
312    }
313
314    StrBuilder.prototype.toString = function(str) {
315        var string = this.datas.join(str || '')
316
317        this.clear()
318
319        return string
320    }
321
322    StrBuilder.prototype.isEmpty = function(){
323        return this.datas.length == 0
324    }
325
326    StrBuilder.prototype.clear = function(){
327        this.datas = []
328        this.datas.length = 0
329    }
330
331    window.BJUI = BJUI
332
333}(jQuery);
334/*!
335 * B-JUI  V1.31 (http://b-jui.com)
336 * Git@OSC (http://git.oschina.net/xknaan/B-JUI)
337 * Copyright 2014 K'naan.
338 * Licensed under Apache (http://www.apache.org/licenses/LICENSE-2.0)
339 */
340
341/* ========================================================================
342 * B-JUI: bjui-regional.zh-CN.js  V1.31
343 * @author K'naan
344 * http://git.oschina.net/xknaan/B-JUI/blob/master/BJUI/js/bjui-regional.zh-CN.js
345 * ========================================================================
346 * Copyright 2014 K'naan.
347 * Licensed under Apache (http://www.apache.org/licenses/LICENSE-2.0)
348 * ======================================================================== */
349
350+function ($) {
351    'use strict';
352
353    $(function() {
354
355        /* 消息提示框 */
356        BJUI.setRegional('alertmsg', {
357            title  : {error : '错误提示', info : '信息提示', warn : '警告信息', correct : '成功信息', confirm : '确认信息', prompt : '确认信息'},
358            btnMsg : {ok    : '确定', yes  : '是',   no   : '否',   cancel  : '取消'}
359        })
360
361        /* dialog */
362        BJUI.setRegional('dialog', {
363            close    : '关闭',
364            maximize : '最大化',
365            restore  : '还原',
366            minimize : '最小化',
367            title    : '弹出窗口'
368        })
369
370        /* order by */
371        BJUI.setRegional('orderby', {
372            asc  : '升序',
373            desc : '降序'
374        })
375
376        /* 分页 */
377        BJUI.setRegional('pagination', {
378            total   : '总记录数/总页数',
379            first   : '首页',
380            last    : '末页',
381            prev    : '上一页',
382            next    : '下一页',
383            jumpto  : '输入跳转页码,回车确认',
384            jump    : '跳转',
385            page    : '页',
386            refresh : '刷新'
387        })
388
389        BJUI.setRegional('datagrid', {
390            asc       : '升序',
391            desc      : '降序',
392            showhide  : '显示/隐藏 列',
393            filter    : '过滤',
394            clear     : '清除',
395            lock      : '锁定列',
396            unlock    : '解除锁定',
397            add       : '添加',
398            edit      : '编辑',
399            save      : '保存',
400            update    : '更新',
401            cancel    : '取消',
402            del       : '删除',
403            prev      : '上一条',
404            next      : '下一条',
405            refresh   : '刷新',
406            query     : '查询',
407            'import'  : '导入',
408            'export'  : '导出',
409            exportf   : '导出筛选',
410            all       : '全部',
411            'true'    : '是',
412            'false'   : '否',
413            noData    : '没有数据!',
414            fAndS     : '过滤和排序!',
415            expandMsg : '点我展开行!',
416            shrinkMsg : '点我收缩行!',
417            selectMsg : '未选中任何行!',
418            editMsg   : '请先保存编辑行!',
419            saveMsg   : '没有需要保存的行!',
420            delMsg    : '确定要删除该行吗?',
421            delMsgM   : '确定要删除选中行?',
422            errorData : '未获取到正确的数据!',
423            failData  : '请求datagrid数据失败!'
424        })
425
426        BJUI.setRegional('findgrid', {
427            choose : '选择选中项',
428            append : '追加选择',
429            empty  : '清空现有值'
430        })
431
432        /* ajax加载提示 */
433        BJUI.setRegional('progressmsg', '正在努力加载数据,请稍等...')
434
435        /* 日期选择器 */
436        BJUI.setRegional('datepicker', {
437            close      : '关闭',
438            prev       : '上月',
439            next       : '下月',
440            today      : '今天', //日期 新增今天按钮  2020-07-28
441            clear      : '清空',
442            ok         : '确定',
443            dayNames   : ['日', '一', '二', '三', '四', '五', '六'],
444            monthNames : ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月']
445        })
446
447        /* navtab右键菜单  */
448        BJUI.setRegional('navtabCM', {
449            refresh    : '刷新本标签',
450            close      : '关闭本标签',
451            closeother : '关闭其他标签',
452            closeall   : '关闭所有标签'
453        })
454
455        /* dialog右键菜单 */
456        BJUI.setRegional('dialogCM', {
457            refresh    : '刷新本窗口',
458            close      : '关闭本窗口',
459            closeother : '关闭其他窗口',
460            closeall   : '关闭所有窗口'
461        })
462
463        /* 503错误提示 */
464        BJUI.setRegional('statusCode_503', '服务器当前负载过大或者正在维护!')
465
466        /* AJAX 状态返回 0 提示 */
467        BJUI.setRegional('ajaxnosend', '与服务器的通信中断,请检查URL链接或服务器状态!')
468
469        /* timeout提示 */
470        BJUI.setRegional('sessiontimeout', '会话超时,请重新登陆!')
471
472        /* 占位符对应选择器无有效值提示 */
473        BJUI.setRegional('plhmsg', '占位符对应的选择器无有效值!')
474
475        /* 未定义复选框组名提示 */
476        BJUI.setRegional('nocheckgroup', '未定义选中项的组名[复选框的"data-group"]!')
477
478        /* 未选中复选框提示 */
479        BJUI.setRegional('notchecked', '未选中任何一项!')
480
481        /* 未选中下拉菜单提示 */
482        BJUI.setRegional('selectmsg', '请选择一个选项!')
483
484        /* 表单验证错误提示信息 */
485        BJUI.setRegional('validatemsg', '提交的表单中 [{0}] 个字段有错误,请更正后再提交!')
486
487        /* ID检查 */
488        BJUI.setRegional('idChecked', '不规范,ID需以字母开头,组成部分包括(0-9,字母,中横线,下划线)')
489
490        /* 框架名称 */
491        BJUI.setRegional('uititle', 'B-JUI')
492
493        /* 主navtab标题 */
494        BJUI.setRegional('maintab', '我的主页')
495
496        /**
497         *
498         *  Plugins regional setting
499         *
500         */
501        /* nice validate - Global configuration */
502        $.validator && $.validator.config({
503            // Custom rules
504            rules: {
505                digits: [/^\d+$/, '请输入整数']
506                ,number: [/^[\-\+]?((([0-9]{1,3})([,][0-9]{3})*)|([0-9]+))?([\.]([0-9]+))?$/, '请输入有效的数字']
507                ,letters: [/^[a-z]+$/i, '{0}只能输入字母']
508                ,upletterandnumberand_:[/^[A-Z]+[A-Z0-9_]*$/, '只能输入大写字母,数字和_']
509                ,downletterandnumberand_:[/^[a-z]+[a-z0-9_]*$/, '首位只能是小写字母,其它只能输入小写字母,数字和_']
510                ,upletterandnumber: [/^[A-Z0-9]+$/, '只能输入大写字母和数字']
511                ,tel: [/^(?:(?:0\d{2,3}[\- ]?[1-9]\d{6,7})|(?:[48]00[\- ]?[1-9]\d{6}))$/, "请填写有效的电话号码"]
512                ,mobile: [/^1[3-9]\d{9}$/, '手机号格式不正确']
513                ,email: [/^[\w\+\-]+(\.[\w\+\-]+)*@[a-z\d\-]+(\.[a-z\d\-]+)*\.([a-z]{2,4})$/i, "请填写有效的邮箱"]
514                ,qq: [/^[1-9]\d{4,}$/, 'QQ号格式不正确']
515                //,date: [/^\d{4}-\d{1,2}-\d{1,2}$/, '请输入正确的日期,例:yyyy-mm-dd']
516                ,date:[/^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$/, '请输入正确的日期,例:yyyy-MM-dd']
517                //,time: [/^([01]\d|2[0-3])(:[0-5]\d){1,2}$/, '请输入正确的时间,例:14:30或14:30:00']
518                ,time: [/^(2[0123]|(1|0?)[0-9]){1}:([0-5][0-9]){1}:([0-5][0-9]){1}$/, '请输入正确的时间,例:HH:mm:ss']
519                ,datetime: [/^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])\s+(2[0123]|(1|0?)[0-9]){1}:([0-5][0-9]){1}:([0-5][0-9]){1}$/,
520                    '请输入正确的日期时间,例:yyyy-MM-dd HH:mm:ss']
521                ,IDcard: [/^\d{6}(19|2\d)?\d{2}(0[1-9]|1[012])(0[1-9]|[12]\d|3[01])\d{3}(\d|X)?$/, "请填写正确的身份证号码"]
522                ,url: [/^(https?|s?ftp):\/\/\S+$/i, "请填写有效的网址"]
523                ,zipcode: [/^\d{6}$/, "请检查邮政编码格式"]
524                ,chinese: [/^[\u0391-\uFFE5]+$/, '请输入中文']
525                ,username: [/^\w{3,12}$/, '请输入3-12位数字、字母、下划线']
526                // ,password: [/^[\S]{6,16}$/, "请填写6-16位字符,不能包含空格"]
527                ,password: [/^(?=.*\d)(?=.*[a-zA-Z])(?=.*[_~!@#$%^&*])[\da-zA-Z_~!@#$%^&*]{6,16}$/,
528                    "密码长度 6~16,必须包含字母、数字、特殊字符(_~!@#$%^&*)"]
529                ,pattern:function(element, params) {
530                    if (!params) return true
531
532                    var date = element.value.parseDate(params)
533
534                    return (!date ? this.renderMsg('错误的日期时间格式!', params) : true)
535                }
536                ,accept: function (element, params){
537                    if (!params) return true;
538                    var ext = params[0],
539                        value = $(element).val();
540                    return (ext === '*') ||
541                        (new RegExp(".(?:" + ext + ")$", "i")).test(value) ||
542                        this.renderMsg("只接受{1}后缀的文件", ext.replace(/\|/g, ','));
543                }
544            },
545
546            // Default error messages
547            messages: {
548                0: "此处",
549                fallback: "{0}格式不正确",
550                loading: "正在验证...",
551                error: "网络异常",
552                timeout: "请求超时",
553                required: "{0}不能为空",
554                remote: "{0}已被使用",
555                integer: {
556                    '*': "请填写整数",
557                    '+': "请填写正整数",
558                    '+0': "请填写正整数或0",
559                    '-': "请填写负整数",
560                    '-0': "请填写负整数或0"
561                },
562                match: {
563                    eq: "{0}与{1}不一致",
564                    neq: "{0}与{1}不能相同",
565                    lt: "{0}必须小于{1}",
566                    gt: "{0}必须大于{1}",
567                    lte: "{0}不能大于{1}",
568                    gte: "{0}不能小于{1}"
569                },
570                range: {
571                    rg: "请填写{1}到{2}的数",
572                    gte: "请填写不小于{1}的数",
573                    lte: "请填写最大{1}的数",
574                    gtlt: "请填写{1}到{2}之间的数",
575                    gt: "请填写大于{1}的数",
576                    lt: "请填写小于{1}的数"
577                },
578                checked: {
579                    eq: "请选择{1}项",
580                    rg: "请选择{1}到{2}项",
581                    gte: "请至少选择{1}项",
582                    lte: "请最多选择{1}项"
583                },
584                length: {
585                    eq: "请填写{1}个字符",
586                    rg: "请填写{1}到{2}个字符",
587                    gte: "请至少填写{1}个字符",
588                    lte: "请最多填写{1}个字符",
589                    eq_2: "",
590                    rg_2: "",
591                    gte_2: "",
592                    lte_2: ""
593                }
594            }
595        })
596
597    })
598
599}(jQuery);
600/*!
601 * B-JUI  V1.31 (http://b-jui.com)
602 * Git@OSC (http://git.oschina.net/xknaan/B-JUI)
603 * Copyright 2014 K'naan.
604 * Licensed under Apache (http://www.apache.org/licenses/LICENSE-2.0)
605 */
606
607/* ========================================================================
608 * B-JUI: bjui-frag.js  V1.31
609 * @author K'naan
610 * http://git.oschina.net/xknaan/B-JUI/blob/master/BJUI/js/bjui-frag.js
611 * ========================================================================
612 * Copyright 2014 K'naan.
613 * Licensed under Apache (http://www.apache.org/licenses/LICENSE-2.0)
614 * ======================================================================== */
615
616+function ($) {
617    'use strict';
618
619    BJUI.setRegional('alertmsg', {
620        title  : {error : 'Error', info : 'Info', warn : 'Warning', correct : 'Correct', confirm : 'Confirm', prompt:'Prompt'},
621        btnMsg : {ok    : 'OK',    yes  : 'YES',  no   : 'NO',      cancel  : 'Cancel'}
622    })
623
624    BJUI.setRegional('dialog', {
625        close    : 'Close',
626        maximize : 'Maximize',
627        restore  : 'Restore',
628        minimize : 'Minimize',
629        title    : 'Popup window'
630    })
631
632    BJUI.setRegional('orderby', {
633        asc  : 'Asc',
634        desc : 'Desc'
635    })
636
637    BJUI.setRegional('pagination', {
638        first  : 'First page',
639        last   : 'Last page',
640        prev   : 'Prev page',
641        next   : 'Next page',
642        jumpto : 'Jump page number',
643        jump   : 'Jump'
644    })
645
646    BJUI.setRegional('datagrid', {
647        asc       : 'ASC',
648        desc      : 'DESC',
649        showhide  : 'Show/Hide columns',
650        filter    : 'Filter',
651        clear     : 'Clear',
652        lock      : 'Lock',
653        unlock    : 'Unlock',
654        add       : 'Add',
655        edit      : 'Edit',
656        save      : 'Save',
657        update    : 'Update',
658        cancel    : 'Cancel',
659        del       : 'Delete',
660        prev      : 'Prev',
661        next      : 'Next',
662        refresh   : 'Refresh',
663        query     : 'Query',
664        'import'  : 'Import',
665        'export'  : 'Export',
666        exportf   : 'Export filter',
667        all       : 'All',
668        'true'    : 'True',
669        'false'   : 'False',
670        noData    : 'No data!',
671        fAndS     : 'Filter && Sort!',
672        expandMsg : 'Click here to expand the tr!',
673        shrinkMsg : 'Click here to shrink the tr!',
674        selectMsg : 'Not selected any rows!',
675        saveMsg   : 'No rows need to save!',
676        editMsg   : 'Please save the edited row!',
677        delMsg    : 'Sure you want to delete this row?',
678        delMsgM   : 'Sure you want to delete selected rows?',
679        errorData : 'Did not get the correct data!',
680        failData  : 'Request data failed!'
681    })
682
683    BJUI.setRegional('findgrid', {
684        choose : 'Choose the selected item',
685        append : 'Append choose the selected item',
686        empty  : 'Empty existing values'
687    })
688
689    BJUI.setRegional('progressmsg', 'Data loading, please waiting...')
690
691    BJUI.setRegional('datepicker', {
692        close      : 'Close',
693        prev       : 'Prev month',
694        next       : 'Next month',
695        today      : 'Today',//日期 新增今天按钮  2020-07-28
696        clear      : 'Clear',
697        ok         : 'OK',
698        dayNames   : ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
699        monthNames : ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
700    })
701
702    BJUI.setRegional('navtabCM', {
703        refresh    : 'Refresh navtab',
704        close      : 'Close navtab',
705        closeother : 'Close other navtab',
706        closeall   : 'Close all navtab'
707    })
708
709    BJUI.setRegional('dialogCM', {
710        refresh    : 'Refresh dialog',
711        close      : 'Close dialog',
712        closeother : 'Close other dialog',
713        closeall   : 'Close all dialog'
714    })
715
716    BJUI.setRegional('statusCode_503', 'HTTP status 503, the current server load is too large or is down for maintenance!')
717
718    BJUI.setRegional('ajaxnosend', 'Communication with the server is interrupted, please check the URL link or server status!')
719
720    BJUI.setRegional('sessiontimout', 'Session timeout, please login!')
721
722    BJUI.setRegional('plhmsg', 'Placeholder corresponding selector None Valid!')
723
724    BJUI.setRegional('nocheckgroup', 'Undefined group name selected item [check box "data-group"]!')
725
726    BJUI.setRegional('notchecked', 'Unchecked any one!')
727
728    BJUI.setRegional('selectmsg', 'Please select one option!')
729
730    BJUI.setRegional('validatemsg', 'Submitted form data has [{0}] field an error, please after modified submitting!')
731
732    BJUI.setRegional('idChecked', 'is not standardized, ID need to start with a letter, components include (0-9, letters, hyphens, underscore)')
733
734    BJUI.setRegional('uititle', 'B-JUI')
735
736    BJUI.setRegional('maintab', 'My home')
737
738
739    window.FRAG = {
740        dialog: '<div class="bjui-dialog bjui-dialog-container" style="top:150px; left:300px;">' +
741            '    <div class="dialogHeader" onselectstart="return false;" oncopy="return false;" onpaste="return false;" oncut="return false;">' +
742            '        <a class="close" href="javascript:;" title="#close#"><i class="fa fa-times"></i></a>' +
743            '        <a class="maximize" href="javascript:;" title="#maximize#"><i class="fa fa-square-o"></i></a>' +
744            '        <a class="restore" href="javascript:;" title="#restore#"><i class="fa fa-clone fa-rotate-90"></i></a>' +
745            '        <a class="minimize" href="javascript:;" title="#minimize#"><i class="fa fa-minus"></i></a>' +
746            '        <h1><span><i class="fa fa-th-large"></i></span> <span class="title">#title#</span></h1>' +
747            '    </div>' +
748            '    <div class="dialogContent unitBox"></div>' +
749            '    <div class="resizable_h_l" tar="nw"></div>' +
750            '    <div class="resizable_h_r" tar="ne"></div>' +
751            '    <div class="resizable_h_c" tar="n"></div>' +
752            '    <div class="resizable_c_l" tar="w" style="height:100%;"></div>' +
753            '    <div class="resizable_c_r" tar="e" style="height:100%;"></div>' +
754            '    <div class="resizable_f_l" tar="sw"></div>' +
755            '    <div class="resizable_f_r" tar="se"></div>' +
756            '    <div class="resizable_f_c" tar="s"></div>' +
757            '</div>'
758        ,
759        taskbar: '<div id="bjui-taskbar" style="left:0px; display:none;">' +
760            '    <div class="taskbarContent">' +
761            '        <ul></ul>' +
762            '    </div>' +
763            '    <div class="taskbarLeft taskbarLeftDisabled"><i class="fa fa-angle-double-left"></i></div>' +
764            '    <div class="taskbarRight"><i class="fa fa-angle-double-right"></i></div>' +
765            '</div>'
766        ,
767        splitBar: '<div id="bjui-splitBar"></div>',
768        splitBarProxy: '<div id="bjui-splitBarProxy"></div>',
769        resizable: '<div id="bjui-resizable" class="bjui-resizable"></div>',
770        alertBackground: '<div class="bjui-alertBackground"></div>',
771        maskBackground: '<div class="bjui-maskBackground bjui-ajax-mask"></div>',
772        maskProgress: '<div class="bjui-maskProgress bjui-ajax-mask"><i class="fa fa-cog fa-spin"></i>&nbsp;&nbsp;#progressmsg#<div class="progressBg"><div class="progress"></div></div></div>',
773        progressBar_custom: '<div id="bjui-progressBar-custom" class="progressBar"><i class="fa fa-cog fa-spin"></i> <span></span></div>',
774        dialogMask: '<div class="bjui-dialogBackground"></div>',
775        orderby: '<a href="javascript:;" class="order asc" data-order-direction="asc" title="#asc#"><i class="fa fa-angle-up"></i></a>' +
776            '<a href="javascript:;" class="order desc" data-order-direction="desc" title="#desc#"><i class="fa fa-angle-down"></i></a>'
777        ,
778        slidePanel: '<div class="panel panel-default">' +
779            '    <div class="panel-heading">' +
780            '        <h4 class="panel-title"><a data-toggle="collapse" data-parent="#bjui-accordionmenu" href="##id#" class="#class#">#icon#&nbsp;#title#<b>#righticon#</b></a></h4>' +
781            '    </div>' +
782            '    <div id="#id#" class="panel-collapse collapse#bodyclass#">' +
783            '        <div class="panel-body">' +
784            '        </div>' +
785            '    </div>' +
786            '</div>'
787        ,
788        gridPaging: '<ul class="pagination">' +
789            '    <li class="page-total">' +
790            '        <span title="#total#">#count#</span>' +
791            '    </li>' +
792            '    <li class="page-jumpto"><span class="page-input"><input class="form-control input-sm-pages" type="text" size="3.2" value="#pageCurrent#" title="#jumpto#"></span></li>' +
793            '    <li class="page-first btn-nav">' +
794            '        <a href="javascript:;" title="#first#"><i class="fa fa-step-backward"></i></a>' +
795            '    </li>' +
796            '    <li class="page-prev btn-nav">' +
797            '        <a href="javascript:;" title="#prev#"><i class="fa fa-backward"></i></a>' +
798            '    </li>' +
799            '    #pageNumFrag#' +
800            '    <li class="page-next btn-nav">' +
801            '        <a href="javascript:;" title="#next#"><i class="fa fa-forward"></i></a>' +
802            '    </li>' +
803            '    <li class="page-last btn-nav">' +
804            '        <a href="javascript:;" title="#last#"><i class="fa fa-step-forward"></i></a>' +
805            '    </li>' +
806            '</ul>'
807        ,
808        gridPageNum : '<li class="page-num#active#"><a href="javascript:;">#num#</a></li>',
809        gridMenu : '<div class="datagrid-menu-box">'
810            + '    <ul>'
811            + '        <li class="datagrid-li-asc"><a href="javascript:;"><span class="icon"><i class="fa fa-sort-amount-asc"></i></span><span class="title">#asc#</span></a></li>'
812            + '        <li class="datagrid-li-desc"><a href="javascript:;"><span class="icon"><i class="fa fa-sort-amount-desc"></i></span><span class="title">#desc#</span></a></li>'
813            + '        <li class="datagrid-li-filter"><a href="javascript:;"><span class="icon"><i class="fa fa-filter"></i></span><span class="title">#filter#</span><span class="arrow"></span></a></li>'
814            + '        <li class="datagrid-li-showhide"><a href="javascript:;"><span class="icon"><i class="fa fa-check-square-o"></i></span><span class="title">#showhide#</span><span class="arrow"></span></a></li>'
815            + '        <li class="datagrid-li-lock"><a href="javascript:;"><span class="icon"><i class="fa fa-lock"></i></span><span class="title">
815#lock#</span></a></li>'
816            + '        <li class="datagrid-li-unlock disable"><a href="javascript:;"><span class="icon"><i class="fa fa-unlock"></i></span><span class="title">#unlock#</span></a></li>'
817            + '    </ul>'
818            + '</div>'
819        ,
820        gridFilter: '<div class="datagrid-filter-box">'
821            + '<fieldset>'
822            + '<legend>#label#</legend>'
823            + '<span class="filter-a"></span>'
824            + '<span class="filter-and"><select data-toggle="selectpicker" data-container="true" data-width="100%"><option value="and">AND</option><option value="or">OR</option></select></span>'
825            + '<span class="filter-b"></span>'
826            + '<span class="filter-ok"><button type="button" class="btn-green ok" data-icon="check">#filter#</button><button type="button" class="btn-orange clear" data-icon="remove">#clear#</button></span>'
827            + '</fieldset>'
828            + '</div>'
829        ,
830        gridShowhide: '<li data-index="#index#" class="datagrid-col-check"><a href="javascript:;"><i class="fa fa-check-square-o"></i>#label#</a></li>',
831        gridEditBtn : '<button type="button" class="btn btn-green bjui-datagrid-btn edit"><i class="fa fa-edit"></i> #edit#</button>'
832            + '<button type="button" class="btn btn-green bjui-datagrid-btn update"><i class="fa fa-edit"></i> #update#</button>'
833            + '<button type="button" class="btn btn-green bjui-datagrid-btn save"><i class="fa fa-check"></i> #save#</button>'
834            + '<button type="button" class="btn btn-orange bjui-datagrid-btn cancel"><i class="fa fa-undo"></i> #cancel#</button>'
835            + '<button type="button" class="btn btn-red bjui-datagrid-btn delete"><i class="fa fa-remove"></i> #del#</button>'
836        ,
837        gridDialogEditBtns: '<ul>'
838            + '    <li class="pull-left"><button type="button" class="btn btn-orange prev" data-icon="arrow-up">#prev#</button></li>'
839            + '    <li class="pull-left"><button type="button" class="btn btn-orange next" data-icon="arrow-down">#next#</button></li>'
840            + '    <li><button type="button" class="btn btn-red cancel" data-icon="remove">#cancel#</button></li>'
841            + '    <li><button type="button" class="btn btn-default save" data-icon="save">#save#</button></li>'
842            + '</ul>'
843        ,
844        gridExpandBtn: '<span title="#expandMsg#"><i class="fa fa-plus"></i></span>',
845        gridShrinkBtn: '<span title="#shrinkMsg#"><i class="fa fa-minus"></i></span>',
846        alertBoxFrag: '<div id="bjui-alertMsgBox" class="bjui-alert"><div class="alertContent"><div class="#type#"><div class="alertInner"><h1><i class="fa #fa#"></i>#title#</h1><div class="msg">#message##prompt#</div></div><div class="toolBar clearfix"><ul>#btnFragment#</ul></div></div></div></div>',
847        alertBtnFrag: '<li><button class="btn btn-#class#" rel="#callback#" type="button">#btnMsg#</button></li>',
848        calendarFrag: '<div id="bjui-calendar">' +
849            '    <div class="main">' +
850            '        <a class="close" href="javascript:;" title="#close#"><i class="fa fa-times-circle"></i></a>' +
851            '        <div class="head">' +
852            '            <table width="100%" border="0" cellpadding="0" cellspacing="2">' +
853            '                <tr>' +
854            '                    <td width="20"><a class="prev" href="javascript:;" title="#prev#"><i class="fa fa-arrow-left"></i></a></td>' +
855            '                    <td><select name="year"></select></td>' +
856            '                    <td><select name="month"></select></td>' +
857            '                    <td width="20"><a class="next" href="javascript:;" title="#next#"><i class="fa fa-arrow-right"></i></a></td>' +
858            '                </tr>' +
859            '            </table>' +
860            '        </div>' +
861            '        <div class="body">' +
862            '            <dl class="dayNames"><dt>7</dt><dt>1</dt><dt>2</dt><dt>3</dt><dt>4</dt><dt>5</dt><dt>6</dt></dl>' +
863            '            <dl class="days"><!-- date list --></dl>' +
864            /*年+月、月 显示配置 begin 2020-11-13*/
865            '            <dl class="yyym" style="padding:4px 0;height:120px"><!-- date list --></dl>' +
866            '            <dl class="onlyy"><!-- date list --></dl>' +
867            /*年+月、月 显示配置 end 2020-11-13*/
868            '            <div style="clear:both;height:0;line-height:0"></div>' +
869            '        </div>' +
870            '        <div class="foot">' +
871            '            <table class="time">' +
872            '                <tr>' +
873            '                    <td>' +
874            '                        <input type="text" class="hh" maxlength="2" data-type="hh" data-start="0" data-end="23">:<input' +
875            '                         type="text" class="mm" maxlength="2" data-type="mm" data-start="0" data-end="59">:<input' +
876            '                         type="text" class="ss" maxlength="2" data-type="ss" data-start="0" data-end="59">' +
877            '                    </td>' +
878            '                    <td><ul><li class="up" data-add="1">&and;</li><li class="down">&or;</li></ul></td>' +
879            '                </tr>' +
880            '            </table>' +
881            '            <button type="button" class="todayBtn btn btn-green" style="padding:2px;">#today#</button>' +//日期 新增今天按钮  2020-07-28
882            '            <button type="button" class="clearBtn btn btn-orange" style="padding:2px;">#clear#</button>' +
883            '            <button type="button" class="okBtn btn btn-default" style="padding:2px;">#ok#</button>' +
884            '        </div>' +
885            '        <div class="tm">' +
886            '            <ul class="hh">' +
887            '                <li>0</li>' +
888            '                <li>1</li>' +
889            '                <li>2</li>' +
890            '                <li>3</li>' +
891            '                <li>4</li>' +
892            '                <li>5</li>' +
893            '                <li>6</li>' +
894            '                <li>7</li>' +
895            '                <li>8</li>' +
896            '                <li>9</li>' +
897            '                <li>10</li>' +
898            '                <li>11</li>' +
899            '                <li>12</li>' +
900            '                <li>13</li>' +
901            '                <li>14</li>' +
902            '                <li>15</li>' +
903            '                <li>16</li>' +
904            '                <li>17</li>' +
905            '                <li>18</li>' +
906            '                <li>19</li>' +
907            '                <li>20</li>' +
908            '                <li>21</li>' +
909            '                <li>22</li>' +
910            '                <li>23</li>' +
911            '            </ul>' +
912            '            <ul class="mm">' +
913            '                <li>0</li>' +
914            '                <li>5</li>' +
915            '                <li>10</li>' +
916            '                <li>15</li>' +
917            '                <li>20</li>' +
918            '                <li>25</li>' +
919            '                <li>30</li>' +
920            '                <li>35</li>' +
921            '                <li>40</li>' +
922            '                <li>45</li>' +
923            '                <li>50</li>' +
924            '                <li>55</li>' +
925            '            </ul>' +
926            '            <ul class="ss">' +
927            '                <li>0</li>' +
928            '                <li>10</li>' +
929            '                <li>20</li>' +
930            '                <li>30</li>' +
931            '                <li>40</li>' +
932            '                <li>50</li>' +
933            '            </ul>' +
934            '        </div>' +
935            '    </div>' +
936            '</div>'
937        ,
938        spinnerBtn:  '<ul class="bjui-spinner"><li class="up" data-add="1">&and;</li><li class="down">&or;</li></ul>',
939        findgridBtn: '<a class="bjui-lookup" href="javascript:;" data-toggle="findgridbtn"><i class="fa fa-search"></i></a>',
940        dateBtn:     '<a class="bjui-lookup" href="javascript:;" data-toggle="datepickerbtn"><i class="fa fa-calendar"></i></a>',
941        navtabCM: '<ul id="bjui-navtabCM">' +
942            //'    <li rel="reload"><span class="icon"><i class="fa fa-refresh"></i></span><span class="title">#refresh#</span></li>' +
943            '    <li rel="closeCurrent"><span class="icon"><i class="fa fa-remove"></i></span><span class="title">#close#</li>' +
944            '    <li rel="closeOther"><span class="icon"><i class="fa fa-remove"></i></span><span class="title">#closeother#</li>' +
945            '    <li rel="closeAll"><span class="icon"><i class="fa fa-remove"></i></span><span class="title">#closeall#</li>' +
946            '</ul>'
947        ,
948        dialogCM: '<ul id="bjui-dialogCM">' +
949            //'    <li rel="reload"><span class="icon"><i class="fa fa-refresh"></i></span><span class="title">#refresh#</span></li>' +
950            '    <li rel="closeCurrent"><span class="icon"><i class="fa fa-remove"></i></span><span class="title">#close#</span></li>' +
951            '    <li rel="closeOther"><span class="icon"><i class="fa fa-remove"></i></span><span class="title">#closeother#</span></li>' +
952            '    <li rel="closeAll"><span class="icon"><i class="fa fa-remove"></i></span><span class="title">#closeall#</span></li>' +
953            '</ul>'
954        ,
955        externalFrag: '<iframe src="{url}" style="width:100%;height:{height};" frameborder="no" border="0" marginwidth="0" marginheight="0"></iframe>'
956    }
957
958}(jQuery);
959/*!
960 * B-JUI  V1.31 (http://b-jui.com)
961 * Git@OSC (http://git.oschina.net/xknaan/B-JUI)
962 * Copyright 2014 K'naan.
963 * Licensed under Apache (http://www.apache.org/licenses/LICENSE-2.0)
964 */
965
966/* ========================================================================
967 * B-JUI: bjui-extends.js  V1.31
968 * @author K'naan
969 * http://git.oschina.net/xknaan/B-JUI/blob/master/BJUI/js/bjui-extends.js
970 * ========================================================================
971 * Copyright 2014 K'naan.
972 * Licensed under Apache (http://www.apache.org/licenses/LICENSE-2.0)
973 * ======================================================================== */
974
975+function ($) {
976    'use strict';
977
978    $.fn.extend({
979        /**
980         * @param {Object} op: {type:GET/POST, url:ajax请求地址, data:ajax请求参数列表, callback:回调函数 }
981         */
982        ajaxUrl: function(op) {
983            var $this = $(this), $target = $this//$this.closest('.bjui-pageContent')
984
985            if (!$target.length)
986                $target = $this
987
988            $this.trigger(BJUI.eventType.beforeAjaxLoad)
989
990            if (op.loadingmask) {
991                $target.trigger(BJUI.eventType.ajaxStatus)
992            }
993
994            $.ajax({
995                type     : op.type || 'GET',
996                url      : op.url,
997                data     : op.data || {},
998                cache    : false,
999                dataType : 'html',
1000                timeout  : BJUI.ajaxTimeout,
1001                success  : function(response) {
1002                    var json = response.toJson(), $ajaxMask = $target.find('> .bjui-ajax-mask')
1003
1004                    if (!json[BJUI.keys.statusCode]) {
1005                        $this.empty().html(response).initui()
1006                    } else {
1007                        if (json[BJUI.keys.statusCode] == BJUI.statusCode.error) {
1008                            if (json[BJUI.keys.message]) $this.alertmsg('error', json[BJUI.keys.message])
1009                            if (!$this.closest('.bjui-layout').length) {
1010                                if ($this.closest('.navtab-panel').length) $this.navtab('closeCurrentTab')
1011                                else $this.dialog('closeCurrent')
1012                            }
1013                        } else if (json[BJUI.keys.statusCode] == BJUI.statusCode.timeout) {
1014                            if ($this.closest('.bjui-dialog').length) $this.dialog('closeCurrent')
1015                            if ($this.closest('.navtab-panel').length) $this.navtab('closeCurrentTab')
1016
1017                            BJUI.alertmsg('info', (json[BJUI.keys.message] || BJUI.regional.sessiontimeout))
1018                            BJUI.loadLogin()
1019                        }
1020                        $ajaxMask.fadeOut('normal', function() {
1021                            $(this).remove()
1022                        })
1023                    }
1024
1025                    if ($.isFunction(op.callback)) op.callback(response)
1026                },
1027                error      : function(xhr, ajaxOptions, thrownError) {
1028                    $this.bjuiajax('ajaxError', xhr, ajaxOptions, thrownError)
1029                    if (!$this.closest('.bjui-layout').length) {
1030                        if ($this.closest('.navtab-panel').length) $this.navtab('closeCurrentTab')
1031                        else $this.dialog('closeCurrent')
1032                    }
1033                    $this.trigger('bjui.ajaxError')
1034                },
1035                statusCode : {
1036                    0  : function(xhr, ajaxOptions, thrownError) {
1037                        BJUI.alertmsg('error', BJUI.regional.ajaxnosend)
1038                    },
1039                    503: function(xhr, ajaxOptions, thrownError) {
1040                        BJUI.alertmsg('error', BJUI.regional.statusCode_503)
1041                    }
1042                }
1043            })
1044        },
1045        loadUrl: function(url,data,callback) {
1046            $(this).ajaxUrl({url:url, data:data, callback:callback})
1047        },
1048        doAjax: function(op) {
1049            var $this = $(this), $target, $ajaxMask
1050
1051            $this.data('holdSubmit', true)
1052
1053            if (!op.url) {
1054                BJUI.debug('The ajax url is undefined!')
1055                return
1056            }
1057            if (!op.callback) {
1058                BJUI.debug('The ajax callback is undefined!')
1059                return
1060            } else {
1061                op.callback = op.callback.toFunc()
1062            }
1063            if (op.loadingmask) {
1064                $target = $this.isTag('form') ? $this.closest('.bjui-pageContent') : $this
1065
1066                if (!$target.length)
1067                    $target = $this
1068
1069                $target.trigger(BJUI.eventType.ajaxStatus)
1070                $ajaxMask = $target.find('> .bjui-ajax-mask')
1071            }
1072            if (!op.type) op.type = 'POST'
1073            if (!op.dataType) op.dataType = 'json'
1074            if (!op.cache) op.cache = false
1075            op.timeout = op.ajaxTimeout || BJUI.ajaxTimeout
1076            op.success = function(response) {
1077                if ($ajaxMask) {
1078                    if (op.callback) {
1079                        $.when(op.callback(response)).done(function() {
1080                            $target.trigger('bjui.ajaxStop')
1081                        })
1082                    } else {
1083                        $target.trigger('bjui.ajaxStop')
1084                    }
1085                } else {
1086                    op.callback(response)
1087                }
1088
1089                $this.data('holdSubmit', false)
1090            }
1091            op.error = function(xhr, ajaxOptions, thrownError) {
1092                if ($ajaxMask)
1093                    $target.trigger('bjui.ajaxError')
1094
1095                $this.bjuiajax('ajaxError', xhr, ajaxOptions, thrownError)
1096
1097                $this.data('holdSubmit', false)
1098            }
1099            op.statusCode = {
1100                0  : function(xhr, ajaxOptions, thrownError) {
1101                    BJUI.alertmsg('error', BJUI.regional.ajaxnosend)
1102
1103                    $this.data('holdSubmit', false)
1104                },
1105                503: function(xhr, ajaxOptions, thrownError) {
1106                    BJUI.alertmsg('error', BJUI.regional.statusCode_503)
1107
1108                    $this.data('holdSubmit', false)
1109                }
1110            }
1111
1112            $.ajax(op)
1113        },
1114        getPageTarget: function() {
1115            var $target
1116
1117            if (this.closest('.bjui-layout').length) $target = this.closest('.bjui-layout')
1118            else if (this.closest('.navtab-panel').length) $target = $.CurrentNavtab
1119            else $target = $.CurrentDialog
1120
1121            return $target
1122        },
1123        resizePageH: function() {
1124            return this.each(function() {
1125                if ($(this).closest('.tab-content').length) return
1126
1127                var $box         = $(this),
1128                    $pageHeader  = $box.find('> .bjui-pageHeader'),
1129                    $pageContent = $box.find('> .bjui-pageContent'),
1130                    $pageFooter  = $box.find('> .bjui-pageFooter'),
1131                    headH        = $pageHeader.outerHeight() || 0,
1132                    footH        = $pageFooter.outerHeight() || 0
1133
1134                if ($pageFooter.css('bottom')) footH += parseInt($pageFooter.css('bottom')) || 0
1135
1136                $pageContent.css({top:headH, bottom:footH})
1137                /*兼容IE11中 ztree 下拉时重叠问题 --2019-09-20*/
1138                // if ($box.hasClass('dialogContent') && !$pageContent.length) {
1139                //     $box.css({padding:10, overflow:'auto'})
1140                // }
1141            })
1142        },
1143        getMaxIndexObj: function($elements) {
1144            var zIndex = 0, index = 0
1145
1146            $elements.each(function(i) {
1147                var newZIndex = parseInt($(this).css('zIndex')) || 1
1148
1149                if (zIndex < newZIndex) {
1150                    zIndex = newZIndex
1151                    index  = i
1152                }
1153            })
1154
1155            return $elements.eq(index)
1156        },
1157        /**
1158         * 将表单数据转成JSON对象 用法:$(form).serializeJson() Author: K'naan
1159         */
1160        serializeJson: function () {
1161            var o = {}
1162            var a = this.serializeArray()
1163
1164            $.each(a, function () {
1165                if (o[this.name] !== undefined) {
1166                    if (!o[this.name].push) {
1167                        o[this.name] = [o[this.name]]
1168                    }
1169                    o[this.name].push(this.value || '')
1170                } else {
1171                    o[this.name] = this.value || ''
1172                }
1173            })
1174
1175            return o
1176        },
1177        isTag: function(tn) {
1178            if (!tn) return false
1179            if (!$(this).prop('tagName')) return false
1180            return $(this)[0].tagName.toLowerCase() == tn ? true : false
1181        },
1182        /**
1183         * 判断当前元素是否已经绑定某个事件
1184         * @param {Object} type
1185         */
1186        isBind: function(type) {
1187            var _events = $(this).data('events')
1188            return _events && type && _events[type]
1189        },
1190        /**
1191         * 输出firebug日志
1192         * @param {Object} msg
1193         */
1194        log: function(msg) {
1195            return this.each(function() {
1196                if (console) console.log('%s: %o', msg, this)
1197            })
1198        }
1199    })
1200
1201    /**
1202     * 扩展String方法
1203     */
1204    $.extend(String.prototype, {
1205        isPositiveInteger: function() {
1206            return (new RegExp(/^[1-9]\d*$/).test(this))
1207        },
1208        isInteger: function() {
1209            return (new RegExp(/^\d+$/).test(this))
1210        },
1211        isNumber: function() {
1212            return (new RegExp(/^([-]{0,1}(\d+)[\.]+(\d+))|([-]{0,1}(\d+))$/).test(this))
1213        },
1214        isNormalID: function() {
1215            return (new RegExp(/^[a-zA-Z][0-9a-zA-Z_-]*$/).test(this))
1216        },
1217        includeChinese: function() {
1218            return (new RegExp(/[\u4E00-\u9FA5]/).test(this))
1219        },
1220        trim: function() {
1221            return $.trim(this)
1222        },
1223        startsWith: function (pattern) {
1224            return this.indexOf(pattern) === 0
1225        },
1226        endsWith: function(pattern) {
1227            var d = this.length - pattern.length
1228            return d >= 0 && this.lastIndexOf(pattern) === d
1229        },
1230        replaceSuffix: function(index) {
1231            return this.replace(/\[[0-9]+\]/,'['+index+']').replace('#index#',index)
1232        },
1233        replaceSuffix2: function(index) {
1234            return this.replace(/\-(i)([0-9]+)$/, '-i'+ index).replace('#index#', index)
1235        },
1236        trans: function() {
1237            return this.replace(/&lt;/g, '<').replace(/&gt;/g,'>').replace(/&quot;/g, '"')
1238        },
1239        encodeTXT: function() {
1240            return (this).replaceAll('&', '&amp;').replaceAll('<','&lt;').replaceAll('>', '&gt;').replaceAll(' ', '&nbsp;')
1241        },
1242        replaceAll: function(os, ns) {
1243            return this.replace(new RegExp(os, 'gm'), ns)
1244        },
1245        /*替换占位符为对应选择器的值*/ //{^(.|\#)[A-Za-z0-9_-\s]*}
1246        replacePlh: function($box) {
1247            $box = $box || $(document)
1248            return this.replace(/{\/?[^}]*}/g, function($1) {
1249                var $input = $box.find($1.replace(/[{}]+/g, ''))
1250
1251                return $input && $input.val() ? $input.val() : $1
1252            })
1253        },
1254        replaceMsg: function(holder) {
1255            return this.replace(new RegExp('({.*})', 'g'), holder)
1256        },
1257        replaceTm: function($data) {
1258            if (!$data) return this
1259
1260            return this.replace(RegExp('({[A-Za-z_]+[A-Za-z0-9_-]*})','g'), function($1) {
1261                return $data[$1.replace(/[{}]+/g, '')]
1262            })
1263        },
1264        replaceTmById: function(_box) {
1265            var $parent = _box || $(document)
1266
1267            return this.replace(RegExp('({[A-Za-z_]+[A-Za-z0-9_-]*})','g'), function($1) {
1268                var $input = $parent.find('#'+ $1.replace(/[{}]+/g, ''))
1269                return $input.val() ? $input.val() : $1
1270            })
1271        },
1272        isFinishedTm: function() {
1273            return !(new RegExp('{\/?[^}]*}').test(this))
1274        },
1275        skipChar: function(ch) {
1276            if (!this || this.length===0) return ''
1277            if (this.charAt(0)===ch) return this.substring(1).skipChar(ch)
1278            return this
1279        },
1280        isValidPwd: function() {
1281            return (new RegExp(/^([_]|[a-zA-Z0-9]){6,32}$/).test(this))
1282        },
1283        isValidMail: function() {
1284            return(new RegExp(/^\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$/).test(this.trim()))
1285        },
1286        isSpaces: function() {
1287            for (var i = 0; i < this.length; i += 1) {
1288                var ch = this.charAt(i)
1289
1290                if (ch!=' '&& ch!='\n' && ch!='\t' && ch!='\r') return false
1291            }
1292            return true
1293        },
1294        isPhone:function() {
1295            return (new RegExp(/(^([0-9]{3,4}[-])?\d{3,8}(-\d{1,6})?$)|(^\([0-9]{3,4}\)\d{3,8}(\(\d{1,6}\))?$)|(^\d{3,8}$)/).test(this))
1296        },
1297        isUrl:function() {
1298            return (new RegExp(/^[a-zA-z]+:\/\/([a-zA-Z0-9\-\.]+)([-\w .\/?%&=:]*)$/).test(this))
1299        },
1300        isExternalUrl:function() {
1301            return this.isUrl() && this.indexOf('://'+ document.domain) == -1
1302        },
1303        toBool: function() {
1304            return (this.toLowerCase() === 'true') ? true : false
1305        },
1306        toJson: function() {
1307            var json = this
1308
1309            try {
1310                if (typeof json === 'object') json = json.toString()
1311                if (!json.trim().match("^\{(.+:.+,*){1,}\}$")) return this
1312                else return JSON.parse(this)
1313            } catch (e) {
1314                return this
1315            }
1316        },
1317        toObj: function() {
1318            var obj = null
1319
1320            try {
1321                obj = (new Function('return '+ this))()
1322            } catch (e) {
1323                obj = this
1324                BJUI.debug('String toObj:Parse "String" to "Object" error! Your str is: '+ this)
1325            }
1326            return obj
1327        },
1328        /**
1329         * String to Function
1330         * 参数(方法字符串或方法名): 'function(){...}' 或 'getName' 或 'USER.getName' 均可
1331         * Author: K'naan
1332         */
1333        toFunc: function() {
1334            if (!this || !this.length) return undefined
1335
1336            if (this.startsWith('function')) {
1337                return (new Function('return '+ this))()
1338            }
1339
1340            try {
1341                var m_arr = this.split('.'), fn = window
1342
1343                for (var i = 0; i < m_arr.length; i++) {
1344                    fn = fn[m_arr[i]]
1345                }
1346
1347                if (typeof fn === 'function') {
1348                    return fn
1349                }
1350            } catch (e) {
1351                return undefined
1352            }
1353        }
1354    })
1355
1356    /* Function */
1357    $.extend(Function.prototype, {
1358        //to fixed String.prototype -> toFunc
1359        toFunc: function() {
1360            return this
1361        }
1362    })
1363
1364    /* Array */
1365    $.extend(Array.prototype, {
1366        remove: function(index) {
1367            if (index < 0) return this
1368            else return this.slice(0, index).concat(this.slice(index + 1, this.length))
1369        },
1370        swap: function(indexA, indexB) {
1371            var arr = this, temp = arr[indexA]
1372
1373            arr[indexA] = arr[indexB]
1374            arr[indexB] = temp
1375
1376            return this
1377        },
1378        move: function(old_index, new_index) {
1379            if (old_index < 0 || new_index < 0)
1380                return this
1381
1382            if (new_index >= this.length) {
1383                var k = new_index - this.length
1384
1385                while ((k--) + 1) {
1386                    this.push(undefined)
1387                }
1388            }
1389
1390            this.splice(new_index, 0, this.splice(old_index, 1)[0])
1391
1392            return this
1393        },
1394        // move continuous item
1395        moveItems: function(startIndex, newIndex, len) {
1396            if (!len || newIndex == startIndex) return this
1397
1398            var moveArr = this.slice(startIndex, startIndex + len)
1399
1400            if (startIndex > newIndex)
1401                this.splice(startIndex, len)
1402
1403            this.splice.apply(this, [newIndex, 0].concat(moveArr))
1404
1405            if (startIndex < newIndex)
1406                this.splice(startIndex, len)
1407
1408            return this
1409        },
1410        unique: function() {
1411            var temp = new Array()
1412
1413            this.sort()
1414            for (var i = 0; i < this.length; i++) {
1415                if (this[i] == this[i + 1]) continue
1416                temp[temp.length] = this[i]
1417            }
1418
1419            return temp
1420        },
1421        myIndexOf: function(e) {
1422            if (!this || !this.length) return -1
1423
1424            for (var i = 0, j; j = this[i]; i++) {
1425                if (j == e) return i
1426            }
1427
1428            return -1
1429        },
1430        /* serializeArray to json */
1431        toJson: function() {
1432            var o = {}
1433            var a = this
1434
1435            $.each(a, function () {
1436                if (o[this.name] !== undefined) {
1437                    if (!o[this.name].push) {
1438                        o[this.name] = [o[this.name]]
1439                    }
1440                    o[this.name].push(this.value || '')
1441                } else {
1442                    o[this.name] = this.value || ''
1443                }
1444            })
1445
1446            return o
1447        }
1448    })
1449
1450    /* Global */
1451    $.isJson = function(obj) {
1452        var flag = true
1453
1454        try {
1455            flag = $.parseJSON(obj)
1456        } catch (e) {
1457            return false
1458        }
1459        return flag ? true : false
1460    }
1461
1462}(jQuery);
1463/*!
1464 * B-JUI  V1.31 (http://b-jui.com)
1465 * Git@OSC (http://git.oschina.net/xknaan/B-JUI)
1466 * Copyright 2014 K'naan.
1467 * Licensed under Apache (http://www.apache.org/licenses/LICENSE-2.0)
1468 */
1469
1470/* ========================================================================
1471 * B-JUI: bjui-basedrag.js  V1.31
1472 * @author K'naan
1473 * http://git.oschina.net/xknaan/B-JUI/blob/master/BJUI/js/bjui-basedrag.js
1474 * ========================================================================
1475 * Copyright 2014 K'naan.
1476 * Licensed under Apache (http://www.apache.org/licenses/LICENSE-2.0)
1477 * ======================================================================== */
1478
1479+function ($) {
1480    'use strict';
1481
1482    // BASEDRAG CLASS DEFINITION
1483    // ======================
1484
1485    var Basedrag = function(element, options) {
1486        this.$element = $(element)
1487        this.options  = options
1488        this.tools    = this.TOOLS()
1489    }
1490
1491    Basedrag.prototype.TOOLS = function() {
1492        var tools = {
1493            isOver: function($drop, x, y) {
1494                var offset = $drop.offset(),
1495                    left   = offset.left,
1496                    top    = offset.top,
1497                    width  = $drop.outerWidth(),
1498                    height = $drop.outerHeight()
1499
1500                return (x > left && x < (left + width)) && (y > top && y < (top + height))
1501            },
1502            mouseDirection: function (element, opts) {
1503                var $element = $(element), dirs = ['top', 'right', 'bottom', 'left']
1504                var calculate = function (e) {
1505                    var w = $element.outerWidth(),
1506                        h = $element.outerHeight(),
1507                        offset = $element.offset(),
1508                        x = (e.pageX - offset.left - (w / 2)) * (w > h ? (h / w) : 1),
1509                        y = (e.pageY - offset.top - (h / 2)) * (h > w ? (w / h) : 1)
1510
1511                    return Math.round((((Math.atan2(y, x) * (180 / Math.PI)) + 180) / 90) + 3) % 4
1512                }
1513
1514                //enter leave代表鼠标移入移出时的回调
1515                opts = $.extend({}, {
1516                    move: $.noop
1517                }, opts || {})
1518
1519                var r = calculate(opts.e)
1520
1521                opts.move($element, dirs[r])
1522                /*
1523                $element.off('mouseenter.basedrag.direction').on('mouseenter.basedrag.direction', function (e) {
1524                    var r = calculate(e)
1525
1526                    opts.enter($element, dirs[r])
1527                }).off('mouseleave.basedrag.direction').on('mouseleave.basedrag.direction', function (e) {
1528                    var r = calculate(e)
1529
1530                    opts.leave($element, dirs[r])
1531                })*/
1532            }
1533        }
1534
1535        return tools
1536    }
1537
1538    Basedrag.prototype.init = function() {
1539        var that = this
1540
1541        that.$drag = this.$element
1542        that.options.$obj = this.$element
1543        if (that.options.obj) this.options.$obj = this.options.obj
1544        if (that.options.event) {
1545            that.hasEvent = true
1546            that.start(this.options.event)
1547        } else {
1548            if (that.options.selector)
1549                that.$drag = that.$element.find(that.options.selector)
1550
1551            if (that.$drag.length) {
1552                that.$drag.on('mousedown', function(e) {
1553                    that.start.apply(that, [e])
1554                    that.options.event = e
1555                })
1556            }
1557        }
1558    }
1559
1560    Basedrag.prototype.start = function(e) {
1561        $(document).on('selectstart', false)
1562        var that = this, options = that.options
1563
1564        if (options.exclude) {
1565            var $exclude = that.$element.find(options.exclude)
1566
1567            if ($exclude.length && $.inArray(e.target, $exclude.add($exclude.f
1567ind('*'))) != -1) {
1568                return false
1569            }
1570        }
1571
1572        if (this.$element.css('position') === 'static') {
1573            this.$element.css('position', 'absolute')
1574            !options.oleft && (options.oleft = this.$element.position().left)
1575            !options.otop  && (options.otop  = this.$element.position().top)
1576            this.$element.css('position', '')
1577        }
1578        if (!options.oleft) options.oleft = parseInt(this.$element.css('left')) || 0
1579        if (!options.otop)  options.otop  = parseInt(this.$element.css('top')) || 0
1580
1581        $(document)
1582            .on('mouseup.bjui.basedrag', function(e) { that.stop.apply(that, [e]) })
1583            .on('mousemove.bjui.basedrag', function(e) { that.drag.apply(that, [e]) })
1584    }
1585
1586    Basedrag.prototype.drop = function(e) {
1587        var that = this, options = that.options, $drop = options.drop
1588
1589        if (!$drop instanceof jQuery)
1590            $drop = $($drop)
1591
1592        if ($drop.length) {
1593            that.$drops = $drop
1594            $drop.each(function() {
1595                if (that.tools.isOver($(this), e.pageX, e.pageY)) {
1596                    $(this).trigger('dropover.bjui.basedrag', [e.pageX, e.pageY, that.$element])
1597
1598                    that.isDrop = true
1599                    that.$drop  = $(this)
1600
1601                    return false
1602                } else {
1603                    $(this).trigger('dropout.bjui.basedrag', [e.pageX, e.pageY, that.$element])
1604                    that.isDrop = false
1605                }
1606            }).css('-moz-user-select', 'none')
1607        }
1608    }
1609
1610    Basedrag.prototype.drag = function(e) {
1611        if (!e) e = window.event
1612
1613        BJUI['bjui.basedrag'] = this.$element
1614
1615        var that       = this,
1616            options    = this.options,
1617            beforeDrag = options.beforeDrag,
1618            trData     = options.treeData,      // only for drop Datagrid
1619            dataIndex  = this.$element.index(), // only for drop Datagrid
1620            left       = options.oleft + (e.pageX - options.event.pageX),
1621            top        = options.otop + (e.pageY - options.event.pageY)
1622
1623        if (beforeDrag && typeof beforeDrag === 'string')
1624            beforeDrag = beforeDrag.toFunc()
1625        if (beforeDrag && typeof beforeDrag === 'function') {
1626            if (this.$element.next().hasClass('datagrid-child-tr'))
1627                dataIndex = dataIndex / 2
1628
1629            if (!beforeDrag.apply(this, [this.$element, (trData ? trData[dataIndex] : '')])) {
1630                return false
1631            }
1632        }
1633
1634        if (options.drop) options.move = ''
1635        //if (top < 1) top = 0
1636        if (options.move === 'horizontal') {
1637            if ((options.minW && left >= parseInt(this.options.$obj.css('left')) + options.minW) && (options.maxW && left <= parseInt(this.options.$obj.css('left')) + options.maxW)) {
1638                this.$element.css('left', left)
1639            } else if (options.scop) {
1640                if (options.relObj) {
1641                    if ((left - parseInt(options.relObj.css('left'))) > options.cellMinW)
1642                        this.$element.css('left', left)
1643                    else
1644                        this.$element.css('left', left)
1645                }
1646            }
1647        } else if (options.move === 'vertical') {
1648            this.$element.css('top', top)
1649        } else {
1650            var $selector = options.selector ? this.options.$obj.find(options.selector) : this.options.$obj
1651
1652            if (options.drop) {
1653                var $placeholder = $('#bjui-drag-placeholder')
1654
1655                if (!$placeholder.length)
1656                    $placeholder = $('<div style="position:absolute; z-index:999;" id="bjui-drag-placeholder"></div>').appendTo($('body'))
1657
1658                $placeholder.css({left:e.pageX, top:e.pageY, opacity:1}).show().empty().append(this.$element.clone())
1659
1660                this.$placeholder = $placeholder
1661            } else {
1662                this.$element.css({left:left, top:top})
1663            }
1664        }
1665        if (options.drag)
1666            options.drag.apply(this.$element, [this.$element, e, left, top])
1667
1668        if (options.drop) {
1669            that.drop(e)
1670        }
1671        if (options.container) {
1672            if (!options.container instanceof jQuery)
1673                options.container = $(options.container)
1674
1675            var scrollTop = options.container.scrollTop()
1676
1677            if (!scrollTop) {
1678                options.container.scrollTop(1)
1679            }
1680            if (options.container.scrollTop()) {
1681                that.tools.mouseDirection(options.container, {
1682                    e: e,
1683                    move: function ($element, dir) {
1684                        if (dir === 'top' || dir === 'bottom') {
1685                            options.container.scrollTop(options.container.scrollTop() + (e.clientY - options.event.clientY) / 13)
1686                        }
1687                    }
1688                })
1689            }
1690        }
1691
1692        return this.preventEvent(e)
1693    }
1694
1695    Basedrag.prototype.stop = function(e) {
1696        var that = this
1697
1698        $(document).off('mousemove.bjui.basedrag').off('mouseup.bjui.basedrag').off('mouseover.bjui.basedrag')
1699
1700        that.options.drop && that.options.drop.off('mouseenter.bjui.basedrag')
1701
1702        if (this.options.stop)
1703            this.options.stop.apply(this.$element, [this.$element, e])
1704
1705        if (this.hasEvent)
1706            this.destroy()
1707        else {
1708            that.$drag.off('mousedown').on('mousedown', $.proxy(function(e) {
1709                that.options.event = e
1710                that.options.oleft = 0
1711                that.options.otop  = 0
1712
1713                that.start(e)
1714            }, that))
1715        }
1716
1717        if (that.options.drop && !that.isDrop) {
1718            var offset = that.$element.offset()
1719
1720            that.$placeholder && that.$placeholder.animate({top:offset.top, left:offset.left, opacity:0.2}, 'normal', function() {
1721                that.$placeholder.hide()
1722            })
1723        }
1724        if (that.isDrop) {
1725            that.$placeholder && that.$placeholder.hide()
1726            that.$drop && that.$drop.trigger('drop.bjui.basedrag', [that.$element])
1727        }
1728
1729        that.$drops && that.$drops.css('-moz-user-select', '')
1730        $(document).off('selectstart')
1731        return this.preventEvent(e)
1732    }
1733
1734    Basedrag.prototype.preventEvent = function(e) {
1735        if (e.stopPropagation) e.stopPropagation()
1736        if (e.preventDefault) e.preventDefault()
1737        return false
1738    }
1739
1740    Basedrag.prototype.destroy = function() {
1741        this.$element.removeData('bjui.basedrag')
1742        if (!this.options.nounbind) this.$element.off('mousedown')
1743    }
1744
1745    // BASEDRAG PLUGIN DEFINITION
1746    // =======================
1747
1748    function Plugin(option) {
1749        var args     = arguments
1750        var property = option
1751
1752        return this.each(function () {
1753            var $this   = $(this)
1754            var options = $.extend({}, $this.data(), typeof option === 'object' && option)
1755            var data    = $this.data('bjui.basedrag')
1756
1757            if (!data) $this.data('bjui.basedrag', (data = new Basedrag(this, options)))
1758            if (typeof property === 'string' && $.isFunction(data[property])) {
1759                [].shift.apply(args)
1760                if (!args) data[property]()
1761                else data[property].apply(data, args)
1762            } else {
1763                data.init()
1764            }
1765        })
1766    }
1767
1768    var old = $.fn.basedrag
1769
1770    $.fn.basedrag             = Plugin
1771    $.fn.basedrag.Constructor = Basedrag
1772
1773    // BASEDRAG NO CONFLICT
1774    // =================
1775
1776    $.fn.basedrag.noConflict = function () {
1777        $.fn.basedrag = old
1778        return this
1779    }
1780
1781}(jQuery);
1782/*!
1783 * B-JUI  V1.31 (http://b-jui.com)
1784 * Git@OSC (http://git.oschina.net/xknaan/B-JUI)
1785 * Copyright 2014 K'naan.
1786 * Licensed under Apache (http://www.apache.org/licenses/LICENSE-2.0)
1787 */
1788
1789/* ========================================================================
1790 * B-JUI: bjui-sidenav.js  V1.31
1791 * @author K'naan
1792 * http://git.oschina.net/xknaan/B-JUI/blob/master/BJUI/js/bjui-sidenav.js
1793 * ========================================================================
1794 * Copyright 2014 K'naan.
1795 * Licensed under Apache (http://www.apache.org/licenses/LICENSE-2.0)
1796 * ======================================================================== */
1797
1798+function ($) {
1799    'use strict';
1800
1801    // SLIDEBAR CLASS DEFINITION
1802    // ======================
1803
1804    var Sidenav = function(element, options) {
1805        this.$element = $(element)
1806        this.options  = options
1807    }
1808
1809    Sidenav.prototype.ajaxHnav = function() {
1810        var that = this, options = that.options, childKey = options.childKey || 'children', $li = that.$element.parent(), $box = $('#bjui-sidenav-box'), html = BJUI.StrBuilder(),
1811            $sidenavbtn = $('#bjui-sidenav-btn')
1812        var createA = function(data) {
1813            var liHtml = BJUI.StrBuilder(), target = data.target || 'navtab'
1814
1815            liHtml.add('<a href="'+ (data.url || 'javascript:;') +'" ')
1816
1817            if (data.url && (target === 'dialog' || target === 'navtab')) {
1818                liHtml.add('data-toggle="'+ target +'" data-options="{id:\''+ data.id +'\', title:\''+ (data.title || data.name) +'\'')
1819
1820                if (data.width)  liHtml.add(', width:'+ data.width)
1821                if (data.height) liHtml.add(', height:'+ data.height)
1822                if (data.fresh)  liHtml.add(', fresh:'+ data.fresh)
1823                if (data.mask)   liHtml.add(', mask:'+ data.mask)
1824
1825                liHtml.add('}"')
1826            } else if (data.url)
1827                liHtml.add('target="'+ target +'"')
1828
1829            if (data[childKey])
1830                liHtml.add(' class="right-arrow"')
1831
1832            liHtml.add('><i class="fa fa-'+ (data.icon || 'caret-right') +'"></i>&nbsp;'+ data.name)
1833
1834            if (data[childKey])
1835                liHtml.add('<b><i class="fa fa-angle-right"></i></b>')
1836
1837            liHtml
1838                .add('</a>')
1839                .add(createChild(data))
1840
1841            return liHtml.toString()
1842        }
1843        var createChild = function(data) {
1844            var childHtml = BJUI.StrBuilder()
1845
1846            if (data[childKey]) {
1847                childHtml.add('<ul class="nav">')
1848
1849                $.each(data[childKey], function(i, m) {
1850                    var target = m.target || 'navtab', id = m.id && String(m.id).isNormalID && m.id
1851
1852                    childHtml.add('<li')
1853
1854                    if (target === 'navtab' && id && m.url)
1855                        childHtml.add(' class="'+ target +'-'+ id +'"')
1856
1857                    childHtml
1858                        .add('>')
1859                        .add(createA(m))
1860                        .add('</li>')
1861                })
1862
1863                childHtml.add('</ul>')
1864            }
1865
1866            return childHtml.toString()
1867        }
1868        var okCallback = function(json) {
1869            if (!$.isArray(json)) {
1870                json = [json]
1871            }
1872
1873            html.add('<ul class="nav">')
1874
1875            $.each(json, function(i, n) {
1876                var target = n.target || 'navtab', id = n.id && String(n.id).isNormalID && n.id
1877
1878                html.add('<li')
1879
1880                if (target === 'navtab' && id && n.url)
1881                    html.add(' class="'+ target +'-'+ id +'"')
1882
1883                html.add('>')
1884                    .add(createA(n))
1885                    .add('</li>')
1886            })
1887
1888            html.add('</ul>')
1889
1890            $box.html(html.toString())
1891                .off('click').on('click', '.nav > li > a', function(e) {
1892                var $this = $(this), $nav = $this.next('.nav'), $li = $this.closest('li'), $other = $li.siblings()
1893
1894                if ($nav.length) {
1895                    $nav.stop().slideToggle(function() {
1896                        $li.toggleClass('open', $nav.is(':visible'))
1897                    })
1898
1899                    if (!$li.hasClass('open')) {
1900                        $other.find('> .nav').stop().slideUp(function() {
1901                            $(this).closest('li').removeClass('open')
1902                        })
1903                    }
1904                }
1905            })
1906
1907            $li.data('bjui.sidenav.hnav.panels', $box.find('> ul'))
1908
1909            $(document).on('switch.bjui.navtab', function(e) {
1910                var datas = $('body').data('bjui.navtab'), $lis
1911
1912                if (datas && datas.current) {
1913                    $box.find('li').removeClass('active').filter('.navtab-'+ datas.current).addClass('active')
1914                }
1915            })
1916
1917            /*清除默认打开第一个子模块--begin 修改于-2018-05-31*/
1918            /* if (BJUI.ui.displayFirst)//
1919                $box.find('> .nav > li:first > a').trigger('click')*/
1920            /*清除默认打开第一个子模块--end*/
1921
1922            !$('body').data('bjui.sidenav.init') && $sidenavbtn.is(':visible') && ($sidenavbtn.trigger('click'))
1923        }
1924        var treeCallback = function(json) {
1925            var single = (typeof options.single === 'undefined' || single), $ul, html = BJUI.StrBuilder()
1926
1927            $box.empty()
1928
1929            if (single) {
1930                $ul =
1931                    $('<ul class="ztree" data-toggle="ztree" id="bjui-sidenav-ztree-0"></ul>')
1932                        .data('options', options.treeOptions)
1933                        .data('nodes', json)
1934
1935                $box.append($ul).initui()
1936            } else {
1937                if (!$.isArray(json))
1938                    json = [json]
1939
1940                $.each(json, function(i, n) {
1941                    $ul =
1942                        $('<ul class="ztree" data-toggle="ztree" id="bjui-sidenav-ztree-'+ i +'"></ul>')
1943                            .data('options', options.treeOptions)
1944                            .data('nodes', json)
1945
1946                    $box.append($ul)
1947                })
1948
1949                $box.initui()
1950            }
1951
1952            !$('body').data('bjui.sidenav.init') && $sidenavbtn.is(':visible') && ($sidenavbtn.trigger('click'))
1953        }
1954
1955        BJUI.ajax('doajax', {
1956            url         : options.url,
1957            loadingmask : false,
1958            target      : $box,
1959            okCallback  : options.tree ? treeCallback : okCallback
1960        })
1961    }
1962    //初始化二级菜单
1963    Sidenav.prototype.initHnav = function() {
1964        var that = this, options = that.options, childKey = options.childKey || 'children', targetKey = options.targetKey || 'target', idKey = options.idKey || 'id',
1965            $li = that.$element.parent(), $box = $('#bjui-sidenav-box'), $sidenavbtn = $('#bjui-sidenav-btn'),
1966            html = BJUI.StrBuilder(), json
1967        var createA = function(data) {
1968            if (!data) data = {}
1969
1970            var liHtml = BJUI.StrBuilder(), target = data[targetKey] || 'navtab'
1971
1972            liHtml.add('<a href="'+ (data.url || 'javascript:;') +'" ')
1973
1974            if (data.url && (target === 'dialog' || target === 'navtab')) {
1975                //liHtml.add('data-toggle="'+ target +'" data-options="{id:\''+ data[idKey] +'\', title:\''+ (data.title || data.name) +'\'')  //update 2018-8-1
1976                //二级菜单添加ID edit by lch 20190226
1977                liHtml.add('id="IF' + data.id + '" title="' + (data.title || data.name) + '" data-toggle="'+ target +'" data-options="{parent_id:\''+ data.parentID +'\',id:\''+ 'sys_'+ data.id +'\',name:\''+data.menuClass+'\', title:\''+ (data.title || data.name) +'\'')  //update 2018-8-22
1978
1979                // liHtml.add('data-toggle="'+ target +'" data-options="{id:\''+'sys_'+data.id +'\', title:\''+ (data.title || data.name) +'\'')
1980
1981                if (data.width)  liHtml.add(', width:'+ data.width)
1982                if (data.height) liHtml.add(', height:'+ data.height)
1983                if (data.fresh)  liHtml.add(', fresh:'+ data.fresh)
1984                if (data.mask)   liHtml.add(', mask:'+ data.mask)
1985
1986                liHtml.add('}"')
1987            } else if (data.url)
1988                liHtml.add('target="'+ target +'"')
1989
1990            if (data[childKey])
1991                liHtml.add(' class="right-arrow"')
1992
1993            // liHtml.add('><i class="fa fa-'+ (data.icon || 'caret-right') +'"></i>&nbsp;'+ data.name)
1994            liHtml.add('onclick="mainSys.openModel(\''+data.menuClass+'\',\''+data.id+'\',\''+data.name+'\',\''+data.url+'\',\''+data.parentID+'\')"><span class="iconfont iconSun_line_Business"></span>&nbsp;'+ data.name)
1995
1996            if (data[childKey])
1997                liHtml.add('<b><i class="fa fa-angle-right"></i></b>')
1998
1999            liHtml
2000                .add('</a>')
2001                .add(createChild(data))
2002
2003            return liHtml.toString()
2004        }
2005
2006        var createChild = function(data) {
2007            var childHtml = BJUI.StrBuilder()
2008
2009            if (data[childKey]) {
2010                childHtml.add('<ul class="nav">')
2011
2012                $.each(data[childKey], function(i, m) {
2013                    var target = m.target || 'navtab', id = m[idKey] && String(m[idKey]).isNormalID && m[idKey]
2014
2015                    childHtml.add('<li')
2016
2017                    if (target === 'navtab' && id && m.url)
2018                        childHtml.add(' class="'+ target +'-'+ id +'"')
2019
2020                    childHtml
2021                        .add('>')
2022                        .add(createA(m))
2023                        .add('</li>')
2024                })
2025
2026                childHtml.add('</ul>')
2027            }
2028
2029            return childHtml.toString()
2030        }
2031        var okCallback = function(json) {
2032            if (!$.isArray(json)) {
2033                json = [json]
2034            }
2035
2036            html.add('<ul class="nav">')
2037
2038            $.each(json, function(i, n) {
2039                //var target = n.target || 'navtab', id = n[idKey] && String(n[idKey]).isNormalID && n[idKey]
2040                //-->update:2018-8-24
2041                var target = n.target || 'navtab', id = n.id && String(n.id).isNormalID && n.id
2042
2043                // html.add('<li onmouseover="showTipMsg(this)" onmouseout="hideTipMsg()"')
2044                html.add('<li') //2020-04-20
2045
2046                if (target === 'navtab' && id && n.url)
2047                    //html.add(' class="'+ target +'-'+ id +'"')  ---->update: 2018-8-24
2048                    var str=n.url
2049                str=str.split("/")
2050                str=str[str.length-1].split(".")[0]
2051
2052                //自定义图标的特殊化拼接处理--update-2019-1-29
2053                if(str=='moduleEng'){
2054                    html.add(' class="'+ target +'-'+ str +'-'+ id +'"')
2055                }
2056                html.add(' class="'+ target +'-'+ str +'"')
2057
2058
2059                html.add('>')
2060                    .add(createA(n))
2061                    .add('</li>')
2062            })
2063
2064            html.add('</ul>')
2065
2066            $box.html(html.toString())
2067                .off('click').on('click', '.nav > li > a', function(e) {
2068
2069                /*给当前点击的二级菜单添加类--begin-->update-2018-8-30*/
2070                $(".nav > li > a").removeClass("subMenu-active");
2071                $(this).addClass("subMenu-active");
2072                /*给当前点击的二级菜单添加类--end*/
2073
2074                /*存储当前点击菜单层级的标识*/
2075//                    if(!commonBlank(sessionObject.activeMenuName)){
2076////                    	sessionObject.activeMenuName = null;
2077//                    }
2078//                    sessionObject.subMenu_active = "subMenu-active"
2079
2080
2081                var $this = $(this), $nav = $this.next('.nav'), $li = $this.closest('li'), $other = $li.siblings()
2082
2083                if ($nav.length) {
2084                    $nav.stop().slideToggle(function() {
2085                        $li.toggleClass('open', $nav.is(':visible'))
2086                    })
2087
2088                    if (!$li.hasClass('open')) {
2089                        $other.find('> .nav').stop().slideUp(function() {
2090                            $(this).closest('li').removeClass('open')
2091                        })
2092                    }
2093                }
2094            })
2095
2096            $li.data('bjui.sidenav.hnav.panels', $box.find('> ul'))
2097
2098            $(document).on('switch.bjui.navtab', function(e) {
2099                var datas = $('body').data('bjui.navtab'), $lis
2100
2101                if (datas && datas.current) {
2102                    $box.find('li').removeClass('active').filter('.navtab-'+ datas.current).addClass('active')
2103                }
2104            })
2105            /*清除默认打开第一个子模块--begin */
2106            /* if (BJUI.ui.displayFirst)
2107                $box.find('> .nav > li:first > a').trigger('click')*/  //update 2018-8-22
2108            /*清除默认打开第一个子模块--end */
2109
2110            !$('body').data('bjui.sidenav.init') && $sidenavbtn.is(':visible') && ($sidenavbtn.trigger('click'))
2111        }
2112        var treeCallback = function(json) {
2113            var single = (typeof options.single === 'undefined' || single), $ul, html = BJUI.StrBuilder()
2114
2115            $box.empty()
2116
2117            if (single) {
2118                $ul =
2119                    $('<ul class="ztree" data-toggle="ztree" id="bjui-sidenav-ztree-0"></ul>')
2120                        .data('options', options.treeOptions)
2121                        .data('nodes', json)
2122
2123                $box.append($ul).initui()
2124            } else {
2125                if (!$.isArray(json))
2126                    json = [json]
2127
2128                $.each(json, function(i, n) {
2129                    $ul =
2130                        $('<ul class="ztree" data-toggle="ztree" id="bjui-sidenav-ztree-'+ i +'"></ul>')
2131                            .data('options', options.treeOptions)
2132                            .data('nodes', json)
2133
2134                    $box.append($ul)
2135                })
2136
2137                $box.initui()
2138            }
2139
2140            !$('body').data('bjui.sidenav.init') && $sidenavbtn.is(':visible') && ($sidenavbtn.trigger('click'))
2141        }
2142
2143        json = that.$element.next('.items').html()
2144        if (json) {
2145            json = $.parseJSON(json)
2146            options.tree ? treeCallback(json) : okCallback(json)
2147        }
2148    }
2149
2150    // SLIDEBAR PLUGIN DEFINITION
2151    // =======================
2152
2153    function Plugin(option) {
2154        var args     = arguments
2155        var property = option
2156
2157        return this.each(function () {
2158            var $this   = $(this)
2159            var options = $.extend({}, $this.data(), typeof option === 'object' && option)
2160            var data    = $this.data('bjui.sidenav')
2161
2162            if (!data) $this.data('bjui.sidenav', (data = new Sidenav(this, options)))
2163
2164            if (typeof property === 'string' && $.isFunction(data[property])) {
2165                [].shift.apply(args)
2166                if (!args) data[property]()
2167                else data[property].apply(data, args)
2168            }
2169        })
2170    }
2171
2172    var old = $.fn.sidenav
2173
2174    $.fn.sidenav             = Plugin
2175    $.fn.sidenav.Constructor = Sidenav
2176
2177    // SLIDEBAR NO CONFLICT
2178    // =================
2179
2180    $.fn.basedrag.noConflict = function () {
2181        $.fn.sidenav = old
2182        return this
2183    }
2184
2185    // SLIDEBAR DATA-API
2186    // ==============
2187    $(function() {
2188        $('#bjui-sidenav-col').on('click.bjui.sidenav', '.nav > li > a', function() {
2189            var $this = $('#bjui-sidenav-col')
2190
2191            if ($(this).hasClass('right-arrow'))
2192                return false
2193
2194            if ($this.hasClass('autohide'))
2195                $('#bjui-sidenav-arrow').trigger('click')
2196        })
2197    })
2198
2199    //update 2019-7-10 huan  click of menuone--> mouseover
2200    //menu two 版本1--底部弹出式: 使用 click;  版本2---下拉式: 使用 mouseover
2201    $(document).on('mouseover.bjui.sidenav.data-api', '[data-toggle="sidenav"]', function(e) {
2202        e.preventDefault()
2203
2204        var $body = $('body'), $this = $(this), href = $this.data('url') || $this.attr('href'), cache = $this.data('cache'),
2205            $li   = $(this).parent(), $box = $('#bjui-sidenav-box'), $panels = $li.data('bjui.sidenav.hnav.panels')
2206
2207        if (typeof $body.data('bjui.sidenav.init') === 'undefined')
2208            $body.data('bjui.sidenav.init', true)
2209        else
2210            $body.data('bjui.sidenav.init', false)
2211
2212        $li.addClass('active').siblings().removeClass('active')
2213
2214        if (href && !(href.startsWith('#') || href.startsWith('javascript'))) {
2215            if (cache && $panels && $panels.length) {
2216                $box.append($panels)
2217            } else {
2218                $this.data('url', href)
2219                Plugin.call($this, 'ajaxHnav')
2220            }
2221        } else {
2222            $box.find('> .nav').detach()
2223
2224            if ($panels && $panels.length) {
2225                $box.append($panels)
2226            } else {
2227                Plugin.call($this, 'initHnav')
2228            }
2229        }
2230    })
2231
2232}(jQuery);
2233/*!
2234 * B-JUI  V1.31 (http://b-jui.com)
2235 * Git@OSC (http://git.oschina.net/xknaan/B-JUI)
2236 * Copyright 2014 K'naan.
2237 * Licensed under Apache (http://www.apache.org/licenses/LICENSE-2.0)
2238 */
2239
2240/* ========================================================================
2241 * B-JUI: bjui-contextmenu.js  V1.31
2242 * @author K'naan
2243 * http://git.oschina.net/xknaan/B-JUI/blob/master/BJUI/js/bjui-contextmenu.js
2244 * ========================================================================
2245 * Copyright 2014 K'naan.
2246 * Licensed under Apache (http://www.apache.org/licenses/LICENSE-2.0)
2247 * ======================================================================== */
2248
2249+function ($) {
2250    'use strict';
2251
2252    // CONTEXTMENU GLOBAL ELEMENTS
2253    // ======================
2254
2255    var $menu, $shadow, hash
2256
2257    $(function() {
2258        var INIT_CONTEXTMENU = function() {
2259            $menu   = $('<div id="bjui-contextmenu"></div>').hide()
2260            $shadow = $('<div id="bjui-contextmenuShadow"></div>').hide()
2261            hash    = []
2262
2263            $('body').append('<!-- contextmenu -->').append($menu).append($shadow)
2264        }
2265
2266        INIT_CONTEXTMENU()
2267    })
2268
2269    // CONTEXTMENU CLASS DEFINITION
2270    // ======================
2271    var Contextmenu = function(element, options) {
2272        this.$element = $(element)
2273        this.options  = options
2274    }
2275
2276    Contextmenu.DEFAULTS = {
2277        id       : undefined,
2278        shadow   : true,
2279        bindings : {},
2280        ctrSub   : null
2281    }
2282
2283    Contextmenu.prototype.init = function() {
2284        var that  = this
2285        var op    = this.options
2286
2287        if (!op.id) return
2288        hash.push({
2289            id       : op.id,
2290            shadow   : op.shadow,
2291            bindings : op.bindings || {},
2292            ctrSub   : op.ctrSub
2293        })
2294
2295        var index = hash.length - 1
2296
2297        this.$element.on('contextmenu', function(e) {
2298            that.display(index, this, e, op)
2299            return false
2300        })
2301    }
2302
2303    Contextmenu.prototype.display = function(index, trigger, e, options) {
2304        var that    = this
2305        var cur     = hash[index]
2306        var cp      = BJUI.regional[cur.id]
2307        var content = FRAG[cur.id]
2308
2309        $.each(cp, function(i, n) {
2310            content = content.replace('#'+ i +'#', cp[i])
2311        })
2312
2313        // Send the content to the menu
2314        $menu.html(content)
2315        $.each(cur.bindings, function(id, func) {
2316            $('[rel="'+ id +'"]', $menu).on('click', function(e) {
2317                that.hide()
2318                func($(trigger), $('#bjui-'+ cur.id))
2319            })
2320        })
2321
2322        var posX = e.pageX
2323        var posY = e.pageY
2324
2325        if ($(window).width() < posX + $menu.width())   posX -= $menu.width()
2326        if ($(window).height() < posY + $menu.height()) posY -= $menu.height()
2327
2328        $menu.css({'left':posX, 'top':posY}).show()
2329        if (cur.shadow)
2330            $shadow.css({width:$menu.width(), height:$menu.height(), left:posX + 3, top:posY + 3}).show()
2331        $(document).one('click', that.hide)
2332
2333        if ($.isFunction(cur.ctrSub))
2334            cur.ctrSub($(trigger), $('#bjui-'+ cur.id))
2335    }
2336
2337    Contextmenu.prototype.hide = function() {
2338        $menu.hide()
2339        $shadow.hide()
2340    }
2341
2342    /* Custom contextmenu */
2343    Contextmenu.prototype.show = function(options) {
2344        var that = this
2345
2346        if (options.items && options.items.length) {
2347            that.$element.on('contextmenu', function(e) {
2348                var isShow = true
2349
2350                /*exclude*/
2351                if (options.exclude) {
2352                    that.$element.find(options.exclude).each(function() {
2353                        if (this == e.target || $(this).find(e.target).length) {
2354                            isShow = false
2355                            return
2356                        }
2357                    })
2358                }
2359
2360                if (!isShow) {
2361                    e.stopPropagation()
2362                    return !isShow
2363                } else {
2364                    that.custom(options.items, e)
2365                }
2366
2367                return false
2368            })
2369        }
2370    }
2371
2372    Contextmenu.prototype.custom = function(items, e) {
2373        $menu.empty().html('<ul></ul>')
2374
2375        var that    = this
2376        var options = that.options
2377        var $ul     = $menu.find('> ul'), $li
2378
2379        $.each(items, function(i, n) {
2380            var icon = ''
2381
2382            if (n.icon) icon = '<i class="fa fa-'+ n.icon +'"></i>'
2383            if (n.title == 'diver') {
2384                $li = $('<li class="diver"></li>')
2385            } else {
2386                $li = $('<li><span class="icon">'+ icon +'</span><span class="title">'+ n.title +'</span></li>')
2387                if (n.func && typeof n.func === 'string') n.func = n.func.toFunc()
2388                if (n.func) {
2389                    $li.on('click', function(evt) {
2390                        that.hide()
2391                        n.func(that.$element, $li)
2392                    })
2393                }
2394            }
2395            $li.appendTo($ul)
2396        })
2397
2398        var posX = e.pageX
2399        var posY = e.pageY
2400
2401        if ($(window).width() < posX + $menu.width())   posX -= $menu.width()
2402        if ($(window).height() < posY + $menu.height()) posY -= $menu.height()
2403
2404        $menu.css({'left':posX, 'top':posY}).show()
2405
2406        if (options.shadow)
2407            $shadow.css({width:$menu.width(), height:$menu.height(), left:posX + 3, top:posY + 3}).show()
2408
2409        $(document).one('click', that.hide)
2410    }
2411
2412    // CONTEXTMENU PLUGIN DEFINITION
2413    // =======================
2414
2415    function Plugin(option) {
2416        var args     = arguments
2417        var property = option
2418
2419        return this.each(function () {
2420            var $this   = $(this)
2421            var options = $.extend({}, Contextmenu.DEFAULTS, $this.data(), typeof option === 'object' && option)
2422            var data    = $this.data('bjui.contextmenu')
2423
2424            if (!data) $this.data('bjui.contextmenu', (data = new Contextmenu(this, options)))
2425            if (typeof property === 'string' && $.isFunction(data[property])) {
2426                [].shift.apply(args)
2427                if (!args) data[property]()
2428                else data[property].apply(data, args)
2429            } else {
2430                data.init()
2431            }
2432        })
2433    }
2434
2435    var old = $.fn.contextmenu
2436
2437    $.fn.contextmenu             = Plugin
2438    $.fn.contextmenu.Constructor = Contextmenu
2439
2440    // CONTEXTMENU NO CONFLICT
2441    // =================
2442
2443    $.fn.contextmenu.noConflict = function () {
2444        $.fn.contextmenu = old
2445        return this
2446    }
2447
2448}(jQuery);
2449/*!
2450 * B-JUI  V1.31 (http://b-jui.com)
2451 * Git@OSC (http://git.oschina.net/xknaan/B-JUI)
2452 * Copyright 2014 K'naan.
2453 * Licensed under Apache (http://www.apache.org/licenses/LICENSE-2.0)
2454 */
2455
2456/* ========================================================================
2457 * B-JUI: bjui-navtab.js  V1.31
2458 * @author K'naan
2459 * http://git.oschina.net/xknaan/B-JUI/blob/master/BJUI/js/bjui-navtab.js
2460 * ========================================================================
2461 * Copyright 2014 K'naan.
2462 * Licensed under Apache (http://www.apache.org/licenses/LICENSE-2.0)
2463 * ======================================================================== */
2464
2465+function ($) {
2466    'use strict';
2467
2468    // NAVTAB GLOBAL ELEMENTS
2469    // ======================
2470
2471    var currentIndex, $currentTab, $currentPanel, $box, $tabHeader, $tabs, $panels, $prevBtn, $nextBtn, $moreBtn, $moreBox, $main, $mainLi,
2472        autorefreshTimer
2473
2474    $(function() {
2475        var INIT_NAVTAB = function() {
2476            currentIndex = 0
2477            $box         = $('#bjui-navtab')
2478            $tabHeader   = $box.find('> .tabsPageHeader')
2479            $tabs        = $box.find('> .tabsPageHeader > .tabsPageHeaderContent > .navtab-tab')
2480            $panels      = $box.find('> .navtab-panel')
2481            $prevBtn     = $box.find('> .tabsPageHeader > .tabsLeft')
2482            $nextBtn     = $box.find('> .tabsPageHeader > .tabsRight')
2483            $moreBtn     = $box.find('> .tabsPageHeader > .tabsMore')
2484            $moreBox     = $box.find('> .tabsMoreList')
2485            $main        = $tabs.find('li:first')
2486            $mainLi      = $moreBox.find('li:first')
2487
2488            $prevBtn.click(function() { $(this).navtab('scrollPrev') })
2489            $nextBtn.click(function() { $(this).navtab('scrollNext') })
2490            $moreBtn.click(function() {
2491                $moreBox.show()
2492
2493                var hh = $(window).height(), mh = $moreBox.height(), th = $('#bjui-top').height() + $('#bjui-navbar').height(), sh = hh - th - 26
2494
2495                if (sh < mh)
2496                    $moreBox.height(sh - 10)
2497                else
2498                    $moreBox.height('')
2499            })
2500
2501            $(document).on('click.bjui.navtab.switchtab', function(e) {
2502                var $target = e.target.tagName == 'I' ? $(e.target).parent() : $(e.target)
2503
2504                if ($moreBtn[0] != $target[0]) $moreBox.hide()
2505            })
2506
2507            var mainTit, options = $.extend({}, Navtab.DEFAULTS, $main.data(), {id:'main', title:mainTit}), mainTab = new Navtab(options)
2508
2509            $('body').data('bjui.navtab', {main:mainTab, current:'main'})
2510
2511            if ($main.attr('data-url')) {
2512                $(document).one(BJUI.eventType.initUI, function(e) {
2513                    $main.removeAttr('data-url').navtab('reload', options)
2514                })
2515            }
2516
2517            $main
2518                .data('options', $.extend({}, options))
2519                .navtab('contextmenu', $main)
2520                .click(function() { if (!$(this).hasClass('active')) BJUI.navtab('switchTab', 'main') })
2521                .find('> a > span').html(function(n, c) { return (mainTit = c.replace('#maintab#', BJUI.regional.maintab)) })
2522
2523            if ($main.attr('data-url')) {
2524                $(document).one(BJUI.eventType.initUI, function(e) {
2525                    $main.removeAttr('data-url').navtab('reload', options)
2526                })
2527            }
2528
2529            setTimeout(function() {
2530                $main.trigger('click')
2531            }, 100)
2532
2533            $mainLi
2534                .click(function() {
2535                    if ($(this).hasClass('active')) $moreBox.hide()
2536                    else BJUI.navtab('switchTab', 'main')
2537                })
2538                .find('> a').html(function(n, c) { return c.replace('#maintab#', BJUI.regional.maintab) })
2539
2540            $.CurrentNavtab = $panels.find('> .navtabPage').eq(0)
2541        }
2542
2543        INIT_NAVTAB()
2544    })
2545
2546    // NAVTAB CLASS DEFINITION
2547    // ======================
2548
2549    var Navtab = function(options) {
2550        this.options  = options
2551        this.tools    = this.TOOLS()
2552    }
2553
2554    Navtab.DEFAULTS = {
2555        id          : null,
2556        title       : 'New tab',
2557        url         : null,
2558        type        : 'GET',
2559        data        : {},
2560        loadingmask : true,
2561        fresh       : false,
2562        autorefresh : false,
2563        onLoad      : null,
2564        beforeClose : null,
2565        onClose     : null
2566    }
2567
2568    Navtab.prototype.TOOLS = function() {
2569        var that = this
2570        var tools = {
2571            getDefaults: function() {
2572                return Navtab.DEFAULTS
2573            },
2574            getTabs: function() {
2575                return $tabs.find('> li')
2576            },
2577            getPanels: function() {
2578                return $panels.find('> div')
2579            },
2580            getMoreLi: function() {
2581                return $moreBox.find('> li')
2582            },
2583            getTab: function(tabid) {
2584                var index = this.indexTabId(tabid)
2585
2586                if (index >= 0) return this.getTabs().eq(index)
2587            },
2588            getPanel: function(tabid) {
2589                var index = this.indexTabId(tabid)
2590
2591                if (index >= 0) return this.getPanels().eq(index)
2592            },
2593            getTabsW: function(iStart, iEnd) {
2594                return this.tabsW(this.getTabs().slice(iStart, iEnd))
2595            },
2596            tabsW: function($tabs) {
2597                var iW = 0
2598
2599                $tabs.each(function() {
2600                    iW += $(this).outerWidth(true)
2601                })
2602
2603                return iW
2604            },
2605            indexTabId: function(tabid) {
2606                var iOpenIndex = -1
2607
2608                if (!tabid) return iOpenIndex
2609
2610                this.getTabs().each(function(index) {
2611                    if ($(this).data('options').id === tabid) {
2612                        iOpenIndex = index
2613                        return false
2614                    }
2615                })
2616
2617                return iOpenIndex
2618            },
2619            getLeft: function() {
2620                return $tabs.position().left
2621            },
2622            getScrollBarW: function() {
2623                // return $box.width() - 55
2624                return $tabHeader.width()-55
2625            },
2626            visibleStart: function() {
2627                var $tabs = this.getTabs(), iLeft = this.getLeft(), iW = 0, index = 0
2628
2629                $tabs.each(function(i) {
2630                    if (iW + iLeft >= 0) {
2631                        index = i
2632                        return false
2633                    }
2634                    iW += $(this).outerWidth(true)
2635                })
2636
2637                return index
2638            },
2639            visibleEnd: function() {
2640                var tools = this, $tabs = this.getTabs(), iLeft = this.getLeft(), iW = 0, index = $tabs.length
2641
2642                $tabs.each(function(i) {
2643                    iW += $(this).outerWidth(true)
2644                    if (iW + iLeft > tools.getScrollBarW()) {
2645                        index = i
2646                        return false
2647                    }
2648                })
2649
2650                return index
2651            },
2652            scrollPrev: function() {
2653                var iStart = this.visibleStart()
2654
2655                if (iStart > 0)
2656                    this.scrollTab(- this.getTabsW(0, iStart - 1))
2657            },
2658            scrollNext: function() {
2659                var iEnd = this.visibleEnd()
2660
2661                if (iEnd < this.getTabs().size())
2662                    this.scrollTab(- this.getTabsW(0, iEnd + 1) + this.getScrollBarW())
2663            },
2664            scrollTab: function(iLeft, isNext) {
2665                $tabs.animate({ left: iLeft }, 150, function() { that.tools.ctrlScrollBtn() })
2666            },
2667            scrollCurrent: function() { // auto scroll current tab
2668                var iW = this.tabsW(this.getTabs()), scrollW = this.getScrollBarW()
2669                //iW:所有li的外宽度     scrollW:tabheader的宽度
2670                // this.getLeft()  得到ul的left值
2671                if (iW <= scrollW)
2672                    this.scrollTab(0)
2673                else if (this.getLeft() < scrollW - iW-53)
2674                    this.scrollTab(scrollW-iW-53)
2675                else if (currentIndex < this.visibleStart())
2676                    this.scrollTab(- this.getTabsW(0, currentIndex))
2677                else if (currentIndex >= this.visibleEnd())
2678                    this.scrollTab(scrollW - this.getTabs().eq(currentIndex).outerWidth(true) - this.getTabsW(0, currentIndex))
2679            },
2680            ctrlScrollBtn: function() {
2681                var iW = this.tabsW(this.getTabs())
2682                if (this.getScrollBarW() > iW) {
2683                    $prevBtn.hide()
2684                    $nextBtn.hide()
2685                    $moreBtn.hide()
2686                    $tabs.parent().removeClass('tabsPageHeaderMargin')
2687                } else {
2688                    $prevBtn.show().removeClass('tabsLeftDisabled')
2689                    $nextBtn.show().removeClass('tabsRightDisabled')
2690                    $moreBtn.show().removeClass('tabsMoreDisabled')
2691                    // $tabs.parent().addClass('tabsPageHeaderMargin')
2692                    if (this.getLeft() >= 0)
2693                        $prevBtn.addClass('tabsLeftDisabled')
2694                    else if (this.getLeft() <= this.getScrollBarW() - iW)
2695                        $nextBtn.addClass('tabsRightDisabled')
2696                }
2697            },
2698            switchTab: function(iTabIndex) {
2699                var $tab = this.getTabs().removeClass('active').eq(iTabIndex).addClass('active'), $panels = this.getPanels(), $panel = $panels.eq(iTabIndex), onSwitch = that.options.onSwitch ? that.options.onSwitch.toFunc() : null
2700                var $ajaxBackground = $(FRAG.maskBackground)
2701
2702                $panels.css({top:'-10000000px'})
2703
2704                if ($tab.data('reloadFlag')) {
2705                    $panel.animate({top:0})
2706                    that.refresh($tab.data('options').id)
2707                } else {
2708                    if ($panel.find('.bjui-ajax-mask').length) {
2709                        $panel.css({top:0})
2710                    } else {
2711                        $panel
2712                            .css({top:0})
2713                            .append($ajaxBackground)
2714
2715                        $ajaxBackground.fadeOut('normal', function() {
2716                            $(this).remove()
2717                        })
2718                    }
2719                }
2720
2721                this.getMoreLi().removeClass('active').eq(iTabIndex).addClass('active')
2722                currentIndex = iTabIndex
2723                this.scrollCurrent()
2724                $currentTab     = $tab
2725                $.CurrentNavtab = $currentPanel = $panel
2726
2727                if (onSwitch) onSwitch.apply(that)
2728
2729                // set current to body data
2730                var datas = $('body').data('bjui.navtab'), id = $tab.data('options').id,parent_id=$tab.data('options').parent_id
2731
2732                if (id !== that.options.id)
2733                    datas.current = id
2734                else {
2735                    datas.current = that.options.id
2736                }
2737
2738                /*update - 2019-7-10 huan begin*/
2739                var $main_nav= $("#main-nav li");
2740                $main_nav.each(function () {
2741                    var link_val=$(this).find("a").attr("data-link");
2742                    if(link_val==parent_id){
2743                        $(this).addClass("active");
2744                    }else{
2745                        $(this).removeClass("active");
2746                    }
2747                });
2748                /*update - 2019-7-10 huan end*/
2749
2750                // events
2751                $panel.trigger('switch.bjui.navtab')
2752            },
2753            closeTab: function(index, openTabid) {
2754                var $tab        = this.getTabs().eq(index),
2755                    $more       = this.getMoreLi().eq(index),
2756                    $panel      = this.getPanels().eq(index),
2757                    options     = $tab.data('options'),
2758                    beforeClose = options.beforeClose ? options.beforeClose.toFunc() : null,
2759                    onClose     = options.onClose ? options.onClose.toFunc() : null,
2760                    canClose    = true
2761
2762                if (beforeClose) canClose = beforeClose.apply(that, [$panel])
2763                if (!canClose) {
2764                    that.tools.switchTab(index)
2765                    return
2766                }
2767                $tab.remove()
2768                $more.remove()
2769                $panel.trigger(BJUI.eventType.beforeCloseNavtab).remove()
2770
2771                if (autorefreshTimer) clearInterval(autorefreshTimer)
2772                if (onClose) onClose.apply(that)
2773                if (currentIndex >= index) currentIndex--
2774                if (openTabid) {
2775                    var openIndex = this.indexTabId(openTabid)
2776
2777                    if (openIndex > 0) currentIndex = openIndex
2778                }
2779
2780                // remove from body
2781                var datas = $('body').data('bjui.navtab')
2782
2783                if (datas[options.id])
2784                    delete datas[options.id]
2785
2786                this.scrollCurrent()
2787                this.switchTab(currentIndex)
2788            },
2789            closeOtherTab: function(index) {
2790                index = index || currentIndex
2791
2792                this.getTabs().each(function(i) {
2793                    if (i > 0 && index != i) $(this).find('> .close').trigger('click')
2794                })
2795            },
2796            loadUrlCallback: function($panel) {
2797                $panel.find(':button.btn-close').click(function() { that.closeCurrentTab() })
2798            },
2799            updateTit: function(index, title) {
2800                this.getTabs().eq(index).find('> a').attr('title', title).find('> span').html(title)
2801                this.getMoreLi().eq(index).find('> a').attr('title', title).html(title)
2802            },
2803            reload: function($tab, flag) {
2804                flag = flag || $tab.data('reloadFlag')
2805
2806                var options = $tab.data('options')
2807
2808                if (flag) {
2809                    $tab.data('reloadFlag', false)
2810                    var $panel = that.tools.getPanel(options.id)
2811
2812                    if ($tab.hasClass('external')) {
2813                        that.openExternal(options.url, $panel, options.data)
2814                    } else {
2815                        that.tools.reloadTab($panel, options)
2816                    }
2817                }
2818            },
2819            reloadTab: function($panel, options) {
2820                var onLoad = options.onLoad ? options.onLoad.toFunc() : null,
2821                    arefre = options.autorefresh && (isNaN(String(options.autorefresh)) ? 15 : options.autorefresh)
2822
2823                $panel
2824                    .trigger(BJUI.eventType.beforeLoadNavtab)
2825                    .ajaxUrl({
2826                        type:(options.type || 'GET'), url:options.url, data:options.data || {}, loadingmask:options.loadingmask, callback:function(response) {
2827                            that.tools.loadUrlCallback($panel)
2828                            if (onLoad) onLoad.apply(that, [$panel])
2829                            if (autorefreshTimer) clearInterval(autorefreshTimer)
2830                            if (arefre) autorefreshTimer = setInterval(function() { $panel.navtab('refresh') }, arefre * 1000)
2831                            if (BJUI.ui.clientPaging && $panel.data('bjui.clientPaging')) $panel.pagination('setPagingAndOrderby', $panel)
2832                        }
2833                    })
2834            },
2835            onLoad:function(){
2836                console.log('onload')
2837            }
2838        }
2839
2840        return tools
2841    }
2842
2843    Navtab.prototype.contextmenu = function($obj) {
2844        var that = this
2845
2846        $obj.contextmenu({
2847            id: 'navtabCM',
2848            bindings: {
2849                reload: function(t, m) {
2850                    if (t.data('options').url)
2851                        that.refresh(t.data('options').id)
2852                },
2853                closeCurrent: function(t, m) {
2854                    var tabId = t.data('options').id
2855
2856                    if (tabId) that.closeTab(tabId)
2857                    else that.closeCurrentTab()
2858                },
2859                closeOther: function(t, m) {
2860                    if (!t.index()) {
2861                        that.closeAllTab()
2862                    } else {
2863                        var index = that.tools.indexTabId(t.data('options').id)
2864
2865                        that.tools.closeOtherTab(index > 0 ? index : currentIndex)
2866                    }
2867                },
2868                closeAll: function(t, m) {
2869                    that.closeAllTab()
2870                }
2871            },
2872            ctrSub: function(t, m) {
2873                var mReload = m.find('[rel="reload"]'),
2874                    mCur    = m.find('[rel="closeCurrent"]'),
2875                    mOther  = m.find('[rel="closeOther"]'),
2876                    mAll    = m.find('[rel="closeAll"]'),
2877                    $tabLi  = that.tools.getTabs()
2878
2879                if (!t.index()) {
2880                    mCur.addClass('disabled')
2881                    if (!t.data('options').url) mReload.addClass('disabled')
2882                }
2883            }
2884        })
2885    }
2886
2887    // if found tabid replace tab, else create a new tab.
2888    Navtab.prototype.openTab = function() {
2889        var that = this, options = this.options, tools = this.tools, iOpenIndex
2890
2891        if (!options.url && options.href) options.url = options.href
2892
2893        if (!options.url) {
2894            BJUI.debug('BJUI.Navtab: Error trying to open a navtab, url is undefined!')
2895            return
2896        } else {
2897            options.url = decodeURI(options.url).replacePlh()
2898
2899            if (!options.url.isFinishedTm()) {
2900                $('body').alertmsg('error', (options.warn || BJUI.regional.plhmsg))
2901                BJUI.debug('BJUI.Navtab: The new navtab\'s url is incorrect, url: '+ options.url)
2902                return
2903            }
2904
2905            options.url = encodeURI(options.url)
2906        }
2907
2908        iOpenIndex = options.id ? tools.indexTabId(options.id) : currentIndex
2909
2910        if (iOpenIndex >= 0) {
2911            var $tab   = tools.getTabs().eq(iOpenIndex),
2912                $panel = tools.getPanels().eq(iOpenIndex),
2913                op     = $tab.data('options')
2914
2915            if (options.fresh || options.url != op.url)
2916                that.reload(options)
2917            else if (options.title != op.title) {
2918                op.title = options.title
2919                tools.updateTit(iOpenIndex, options.title)
2920            }
2921
2922            currentIndex = iOpenIndex
2923
2924            if (options.id == 'main') {
2925                this.contextmenu($tab)
2926            }
2927        } else {
2928            var tabFrag = '<li><a href="javascript:" name="'+options.name+'"  title="#title#"><span>#title#</span></a><span class="close">&times;</span></li>',
2929                $tab = $(tabFrag.replaceAll('#title#', options.title)),
2930                $panel = $('<div class="navtabPage unitBox"></div>'),
2931                $more  = $('<li><a href="javascript:" title="#title#">#title#</a></li>'.replaceAll('#title#', options.title))
2932
2933            $tab.appendTo($tabs)
2934            $panel.appendTo($panels)
2935            $more.appendTo($moreBox)
2936
2937            $tab.data('options', $.extend({}, options))
2938
2939            if (options.external || (options.url && options.url.isExternalUrl())) {
2940                $tab.addClass('external')
2941                this.openExternal(options.url, $panel, options.data)
2942            } else {
2943                $tab.removeClass('external')
2944                tools.reloadTab($panel, options)
2945            }
2946
2947            currentIndex = tools.getTabs().length - 1
2948            this.contextmenu($tab)
2949
2950            //events
2951            $tab.on('click', function(e) {
2952                if (!$(this).hasClass('active'))
2953                    that.switchTab(options.id)
2954            }).on('click.bjui.navtab.close', '.close', function(e) {
2955                that.closeTab(options.id)
2956            }).on('mousedown.bjui.navtab.drag', 'a', function(e) {
2957                $tab.data('bjui.navtab.drag', true)
2958
2959                setTimeout($.proxy(function () {
2960                    if ($tab.data('bjui.navtab.drag')) that.drag(e, $tab, $panel, $more)
2961                }, that), 150)
2962
2963                e.preventDefault()
2964            }).on('mouseup.bjui.navtab.drag', 'a', function(e) {
2965                $tab.data('bjui.navtab.drag', false)
2966            })
2967
2968            $more.on('click', function() {
2969                that.switchTab(options.id)
2970            })
2971        }
2972
2973        tools.switchTab(currentIndex)
2974        tools.scrollCurrent()
2975    }
2976
2977    Navtab.prototype.closeTab = function(tabid) {
2978        var index = this.tools.indexTabId(tabid)
2979
2980        if (index > 0)
2981            this.tools.closeTab(index)
2982    }
2983
2984    Navtab.prototype.closeCurrentTab = function(openTabid) { //openTabid can be empty. close current tab by default, and open the last tab
2985        if (currentIndex > 0)
2986            this.tools.closeTab(currentIndex, openTabid)
2987    }
2988
2989    Navtab.prototype.closeAllTab = function() {
2990        this.tools.getTabs().find('> .close').trigger('click')
2991    }
2992
2993    Navtab.prototype.reloadFlag = function(tabids) {
2994        var arr = tabids.split(',')
2995
2996        for (var i = 0; i < arr.length; i++) {
2997            var $tab = this.tools.getTab(arr[i].trim())
2998
2999            if ($tab) {
3000                if (this.tools.indexTabId(arr[i]) == currentIndex) this.tools.reload($tab, true)
3001                else $tab.data('reloadFlag', true)
3002            }
3003        }
3004    }
3005
3006    Navtab.prototype.switchTab = function(tabid) {
3007        var index = this.tools.indexTabId(tabid)
3008
3009        this.tools.switchTab(index)
3010    }
3011
3012    Navtab.prototype.scrollPrev = function() {
3013        this.tools.scrollPrev()
3014    }
3015
3016    Navtab.prototype.scrollNext = function() {
3017        this.tools.scrollNext()
3018    }
3019
3020    Navtab.prototype.refresh = function(tabid) {
3021        var $tab, $panel
3022
3023        if (!tabid) {
3024            $tab = $currentTab
3025        } else if (typeof tabid === 'string') {
3026            $tab = this.tools.getTab(tabid)
3027        } else {
3028            $tab = tabid
3029        }
3030
3031        if ($tab && $tab.length) {
3032            $panel = this.tools.getPanel($tab.data('options').id)
3033            $panel.removeData('bjui.clientPaging')
3034
3035            this.reload($tab.data('options'))
3036        }
3037    }
3038
3039    Navtab.prototype.reload = function(option) {
3040        var that    = this,
3041            options = $.extend({}, typeof option === 'object' && option),
3042            $tab    = options.id ? this.tools.getTab(options.id) : this.tools.getTabs().eq(currentIndex)
3043
3044        if ($tab) {
3045            var op      = $tab.data('options')
3046            var _reload = function() {
3047                if (options.title && options.title != op.title) {
3048                    that.tools.updateTit($tab.index(), options.title)
3049                }
3050                $tab.data('options', $.extend({}, op, options))
3051                that.tools.reload($tab, true)
3052            }
3053
3054            if (op.reloadWarn) {
3055                $('body').alertmsg('confirm', op.reloadWarn, {
3056                    okCall: function() {
3057                        _reload()
3058                    }
3059                })
3060            } else {
3061                _reload()
3062            }
3063        }
3064    }
3065
3066    Navtab.prototype.reloadForm = function(clearQuery, option) {
3067        var options = $.extend({}, typeof option === 'object' && option),
3068            $tab    = options.id ? this.tools.getTab(options.id) : $currentTab,
3069            $panel  = options.id ? this.tools.getPanel(options.id) : $currentPanel
3070
3071        if ($tab && $panel) {
3072            var op         = $tab.data('options'),
3073                data       = {},
3074                pageData   = {},
3075                $pagerForm = options.form
3076
3077            if ($pagerForm && $pagerForm.length) {
3078                options.type = options.type || $pagerForm.attr('method') || 'POST'
3079                options.url  = options.url || $pagerForm.attr('action')
3080
3081                pageData = $pagerForm.serializeJson()
3082
3083                if (clearQuery) {
3084                    var pageInfo = BJUI.pageInfo
3085
3086                    for (var key in pageInfo) {
3087                        data[pageInfo[key]] = pageData[pageInfo[key]]
3088                    }
3089                } else {
3090                    data = pageData
3091                }
3092            }
3093
3094            options.data = $.extend({}, options.data || {}, data)
3095
3096            if (!$tab.hasClass('external')) {
3097                this.tools.reloadTab($panel, options)
3098            } else {
3099                this.openExternal(options.url, $panel, options.data)
3100            }
3101        }
3102    }
3103
3104    Navtab.prototype.getCurrentPanel = function() {
3105        return this.tools.getPanels().eq(currentIndex)
3106    }
3107
3108    Navtab.prototype.checkTimeout = function() {
3109        var json = JSON.parse($currentPanel.html())
3110
3111        if (json && json[BJUI.keys.statusCode] == BJUI.statusCode.timeout) this.closeCurrentTab()
3112    }
3113
3114    Navtab.prototype.openExternal = function(url, $panel, data) {
3115        var ih = $panel.closest('.navtab-panel').height()
3116
3117        if (data && !$.isEmptyObject(data)) {
3118            url.indexOf('?') ? url += '&' : '?'
3119            url += $.param(data)
3120        }
3121
3122        $panel.html(FRAG.externalFrag.replaceAll('{url}', url).replaceAll('{height}', ih +'px'))
3123    }
3124
3125    Navtab.prototype.drag = function(e, $tab, $panel, $more) {
3126        var that  = this,
3127            $lis  = that.tools.getTabs(), $panels = that.tools.getPanels(), $mores = that.tools.getMoreLi(),
3128            $drag = $tabs.next('.bjui-navtab-drag'),
3129            $prev = $tab.prev(), $next  = $tab.next(),
3130            index = $tab.index(), width = $tab.width(),
3131            oleft = $tab.position().left,
3132            leftarr = [], newArr = [], newIndex
3133
3134        if ($lis.length <= 2) return
3135
3136        if (!$drag.length) {
3137            $drag = $('<div class="bjui-navtab-drag" style="position:absolute; top:0; left:1px; width:2px; height:25px; background:#ff6600; display:none;"></div>')
3138            $drag.insertAfter($tabs)
3139        }
3140
3141        $drag.css('left', oleft - 2)
3142
3143        $tabs.find('> li').each(function() {
3144            leftarr.push($(this).position().left)
3145        })
3146
3147        $tab.find('> a').basedrag({
3148            move:'horizontal',
3149            oleft    : oleft,
3150            drag     : function($target, e, left, top) {
3151                $tab.addClass('navtab-drag')
3152
3153                newArr = [left]
3154                $.merge(newArr, leftarr)
3155                newArr.sort(function(a, b) { return a - b })
3156
3157                newIndex = $.inArray(left, newArr)
3158                if (!newIndex) newIndex = 1
3159                if (newIndex == $lis.length)
3160                    $drag.css('left', leftarr[newIndex - 1] - 2 + $lis.last().width())
3161                else
3162                    $drag.css('left', leftarr[newIndex] - 2)
3163
3164                $drag.show()
3165            },
3166            stop     : function() {
3167                $tab.removeClass('navtab-drag')
3168                $drag.hide()
3169
3170                if (index != newIndex) {
3171                    if (newIndex == $lis.length) {
3172                        if (index != $lis.length - 1) {
3173                            $tab.insertAfter($lis.eq(newIndex - 1))
3174                            $panel.insertAfter($panels.eq(newIndex - 1))
3175                            $more.insertAfter($mores.eq(newIndex - 1))
3176                        }
3177                    } else {
3178                        $tab.insertBefore($lis.eq(newIndex))
3179                        $panel.insertBefore($panels.eq(newIndex))
3180                        $more.insertBefore($mores.eq(newIndex))
3181                    }
3182                }
3183            },
3184            event    : e,
3185            nounbind : true
3186        })
3187    }
3188
3189    // NAVTAB PLUGIN DEFINITION
3190    // =======================
3191
3192    function Plugin(option) {
3193        var args     = arguments,
3194            property = option,
3195            navtab   = 'bjui.navtab',
3196            $body    = $('body'),
3197            datas    = $body.data(navtab) || {}
3198
3199        return this.each(function () {
3200            var $this   = $(this),
3201                options = $.extend({}, Navtab.DEFAULTS, typeof option === 'object' && option),
3202                id      = options && options.id,
3203                data    = datas && datas[datas.current]
3204
3205            if (typeof property === 'string' && $.isFunction(data[property])) {
3206                if (!data) return
3207
3208                [].shift.apply(args)
3209                if (!args) data[property]()
3210                else data[property].apply(data, args)
3211            } else {
3212                if (!id) {
3213                    id = datas ? datas.current : 'main'
3214
3215                    if (!BJUI.ui.overwriteHomeTab && id === 'main')
3216                        id = 'navtab'
3217                } else {
3218                    if (!id.isNormalID()) {
3219                        BJUI.debug('BJUI.Navtab: ID ['+ id +'] '+ BJUI.regional.idChecked)
3220
3221                        return
3222                    }
3223                }
3224
3225                options.id = id
3226
3227                if (!datas[id]) {
3228                    datas[id] = (data = new Navtab(options))
3229                } else {
3230                    data = datas[id]
3231                    if (typeof option === 'object' && option)
3232                        $.extend(data.options, option)
3233                }
3234
3235                $body.data(navtab, datas)
3236
3237                data.openTab()
3238            }
3239        })
3240    }
3241
3242    var old = $.fn.navtab
3243
3244    $.fn.navtab             = Plugin
3245    $.fn.navtab.Constructor = Navtab
3246
3247    // NAVTAB NO CONFLICT
3248    // =================
3249
3250    $.fn.navtab.noConflict = function () {
3251        $.fn.navtab = old
3252        return this
3253    }
3254
3255    // NOT SELECTOR
3256    // ==============
3257
3258    BJUI.navtab = function() {
3259        Plugin.apply($('body'), arguments)
3260    }
3261
3262    // NAVTAB DATA-API
3263    // ==============
3264
3265    $(document).on('click.bjui.navtab.data-api', '[data-toggle="navtab"]', function(e) {
3266        e.preventDefault()
3267
3268        var $this = $(this), href = $this.attr('href'), data = $this.data(), options = data.options
3269
3270        if (options) {
3271            if (typeof options === 'string') options = options.toObj()
3272            if (typeof options === 'object')
3273                $.extend(data, options)
3274        }
3275
3276        if (!data.title) data.title = $this.text()
3277        if (href && !data.url) data.url = href
3278
3279        Plugin.call($this, data)
3280    })
3281
3282}(jQuery);
3283/*!
3284 * B-JUI  V1.31 (http://b-jui.com)
3285 * Git@OSC (http://git.oschina.net/xknaan/B-JUI)
3286 * Copyright 2014 K'naan.
3287 * Licensed under Apache (http://www.apache.org/licenses/LICENSE-2.0)
3288 */
3289
3290/* ========================================================================
3291 * B-JUI: bjui-dialog.js  V1.31
3292 * @author K'naan
3293 * http://git.oschina.net/xknaan/B-JUI/blob/master/BJUI/js/bjui-dialog.js
3294 * ========================================================================
3295 * Copyright 2014 K'naan.
3296 * Licensed under Apache (http://www.apache.org/licenses/LICENSE-2.0)
3297 * ======================================================================== */
3298
3299+function ($) {
3300    'use strict';
3301
3302    // DIALOG GLOBAL ELEMENTS
3303    // ======================
3304
3305    var $resizable
3306    var $current, shadow, zindex
3307
3308    $(function() {
3309        var INIT_DIALOG = function() {
3310            $resizable = $('#bjui-resizable')
3311            shadow     = 'dialogShadow'
3312            zindex     = Dialog.ZINDEX
3313
3314            $('body').append('<!-- dialog resizable -->').append(FRAG.resizable)
3315        }
3316
3317        INIT_DIALOG()
3318    })
3319
3320    // DIALOG CLASS DEFINITION
3321    // ======================
3322    var Dialog = function(options) {
3323        this.$element = $('body')
3324        this.options  = options
3325        this.tools    = this.TOOLS()
3326    }
3327
3328    Dialog.DEFAULTS = {
3329        id          : null,
3330        title       : 'New Dialog',
3331        url         : null,
3332        type        : 'GET',
3333        data        : {},
3334        loadingmask : true,
3335        width       : 500,
3336        height      : 300,
3337        minW        : 65,
3338        minH        : 40,
3339        max         : false,
3340        mask        : false,
3341        resizable   : true,
3342        drawable    : true,
3343        maxable     : true,
3344        minable     : true,
3345        fresh       : false,
3346        onLoad      : null,
3347        beforeClose : null,
3348        onClose     : null
3349    }
3350
3351    Dialog.ZINDEX = 30
3352
3353    Dialog.prototype.TOOLS = function() {
3354        var that  = this
3355        var tools = {
3356            getDefaults: function() {
3357                return Dialog.DEFAULTS
3358            },
3359            init: function($dialog) {
3360                var width  = that.options.width > that.options.minW ? that.options.width : that.options.minW
3361                var height = that.options.height > that.options.minH ? that.options.height : that.options.minH
3362                var wW     = $(window).width(),
3363                    wH     = $(window).height(),
3364                    iTop   = that.options.max ? 0 : ((wH - height) / 3)
3365
3366                if (width > wW)  width  = wW
3367                if (height > wH) height = wH
3368
3369                $dialog
3370                    .height(height)
3371                    .width(width)
3372                    .show()
3373                    .css({left:(wW - width) / 2, top:0, opacity:0.1})
3374                    // modify by liu.ew 2018-05-14
3375                    .animate({top:iTop > 0 ? iTop : 0, opacity:1}, {
3376                        step: function(){
3377                            if (that.options.onStep != null && that.options.onStep != undefined) {
3378                                that.options.onStep($dialog);
3379                            }
3380                        }
3381                    })
3382                    .addClass(shadow)
3383                    .find('> .dialogContent').height(height - $('> .dialogHeader', $dialog).outerHeight())
3384
3385                $('body').find('> .bjui-dialog-container').not($dialog).removeClass(shadow)
3386            },
3387            reload: function($dialog, options) {
3388                var tools = this, $dialogContent = $dialog.find('> .dialogContent'), onLoad, data = options && options.data, html
3389
3390                options = options || $dialog.data('options')
3391                onLoad  = options.onLoad ? options.onLoad.toFunc() : null
3392
3393                $dialog.trigger(BJUI.eventType.beforeLoadDialog)
3394
3395                if (options.url) {
3396                    if (data) {
3397                        if (typeof data === 'string') {
3398                            if (data.trim().startsWith('{')) {
3399                                data = data.toObj()
3400                            } else {
3401                                data = data.toFunc()
3402                            }
3403                        }
3404                        if (typeof data === 'function') {
3405                            data = data.apply()
3406                        }
3407                    }
3408                    $dialogContent.ajaxUrl({
3409                        type:options.type || 'GET', url:options.url, data:data || {}, loadingmask:options.loadingmask, callback:function(response) {
3410                            if (onLoad) onLoad.apply(that, [$dialog])
3411                            if (BJUI.ui.clientPaging && $dialog.data('bjui.clientPaging')) $dialog.pagination('setPagingAndOrderby', $dialog)
3412
3413                            tools.resizeBjuiRow($dialog)
3414                        }
3415                    })
3416                } else {
3417                    if (options.image) {
3418                        html = '<img src="'+ decodeURIComponent(options.image) +'" style="max-width:100%;">'
3419                    } else if (options.html) {
3420                        html = options.html
3421                        if (typeof html === 'string' && $.isFunction(html.toFunc()))
3422                            html = html.toFunc()
3423                    } else if (options.target) {
3424                        html = $(options.target).html() || $dialog.data('bjui.dialog.target')
3425                        $(options.target).empty()
3426                        $dialog.data('bjui.dialog.target', html)
3427                    }
3428
3429                    $dialogContent.trigger(BJUI.eventType.beforeAjaxLoad).html(html).initui()
3430
3431                    if (onLoad) onLoad.apply(that, [$dialog])
3432
3433                    this.resizeBjuiRow($dialog)
3434                }
3435            },
3436            resizeContent: function($dialog) {
3437                var $dialogContent = $dialog.find('> .dialogContent')
3438
3439                $dialogContent
3440                    .css({height:($dialog.height() - $dialog.find('> .dialogHeader').outerHeight())})
3441                $(window).trigger(BJUI.eventType.resizeGrid)
3442            },
3443            resizeBjuiRow: function($dialog) {
3444                var width = $dialog.width(), colWidth = BJUI.formColWidth
3445
3446                $dialog.find('.bjui-row').each(function() {
3447                    var $rows = $(this)
3448
3449                    // 如果有cus-row时屏蔽bjui定义的固定的div样式
3450                    if ($rows.hasClass("cus-row")) {
3451                        return;
3452                    }
3453
3454                    if (($rows.attr('class')).indexOf('col-') === -1) {
3455                        $rows.addClass('col-none')
3456                    }
3457
3458                    $rows.filter('.col-4')
3459                        .toggleClass('col-3', (width < colWidth.L && width > colWidth.M))
3460                        .end()
3461                        .filter('.col-3, .col-4')
3462                        .toggleClass('col-2', (width < colWidth.M && width >
3462 colWidth.S))
3463                        .end()
3464                        .filter('.col-2, .col-3, .col-4')
3465                        .toggleClass('col-1', (width < colWidth.S && width > colWidth.SS))
3466                        .end()
3467                        .filter('.col-none, .col-1, .col-2, .col-3, .col-4')
3468                        .toggleClass('col-0', (width < colWidth.SS))
3469                })
3470            }
3471        }
3472
3473        return tools
3474    }
3475
3476    Dialog.prototype.open = function() {
3477        var that    = this,
3478            options = that.options,
3479            $body   = $('body'),
3480            datas   = $body.data('bjui.dialog'),
3481            data    = datas[options.id],
3482            $dialog = data && data.dialog
3483
3484        if (!(options.target || $(options.target).length) && !(options.html || options.image)) {
3485            if (!options.url && options.href) options.url = options.href
3486            if (!options.url) {
3487                BJUI.debug('BJUI.Dialog: Error trying to open a dialog, url is undefined!')
3488                return
3489            } else {
3490                options.url = decodeURI(options.url).replacePlh()
3491
3492                if (!options.url.isFinishedTm()) {
3493                    BJUI.alertmsg('error', (options.warn || BJUI.regional.plhmsg))
3494                    BJUI.debug('BJUI.Dialog: The new dialog\'s url is incorrect, url: '+ options.url)
3495                    return
3496                }
3497
3498                options.url = encodeURI(options.url)
3499            }
3500        } else {
3501            options.url = undefined
3502        }
3503        if ($dialog) { //if the dialog id already exists
3504            var op = $dialog.data('options')
3505
3506            this.switchDialog($dialog)
3507
3508            if ($dialog.is(':hidden')) $dialog.show()
3509            if (options.fresh || options.url != op.url) {
3510                that.reload(options)
3511            }
3512        } else { //open a new dialog
3513            var dr     = BJUI.regional.dialog,
3514                dialog = FRAG.dialog
3515                    .replace('#close#', dr.close)
3516                    .replace('#maximize#', dr.maximize)
3517                    .replace('#restore#', dr.restore)
3518                    .replace('#minimize#', dr.minimize)
3519                    .replace('#title#', dr.title)
3520
3521            $dialog = $(dialog)
3522                .data('options', $.extend({}, options))
3523                .css('z-index', (++ zindex))
3524                .hide()
3525                .appendTo($body)
3526
3527            $dialog.find('> .dialogHeader > h1 > span.title').html(options.title)
3528
3529            this.tools.init($dialog)
3530
3531            if (options.maxable) $dialog.find('a.maximize').show()
3532            else $dialog.find('a.maximize').hide()
3533            if (options.minable) $dialog.find('a.minimize').show()
3534            else $dialog.find('a.minimize').hide()
3535            if (options.max) that.maxsize($dialog)
3536            if (options.mask) this.addMask($dialog)
3537            else if (options.minable && $.fn.taskbar) this.$element.taskbar({id:options.id, title:options.title})
3538
3539            $dialog.on('click', function(e) {
3540                if (!$(e.target).data('bjui.dialog'))
3541                    if ($current && $current[0] != $dialog[0]) that.switchDialog($dialog)
3542            }).on('click', '.btn-close', function(e) {
3543                that.close($dialog)
3544
3545                e.preventDefault()
3546            }).on('click', '.dialogHeader > a', function(e) {
3547                var $a = $(this)
3548
3549                if ($a.hasClass('close')) that.close($dialog)
3550                if ($a.hasClass('minimize')) {
3551                    that.minimize($dialog)
3552                }
3553                if ($a.hasClass('maximize')) {
3554                    that.switchDialog($dialog)
3555                    that.maxsize($dialog)
3556                    commonDialogResize($dialog);
3557                }
3558                if ($a.hasClass('restore')) {
3559                    that.restore($dialog);
3560                    commonDialogResize($dialog,20);
3561                }
3562                e.preventDefault()
3563                e.stopPropagation()
3564            }).on('dblclick', '.dialogHeader > h1', function(e) {
3565                if (options.maxable) {
3566                    if ($dialog.find('> .dialogHeader > a.restore').is(':hidden')) $dialog.find('a.maximize').trigger('click')
3567                    else $dialog.find('> .dialogHeader > a.restore').trigger('click')
3568                }
3569            }).on('mousedown.bjui.dialog.drag', '.dialogHeader > h1', function(e) {
3570                that.switchDialog($dialog)
3571
3572                if (!options.drawable || $dialog.data('max')) return
3573
3574                $dialog.data('bjui.dialog.task', true)
3575                setTimeout($.proxy(function () {
3576                    if ($dialog.data('bjui.dialog.task')) that.drag(e, $dialog)
3577                }, that), 150)
3578
3579                e.preventDefault()
3580            }).on('mouseup.bjui.dialog.drag', '.dialogHeader > h1', function(e) {
3581                $dialog.data('bjui.dialog.task', false)
3582            }).on('mousedown.bjui.dialog.resize', 'div[class^="resizable"]', function(e) {
3583                if (!options.drawable || $dialog.data('max')) return false
3584                if (!options.resizable) return false
3585
3586                var $bar = $(this)
3587
3588                that.switchDialog($dialog)
3589                that.resizeInit(e, $('#bjui-resizable'), $dialog, $bar)
3590                $bar.show()
3591
3592                e.preventDefault()
3593            }).on('mouseup.bjui.dialog.resize', 'div[class^="resizable"]', function(e) {
3594                e.preventDefault()
3595            })
3596
3597            data.dialog = $dialog
3598            this.tools.reload($dialog, options)
3599        }
3600
3601        $.CurrentDialog = $current = $dialog
3602
3603        // set current to body data
3604        datas.current = options.id
3605    }
3606
3607    Dialog.prototype.addMask = function($dialog) {
3608        var $mask = $dialog.data('bjui.dialog.mask')
3609
3610        $dialog.wrap('<div style="z-index:'+ zindex +'" class="bjui-dialog-wrap"></div>')
3611        $dialog.find('> .dialogHeader > a.minimize').hide()
3612        if (!$mask || !$mask.length) {
3613            $mask = $(FRAG.dialogMask)
3614            $mask.css('z-index', 1).show().insertBefore($dialog)
3615            $dialog.data('bjui.dialog.mask', $mask)
3616        }
3617    }
3618
3619    Dialog.prototype.refresh = function(id) {
3620        if (id && typeof id === 'string') {
3621            var arr = id.split(','), datas = $('body').data('bjui.dialog')
3622
3623            for (var i = 0; i < arr.length; i++) {
3624                var $dialog = datas && datas[arr[i].trim()] && datas[arr[i].trim()].dialog
3625
3626                if ($dialog) {
3627                    $dialog.removeData('bjui.clientPaging')
3628                    this.tools.reload($dialog)
3629                }
3630            }
3631        } else {
3632            if ($current) {
3633                $current.removeData('bjui.clientPaging')
3634                this.tools.reload($current)
3635            }
3636        }
3637    }
3638
3639    Dialog.prototype.resize = function($dialog, width, height) {
3640        var that = this, options, $dialogContent, ww = $(window).width(), hh = $(window).height()
3641
3642        if (!$dialog) {
3643            $dialog = $current
3644        }
3645
3646        options = $dialog.data('options')
3647        $dialogContent = $dialog.find('> .dialogContent')
3648
3649        if (width != options.width) {
3650            if (width > ww)
3651                width = ww
3652
3653            if (options.max) {
3654                $dialog.animate({ width:width, left:(ww - width)/2 }, 'normal')
3655            } else {
3656                $dialog.width(width).css('left', (ww - width)/2)
3657            }
3658
3659            options.width = width
3660        }
3661        if (height != options.height) {
3662            var itop = 0
3663
3664            if (height < hh)
3665                itop = (hh - height) / 2 - 20
3666            if (itop < 0)
3667                itop = 0
3668
3669            if (options.max) {
3670                $dialog.animate({ height:height, top:itop }, 'normal', function() {
3671                    $dialogContent.height(height - $dialog.find('> .dialogHeader').outerHeight())
3672                })
3673            } else {
3674                $dialog.height(height).css('top', itop)
3675                $dialogContent.height(height - $dialog.find('> .dialogHeader').outerHeight())
3676            }
3677
3678            options.height = height
3679        }
3680    }
3681
3682    Dialog.prototype.reload = function(option) {
3683        var that     = this,
3684            options  = $.extend({}, typeof option === 'object' && option),
3685            datas    = $('body').data('bjui.dialog'),
3686            $dialog  = (options.id && datas[options.id] && datas[options.id].dialog) || that.getCurrent()
3687
3688        if ($dialog && $dialog.length) {
3689            var op = $dialog.data('options')
3690
3691            options = $.extend({}, op, options)
3692
3693            var _reload = function() {
3694                var $dialogContent = $dialog.find('> .dialogContent'), ww = $(window).width(), hh = $(window).height(), w = options.width, h = options.height
3695
3696                if (w != op.width) {
3697                    if (w > ww)
3698                        w = ww
3699
3700                    if (options.max) {
3701                        $dialog.animate({ width:w, left:(ww - w)/2 }, 'normal'/*, function() { $dialogContent.width(options.width) }*/)
3702                    } else {
3703                        $dialog.width(w).css('left', (ww - w)/2)
3704                    }
3705                }
3706                if (h != op.height) {
3707                    var itop = 0
3708
3709                    if (h < hh)
3710                        itop = (hh - h) / 2 - 20
3711                    if (itop < 0)
3712                        itop = 0
3713
3714                    if (options.max) {
3715                        $dialog.animate({ height:h, top:itop }, 'normal', function() {
3716                            $dialogContent.height(h - $dialog.find('> .dialogHeader').outerHeight())
3717                        })
3718                    } else {
3719                        $dialog.height(h).css('top', itop)
3720                        $dialogContent.height(h - $dialog.find('> .dialogHeader').outerHeight())
3721                    }
3722                }
3723                if (options.maxable != op.maxable) {
3724                    if (options.maxable) $dialog.find('a.maximize').show()
3725                    else $dialog.find('a.maximize').hide()
3726                }
3727                if (options.minable != op.minable) {
3728                    if (options.minable) $dialog.find('a.minimize').show()
3729                    else $dialog.find('a.minimize').hide()
3730                }
3731                if (options.max != op.max)
3732                    if (options.max)
3733                        setTimeout(that.maxsize($dialog), 10)
3734                if (options.mask != op.mask) {
3735                    if (options.mask) {
3736                        that.addMask($dialog)
3737                        if ($.fn.taskbar) that.$element.taskbar('closeDialog', options.id)
3738                    } else if (options.minable && $.fn.taskbar) {
3739                        that.$element.taskbar({id:options.id, title:options.title})
3740                    }
3741                }
3742                if (options.title != op.title) {
3743                    $dialog.find('> .dialogHeader > h1 > span.title').html(options.title)
3744                    $dialog.taskbar('changeTitle', options.id, options.title)
3745                }
3746
3747                $dialog.data('options', $.extend({}, options))
3748
3749                that.tools.reload($dialog, options)
3750            }
3751
3752            if (options.reloadWarn) {
3753                $dialog.alertmsg('confirm', options.reloadWarn, {
3754                    okCall: function() {
3755                        _reload()
3756                    }
3757                })
3758            } else {
3759                _reload()
3760            }
3761        }
3762    }
3763
3764    Dialog.prototype.reloadForm = function(clearQuery, option) {
3765        var options = $.extend({}, typeof option === 'object' && option),
3766            datas   = $('body').data('bjui.dialog'),
3767            $dialog
3768
3769        if (options.id) {
3770            if (datas && datas[options.id])
3771                $dialog = datas[options.id].dialog
3772        } else {
3773            $dialog = $current
3774        }
3775
3776        if ($dialog) {
3777            var op         = $dialog.data('options'),
3778                data       = {},
3779                pageData   = {},
3780                $pagerForm = options.form
3781
3782            if ($pagerForm && $pagerForm.length) {
3783                options.type = options.type || $pagerForm.attr('method') || 'POST'
3784                options.url  = options.url || $pagerForm.attr('action')
3785
3786                pageData = $pagerForm.serializeJson()
3787
3788                if (clearQuery) {
3789                    var pageInfo = BJUI.pageInfo
3790
3791                    for (var key in pageInfo) {
3792                        data[pageInfo[key]] = pageData[pageInfo[key]]
3793                    }
3794                } else {
3795                    data = pageData
3796                }
3797            }
3798
3799            options.data = $.extend({}, options.data || {}, data)
3800
3801            this.tools.reload($dialog, options)
3802        }
3803    }
3804
3805    Dialog.prototype.getCurrent = function() {
3806        return $current
3807    }
3808
3809    Dialog.prototype.switchDialog = function($dialog) {
3810        var index = $dialog.css('z-index')
3811
3812        if ($current && $current != $dialog) {
3813            var cindex = $current.css('z-index'),
3814                datas  = $('body').data('bjui.dialog'),
3815                pindex
3816
3817            if ($current.data('options').mask) {
3818                pindex = $current.parent().css('z-index')
3819
3820                if (Number(pindex) > Number(index))
3821                    return
3822            }
3823
3824            $current.css('z-index', index)
3825            $dialog.css('z-index', cindex)
3826            $.CurrentDialog = $current = $dialog
3827
3828            // set current to body data
3829            datas.current = $dialog.data('options').id
3830
3831            if ($.fn.taskbar) this.$element.taskbar('switchTask', datas.current)
3832        }
3833
3834        $dialog.addClass(shadow)
3835        $('body').find('> .bjui-dialog-container, > .bjui-dialog-wrap > .bjui-dialog-container').not($dialog).removeClass(shadow)
3836    }
3837
3838    Dialog.prototype.close = function(dialog) {
3839        var datas = $('body').data('bjui.dialog'), $dialog = (typeof dialog === 'string') ? datas[dialog].dialog : dialog
3840
3841        if (!$dialog || !$dialog.length) {
3842            return
3843        }
3844
3845        var that        = this,
3846            $mask       = $dialog.data('bjui.dialog.mask'),
3847            options     = $dialog.data('options'),
3848            target      = $dialog.data('bjui.dialog.target'),
3849            beforeClose = options.beforeClose ? options.beforeClose.toFunc() : null,
3850            onClose     = options.onClose ? options.onClose.toFunc() : null,
3851            canClose    = true,
3852            closeFunc   = function() {
3853                delete datas[options.id]
3854
3855                if (onClose) onClose.apply(that,[$dialog,options])
3856
3857                $.CurrentDialog = $current = null
3858
3859                var $dialogs  = $('body').find('.bjui-dialog-container'),
3860                    $_current = null
3861
3862                if ($dialogs.length) {
3863                    $_current = that.$element.getMaxIndexObj($dialogs)
3864                } else {
3865                    zindex = Dialog.ZINDEX
3866                }
3867                if ($_current && $_current.is(':visible')) {
3868                    $.CurrentDialog = $current = $_current
3869                    that.switchDialog($_current)
3870                }
3871            }
3872
3873        if (!$dialog || !options) return
3874        if (beforeClose) canClose = beforeClose.apply(that, [$dialog,options])
3875        if (!canClose) {
3876            that.switchDialog($dialog)
3877            return
3878        }
3879        if (options.target && target) $(options.target).html(target)
3880        if ($mask && $mask.length) {
3881            $mask.remove()
3882            $dialog.unwrap()
3883        } else if ($.fn.taskbar) {
3884            this.$element.taskbar('closeDialog', options.id)
3885        }
3886
3887        if (options.noCloseAnimate) {
3888            /**
3889             * modify by liu.ew 2018-06-05
3890             *
3891             * 添加一定延时,避免无动画效果时关闭弹框出现异常
3892             */
3893            setTimeout(function() {
3894                $dialog.trigger(BJUI.eventType.beforeCloseDialog).remove()
3895                closeFunc()
3896            }, 20)
3897        } else {
3898            $dialog.animate({top:- $dialog.outerHeight(), opacity:0.1}, 'normal', function() {
3899                $dialog.trigger(BJUI.eventType.beforeCloseDialog).remove()
3900                closeFunc()
3901            })
3902        }
3903    }
3904
3905    Dialog.prototype.closeCurrent = function() {
3906        this.close($current)
3907    }
3908    //关闭所有打开的弹出框 2020-05-26
3909    Dialog.prototype.closeAll = function() {
3910        var datas=$('body').data('bjui.dialog');
3911        for(var key in datas){
3912            if(key!='dialog' && $current!='undefined' && key!='current'){
3913                this.close(key)
3914            }
3915        }
3916
3917    }
3918
3919    Dialog.prototype.checkTimeout = function() {
3920        var $dialogConetnt = $current.find('> .dialogContent'),
3921            json = JSON.parse($dialogConetnt.html())
3922
3923        if (json && json[BJUI.keys.statusCode] == BJUI.statusCode.timeout) this.closeCurrent()
3924    }
3925
3926    Dialog.prototype.maxsize = function($dialog) {
3927        var $taskbar = $('#bjui-taskbar'), taskH = ($taskbar.is(':visible') ? $taskbar.height() : 0) + 1
3928
3929        $dialog.data('original', {
3930            top   : $dialog.css('top'),
3931            left  : $dialog.css('left'),
3932            width : $dialog.css('width'),
3933            height: $dialog.css('height')
3934        }).data('max', true)
3935
3936        $dialog.find('> .dialogHeader > a.maximize').hide()
3937        $dialog.find('> .dialogHeader > a.restore').show()
3938
3939        var iContentW = $(window).width() - 1,
3940            iContentH = $(window).height() - taskH
3941
3942        $dialog.css({ top:0, right:0, left:0, bottom:taskH, width:'100%', height:'auto'})
3943
3944        this.tools.resizeContent($dialog)
3945        this.tools.resizeBjuiRow($dialog)
3946    }
3947
3948    Dialog.prototype.restore = function($dialog) {
3949        var original = $dialog.data('original'),
3950            dwidth   = original.width,
3951            dheight  = original.height
3952
3953        $dialog.css({
3954            top   : original.top,
3955            right : '',
3956            bottom: '',
3957            left  : original.left,
3958            width : dwidth,
3959            height: dheight
3960        })
3961        this.tools.resizeContent($dialog)
3962        this.tools.resizeBjuiRow($dialog)
3963
3964        $dialog.find('> .dialogHeader > a.maximize').show()
3965        $dialog.find('> .dialogHeader > a.restore').hide()
3966        $dialog.data('max', false)
3967    }
3968
3969    Dialog.prototype.minimize = function($dialog) {
3970        $dialog.hide()
3971        if ($.fn.taskbar) this.$element.taskbar('minimize', $dialog)
3972
3973        var $dialogs  = $('body').find('.bjui-dialog-container:visible'),
3974            $_current = null
3975
3976        if ($dialogs.length) {
3977            $_current = this.$element.getMaxIndexObj($dialogs)
3978        }
3979        if ($_current) this.switchDialog($_current)
3980    }
3981
3982    Dialog.prototype.drag = function(e, $dialog) {
3983        var $shadow = $('#bjui-dialogProxy')
3984
3985        $dialog.find('> .dialogContent').css('opacity', '.3')
3986        $dialog.basedrag({
3987            selector : '> .dialogHeader',
3988            stop     : function() {
3989
3990                /*3914-3921:解決弹出框拖动超出问题--update-2018-10-9-huan*/
3991                /*-------begin-------*/
3992                var dialogLeft=$dialog.css('left')
3993                var dialogTop=$dialog.css('top')
3994
3995                if(parseInt(dialogLeft)<0){
3996                    dialogLeft=0;
3997                }else if(parseInt(dialogTop)<0){
3998                    dialogTop=0;
3999                }
4000                /*-------end------*/
4001
4002                $dialog
4003                    .css({left:dialogLeft, top:dialogTop})
4004                    .find('> .dialogContent').css('opacity', 1)
4005
4006            },
4007            event    : e,
4008            nounbind : true
4009        })
4010    }
4011
4012    Dialog.prototype.resizeDialog = function($resizable, $dialog, target) {
4013        var oleft  = parseInt($resizable.css('left'), 10),
4014            otop   = parseInt($resizable.css('top'), 10),
4015            height = parseInt($resizable.css('height'), 10),
4016            width  = parseInt($resizable.css('width'), 10)
4017
4018        if (otop < 0) otop = 0
4019
4020        $dialog.css({top:otop, left:oleft, width:width, height:height})
4021
4022        if (target != 'w' && target != 'e')
4023            this.tools.resizeContent($dialog)
4024        if (target != 'n' && target != 's') {
4025            this.tools.resizeBjuiRow($dialog)
4026            $(window).trigger(BJUI.eventType.resizeGrid)
4027        }
4028    }
4029
4030    Dialog.prototype.resizeInit = function(e, $resizable, $dialog, $bar) {
4031        var that = this, target = $bar.attr('tar')
4032
4033        $('body').css('cursor', target +'-resize')
4034        $resizable
4035            .css({
4036                top    : $dialog.css('top'),
4037                left   : $dialog.css('left'),
4038                height : $dialog.outerHeight(),
4039                width  : $dialog.css('width')
4040            })
4041            .show()
4042
4043        if (!this.options.dragCurrent) {
4044            this.options.dragCurrent = {
4045                $resizable : $resizable,
4046                $dialog    : $dialog,
4047                target     : target,
4048                oleft      : parseInt($resizable.css('left'), 10)   || 0,
4049                owidth     : parseInt($resizable.css('width'), 10)  || 0,
4050                otop       : parseInt($resizable.css('top'), 10)    || 0,
4051                oheight    : parseInt($resizable.css('height'), 10) || 0,
4052                ox         : e.pageX || e.screenX,
4053                oy         : e.pageY || e.clientY
4054            }
4055            $(document).on('mouseup.bjui.dialog.resize', $.proxy(that.resizeStop, that))
4056            $(document).on('mousemove.bjui.dialog.resize', $.proxy(that.resizeStart, that))
4057        }
4058    }
4059
4060    Dialog.prototype.resizeStart = function(e) {
4061        var current = this.options.dragCurrent
4062
4063        if (!current) return
4064        if (!e) var e = window.event
4065
4066        var lmove     = (e.pageX || e.screenX) - current.ox,
4067            tmove     = (e.pageY || e.clientY) - current.oy,
4068            $mask = current.$dialog.data('bjui.dialog.mask')
4069
4070        if (!$mask || !$mask.length)
4071            if ((e.pageY || e.clientY) <= 0 || (e.pageY || e.clientY) >
4071= ($(window).height() - current.$dialog.find('> .dialogHeader').outerHeight())) return
4072
4073        var target = current.target,
4074            width  = current.owidth,
4075            height = current.oheight
4076
4077        if (target != 'n' && target != 's')
4078            width += (target.indexOf('w') >= 0) ? -lmove : lmove
4079        if (width >= this.options.minW) {
4080            if (target.indexOf('w') >= 0)
4081                current.$resizable.css('left', (current.oleft + lmove))
4082            if (target != 'n' && target != 's')
4083                current.$resizable.css('width', width)
4084        }
4085        if (target != 'w' && target != 'e')
4086            height += (target.indexOf('n') >= 0) ? -tmove : tmove
4087        if (height >= this.options.minH) {
4088            if (target.indexOf('n') >= 0)
4089                current.$resizable.css('top', (current.otop + tmove))
4090            if (target != 'w' && target != 'e')
4091                current.$resizable.css('height', height)
4092        }
4093    }
4094
4095    Dialog.prototype.resizeStop = function(e) {
4096        var current = this.options.dragCurrent
4097
4098        if (!current) return false
4099
4100        $(document).off('mouseup.bjui.dialog.resize').off('mousemove.bjui.dialog.resize')
4101
4102        this.options.dragCurrent = null
4103        this.resizeDialog(current.$resizable, current.$dialog, current.target)
4104
4105        $('body').css('cursor', '')
4106        current.$resizable.hide()
4107    }
4108
4109    // DIALOG PLUGIN DEFINITION
4110    // =======================
4111
4112    function Plugin(option) {
4113        var args     = arguments,
4114            property = option,
4115            dialog   = 'bjui.dialog',
4116            $body    = $('body'),
4117            datas    = $body.data(dialog) || {}
4118
4119        return this.each(function () {
4120            var $this   = $(this),
4121                options = $.extend({}, Dialog.DEFAULTS, typeof option === 'object' && option),
4122                id      = options && options.id,
4123                data
4124
4125            if (!id) {
4126                if (datas.current) id = datas.current
4127                else id = 'dialog'
4128            } else {
4129                if (!id.isNormalID()) {
4130                    BJUI.debug('BJUI.Dialog: ID ['+ id +'] '+ BJUI.regional.idChecked)
4131
4132                    return
4133                }
4134            }
4135
4136            options.id = id
4137            data = datas && datas[id]
4138
4139            if (!data) {
4140                datas[id] = (data = new Dialog(options))
4141            } else {
4142                if (typeof option === 'object' && option)
4143                    $.extend(data.options, option)
4144            }
4145
4146            $body.data(dialog, datas)
4147
4148            if (typeof property === 'string' && $.isFunction(data[property])) {
4149                [].shift.apply(args)
4150                if (!args) data[property]()
4151                else data[property].apply(data, args)
4152            } else {
4153                data.open()
4154            }
4155        })
4156    }
4157
4158    var old = $.fn.dialog
4159
4160    $.fn.dialog             = Plugin
4161    $.fn.dialog.Constructor = Dialog
4162
4163    // DIALOG NO CONFLICT
4164    // =================
4165
4166    $.fn.dialog.noConflict = function () {
4167        $.fn.dialog = old
4168        return this
4169    }
4170
4171    // NOT SELECTOR
4172    // ==============
4173
4174    BJUI.dialog = function() {
4175        Plugin.apply($('body'), arguments)
4176    }
4177
4178    // DIALOG DATA-API
4179    // ==============
4180
4181    $(document).on('click.bjui.dialog.data-api', '[data-toggle="dialog"]', function(e) {
4182        var $this   = $(this), href = $this.attr('href'), data = $this.data(), options = data.options
4183
4184        if (options) {
4185            if (typeof options === 'string') options = options.toObj()
4186            if (typeof options === 'object')
4187                $.extend(data, options)
4188        }
4189
4190        if (!data.title) data.title = $this.text()
4191        if (href && !data.url) data.url = href
4192
4193        Plugin.call($this, data)
4194
4195        e.preventDefault()
4196    })
4197
4198}(jQuery);
4199/*!
4200 * B-JUI  V1.31 (http://b-jui.com)
4201 * Git@OSC (http://git.oschina.net/xknaan/B-JUI)
4202 * Copyright 2014 K'naan.
4203 * Licensed under Apache (http://www.apache.org/licenses/LICENSE-2.0)
4204 */
4205
4206/* ========================================================================
4207 * B-JUI: bjui-taskbar.js  V1.31
4208 * reference: bjui-dialog.js
4209 * @author K'naan
4210 * http://git.oschina.net/xknaan/B-JUI/blob/master/BJUI/js/bjui-taskbar.js
4211 * ========================================================================
4212 * Copyright 2014 K'naan.
4213 * Licensed under Apache (http://www.apache.org/licenses/LICENSE-2.0)
4214 * ======================================================================== */
4215
4216+function ($) {
4217    'use strict';
4218
4219    // TASKBAR GLOBAL ELEMENTS
4220    // ======================
4221
4222    var $resizable
4223    var $taskBar, $taskBox, $taskList, $prevBtn, $nextBtn, taskDisabled, taskSelected, taskMargin
4224
4225    $(function() {
4226        var INIT_TASKBAR = function() {
4227            $resizable   = $('#bjui-resizable')
4228            $taskBar     = $(FRAG.taskbar)
4229            $taskBox     = $taskBar.find('.taskbarContent')
4230            $taskList    = $taskBox.find('> ul')
4231            $prevBtn     = $taskBar.find('.taskbarLeft')
4232            $nextBtn     = $taskBar.find('.taskbarRight')
4233            taskDisabled = 'disabled'
4234            taskSelected = 'selected'
4235            taskMargin   = 'taskbarMargin'
4236
4237            $('body').append('<!-- dialog task bar -->').append($taskBar)
4238
4239            //events
4240            $prevBtn.click(function(e) { $(this).taskbar('scrollLeft') })
4241            $nextBtn.click(function(e) { $(this).taskbar('scrollRight') })
4242        }
4243        INIT_TASKBAR()
4244    })
4245
4246    // TASKBAR CLASS DEFINITION
4247    // ======================
4248
4249    var Taskbar = function(element, options) {
4250        this.$element = $(element)
4251        this.$task    = null
4252        this.options  = options
4253        this.tools    = this.TOOLS()
4254    }
4255
4256    Taskbar.DEFAULTS = {
4257        id: undefined,
4258        title: undefined
4259    }
4260
4261    Taskbar.prototype.init = function() {
4262        var that = this
4263        var $task = $taskList.find('#task-'+ this.options.id)
4264
4265        this.show()
4266        if (!$task.length) {
4267            var taskFrag = '<li id="#taskid#"><div class="taskbutton"><span><i class="fa fa-th-large"></i></span> <span class="title">#title#</span></div><div class="close"><i class="fa fa-times-circle"></i></div></li>';
4268
4269            $task = $(taskFrag.replace('#taskid#', 'task-'+ this.options.id).replace('#title#', this.options.title))
4270            $task.appendTo($taskList)
4271        } else {
4272            $task.find('> div > span.title').html(this.options.title)
4273        }
4274        this.contextmenu($task)
4275        this.switchTask($task)
4276        this.tools.scrollTask($task)
4277
4278        //events
4279        $task.click(function(e) {
4280            if ($(e.target).closest('div').hasClass('close') || $(e.target).hasClass('close')) {
4281                $task.dialog('close', that.options.id)
4282            } else {
4283                var datas   = $('body').data('bjui.dialog'),
4284                    $dialog = datas[that.options.id].dialog
4285
4286                if ($task.hasClass('selected')) {
4287                    $dialog.find('.dialogHeader a.minimize').trigger('click')
4288                } else {
4289                    if ($dialog.is(':hidden')) {
4290                        that.restoreDialog($dialog)
4291                    } else {
4292                        $dialog.trigger('click')
4293                        $task.addClass(taskSelected)
4294                    }
4295                }
4296                that.scrollCurrent($task)
4297            }
4298
4299            return false
4300        })
4301    }
4302
4303    Taskbar.prototype.TOOLS = function() {
4304        var that  = this
4305        var tools = {
4306            scrollCurrent: function() {
4307                var iW = this.tasksW(this.getTasks())
4308
4309                if (iW > this.getTaskBarW()) {
4310                    var $tools = this
4311                    var lTask  = $taskList.find('> li:last-child')
4312                    var left   = this.getTaskBarW() - lTask.position().left - lTask.outerWidth(true)
4313
4314                    $taskList.animate({left: left}, 200, function() {
4315                        $tools.ctrlScrollBtn()
4316                    })
4317                } else {
4318                    this.ctrlScrollBtn()
4319                }
4320            },
4321            getTaskBarW: function() {
4322                return $taskBox.width()- ($prevBtn.is(':hidden') ? $prevBtn.width() + 2 : 0) - ($nextBtn.is(':hidden') ? $nextBtn.width() + 2 : 0)
4323            },
4324            scrollTask: function($task) {
4325                var $tools = this
4326
4327                if ($task.position().left + this.getLeft() + $task.outerWidth() > this.getBarWidth()) {
4328                    var left = this.getTaskBarW() - $task.position().left  - $task.outerWidth(true) - 2
4329
4330                    $taskList.animate({left:left}, 200, function() {
4331                        $tools.ctrlScrollBtn()
4332                    })
4333                } else if ($task.position().left + this.getLeft() < 0) {
4334                    var left = this.getLeft() - ($task.position().left + this.getLeft())
4335
4336                    $taskList.animate({left:left}, 200, function() {
4337                        $tools.ctrlScrollBtn()
4338                    })
4339                }
4340            },
4341            ctrlScrollBtn: function() {
4342                var iW = this.tasksW(this.getTasks())
4343
4344                if (this.getTaskBarW() > iW) {
4345                    $taskBox.removeClass(taskMargin)
4346                    $nextBtn.hide()
4347                    $prevBtn.hide()
4348                    if (this.getTasks().eq(0).length) this.scrollTask(this.getTasks().eq(0))
4349                } else {
4350                    $taskBox.addClass(taskMargin)
4351                    $nextBtn.show().removeClass(taskDisabled)
4352                    $prevBtn.show().removeClass(taskDisabled)
4353                    if (this.getLeft() >= 0) $prevBtn.addClass(taskDisabled)
4354                    if (this.getLeft() <= this.getTaskBarW() - iW) $nextBtn.addClass(taskDisabled)
4355                }
4356            },
4357            getLeft: function(){
4358                return $taskList.position().left
4359            },
4360            visibleStart: function() {
4361                var iLeft = this.getLeft()
4362                var jTasks = this.getTasks() //得到ul下所有的li
4363
4364                for (var i = 0; i < jTasks.size(); i++) {
4365                    if (jTasks.eq(i).position().left + jTasks.eq(i).outerWidth(true) + iLeft >= 0) return jTasks.eq(i)
4366                }
4367
4368                return jTasks.eq(0)
4369            },
4370            visibleEnd: function() {
4371                var iLeft = this.getLeft()
4372                var jTasks = this.getTasks()
4373
4374                for (var i = 0; i < jTasks.size(); i++) {
4375                    if (jTasks.eq(i).position().left + jTasks.eq(i).outerWidth(true) + iLeft > this.getBarWidth()) return jTasks.eq(i)
4376                }
4377
4378                return jTasks.eq(jTasks.size() - 1)
4379            },
4380            getTasks: function() {
4381                return $taskList.find('> li')
4382            },
4383            tasksW: function(jTasks) {
4384                var iW = 0
4385
4386                jTasks.each(function() {
4387                    iW += $(this).outerWidth(true)
4388                })
4389
4390                return iW
4391            },
4392            getBarWidth: function() {
4393                return $taskBar.innerWidth()
4394            },
4395            getCurrent: function() {
4396                return $taskList.find('li.'+ taskSelected)
4397            }
4398        }
4399
4400        return tools
4401    }
4402
4403    Taskbar.prototype.contextmenu = function($obj) {
4404        var that = this
4405
4406        $obj.contextmenu({
4407            id: 'dialogCM',
4408            bindings: {
4409                reload: function(t) {
4410                    t.dialog('refresh', that.options.id)
4411                },
4412                closeCurrent: function(t, m) {
4413                    var $obj = t.isTag('li') ? t : that.tools.getCurrent()
4414
4415                    $obj.find('.close').trigger('click')
4416                },
4417                closeOther: function(t, m){
4418                    var $tasks = $taskList.find('> li').not(t)
4419
4420                    $tasks.each(function(i) {
4421                        $(this).find('.close').trigger('click')
4422                    })
4423                },
4424                closeAll: function(t, m) {
4425                    var $tasks = that.tools.getTasks()
4426
4427                    $tasks.each(function(i) {
4428                        $(this).find('.close').trigger('click')
4429                    })
4430                }
4431            },
4432            ctrSub: function(t, m) {
4433                var mCur = m.find('[rel="closeCurrent"]')
4434                var mOther = m.find('[rel="closeOther"]')
4435
4436                if (!that.tools.getCurrent().length) {
4437                    mCur.addClass(taskDisabled)
4438                    mOther.addClass(taskDisabled)
4439                } else {
4440                    if (that.tools.getTasks().size() == 1)
4441                        mOther.addClass(taskDisabled)
4442                }
4443            }
4444        })
4445    }
4446
4447    Taskbar.prototype.closeDialog = function(task) {
4448        var $task = (typeof task === 'string') ? this.getTask(task) : task
4449
4450        if (!$task || !$task.length) return
4451
4452        $task.remove()
4453        if (!this.tools.getTasks().size()) {
4454            this.hide()
4455        }
4456        this.tools.scrollCurrent()
4457        this.$element.removeData('bjui.taskbar')
4458    }
4459
4460    Taskbar.prototype.minimize = function(dialog) {
4461        var that    = this,
4462            datas   = $('body').data('bjui.dialog'),
4463            $dialog = (typeof dialog === 'string') ? datas[dialog].dialog : dialog,
4464            $task   = this.getTask($dialog.data('options').id)
4465
4466        $resizable.css({
4467            top: $dialog.css('top'),
4468            left: $dialog.css('left'),
4469            height: $dialog.css('height'),
4470            width: $dialog.css('width')
4471        }).show().animate({top:$(window).height() - 60, left:$task.position().left, width:$task.outerWidth(), height:$task.outerHeight()}, 250, function() {
4472            $(this).hide()
4473            that.inactive($task)
4474        })
4475    }
4476
4477    /**
4478     * @param {Object} id or dialog
4479     */
4480    Taskbar.prototype.restoreDialog = function($dialog) {
4481        var $task = this.getTask($dialog.data('options').id)
4482
4483        $resizable.css({top:$(window).height() - 60, left:$task.position().left, height:$task.outerHeight(), width:$task.outerWidth()})
4484            .show()
4485            .animate({top:$dialog.css('top'), left:$dialog.css('left'), width:$dialog.css('width'), height:$dialog.css('height')}, 250, function() {
4486                $(this).hide()
4487
4488                $dialog.show().trigger('click.bjui.taskbar.restore')
4489            })
4490
4491        this.switchTask($task)
4492    }
4493
4494    /**
4495     * @param {Object} id
4496     */
4497    Taskbar.prototype.inactive = function(task) {
4498        var $task = (typeof task === 'string') ? this.getTask(task) : task
4499
4500        $task.removeClass(taskSelected)
4501    }
4502
4503    Taskbar.prototype.scrollLeft = function() {
4504        var $task = this.tools.visibleStart()
4505
4506        this.tools.scrollTask($task)
4507    }
4508
4509    Taskbar.prototype.scrollRight = function() {
4510        var $task = this.tools.visibleEnd()
4511
4512        this.tools.scrollTask($task)
4513    }
4514
4515    Taskbar.prototype.scrollCurrent = function($task) {
4516        this.tools.scrollTask($task)
4517    }
4518
4519    /**
4520     * @param {Object} id or $task
4521     */
4522    Taskbar.prototype.switchTask = function(task) {
4523        this.tools.getCurrent().removeClass(taskSelected)
4524        var $task = (typeof task === 'string') ? this.getTask(task) : task
4525
4526        $task.addClass(taskSelected)
4527    }
4528
4529    Taskbar.prototype.getTask = function(id) {
4530        return $taskList.find('#task-'+ id)
4531    }
4532
4533    Taskbar.prototype.changeTitle = function(id, title) {
4534        var $task = this.getTask(id)
4535
4536        if ($task && title) $task.find('.title').html(title)
4537    }
4538
4539    Taskbar.prototype.show = function() {
4540        if ($taskBar.is(':hidden')) $taskBar.show().animate({bottom:0}, 500)
4541    }
4542
4543    Taskbar.prototype.hide = function() {
4544        if ($taskBar.is(':visible')) $taskBar.animate({bottom:-50}, 500, function() { $taskBar.hide() })
4545    }
4546
4547    // TASKBAR PLUGIN DEFINITION
4548    // =======================
4549
4550    function Plugin(option) {
4551        var args = arguments
4552        var property = option
4553
4554        return this.each(function () {
4555            var $this   = $(this)
4556            var options = $.extend({}, Taskbar.DEFAULTS, $this.data(), typeof option === 'object' && option)
4557            var data    = $this.data('bjui.taskbar')
4558
4559            if (!data) $this.data('bjui.taskbar', (data = new Taskbar(this, options)))
4560            else if (data.options.id != options.id) $this.data('bjui.taskbar', (data = new Taskbar(this, options)))
4561
4562            if (typeof property === 'string' && $.isFunction(data[property])) {
4563                [].shift.apply(args)
4564                if (!args) data[property]()
4565                else data[property].apply(data, args)
4566            } else {
4567                data.init()
4568            }
4569        })
4570    }
4571
4572    var old = $.fn.taskbar
4573
4574    $.fn.taskbar             = Plugin
4575    $.fn.taskbar.Constructor = Taskbar
4576
4577    // TASKBAR NO CONFLICT
4578    // =================
4579
4580    $.fn.taskbar.noConflict = function () {
4581        $.fn.taskbar = old
4582        return this
4583    }
4584
4585}(jQuery);
4586/*!
4587 * B-JUI  V1.31 (http://b-jui.com)
4588 * Git@OSC (http://git.oschina.net/xknaan/B-JUI)
4589 * Copyright 2014 K'naan.
4590 * Licensed under Apache (http://www.apache.org/licenses/LICENSE-2.0)
4591 */
4592
4593/* ========================================================================
4594 * B-JUI: bjui-ajax.js  V1.31
4595 * @author K'naan
4596 * http://git.oschina.net/xknaan/B-JUI/blob/master/BJUI/js/bjui-ajax.js
4597 * ========================================================================
4598 * Copyright 2014 K'naan.
4599 * Licensed under Apache (http://www.apache.org/licenses/LICENSE-2.0)
4600 * ======================================================================== */
4601
4602+function ($) {
4603    'use strict';
4604
4605    // BJUIAJAX GLOBAL ELEMENTS
4606    // ======================
4607
4608    var autorefreshTimer
4609
4610    // BJUIAJAX CLASS DEFINITION
4611    // ======================
4612
4613    var Bjuiajax = function(element, options) {
4614        var $this     = this
4615
4616        this.$element = $(element)
4617        this.options  = options
4618        this.tools    = this.TOOLS()
4619    }
4620
4621    Bjuiajax.DEFAULTS = {
4622        okalert         : true,
4623        reload          : true,
4624        loadingmask     : true,
4625        gridrefreshflag : true
4626    }
4627
4628    Bjuiajax.NAVTAB = 'navtab'
4629
4630    Bjuiajax.prototype.TOOLS = function() {
4631        var that  = this
4632        var tools = {
4633            getTarget: function() {
4634                if (that.$element.closest('.navtab-panel').length) return Bjuiajax.NAVTAB
4635                else return 'dialog'
4636            }
4637        }
4638
4639        return tools
4640    }
4641
4642    Bjuiajax.prototype.ajaxdone = function(json) {
4643        if (json[BJUI.keys.statusCode] == BJUI.statusCode.error) {
4644            if (json[BJUI.keys.message]) BJUI.alertmsg('error', json[BJUI.keys.message])
4645        } else if (json[BJUI.keys.statusCode] == BJUI.statusCode.timeout) {
4646            BJUI.alertmsg('info', (json[BJUI.keys.message] || BJUI.regional.sessiontimeout))
4647            BJUI.loadLogin()
4648        } else {
4649            if (json[BJUI.keys.message]) BJUI.alertmsg('correct', json[BJUI.keys.message])
4650        }
4651    }
4652
4653    Bjuiajax.prototype.ajaxerror = function(xhr, ajaxOptions, thrownError) {
4654        var msg = xhr.responseText, that = this, options = that.$element.data('bjui.ajax.options') || that.options, failCallback = options.failCallback
4655
4656        if (typeof msg === 'string' && msg.startsWith('{')) {
4657            this.ajaxdone(msg.toObj())
4658        } else {
4659            BJUI.alertmsg('error', '<div>Http status: ' + xhr.status + ' ' + xhr.statusText + '</div>'
4660                + '<div>ajaxOptions: '+ ajaxOptions +' </div>'
4661                + '<div>thrownError: '+ thrownError +' </div>'
4662                + '<div>'+ msg +'</div>')
4663        }
4664
4665        if (failCallback) {
4666            if (typeof failCallback === 'string')
4667                failCallback = failCallback.toFunc()
4668            if (typeof failCallback === 'function')
4669                failCallback.apply(that, [msg, options])
4670            else
4671                BJUI.debug('The callback function \'failCallback\' is incorrect: '+ failCallback)
4672        }
4673    }
4674
4675    Bjuiajax.prototype.ajaxcallback = function(json) {
4676        var that = this, options = that.options,
4677            okCallback = options.okCallback, errCallback = options.errCallback, okAfterCallback = options.okAfterCallback,
4678            tabids = [], dialogids = [], divids = [], datagrids = []
4679
4680        var okFunc = function() {
4681                if (typeof okCallback === 'string')
4682                    okCallback = okCallback.toFunc()
4683                if (typeof okCallback === 'function')
4684                    okCallback.apply(that, [json, options])
4685                else
4686                    BJUI.debug('The callback function \'okCallback\' is incorrect: '+ okCallback)
4687            },
4688            okAfterFunc = function() {
4689                if (typeof okAfterCallback === 'string')
4690                    okAfterCallback = okAfterCallback.toFunc()
4691                if (typeof okAfterCallback === 'function')
4692                    okAfterCallback.apply(that, [json, options])
4693                else
4694                    BJUI.debug('The callback function \'okAfterCallback\' is incorrect: '+ okAfterCallback)
4695            },
4696            errFunc = function() {
4697                if (typeof errCallback === 'string')
4698                    errCallback = errCallback.toFunc()
4699                if (typeof errCallback === 'function')
4700                    errCallback.apply(that, [json, options])
4701                else
4702                    BJUI.debug('The callback function \'errCallback\' is incorrect: '+ errCallback)
4703            }
4704
4705        if (typeof json === 'string')
4706            json = json.toObj()
4707
4708        if (options.okalert)
4709            that.ajaxdone(json)
4710
4711        if (!json[BJUI.keys.statusCode]) {
4712            if (okCallback) {
4713                okFunc()
4714                return
4715            }
4716        }
4717        if (json[BJUI.keys.statusCode] == BJUI.statusCode.ok) {
4718            if (okCallback) {
4719                okFunc()
4720                return
4721            }
4722
4723            if (json.tabid)
4724                $.merge(tabids, json.tabid.split(','))
4725            if (options.tabid)
4726                $.merge(tabids, options.tabid.split(','))
4727
4728            if (json.dialogid)
4729                $.merge(dialogids, json.dialogid.split(','))
4730            if (options.dialogid)
4731                $.merge(dialogids, options.dialogid.split(','))
4732
4733            if (json.divid)
4734                $.merge(divids, json.divid.split(','))
4735            if (options.divid)
4736                $.merge(divids, options.divid.split(','))
4737
4738            if (json.datagrid)
4739                $.merge(datagrids, json.datagrid.split(','))
4740            if (options.datagrid)
4741                $.merge(datagrids, options.datagrid.split(','))
4742
4743            // refresh
4744            if (tabids.length) {
4745                $.unique(tabids)
4746                setTimeout(function() { BJUI.navtab('reloadFlag', tabids.join(',')) }, 100)
4747            }
4748            if (dialogids.length) {
4749                $.unique(dialogids)
4750                setTimeout(function() { BJUI.dialog('refresh', dialogids.join(',')) }, 100)
4751            }
4752            if (divids.length) {
4753                $.unique(divids)
4754                setTimeout(function() { that.refreshdiv(divids.join(',')) }, 100)
4755            }
4756            if (datagrids.length) {
4757                setTimeout(function() {
4758                    $.each(datagrids, function(i, n) {
4759                        $('#'+ n.trim()).datagrid('refresh', options.gridrefreshflag)
4760                    })
4761                }, 100)
4762            }
4763
4764            if (that.$target == $.CurrentNavtab) {
4765                that.navtabcallback(json)
4766            } else if (that.$target == $.CurrentDialog) {
4767                that.dialogcallback(json)
4768            } else {
4769                that.divcallback(json)
4770            }
4771
4772            if (okAfterCallback) {
4773                okAfterFunc()
4774            }
4775        } else {
4776            if (errCallback) {
4777                errFunc()
4778            }
4779        }
4780    }
4781
4782    Bjuiajax.prototype.divcallback = function(json, $target, options) {
4783        var that = this, options = that.options,
4784            forward = json.forward || options.forward || null,
4785            forwardConfirm = json.forwardConfirm || options.forwardConfirm || null
4786
4787
4788        if (options.reload && !forward) {
4789            that.refreshlayout()
4790        }
4791
4792        if (options.reloadNavtab)
4793            setTimeout(function() { BJUI.navtab('refresh') }, 100)
4794
4795        if (forward) {
4796            var _forward = function() {
4797                $.extend(options, {url: forward})
4798                that.refreshlayout()
4799            }
4800
4801            if (forwardConfirm) {
4802                BJUI.alertmsg('confirm', forwardConfirm, {
4803                    okCall: function() { _forward() }
4804                })
4805            } else {
4806                _forward()
4807            }
4808        }
4809    }
4810
4811    Bjuiajax.prototype.navtabcallback = function(json) {
4812        var that = this, options = that.options,
4813            closeCurrent = json.closeCurrent || options.closeCurrent || false,
4814            forward = json.forward || options.forward || null,
4815            forwardConfirm = json.forwardConfirm || options.forwardConfirm || null
4816
4817        if (closeCurrent && !forward)
4818            BJUI.navtab('closeCurrentTab')
4819        else if (options.reload && !forward)
4820            setTimeout(function() { BJUI.navtab('refresh') }, 100)
4821
4822        if (forward) {
4823            var _forward = function() {
4824                BJUI.navtab('reload', {url:forward})
4825            }
4826
4827            if (forwardConfirm) {
4828                BJUI.alertmsg('confirm', forwardConfirm, {
4829                    okCall: function() { _forward() },
4830                    cancelCall: function() { if (closeCurrent) { BJUI.navtab('closeCurrentTab') } }
4831                })
4832            } else {
4833                _forward()
4834            }
4835        }
4836    }
4837
4838    Bjuiajax.prototype.dialogcallback = function(json) {
4839        var that = this, options = that.options,
4840            closeCurrent = json.closeCurrent || options.closeCurrent || false,
4841            forward = json.forward || options.forward || null,
4842            forwardConfirm = json.forwardConfirm || options.forwardConfirm || null
4843
4844        if (closeCurrent && !forward)
4845            BJUI.dialog('closeCurrent')
4846        else if (options.reload && !forward)
4847            setTimeout(function() { BJUI.dialog('refresh') }, 100)
4848
4849        if (options.reloadNavtab)
4850            setTimeout(function() { BJUI.navtab('refresh') }, 100)
4851        if (forward) {
4852            var _forward = function() {
4853                BJUI.dialog('reload', {url:forward})
4854            }
4855
4856            if (forwardConfirm) {
4857                BJUI.alertmsg('confirm', json.forwardConfirm, {
4858                    okCall: function() { _forward() },
4859                    cancelCall: function() { if (closeCurrent) { BJUI.dialog('closeCurrent') } }
4860                })
4861            } else {
4862                _forward()
4863            }
4864        }
4865    }
4866
4867    Bjuiajax.prototype.doajax = function(options) {
4868        var that = this, $target, $element = that.$element
4869
4870        if (!options) options = {}
4871        if (!options.loadingmask) options.loadingmask = false
4872
4873        options = $.extend({}, Bjuiajax.DEFAULTS, typeof options === 'object' && options)
4874        that.options = options
4875
4876        if (options.target) {
4877            if (options.target instanceof jQuery)
4878                $target = options.target
4879            else
4880                $target = $(options.target)
4881        } else {
4882            if ($element[0] !== $('body')[0]) {
4883                $target = $element.closest('.bjui-layout')
4884            }
4885        }
4886
4887        if (!$target || !$target.length)
4888            $target = $.CurrentDialog || $.CurrentNavtab
4889
4890        that.$target = $target
4891
4892        if (!options.url) {
4893            BJUI.debug('BJUI.ajax: \'doajax\' method: the url is undefined!')
4894            return
4895        } else {
4896            options.url = decodeURI(options.url).replacePlh($target)
4897
4898            if (!options.url.isFinishedTm()) {
4899                BJUI.alertmsg('error', (options.warn || BJUI.regional.plhmsg))
4900                BJUI.debug('BJUI.ajax: \'doajax\' method: The url is incorrect: '+ options.url)
4901                return
4902            }
4903
4904            options.url = encodeURI(options.url)
4905        }
4906
4907        var callback = options.callback && options.callback.toFunc()
4908        var todo     = function() {
4909            if (!options.callback)
4910                options.callback = $.proxy(function(data) {that.ajaxcallback(data)}, that)
4911
4912            $target.data('bjui.ajax.options', options).doAjax(options)
4913        }
4914
4915        if (options.confirmMsg) {
4916            BJUI.alertmsg('confirm', options.confirmMsg,
4917                {
4918                    okCall : function() {
4919                        todo()
4920                    }
4921                }
4922            )
4923        } else {
4924            todo()
4925        }
4926    }
4927
4928    Bjuiajax.prototype._ajaxform = function($form, options) {
4929        var that         = this,
4930            $target      = null,
4931            beforeSubmit = options.beforeSubmit,
4932            callback     = options.callback,
4933            isSubmit     = false,
4934            enctype
4935
4936        if ($form.data('holdSubmit')) {
4937            return
4938        }
4939        // beforeSubmit
4940        if (beforeSubmit) {
4941            if (typeof beforeSubmit === 'string')
4942                beforeSubmit = beforeSubmit.toFunc()
4943            if (typeof beforeSubmit === 'function') {
4944                if (!beforeSubmit.apply(that, [$form])) {
4945                    return
4946                }
4947            } else {
4948                BJUI.debug('BJUI.ajax: \'ajaxform\' options \'beforeSubmit\': Not a function!')
4949                return
4950            }
4951        }
4952
4953        // for webuploader
4954        var $uploaders = $form.find('input[data-toggle="webuploader"]'), requiredMsg, error4Uploader = false
4955
4956        if ($uploaders.length && WebUploader) {
4957            $uploaders.each(function(i, n) {
4958                var uploader = $(this).data('webuploader'), $lis = $(this).data('webuploader.wrap').find('.filelist > li'), fileCount = $lis.length, waitCount = fileCount - $lis.filter('.uploaded').length
4959
4960                if (waitCount && uploader) {
4961                    if (waitCount !== uploader.getStats().successNum) {
4962                        // 自动上传
4963                        uploader.upload()
4964                        // 上传完成后触发
4965                        uploader.on('uploadFinished', function() {
4966                            $form.submit()
4967                        })
4968
4969                        error4Uploader = true
4970                        return false
4971                    }
4972                }
4973                if (uploader && uploader.options.required) {
4974                    if (!fileCount) {
4975                        requiredMsg = uploader.options.requiredMsg || '请上传图片!'
4976                        return false
4977                    }
4978                }
4979            })
4980        }
4981
4982        if (requiredMsg) {
4983            BJUI.alertmsg('info', requiredMsg)
4984            return
4985        }
4986        if (error4Uploader) {
4987            BJUI.alertmsg('info', '表单将在图片上传完成后自动提交!')
4988            return
4989        }
4990
4991        enctype = $form.attr('enctype')
4992
4993        // target
4994        if (!options.target)
4995            options.target = $form.closest('.bjui-layout')
4996        if (options.target) {
4997            $target = options.target
4998
4999            if (!($target instanceof jQuery))
5000                $target = $($target)
5001        }
5002        if (!$target || !$target.length)
5003            $target = $.CurrentDialog || $.CurrentNavtab
5004
5005        that.$target = $target
5006
5007        options.url  = options.url || $form.attr('action')
5008        // for ie8
5009        if (BJUI.isIE(8) && !options.type) {
5010            if (!$form[0].getAttributeNode('method').specified) options.type = 'POST'
5011        }
5012        options.type = options.type || $form.attr('method') || 'POST'
5013
5014        $.extend(that.options, options)
5015
5016        if (callback) callback = callback.toFunc()
5017
5018        var successFn = function(data, textStatus, jqXHR) {
5019            callback ? callback.apply(that, [data, $form]) : $.proxy(that.ajaxcallback(data), that)
5020        }
5021        var _submitFn = function() {
5022            var op = {loadingmask:that.options.loadingmask, type:that.options.type, url:that.options.url, callback:successFn}
5023
5024            if (enctype && enctype == 'multipart/form-data') {
5025                if (window.FormData) {
5026                    $.extend(op, {data:new FormData($form[0]), contentType:false, processData:false})
5027                } else {
5028                    $.extend(op, {data:$form.serializeArray(), files:$form.find(':file'), iframe:true, processData:false})
5029                }
5030            } else {
5031                $.extend(op, {data:$form.serializeArray()})
5032            }
5033
5034            if (that.options.ajaxTimeout) op.ajaxTimeout = that.options.ajaxTimeout
5035
5036            $form.doAjax(op)
5037        }
5038
5039        if (that.options.confirmMsg) {
5040            BJUI.alertmsg('confirm', that.options.confirmMsg, {okCall: _submitFn})
5041        } else {
5042            _submitFn()
5043        }
5044    }
5045
5046    Bjuiajax.prototype.ajaxform = function(option) {
5047        var that     = this,
5048            options  = $.extend({}, typeof option === 'object' && option),
5049            $element = that.$element,
5050            $form    = null,
5051            valiOpts = {
5052                validClass : 'ok',
5053                msgClass   : 'n-bottom',
5054                theme      : 'red_bottom_effect_grid'
5055            }
5056
5057        // form
5058        if ($element[0] === $('body')[0]) {
5059            $form = options.form
5060
5061            if (!($form instanceof jQuery))
5062                $form = $(options.form)
5063        } else {
5064            $form   = $element
5065        }
5066        if (!$form || !$form.length || !($form.isTag('form'))) {
5067            BJUI.debug('BJUI.ajax: \'ajaxform\' method: Not set the form!')
5068            return
5069        }
5070
5071        if (typeof options.validate === 'undefined')
5072            options.validate = true
5073
5074        if ($.fn.validator && options.validate) {
5075            if (!$form.data('validator'))
5076                $form.validator(valiOpts)
5077
5078            $form
5079                .on('valid.form', function(e) {
5080                    that._ajaxform($form, options)
5081                })
5082                .on('invalid.form', function(e, form, errors) {
5083                    if (options.alertmsg) BJUI.alertmsg('error', BJUI.regional.validatemsg.replaceMsg(errors.length))
5084                })
5085
5086            $form.trigger('validate')
5087        } else {
5088            that._ajaxform($form, options)
5089        }
5090    }
5091
5092    Bjuiajax.prototype._ajaxsearch = function($form, options) {
5093        var that         = this,
5094            $target      = null,
5095            beforeSubmit = options.beforeSubmit,
5096            callback     = options.callback,
5097            isSubmit     = false,
5098            enctype
5099
5100        if ($form.data('holdSubmit')) {
5101            return
5102        }
5103        // beforeSubmit
5104        if (beforeSubmit) {
5105            if (typeof beforeSubmit === 'string')
5106                beforeSubmit = beforeSubmit.toFunc()
5107            if (typeof beforeSubmit === 'function') {
5108                if (!beforeSubmit.apply(that, [$form])) {
5109                    return
5110                }
5111            } else {
5112                BJUI.debug('BJUI.ajax: \'ajaxform\' options \'beforeSubmit\': Not a function!')
5113                return
5114            }
5115        }
5116        // pagination
5117        if ($form.data('bjui.paging')) {
5118            if (!options.data)
5119                options.data = {}
5120
5121            $.extend(options.data, $form.data('bjui.paging'))
5122        }
5123        // search for datagrid
5124        if (options.searchDatagrid) {
5125            var $datagrid = options.searchDatagrid
5126
5127            if (!($datagrid instanceof jQuery)) {
5128                $datagrid = $($datagrid)
5129            }
5130
5131            if (!$datagrid || !$datagrid.length || !$datagrid.data('bjui.datagrid')) {
5132                BJUI.debug('BJUI.ajax: \'ajaxsearch\' method: The options \'searchDatagrid\' is not incorrect!')
5133                return
5134            }
5135
5136            $form.data('holdSubmit', true)
5137
5138            $datagrid.datagrid('filter', $form.serializeJson())
5139
5140            $datagrid.on('afterLoad.bjui.datagrid', function() {
5141                $form.data('holdSubmit', false)
5142            })
5143
5144            return
5145        }
5146        // target
5147        if (!options.target)
5148            options.target = $form.closest('.bjui-layout')
5149        if (options.target) {
5150            $target = options.target
5151
5152            if (!($target instanceof jQuery))
5153                $target = $($target)
5154        }
5155        if (!$target || !$target.length)
5156            $target = $.CurrentDialog || $.CurrentNavtab
5157
5158        that.$target = $target
5159
5160        options.url  = options.url || $form.attr('action')
5161        // for ie8
5162        if (BJUI.isIE(8) && !options.type) {
5163            if (!$form[0].getAttributeNode('method').specified) options.type = 'POST'
5164        }
5165        options.type = options.type || $form.attr('method') || 'POST'
5166
5167        if (!options.url) {
5168            BJUI.debug('BJUI.ajax: \'ajaxsearch\' method: The form\'s action or url is undefined!')
5169            return
5170        } else {
5171            options.url = decodeURI(options.url).replacePlh($form.closest('.unitBox'))
5172
5173            if (!options.url.isFinishedTm()) {
5174                BJUI.alertmsg('error', (options.warn || BJUI.regional.plhmsg))
5175                BJUI.debug('BJUI.ajax: \'ajaxsearch\' method: The form\'s action or url is incorrect: '+ options.url)
5176                return
5177            }
5178
5179            options.url = encodeURI(options.url)
5180        }
5181
5182        $.extend(that.options, options)
5183
5184        if ($target.hasClass('bjui-layout')) {
5185            var data = $.extend($form.serializeJson(), options.data)
5186
5187            that.reloadlayout({target:$target[0], type:that.options.type, url:that.options.url, data:data, loadingmask:that.options.loadingmask})
5188        } else {
5189            options.form = $form
5190            if ($target[0] === ($.CurrentNavtab)[0]) {
5191                BJUI.navtab('reloadForm', that.options.clearQuery, options)
5192            } else {
5193                BJUI.dialog('reloadForm', that.options.clearQuery, options)
5194            }
5195        }
5196    }
5197
5198    Bjuiajax.prototype.ajaxsearch = function(option) {
5199        var that     = this,
5200            options  = $.extend({}, typeof option === 'object' && option),
5201            $element = that.$element,
5202            $form    = null,
5203            valiOpts = {
5204                validClass : 'ok',
5205                msgClass   : 'n-bottom',
5206                theme      : 'red_bottom_effect_grid'
5207            }
5208
5209        // form
5210        if ($element[0] === $('body')[0]) {
5211            $form = options.form
5212
5213            if (!($form instanceof jQuery)) {
5214                $form = $(options.form)
5215            }
5216        } else {
5217            $form = $element
5218        }
5219        if (!$form || !$form.length || !($form.isTag('form'))) {
5220            BJUI.debug('BJUI.ajax: \'ajaxsearch\' method: Not set the form!')
5221            return
5222        }
5223
5224        if (typeof options.validate === 'undefined')
5225            options.validate = true
5226
5227        if ($.fn.validator && options.validate) {
5228            if (!$form.data('validator'))
5229                $form.validator(valiOpts)
5230
5231            $form
5232                .on('valid.form', function(e) {
5233                    that._ajaxsearch($form, options)
5234                })
5235                .on('invalid.form', function(e, form, errors) {
5236                    if (options.alertmsg) BJUI.alertmsg('error', BJUI.regional.validatemsg.replaceMsg(errors.length))
5237                })
5238
5239            $form.trigger('validate')
5240        } else {
5241            that._ajaxsearch($form, options)
5242        }
5243    }
5244
5245    Bjuiajax.prototype.doload = function(option) {
5246        var that = this, $target = null, options = that.options
5247
5248        $.extend(options, typeof option === 'object' && option)
5249
5250        if (options.target) {
5251            $target = options.target
5252
5253            if (!($target instanceof jQuery))
5254                $target = $($target)
5255        }
5256
5257        if (!$target || !$target.length) {
5258            BJUI.debug('BJUI.ajax: \'doload\' method: Not set loaded container, like [data-target].')
5259            return
5260        }
5261
5262        if (!options.url) {
5263            BJUI.debug('BJUI.ajax: \'doload\' method: The url is undefined!')
5264            return
5265        } else {
5266            options.url = decodeURI(options.url).replacePlh()
5267
5268            if (!options.url.isFinishedTm()) {
5269                BJUI.alertmsg('error', (options.warn || BJUI.regional.plhmsg))
5270                BJUI.debug('BJUI.ajax: \'doload\' method: The url is incorrect: '+ options.url)
5271                return
5272            }
5273
5274            options.url = encodeURI(options.url)
5275        }
5276
5277        $target.removeData('bjui.clientPaging').data('options', options)
5278        that.reloadlayout(options)
5279    }
5280
5281    Bjuiajax.prototype.refreshlayout = function(target) {
5282        var that = this, $target
5283
5284        if (target) {
5285            $target = target
5286
5287            if (!($target instanceof jQuery))
5288                $target = $($target)
5289        } else {
5290            $target = that.$target
5291        }
5292
5293        if (!$target || !$target.length) {
5294            if (autorefreshTimer) clearInterval(autorefreshTimer)
5295            BJUI.debug('BJUI.ajax: \'refreshlayout\' method: No argument, can not refresh DIV.(parameters:[selector/jQuery object/element])')
5296            return
5297        }
5298        if ($target && $target.length) {
5299            if (!$target.data('options')) {
5300                BJUI.debug('BJUI.ajax: \'refreshlayout\' method: The target(DIV) is not a reload layout!')
5301                return
5302            }
5303            $target.removeData('bjui.clientPaging')
5304            that.reloadlayout($target.data('options'))
5305        }
5306    }
5307
5308    Bjuiajax.prototype.reloadlayout = function(option) {
5309        var $target = null,
5310            options = $.extend({}, typeof option === 'object' && option),
5311            arefre  = options && options.autorefresh && (isNaN(String(options.autorefresh)) ? 15 : options.autorefresh)
5312
5313        if (options.target) {
5314            $target = options.target
5315
5316            if (!($target instanceof jQuery))
5317                $target = $($target)
5318        }
5319
5320        if (!$target || !$target.length) {
5321            if (autorefreshTimer) clearInterval(autorefreshTimer)
5322            BJUI.debug('BJUI.ajax: \'refreshlayout\' method: Not set loaded container, like [data-target].')
5323            return
5324        } else {
5325            if (!$target.data('options')) {
5326                BJUI.debug('BJUI.ajax: \'refreshlayout\' method: This target(DIV) is not initialized!')
5327                return
5328            }
5329            options = $.extend({}, $target.data('options'), options)
5330        }
5331
5332        $target
5333            .addClass('bjui-layout')
5334            .data('options', options)
5335            .ajaxUrl({ type:options.type, url:options.url, data:options.data, loadingmask:options.loadingmask, callback:function(html) {
5336                    if (BJUI.ui.clientPaging && $target.data('bjui.clientPaging'))
5337                        $target.pagination('setPagingAndOrderby', $target)
5338                    if (options.callback)
5339                        options.callback.apply(this, [$target, html])
5340                    if (autorefreshTimer)
5341                        clearInterval(autorefreshTimer)
5342                    if (arefre)
5343                        autorefreshTimer = setInterval(function() { $target.bjui
5343ajax('refreshlayout', $target) }, arefre * 1000)
5344                    if(!$target.height()) {
5345                        $target.css('position', 'static')
5346                    }
5347                }
5348            })
5349    }
5350
5351    Bjuiajax.prototype.refreshdiv = function(divid) {
5352        if (divid && typeof divid === 'string') {
5353            var arr = divid.split(',')
5354
5355            for (var i = 0; i < arr.length; i++) {
5356                this.refreshlayout('#'+ arr[i])
5357            }
5358        }
5359    }
5360
5361    Bjuiajax.prototype.ajaxdownload = function(option) {
5362        var that = this, $target, options = $.extend({}, {loadingmask: false}, typeof option === 'object' && option)
5363
5364        $.extend(that.options, options)
5365
5366        if (options.target) {
5367            $target = options.target
5368
5369            if (!($target instanceof jQuery))
5370                $target = $($target)
5371        }
5372
5373        if (!$target || !$target.length)
5374            $target = $.CurrentDialog || $.CurrentNavtab
5375
5376        that.$target = $target
5377
5378        if (!options.url) {
5379            BJUI.debug('BJUI.ajax: \'ajaxdownload\' method: The url is undefined!')
5380            return
5381        } else {
5382            options.url = decodeURI(options.url).replacePlh($target)
5383
5384            if (!options.url.isFinishedTm()) {
5385                BJUI.alertmsg('error', (options.warn || BJUI.regional.plhmsg))
5386                BJUI.debug('BJUI.ajax: \'ajaxdownload\' method: The url is incorrect: '+ options.url)
5387                return
5388            }
5389        }
5390
5391        var todo = function() {
5392            var downloadOptions = {}
5393
5394            downloadOptions.failCallback = function(responseHtml, url) {
5395                if (responseHtml.trim().startsWith('{')) responseHtml = responseHtml.toObj()
5396                that.ajaxdone(responseHtml)
5397                $target.trigger('bjui.ajaxError')
5398            }
5399            downloadOptions.prepareCallback = function(url) {
5400                if (options.loadingmask) {
5401                    $target.trigger('bjui.ajaxStart')
5402                }
5403            }
5404            downloadOptions.successCallback = function(url) {
5405                $target.trigger('bjui.ajaxStop')
5406            }
5407
5408            if (options.type && !options.httpMethod)
5409                options.httpMethod = options.type
5410
5411            $.extend(downloadOptions, options)
5412
5413            if (!downloadOptions.data) downloadOptions.data = {}
5414            if (typeof downloadOptions.data.ajaxrequest === 'undefined') downloadOptions.data.ajaxrequest = true
5415
5416            $.fileDownload(options.url, downloadOptions)
5417        }
5418
5419        if (options.confirmMsg) {
5420            BJUI.alertmsg('confirm', options.confirmMsg, {
5421                okCall: function() {
5422                    todo()
5423                }
5424            })
5425        } else {
5426            todo()
5427        }
5428    }
5429
5430    // BJUIAJAX PLUGIN DEFINITION
5431    // =======================
5432
5433    function Plugin(option) {
5434        var args     = arguments,
5435            property = option,
5436            ajax     = 'bjui.ajax',
5437            $body    = $('body')
5438
5439        return this.each(function () {
5440            var $this   = $(this),
5441                options = $.extend({}, Bjuiajax.DEFAULTS, typeof option === 'object' && option),
5442                data    = $this.data(ajax),
5443                func
5444
5445            if (!data) {
5446                data = new Bjuiajax(this, options)
5447            } else {
5448                if (this === $body[0]) {
5449                    data = new Bjuiajax(this, options)
5450                } else {
5451                    $.extend(data.options, typeof option === 'object' && option)
5452                }
5453            }
5454
5455            $this.data(ajax, data)
5456
5457            if (typeof property === 'string') {
5458                func = data[property.toLowerCase()]
5459                if ($.isFunction(func)) {
5460                    [].shift.apply(args)
5461                    if (!args) func()
5462                    else func.apply(data, args)
5463                }
5464            }
5465        })
5466    }
5467
5468    var old = $.fn.bjuiajax
5469
5470    $.fn.bjuiajax             = Plugin
5471    $.fn.bjuiajax.Constructor = Bjuiajax
5472
5473    // BJUIAJAX NO CONFLICT
5474    // =================
5475
5476    $.fn.bjuiajax.noConflict = function () {
5477        $.fn.bjuiajax = old
5478        return this
5479    }
5480
5481    // NOT SELECTOR
5482    // ==============
5483
5484    BJUI.ajax = function() {
5485        Plugin.apply($('body'), arguments)
5486    }
5487
5488    // BJUIAJAX DATA-API
5489    // ==============
5490
5491    $(document).on(BJUI.eventType.initUI, function(e) {
5492        if ($.fn.validator) {
5493            $(e.target).find('form[data-toggle="ajaxform"], form[data-toggle="ajaxsearch"]').each(function() {
5494                var $this = $(this), data = $this.data(), options = data.options,
5495                    valiOpts = {
5496                        validClass : 'ok',
5497                        msgClass   : 'n-bottom',
5498                        theme      : 'red_bottom_effect_grid'
5499                    }
5500
5501                if (options) {
5502                    if (typeof options === 'string') options = options.toObj()
5503                    if (typeof options === 'object') {
5504                        delete data.options
5505                        $.extend(data, options)
5506                    }
5507                }
5508                if (typeof data.validate === 'undefined')
5509                    data.validate = true
5510                if (!data.validate) {
5511                    valiOpts.ignore = '*'
5512                }
5513
5514                $this
5515                    .validator(valiOpts)
5516                    .on('valid.form', function(e) {
5517                        BJUI.ajax('_'+ data.toggle, $this, data)
5518                    })
5519                    .on('invalid.form', function(e, form, errors) {
5520                        if (data.alertmsg) BJUI.alertmsg('error', BJUI.regional.validatemsg.replaceMsg(errors.length))
5521                    })
5522            })
5523        }
5524    })
5525
5526    $(document).on('submit.bjui.bjuiajax.data-api', 'form[data-toggle="ajaxform"], form[data-toggle="ajaxsearch"]', function(e) {
5527        if (!$.fn.validator) {
5528            var $this = $(this), data = $this.data(), options = data.options
5529
5530            if (options) {
5531                if (typeof options === 'string') options = options.toObj()
5532                if (typeof options === 'object') {
5533                    delete data.options
5534                    $.extend(data, options)
5535                }
5536            }
5537
5538            Plugin.call($this, '_'+ data.toggle, $this, data)
5539
5540            e.preventDefault()
5541        }
5542    })
5543
5544    $(document).on('click.bjui.bjuiajax.data-api', '[data-toggle="ajaxload"]', function(e) {
5545        var $this = $(this), data = $this.data(), options = data.options
5546
5547        if (options) {
5548            if (typeof options === 'string') options = options.toObj()
5549            if (typeof options === 'object') {
5550                delete data.options
5551                $.extend(data, options)
5552            }
5553        }
5554
5555        if (!data.url) data.url = $this.attr('href')
5556
5557        Plugin.call($this, 'doload', data)
5558
5559        e.preventDefault()
5560    })
5561
5562    $(document).on(BJUI.eventType.initUI, function(e) {
5563        $(e.target).find('[data-toggle="autoajaxload"]').each(function() {
5564            var $element = $(this), data = $this.data(), options = data.options
5565
5566            if (options) {
5567                if (typeof options === 'string') options = options.toObj()
5568                if (typeof options === 'object') {
5569                    delete data.options
5570                    $.extend(data, options)
5571                }
5572            }
5573
5574            data.target = this
5575            Plugin.call($element, 'doload', data)
5576        })
5577    })
5578
5579    $(document).on('click.bjui.bjuiajax.data-api', '[data-toggle="refreshlayout"]', function(e) {
5580        var $this = $(this), target = $this.data('target')
5581
5582        Plugin.call($this, 'refreshlayout', target)
5583
5584        e.preventDefault()
5585    })
5586
5587    $(document).on('click.bjui.bjuiajax.data-api', '[data-toggle="reloadlayout"]', function(e) {
5588        var $this = $(this), data = $this.data()
5589
5590        Plugin.call($this, 'reloadlayout', data)
5591
5592        e.preventDefault()
5593    })
5594
5595    $(document).on('click.bjui.bjuiajax.data-api', '[data-toggle="doajax"]', function(e) {
5596        var $this = $(this), data = $this.data(), options = data.options
5597
5598        if (options) {
5599            if (typeof options === 'string') options = options.toObj()
5600            if (typeof options === 'object') {
5601                delete data.options
5602                $.extend(data, options)
5603            }
5604        }
5605
5606        if (!data.url) data.url = $this.attr('href')
5607
5608        Plugin.call($this, 'doajax', data)
5609
5610        e.preventDefault()
5611    })
5612
5613    $(document).on('click.bjui.bjuiajax.data-api', '[data-toggle="ajaxdownload"]', function(e) {
5614        var $this = $(this), data = $this.data(), options = data.options
5615
5616        if (options) {
5617            if (typeof options === 'string') options = options.toObj()
5618            if (typeof options === 'object') {
5619                delete data.options
5620                $.extend(data, options)
5621            }
5622        }
5623        if (!data.url) data.url = $this.attr('href')
5624
5625        Plugin.call($this, 'ajaxdownload', data)
5626
5627        e.preventDefault()
5628    })
5629
5630}(jQuery);
5631/*!
5632 * B-JUI  V1.31 (http://b-jui.com)
5633 * Git@OSC (http://git.oschina.net/xknaan/B-JUI)
5634 * Copyright 2014 K'naan.
5635 * Licensed under Apache (http://www.apache.org/licenses/LICENSE-2.0)
5636 */
5637
5638/* ========================================================================
5639 * B-JUI: bjui-alertmsg.js  V1.31
5640 * @author K'naan
5641 * http://git.oschina.net/xknaan/B-JUI/blob/master/BJUI/js/bjui-alertmsg.js
5642 * ========================================================================
5643 * Copyright 2014 K'naan.
5644 * Licensed under Apache (http://www.apache.org/licenses/LICENSE-2.0)
5645 * ======================================================================== */
5646
5647+function ($) {
5648    'use strict';
5649
5650    // ALERTMSG GLOBAL ELEMENTS
5651    // ======================
5652
5653    var $box, $alertbg, timer
5654
5655    $(function() {
5656        var INIT_ALERTMSG = function() {
5657            $box     = $(FRAG.alertBoxFrag).hide().html('')
5658            $alertbg = $(FRAG.alertBackground).hide().html('')
5659            $('body').append('<!-- alert msg box -->').append($box).append('<!-- alert msg box mask bg -->').append($alertbg)
5660        }
5661
5662        INIT_ALERTMSG()
5663    })
5664
5665    // ALERTMSG CLASS DEFINITION
5666    // ======================
5667    var Alertmsg = function(options) {
5668        this.options   = options
5669        this.tools     = this.TOOLS()
5670        this.clearTime = null
5671    }
5672
5673    Alertmsg.DEFAULTS = {
5674        displayPosition : 'topcenter', // Optional 'topleft, topcenter, topright, middleleft, middlecenter, middleright, bottomleft, bottomcenter, bottomright'
5675        displayMode     : 'slide',     // Optional 'none, fade, slide'
5676        autoClose       : null,
5677        alertTimeout    : 3000,
5678        mask            : null,
5679        promptRequired  : 'required',
5680        types           : {error:'error', info:'info', warn:'warn', correct:'correct', confirm:'confirm', prompt:'prompt'},
5681        fas             : {error:'fa-times-circle', info:'fa-info-circle', warn:'fa-exclamation-circle', correct:'fa-check-circle', confirm:'fa-question-circle', prompt:'fa-paper-plane-o'}
5682    }
5683
5684    Alertmsg.prototype.TOOLS = function() {
5685        var that  = this
5686        var tools = {
5687            getTitle: function(key){
5688                return that.options.title || BJUI.regional.alertmsg.title[key]
5689            },
5690            keydownOk: function(event) {
5691                if (event.which == BJUI.keyCode.ENTER) {
5692                    event.data.target.trigger('click')
5693                    return false
5694                }
5695                return true
5696            },
5697            keydownEsc: function(event) {
5698                if (event.which == BJUI.keyCode.ESC) event.data.target.trigger('click')
5699            },
5700            openPosition: function() {
5701                var position = BJUI.alertMsg.displayPosition, mode = BJUI.alertMsg.displayMode, width = 460, height = $box.outerHeight(), startCss = {}, endCss = {}
5702
5703                if (position) {
5704                    if (that.options.displayPosition && that.options.displayPosition != 'topcenter')
5705                        position = that.options.displayPosition
5706                } else {
5707                    position = that.options.displayPosition
5708                }
5709
5710                if (mode) {
5711                    if (that.options.displayMode && that.options.displayMode != 'slide')
5712                        mode = that.options.displayMode
5713                } else {
5714                    mode = that.options.displayMode
5715                }
5716
5717                switch (position) {
5718                    case 'topleft':
5719                        startCss = {top:0 - height, left:0, 'margin-left':0}
5720                        endCss   = {top:0}
5721
5722                        break
5723                    case 'topcenter':
5724                        startCss = {top:0 - height}
5725                        endCss   = {top:0}
5726
5727                        break
5728                    case 'topright':
5729                        startCss = {top:0 - height, left:'auto', right:0, 'margin-left':0}
5730                        endCss   = {top:0}
5731
5732                        break
5733                    case 'middleleft':
5734                        startCss = {top:'50%', left:0 - width, 'margin-left':0, 'margin-top':0 - height/2}
5735                        endCss   = {left:0}
5736
5737                        break
5738                    case 'middlecenter':
5739                        startCss = {top:'0', 'margin-top':0 - height/2}
5740                        endCss   = {top:'50%'}
5741
5742                        break
5743                    case 'middleright':
5744                        startCss = {top:'50%', left:'auto', right:0 - width, 'margin-top':0 - height/2}
5745                        endCss   = {right:0}
5746
5747                        break
5748                    case 'bottomleft':
5749                        startCss = {top:'auto', left:0, bottom:0 - height, 'margin-left':0}
5750                        endCss   = {bottom:0}
5751
5752                        break
5753                    case 'bottomcenter':
5754                        startCss = {top:'auto', bottom:0 - height}
5755                        endCss   = {bottom:0}
5756
5757                        break
5758                    case 'bottomright':
5759                        startCss = {top:'auto', left:'auto', right:0, bottom:0 - height, 'margin-left':0}
5760                        endCss   = {bottom:0}
5761
5762                        break
5763                }
5764
5765                if (mode == 'slide') {
5766                    $box.css(startCss).show().animate(endCss, 500)
5767                } else if (mode == 'fade') {
5768                    startCss.opacity = 0.1
5769                    $box.css(startCss).css(endCss).show().animate({opacity:1}, 500)
5770                } else {
5771                    $box.css(startCss).css(endCss).show()
5772                }
5773            },
5774            closePosition: function() {
5775                var position = BJUI.alertMsg.displayPosition, mode = BJUI.alertMsg.displayMode, width = 460, height = $box.outerHeight(), endCss = {}
5776
5777                if (position) {
5778                    if (that.options.displayPosition && that.options.displayPosition != 'topcenter')
5779                        position = that.options.displayPosition
5780                } else {
5781                    position = that.options.displayPosition
5782                }
5783
5784                if (mode) {
5785                    if (that.options.displayMode && that.options.displayMode != 'slide')
5786                        mode = that.options.displayMode
5787                } else {
5788                    mode = that.options.displayMode
5789                }
5790
5791                switch (position) {
5792                    case 'topleft':
5793                        endCss   = {top:0 - height}
5794
5795                        break
5796                    case 'topcenter':
5797                        endCss   = {top:0 - height}
5798
5799                        break
5800                    case 'topright':
5801                        endCss   = {top:0 - height}
5802
5803                        break
5804                    case 'middleleft':
5805                        endCss   = {left:0 - width}
5806
5807                        break
5808                    case 'middlecenter':
5809                        endCss   = {top:0 - height}
5810
5811                        break
5812                    case 'middleright':
5813                        endCss   = {right:0 - width}
5814
5815                        break
5816                    case 'bottomleft':
5817                        endCss   = {bottom:0 - height}
5818
5819                        break
5820                    case 'bottomcenter':
5821                        endCss   = {bottom:0 - height}
5822
5823                        break
5824                    case 'bottomright':
5825                        endCss   = {bottom:0 - height}
5826
5827                        break
5828                }
5829
5830                if (mode == 'slide') {
5831                    $box.animate(endCss, 500, function() {
5832                        $alertbg.hide()
5833                        $(this).hide().empty()
5834                    })
5835                } else if (mode == 'fade') {
5836                    $box.animate({opacity:0}, 500, function() {
5837                        $alertbg.hide()
5838                        $(this).hide().empty()
5839                    })
5840                } else {
5841                    $box.hide().remove()
5842                    $alertbg.hide()
5843                }
5844            },
5845            open: function(type, msg, buttons) {
5846                var tools = this, btnsHtml = '', $newbox, $btns, alertTimeout = BJUI.alertMsg.alertTimeout, input = ''
5847
5848                if (buttons) {
5849                    for (var i = 0; i < buttons.length; i++) {
5850                        var sRel = buttons[i].call ? 'callback' : '',
5851                            sCls = buttons[i].cls  ? buttons[i].cls : 'default',
5852                            sIco = (buttons[i].cls && buttons[i].cls == 'green') ? 'check' : 'close'
5853
5854                        btnsHtml += FRAG.alertBtnFrag.replace('#btnMsg#', '<i class="fa fa-'+ sIco +'"></i> '+ buttons[i].name).replace('#callback#', sRel).replace('#class#', sCls)
5855                    }
5856                }
5857                if (type == that.options.types.prompt) {
5858                    input = '<p style="padding-top:5px;"><input type="text" class="form-control" name="'+ (that.options.promptname || 'prompt') +'" value=""></p>'
5859                }
5860
5861                $newbox =
5862                    $(FRAG.alertBoxFrag.replace('#type#', type)
5863                        .replace('#fa#', that.options.fas[type])
5864                        .replace('#title#', this.getTitle(type))
5865                        .replace('#message#', msg)
5866                        .replace('#prompt#', input)
5867                        .replace('#btnFragment#', btnsHtml))
5868                        .hide()
5869                        .appendTo('body')
5870
5871                if ($box && $box.length) $box.remove()
5872                $box = $newbox
5873
5874                tools.openPosition()
5875
5876                if (timer) {
5877                    clearTimeout(timer)
5878                    timer = null
5879                }
5880
5881                if (that.options.mask == null) {
5882                    if (!(that.options.types.info == type || that.options.types.correct == type))
5883                        $alertbg.show()
5884                }
5885                if (that.options.autoClose == null) {
5886                    if (that.options.types.info == type || that.options.types.correct == type) {
5887                        if (alertTimeout) {
5888                            if (that.options.alertTimeout && that.options.alertTimeout != 3000)
5889                                alertTimeout = that.options.alertTimeout
5890                        } else {
5891                            alertTimeout = that.options.alertTimeout
5892                        }
5893                        timer = setTimeout(function() { tools.close() }, alertTimeout)
5894                    }
5895                }
5896                if (type == that.options.types.prompt) {
5897                    $box.find(':text').focus().val(that.options.promptval)
5898                }
5899
5900                $btns = $box.find('.btn')
5901
5902                $btns.each(function(i) {
5903                    $(this).on('click', $.proxy(function() {
5904                            if (type !== that.options.types.prompt || $btns.eq(i).hasClass('btn-red'))
5905                                that.tools.close()
5906
5907                            var call = buttons[i].call
5908
5909                            if (typeof call === 'string')   call = call.toFunc()
5910                            if (typeof call === 'function') {
5911                                if (type == that.options.types.prompt) {
5912                                    var $input = $box.find('input'), value = $input.val()
5913
5914                                    $input.focus(function() {
5915                                        $box.removeClass('has-error')
5916                                    })
5917
5918                                    if (that.options.promptRequired === 'required' && !value) {
5919                                        $box.addClass('has-error')
5920                                    } else {
5921                                        that.tools.close()
5922                                        call.call(that, value)
5923                                    }
5924                                } else {
5925                                    call.call()
5926                                }
5927                            }
5928                        }, that)
5929                    )
5930
5931                    if (buttons[i].keyCode === BJUI.keyCode.ENTER) {
5932                        $(document).on('keydown.bjui.alertmsg.ok', {target:$btns.eq(i)}, tools.keydownOk)
5933                    }
5934                    if (buttons[i].keyCode === BJUI.keyCode.ESC) {
5935                        $(document).on('keydown.bjui.alertmsg.esc', {target:$btns.eq(i)}, tools.keydownEsc)
5936                    }
5937                })
5938            },
5939            alert: function(type, msg, btnoptions) {
5940                $.extend(that.options, typeof btnoptions === 'object' && btnoptions)
5941
5942                var op      = $.extend({}, {okName:BJUI.regional.alertmsg.btnMsg.ok, okCall:null}, that.options)
5943                var buttons = [
5944                    {name:op.okName, call:op.okCall, cls:'default', keyCode:BJUI.keyCode.ENTER}
5945                ]
5946
5947                this.open(type, msg, buttons)
5948            },
5949            close: function() {
5950                $(document).off('keydown.bjui.alertmsg.ok').off('keydown.bjui.alertmsg.esc')
5951
5952                this.closePosition()
5953            }
5954        }
5955
5956        return tools
5957    }
5958
5959    Alertmsg.prototype.error = function(msg, btnoptions) {
5960        this.tools.alert(this.options.types.error, msg, btnoptions)
5961    }
5962
5963    Alertmsg.prototype.info = function(msg, btnoptions) {
5964        this.tools.alert(this.options.types.info, msg, btnoptions)
5965    }
5966
5967    Alertmsg.prototype.warn = function(msg, btnoptions) {
5968        this.tools.alert(this.options.types.warn, msg, btnoptions)
5969    }
5970
5971    Alertmsg.prototype.ok = function(msg, btnoptions) {
5972        this.tools.alert(this.options.types.correct, msg, btnoptions)
5973    }
5974
5975    Alertmsg.prototype.correct = function(msg, btnoptions) {
5976        this.tools.alert(this.options.types.correct, msg, btnoptions)
5977    }
5978
5979    Alertmsg.prototype.confirm = function(msg, btnoptions) {
5980        $.extend(this.options, typeof btnoptions === 'object' && btnoptions)
5981
5982        var op      = $.extend({}, {okName:BJUI.regional.alertmsg.btnMsg.ok, okCall:null, cancelName:BJUI.regional.alertmsg.btnMsg.cancel, cancelCall:null}, this.options)
5983        var buttons = [
5984            {name:op.okName, call:op.okCall, cls:'green', keyCode:BJUI.keyCode.ENTER},
5985            {name:op.cancelName, call:op.cancelCall, cls:'red', keyCode:BJUI.keyCode.ESC}
5986        ]
5987
5988        this.tools.open(this.options.types.confirm, msg, buttons)
5989    }
5990
5991    Alertmsg.prototype.prompt = function(msg, btnoptions) {
5992        $.extend(this.options, typeof btnoptions === 'object' && btnoptions)
5993
5994        var that = this, op = $.extend({}, {okName:BJUI.regional.alertmsg.btnMsg.ok, okCall:null, cancelName:BJUI.regional.alertmsg.btnMsg.cancel, cancelCall:null}, this.options)
5995
5996        if (op.okCall == null && (typeof that.options.prompt === 'object' && that.options.prompt)) {
5997            op.okCall = function(val) {
5998                var data = {}
5999
6000                data[(that.options.promptname || 'prompt')] = val
6001
6002                if (!that.options.prompt.data)
6003                    that.options.prompt.data = data
6004                else
6005                    $.extend(that.options.prompt.data, data)
6006
6007                BJUI.ajax('doajax', that.options.prompt)
6008            }
6009        }
6010
6011        var buttons = [
6012            {name:op.okName, call:op.okCall, cls:'green', keyCode:BJUI.keyCode.ENTER},
6013            {name:op.cancelName, call:op.cancelCall, cls:'red', keyCode:BJUI.keyCode.ESC}
6014        ]
6015
6016        this.tools.open(this.options.types.prompt, msg, buttons)
6017    }
6018
6019    // ALERTMSG PLUGIN DEFINITION
6020    // =======================
6021
6022    function Plugin(option) {
6023        var args     = arguments,
6024            property = option,
6025            alertmsg = 'bjui.alertmsg',
6026            $body    = $('body'),
6027            data     = $body.data(alertmsg)
6028
6029        return this.each(function () {
6030            var $this   = $(this),
6031                options = $.extend({}, Alertmsg.DEFAULTS, typeof option === 'object' && option)
6032
6033            if (!data) {
6034                data = new Alertmsg(options)
6035            } else {
6036                data.options = options
6037            }
6038
6039            $body.data(alertmsg, data)
6040
6041            if (typeof property === 'string' && $.isFunction(data[property])) {
6042                [].shift.apply(args)
6043                if (!args) data[property]()
6044                else data[property].apply(data, args)
6045            }
6046        })
6047    }
6048
6049    var old = $.fn.alertmsg
6050
6051    $.fn.alertmsg             = Plugin
6052    $.fn.alertmsg.Constructor = Alertmsg
6053
6054    // ALERTMSG NO CONFLICT
6055    // =================
6056
6057    $.fn.alertmsg.noConflict = function () {
6058        $.fn.alertmsg = old
6059        return this
6060    }
6061
6062    // NOT SELECTOR
6063    // ==============
6064
6065    BJUI.alertmsg = function() {
6066        Plugin.apply($('body'), arguments)
6067    }
6068
6069    // NAVTAB DATA-API
6070    // ==============
6071
6072    $(document).on('click.bjui.alertmsg.data-api', '[data-toggle="alertmsg"]', function(e) {
6073        var $this = $(this), data = $this.data(), options = data.options, type
6074
6075        if (options) {
6076            if (typeof options === 'string') options = options.toObj()
6077            if (typeof options === 'object') {
6078                $.extend(data, options)
6079            }
6080        }
6081
6082        type = data.type
6083        if (!type) return false
6084        if (!data.msg) {
6085            if (options.msg) data.msg = options.msg
6086        }
6087
6088        Plugin.call($this, type, data.msg || type, data)
6089
6090        e.preventDefault()
6091    })
6092
6093}(jQuery);
6094/*!
6095 * B-JUI  V1.31 (http://b-jui.com)
6096 * Git@OSC (http://git.oschina.net/xknaan/B-JUI)
6097 * Copyright 2014 K'naan.
6098 * Licensed under Apache (http://www.apache.org/licenses/LICENSE-2.0)
6099 */
6100
6101/* ========================================================================
6102 * B-JUI: bjui-pagination.js  V1.31
6103 * @author K'naan
6104 * http://git.oschina.net/xknaan/B-JUI/blob/master/BJUI/js/bjui-pagination.js
6105 * ========================================================================
6106 * Copyright 2014 K'naan.
6107 * Licensed under Apache (http://www.apache.org/licenses/LICENSE-2.0)
6108 * ======================================================================== */
6109
6110+function ($) {
6111    'use strict';
6112
6113    // PAGINATION CLASS DEFINITION
6114    // ======================
6115
6116    var Pagination = function(element, options) {
6117        this.$element = $(element)
6118        this.options  = options
6119        this.tools    = this.TOOLS()
6120    }
6121
6122    Pagination.DEFAULTS = {
6123        width          : '100%',
6124        pageSize       : 4000,
6125        selectPageSize : '30,60,90',
6126        pageCurrent    : 1,
6127        total          : 0,
6128        showPagenum    : 5,
6129        form           : null,
6130        callback       : null
6131    }
6132
6133    Pagination.prototype.TOOLS = function() {
6134        var that    = this
6135        var tools   = {
6136            getPageCount: function(pageSize, total) {
6137                return Math.ceil(total / pageSize)
6138            },
6139            getPageInterval: function(count, pageCurrent, showPageNum) {
6140                var half  = Math.ceil(showPageNum / 2), limit = count - showPageNum,
6141                    start = pageCurrent > half ? Math.max(Math.min(pageCurrent - half, limit), 0) : 0,
6142                    end   = pageCurrent > half ? Math.min((pageCurrent + half), count) : Math.min(showPageNum, count)
6143
6144                if (end - start == showPageNum) end = end + 1
6145                if (end < showPageNum) end = end + 1
6146                if (start + 1 == end) end = end + 1
6147
6148                return {start:start + 1, end:end}
6149            },
6150            // jump to page
6151            jumpPage: function(pageCurrent, pageSize) {
6152                var callback = that.options.callback
6153
6154                if (typeof callback === 'string')
6155                    callback = callback.toFunc()
6156
6157                if (pageCurrent) {
6158                    that.options.pageCurrent = pageCurrent
6159                }
6160                if (pageSize) {
6161                    that.options.pageSize = pageSize
6162                    that.pageCount = this.getPageCount(pageSize, that.options.total)
6163
6164                    if (that.options.pageCurrent > that.pageCount)
6165                        that.options.pageCurrent = that.pageCount
6166                }
6167
6168                if (callback && typeof callback === 'function') {
6169                    callback.call(that, that.options.pageCurrent, pageSize)
6170                } else {
6171                    this.setPaging(that.options.pageCurrent, pageSize, true)
6172                }
6173
6174                that.$element.trigger('bjui.pagination.jump')
6175            },
6176            setPaging: function(pageCurrent, pageSize, isSubmit) {
6177                var $form = that.options.form, paging = {}
6178
6179                if ($form) {
6180                    if (!($form instanceof jQuery)) {
6181                        $form = $($form)
6182                    }
6183                    if (!$form || !$form.length) {
6184                        BJUI.debug('BJUI.Pagination: The options \'form\' is not incorrect!')
6185                        return
6186                    }
6187
6188                    paging[BJUI.pageInfo.pageCurrent] = pageCurrent
6189                    paging[BJUI.pageInfo.pageSize]    = pageSize
6190
6191                    $form.data('bjui.paging', paging)
6192
6193                    if (isSubmit)
6194                        $form.trigger('submit')
6195                }
6196            }
6197        }
6198        return tools
6199    }
6200
6201    Pagination.prototype.jumpPage = function(pageCurrent, pageSize) {
6202        var that = this, options = that.options, pageCount = that.pageCount
6203
6204        if (pageCurrent && isNaN(pageCurrent)) return
6205        if (pageSize && isNaN(pageSize))       return
6206        if (pageCurrent) {
6207            pageCurrent = parseInt(pageCurrent, 10)
6208
6209            if (pageCurrent < 1)         pageCurrent = 1
6210            if (pageCurrent > pageCount) pageCurrent = pageCount
6211            if (pageCurrent == options.pageCurrent) return
6212        }
6213        if (pageSize) {
6214            pageSize = parseInt(pageSize, 10)
6215        }
6216
6217        that.tools.jumpPage(pageCurrent || options.pageCurrent, pageSize || options.pageSize)
6218    }
6219
6220    Pagination.prototype.init = function() {
6221        var that = this, tools = that.tools, options = that.options, pr = BJUI.regional.pagination, btnpaging = FRAG.gridPaging, pageNums = [], interval, selectPages = [], pagingHtml = BJUI.StrBuilder()
6222
6223        that.pageCount = tools.getPageCount(options.pageSize, options.total)
6224
6225        interval = tools.getPageInterval(that.pageCount, options.pageCurrent, options.showPagenum)
6226
6227        for (var i = interval.start; i < interval.end; i++) {
6228            pageNums.push(FRAG.gridPageNum.replace('#num#', i).replace('#active#', (options.pageCurrent == i ? ' active' : '')))
6229        }
6230
6231        btnpaging = BJUI.doRegional(btnpaging.replaceAll('#pageCurrent#', options.pageCurrent).replaceAll('#count#', options.total +'/'+ parseInt((that.pageCount || 0), 10)), pr)
6232
6233        pagingHtml
6234            .add('<div class="paging-content">')
6235            .add('<span></span><div class="paging-pagesize"><button type="button" class="btn-default btn-refresh" title="'+ pr.refresh +'" data-icon="refresh"></button>')
6236            .add('<select data-toggle="selectpicker"></select>')
6237            .add('</div>')
6238            .add('<div class="paging-box">')
6239            .add(btnpaging.replace('#pageNumFrag#', pageNums.join('')))
6240            .add('</div>')
6241            .add('</div>')
6242
6243        that.$element.addClass('bjui-paging-box').html(pagingHtml.toString())
6244        that.$element.find('> .paging-content').width(options.width).initui()
6245
6246        tools.setPaging(options.pageCurrent, options.pageSize)
6247
6248        //events
6249        var $select    = that.$element.find('div.paging-pagesize > select'),
6250            $pagenum   = that.$element.find('ul.pagination'),
6251            $pagetotal = $pagenum.find('> li.page-total'),
6252            $jumpto    = $pagetotal.next(),
6253            $first     = $jumpto.next(),
6254            $prev      = $first.next(),
6255            $next      = $prev.nextAll('.page-next'),
6256            $last      = $next.next()
6257
6258        var disablePrev = function() {
6259            $first.addClass('disabled')
6260            $prev.addClass('disabled')
6261        }
6262        var enablePrev = function() {
6263            $first.removeClass('disabled')
6264            $prev.removeClass('disabled')
6265        }
6266        var disableNext = function() {
6267            $next.addClass('disabled')
6268            $last.addClass('disabled')
6269        }
6270        var enableNext = function() {
6271            $next.removeClass('disabled')
6272            $last.removeClass('disabled')
6273        }
6274        var pageFirst = function() {
6275            disablePrev()
6276            enableNext()
6277        }
6278        var pageLast = function() {
6279            enablePrev()
6280            disableNext()
6281        }
6282        var setPageSize = function(pageSize) {
6283            $select.empty()
6284
6285            if (!pageSize) pageSize = that.options.pageSize
6286
6287            selectPages = options.selectPageSize.split(',')
6288            selectPages.push(String(pageSize))
6289
6290            $.unique(selectPages).sort(function(a, b) { return a - b })
6291
6292            var opts = []
6293
6294            $.each(selectPages, function(i, n) {
6295                opts.push('<option value="'+ n +'"'+ (n == options.pageSize && 'selected') +'>'+ n +'/'+ pr.page +'</option>')
6296            })
6297
6298            $select.html(opts.join('')).selectpicker('refresh')
6299        }
6300
6301        if (options.pageCurrent == 1) pageFirst()
6302        if (options.pageCurrent == that.pageCount) {
6303            pageLast()
6304            if (options.pageCurrent == 1) disablePrev()
6305        }
6306        if (!options.total) disableNext()
6307        setPageSize()
6308
6309        that.$element.on('click.bjui.pagination.pagenum', 'li.page-num', function(e) {
6310            var $num = $(this)
6311
6312            if (!$num.hasClass('active')) {
6313                that.jumpPage($num.text())
6314            }
6315
6316            e.preventDefault()
6317        }).on('click.bjui.pagination.refresh', 'button.btn-refresh', function() {
6318            that.jumpPage()
6319        }).on('bjui.pagination.jump', function(e) {
6320            var pageCurrent = that.options.pageCurrent, interval = tools.getPageInterval(that.pageCount, pageCurrent, options.showPagenum), pageNums = []
6321
6322            for (var i = interval.start; i < interval.end; i++) {
6323                pageNums.push(FRAG.gridPageNum.replace('#num#', i).replace('#active#', (pageCurrent == i ? ' active' : '')))
6324            }
6325
6326            $pagenum.find('> li.page-num').remove()
6327            $prev.after(pageNums.join(''))
6328
6329            if (pageCurrent == 1) {
6330                pageFirst()
6331                if (pageCurrent == that.pageCount) disableNext()
6332                if (!that.options.total) disableNext()
6333            } else if (pageCurrent == that.pageCount) {
6334                pageLast()
6335            } else {
6336                enablePrev()
6337                enableNext()
6338            }
6339
6340            $jumpto.find('input').val(pageCurrent)
6341            $pagetotal.find('> span').html(that.options.total +'/'+ that.pageCount)
6342        }).on('bjui.pagination.pageSize', function(e, pageSize) {
6343            setPageSize(pageSize)
6344        }).on('change', 'div.paging-pagesize > select', function() {
6345            var pageSize = $(this).val()
6346
6347            that.pageCount = tools.getPageCount(pageSize, options.total)
6348
6349            that.jumpPage(null, pageSize)
6350        })
6351
6352        $jumpto.find('input').on('keyup', function(e) {
6353            if (e.which === BJUI.keyCode.ENTER) {
6354                var page = $(this).val()
6355
6356                if (page) that.jumpPage(page)
6357            }
6358        })
6359
6360        $first.on('click', function() {
6361            if (that.options.pageCurrent > 1)
6362                that.jumpPage(1)
6363        })
6364
6365        $prev.on('click', function() {
6366            if (that.options.pageCurrent > 1)
6367                that.jumpPage(that.options.pageCurrent - 1)
6368        })
6369
6370        $next.on('click', function() {
6371            if (that.options.pageCurrent < that.pageCount)
6372                that.jumpPage(that.options.pageCurrent + 1)
6373        })
6374
6375        $last.on('click', function() {
6376            if (that.options.pageCurrent < that.pageCount)
6377                that.jumpPage(that.pageCount)
6378        })
6379    }
6380
6381    Pagination.prototype.destroy = function() {
6382        this.$element.removeData('bjui.pagination').empty()
6383    }
6384
6385    // PAGINATION PLUGIN DEFINITION
6386    // =======================
6387
6388    function Plugin(option) {
6389        var args     = arguments,
6390            property = option
6391
6392        return this.each(function () {
6393            var $this   = $(this),
6394                options = $.extend({}, Pagination.DEFAULTS, $this.data(), typeof option === 'object' && option),
6395                data    = $this.data('bjui.pagination')
6396
6397            if (!data) $this.data('bjui.pagination', (data = new Pagination(this, options)))
6398            if (typeof property === 'string' && $.isFunction(data[property])) {
6399                [].shift.apply(args)
6400                if (!args) data[property]()
6401                else data[property].apply(data, args)
6402            } else {
6403                data.init()
6404            }
6405        })
6406    }
6407
6408    var old = $.fn.pagination
6409
6410    $.fn.pagination             = Plugin
6411    $.fn.pagination.Constructor = Pagination
6412
6413    // PAGINATION NO CONFLICT
6414    // =================
6415
6416    $.fn.pagination.noConflict = function () {
6417        $.fn.pagination = old
6418        return this
6419    }
6420
6421    // PAGINATION DATA-API
6422    // ==============
6423
6424    $(document).on(BJUI.eventType.initUI, function(e) {
6425        $(e.target).find('[data-toggle="pagination"]').each(function() {
6426            var $this = $(this), data = $this.data(), options = data.options
6427
6428            if (options) {
6429                if (typeof options === 'string') options = options.toObj()
6430                if (typeof options === 'object') {
6431                    delete data.options
6432                    $.extend(data, options)
6433                }
6434            }
6435
6436            Plugin.call($this, data)
6437        })
6438    })
6439
6440}(jQuery);
6441/*!
6442 * B-JUI  V1.31 (http://b-jui.com)
6443 * Git@OSC (http://git.oschina.net/xknaan/B-JUI)
6444 * Copyright 2014 K'naan.
6445 * Licensed under Apache (http://www.apache.org/licenses/LICENSE-2.0)
6446 */
6447
6448/* ========================================================================
6449 * B-JUI: bjui-util.date.js  V1.31
6450 * @author K'naan
6451 * http://git.oschina.net/xknaan/B-JUI/blob/master/BJUI/js/bjui-util.date.js
6452 * ========================================================================
6453 * Copyright 2014 K'naan.
6454 * Licensed under Apache (http://www.apache.org/licenses/LICENSE-2.0)
6455 * ======================================================================== */
6456
6457+function ($) {
6458    'use strict';
6459
6460    var MONTH_NAMES = new Array('January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December', 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec')
6461
6462    var DAY_NAMES   = new Array('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat')
6463
6464    function LZ(x) {
6465        return (x < 0 || x > 9 ? '' :'0') + x
6466    }
6467
6468    /**
6469     * formatDate (date_object, format)
6470     * Returns a date in the output format specified.
6471     * The format string uses the same abbreviations as in parseDate()
6472     * @param {Object} date
6473     * @param {Object} format
6474     */
6475    function formatDate(date, format) {
6476        format       = format + ''
6477        var result   = ''
6478        var i_format = 0
6479        var c        = ''
6480        var token    = ''
6481        var y        = date.getFullYear() + ''
6482        var M        = date.getMonth() + 1
6483        var d        = date.getDate()
6484        var E        = date.getDay()
6485        var H        = date.getHours()
6486        var m        = date.getMinutes()
6487        var s        = date.getSeconds()
6488        var yyyy, yy, MMM, MM, dd, hh, h, mm, ss, ampm, HH, H, KK, K, kk, k
6489        // Convert real date parts into formatted versions
6490        var value = {}
6491
6492        if (y.length < 4) {
6493            y = '' + (y - 0 + 1900)
6494        }
6495        value['y']    = '' + y
6496        value['yyyy'] = y
6497        value['yy']   = y.substring(2, 4)
6498        value['M']    = M
6499        value['MM']   = LZ(M)
6500        value['MMM']  = MONTH_NAMES[M - 1]
6501        value['NNN']  = MONTH_NAMES[M + 11]
6502        value['d']    = d
6503        value['dd']   = LZ(d)
6504        value['E']    = DAY_NAMES[E + 7]
6505        value['EE']   = DAY_NAMES[E]
6506        value['H']    = H
6507        value['HH']   = LZ(H)
6508
6509        if (!H) {
6510            value['h'] = 12
6511        } else if (H > 12) {
6512            value['h'] = H - 12
6513        } else {
6514            value['h'] = H
6515        }
6516        value['hh'] = LZ(value['h'])
6517
6518        if (H > 11) {
6519            value['K'] = H - 12
6520        } else {
6521            value['K'] = H
6522        }
6523        value['k']  = H + 1
6524        value['KK'] = LZ(value['K'])
6525        value['kk'] = LZ(value['k'])
6526
6527        if (H > 11) {
6528            value['a'] = 'PM'
6529        } else {
6530            value['a'] = 'AM'
6531        }
6532        value['m']  = m
6533        value['mm'] = LZ(m)
6534        value['s']  = s
6535        value['ss'] = LZ(s)
6536
6537        while (i_format < format.length) {
6538            c     = format.charAt(i_format)
6539            token = ''
6540
6541            while (format.charAt(i_format) == c && i_format < format.length) {
6542                token += format.charAt(i_format++)
6543            }
6544            if (value[token] != null) {
6545                result += value[token]
6546            } else {
6547                result += token
6548            }
6549        }
6550        return result
6551    }
6552
6553    function _isInteger(val) {
6554        return new RegExp(/^\d+$/).test(val)
6555    }
6556
6557    function _getInt(str, i, minlength, maxlength) {
6558        for (var x = maxlength; x >= minlength; x--) {
6559            var token = str.substring(i, i + x)
6560
6561            if (token.length < minlength) {
6562                return null
6563            }
6564            if (_isInteger(token)) {
6565                return token
6566            }
6567        }
6568        return null
6569    }
6570
6571    /**
6572     * parseDate( date_string , format_string )
6573     *
6574     * This function takes a date string and a format string. It matches
6575     * If the date string matches the format string, it returns the date.
6576     * If it does not match, it returns 0.
6577     * @param {Object} val
6578     * @param {Object} format
6579     */
6580    function parseDate(val, format) {
6581        val          = val + ''
6582        format       = format + ''
6583
6584        var i_val    = 0
6585        var i_format = 0
6586        var c        = ''
6587        var token    = ''
6588        var token2   = ''
6589        var x, y
6590        var now      = new Date(1900, 0, 1)
6591        var year     = now.getYear()
6592        var month    = now.getMonth() + 1
6593        var date     = 1
6594        var hh       = now.getHours()
6595        var mm       = now.getMinutes()
6596        var ss       = now.getSeconds()
6597        var ampm     = ''
6598
6599        while (i_format < format.length) {
6600            // Get next token from format string
6601            c     = format.charAt(i_format)
6602            token = ''
6603            while (format.charAt(i_format) == c && i_format < format.length) {
6604                token += format.charAt(i_format++)
6605            }
6606            // Extract contents of value based on format token
6607            if (token == 'yyyy' || token == 'yy' || token == 'y') {
6608                if (token == 'yyyy') {
6609                    x = 4
6610                    y = 4
6611                }
6612                if (token == 'yy') {
6613                    x = 2
6614                    y = 2
6615                }
6616                if (token == 'y') {
6617                    x = 2
6618                    y = 4
6619                }
6620                year = _getInt(val, i_val, x, y)
6621                if (year == null) {
6622                    return 0
6623                }
6624                i_val += year.length
6625                if (year.length == 2) {
6626                    if (year > 70) {
6627                        year = 1900 + (year - 0)
6628                    } else {
6629                        year = 2e3 + (year - 0)
6630                    }
6631                }
6632            } else if (token == 'MMM' || token == 'NNN') {
6633                month = 0
6634                for (var i = 0; i < MONTH_NAMES.length; i++) {
6635                    var month_name = MONTH_NAMES[i]
6636
6637                    if (val.substring(i_val, i_val + month_name.length).toLowerCase() == month_name.toLowerCase()) {
6638                        if (token == 'MMM' || token == 'NNN' && i > 11) {
6639                            month = i + 1
6640                            if (month > 12) {
6641                                month -= 12
6642                            }
6643                            i_val += month_name.length
6644                            break
6645                        }
6646                    }
6647                }
6648                if (month < 1 || month > 12) {
6649                    return 0
6650                }
6651            } else if (token == 'EE' || token == 'E') {
6652                for (var i = 0; i < DAY_NAMES.length; i++) {
6653                    var day_name = DAY_NAMES[i]
6654
6655                    if (val.substring(i_val, i_val + day_name.length).toLowerCase() == day_name.toLowerCase()) {
6656                        i_val += day_name.length
6657                        break
6658                    }
6659                }
6660            } else if (token == 'MM' || token == 'M') {
6661                month = _getInt(val, i_val, token.length, 2)
6662                if (month == null || month < 1 || month > 12) {
6663                    return 0
6664                }
6665                i_val += month.length
6666            } else if (token == 'dd' || token == 'd') {
6667                date = _getInt(val, i_val, token.length, 2)
6668                if (date == null || date < 1 || date > 31) {
6669                    return 0
6670                }
6671                i_val += date.length
6672            } else if (token == 'hh' || token == 'h') {
6673                hh = _getInt(val, i_val, token.length, 2)
6674                if (hh == null || hh < 1 || hh > 12) {
6675                    return 0
6676                }
6677                i_val += hh.length
6678            } else if (token == 'HH' || token == 'H') {
6679                hh = _getInt(val, i_val, token.length, 2)
6680                if (hh == null || hh < 0 || hh > 23) {
6681                    return 0
6682                }
6683                i_val += hh.length
6684            } else if (token == 'KK' || token == 'K') {
6685                hh = _getInt(val, i_val, token.length, 2)
6686                if (hh == null || hh < 0 || hh > 11) {
6687                    return 0
6688                }
6689                i_val += hh.length
6690            } else if (token == 'kk' || token == 'k') {
6691                hh = _getInt(val, i_val, token.length, 2)
6692                if (hh == null || hh < 1 || hh > 24) {
6693                    return 0
6694                }
6695                i_val += hh.length
6696                hh--
6697            } else if (token == 'mm' || token == 'm') {
6698                mm = _getInt(val, i_val, token.length, 2)
6699                if (mm == null || mm < 0 || mm > 59) {
6700                    return 0
6701                }
6702                i_val += mm.length
6703            } else if (token == 'ss' || token == 's') {
6704                ss = _getInt(val, i_val, token.length, 2)
6705                if (ss == null || ss < 0 || ss > 59) {
6706                    return 0
6707                }
6708                i_val += ss.length
6709            } else if (token == 'a') {
6710                if (val.substring(i_val, i_val + 2).toLowerCase() == 'am') {
6711                    ampm = 'AM'
6712                } else if (val.substring(i_val, i_val + 2).toLowerCase() == 'pm') {
6713                    ampm = 'PM'
6714                } else {
6715                    return 0
6716                }
6717                i_val += 2
6718            } else {
6719                if (val.substring(i_val, i_val + token.length) != token) {
6720                    return 0
6721                } else {
6722                    i_val += token.length
6723                }
6724            }
6725        }
6726        // If there are any trailing characters left in the value, it doesn't match
6727        if (i_val != val.length) {
6728            return 0
6729        }
6730        // Is date valid for month?
6731        if (month == 2) {
6732            // Check for leap year
6733            if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
6734                // leap year
6735                if (date > 29) {
6736                    return 0
6737                }
6738            } else {
6739                if (date > 28) {
6740                    return 0
6741                }
6742            }
6743        }
6744        if (month == 4 || month == 6 || month == 9 || month == 11) {
6745            if (date > 30) {
6746                return 0
6747            }
6748        }
6749        // Correct hours value
6750        if (hh < 12 && ampm == 'PM') {
6751            hh = hh - 0 + 12
6752        } else if (hh > 11 && ampm == 'AM') {
6753            hh -= 12
6754        }
6755
6756        return new Date(year, month - 1, date, hh, mm, ss)
6757    }
6758
6759    Date.prototype.formatDate = function(dateFmt) {
6760        return formatDate(this, dateFmt)
6761    }
6762
6763    String.prototype.parseDate = function(dateFmt) {
6764        if (this.length < dateFmt.length) {
6765            dateFmt = dateFmt.slice(0, this.length)
6766        }
6767        return parseDate(this, dateFmt)
6768    }
6769
6770    /**
6771     * replaceTmEval('{1+2}-{2-1}')
6772     */
6773    function replaceTmEval(data) {
6774        return data.replace(RegExp('({[A-Za-z0-9_+-]*})', 'g'), function($1) {
6775            return eval('(' + $1.replace(/[{}]+/g, '') + ')')
6776        })
6777    }
6778
6779    /**
6780     * dateFmt:%y-%M-%d
6781     * %y-%M-{%d+1}
6782     * ex: new Date().formatDateTm('%y-%M-{%d-1}')
6783     *     new Date().formatDateTm('2012-1')
6784     */
6785    Date.prototype.formatDateTm = function(dateFmt) {
6786        var y = this.getFullYear()
6787        var m = this.getMonth() + 1
6788        var d = this.getDate()
6789        var sDate = dateFmt.replaceAll('%y', y).replaceAll('%M', m).replaceAll('%d', d)
6790
6791        sDate = replaceTmEval(sDate)
6792
6793        var _y = 1900, _m = 0, _d = 1
6794        var aDate = sDate.split('-')
6795
6796        if (aDate.length > 0) _y = aDate[0]
6797        if (aDate.length > 1) _m = aDate[1] - 1
6798        if (aDate.length > 2) _d = aDate[2]
6799
6800        return new Date(_y, _m, _d).formatDate('yyyy-MM-dd')
6801    }
6802
6803}(jQuery);
6804/*!
6805 * B-JUI  V1.31 (http://b-jui.com)
6806 * Git@OSC (http://git.oschina.net/xknaan/B-JUI)
6807 * Copyright 2014 K'naan.
6808 * Licensed under Apache (http://www.apache.org/licenses/LICENSE-2.0)
6809 */
6810
6811/* ========================================================================
6812 * B-JUI: bjui-datepicker.js  V1.31
6813 * reference: util.date.js
6814 * @author K'naan
6815 * http://git.oschina.net/xknaan/B-JUI/blob/master/BJUI/js/bjui-datepicker.js
6816 * ========================================================================
6817 * Copyright 2014 K'naan.
6818 * Licensed under Apache (http://www.apache.org/licenses/LICENSE-2.0)
6819 * ========================================================================
6820 * $yyym 年+月 显示配置 2020-11-13
6821 * $onlyy 年 显示配置 2020-11-13
6822 * */
6823
6824+function ($) {
6825    'use strict';
6826
6827    // DATEPICKER GLOBAL ELEMENTS
6828    // ======================
6829    //日期 新增今天按钮 todayBtn  2020-07-28
6830    var $box, $main, $prev, $next, $year, $month, $time, $timeinps, $spinner, $hh, $mm, $ss, $tm, $close, $days, $dayNames,$yyym,$onlyy,$todayBtn, $clearBtn, $okBtn
6831
6832    $(function() {
6833        var INIT_DATEPICKER = function() {
6834            var cp       = BJUI.regional.datepicker
6835            var calendar = FRAG.calendarFrag
6836                .replace('#close#', cp.close)
6837                .replace('#prev#', cp.prev)
6838                .replace('#next#', cp.next)
6839                .replace('#today#', cp.today) //日期 新增今天按钮 todayBtn  2020-07-28
6840                .replace('#clear#', cp.clear)
6841                .replace('#ok#', cp.ok)
6842
6843            $box      = $(calendar).hide()
6844            $('body').append('<!-- datepicker -->').append($box)
6845            $main     = $box.find('> .main')
6846            $prev     = $box.find('a.prev')
6847            $next     = $box.find('a.next')
6848            $year     = $box.find('select[name=year]')
6849            $month    = $box.find('select[name=month]')
6850            $time     = $box.find('.time')
6851            $timeinps = $time.find(':text')
6852            $spinner  = $time.find('ul > li')
6853            $hh       = $time.find('.hh')
6854            $mm       = $time.find('.mm')
6855            $ss       = $time.find('.ss')
6856            $tm       = $main.find('> .tm')
6857            $close    = $box.find('.close')
6858            $days     = $main.find('> .body > .days')
6859            $dayNames = $main.find('> .body > .dayNames')
6860            $todayBtn = $box.find('.todayBtn')//日期 新增今天按钮 todayBtn  2020-07-28
6861            $clearBtn = $box.find('.clearBtn')
6862            $okBtn    = $box.find('.okBtn')
6863            $yyym = $main.find('> .body > .yyym') //年+月 显示配置  2020-11-13
6864            $onlyy = $main.find('> .body >
6864 .onlyy')//年 显示配置  2020-11-13
6865            //regional
6866            var dayNames = '', dr = BJUI.regional.datepicker
6867
6868            $.each(dr.dayNames, function(i, v) {
6869                dayNames += '<dt>'+ v +'</dt>'
6870            })
6871            $dayNames.html(dayNames)
6872            $.each(dr.monthNames, function(i, v) {
6873                var m = i + 1
6874
6875                $month.append('<option value="'+ m +'">'+ v +'</option>')
6876            })
6877
6878            $box.on('selectstart', function() { return false })
6879        }
6880
6881        INIT_DATEPICKER()
6882    })
6883
6884    // DATEPICKER CLASS DEFINITION
6885    // ======================
6886    var Datepicker = function(element, options) {
6887        this.$element = $(element)
6888        this.options  = options
6889        this.tools    = this.TOOLS()
6890        this.$dateBtn = null
6891        // ie下屏蔽backspace键
6892        if (g_browser.versions.trident) {
6893            this.$element.keydown(function(event) {
6894                if (event.keyCode == 8) {
6895                    return false;
6896                }
6897            });
6898        }
6899
6900        // minDate、maxDate
6901        var now = new Date()
6902
6903        this.options.minDate = now.formatDateTm(this.options.minDate)
6904        this.options.maxDate = now.formatDateTm(this.options.maxDate)
6905
6906        //events
6907        this.events = {
6908            focus_time    : 'focus.bjui.datepicker.time',
6909            click_prev    : 'click.bjui.datepicker.prev',
6910            click_next    : 'click.bjui.datepicker.next',
6911            click_ok      : 'click.bjui.datepicker.ok',
6912            click_days    : 'click.bjui.datepicker.days',
6913            click_yyym    : 'click.bjui.datepicker.yyym',//年+月 新增 todayBtn  2020-11-13
6914            click_onlyy    : 'click.bjui.datepicker.onlyy',//月 新增 todayBtn  2020-11-13
6915            click_clear   : 'click.bjui.datepicker.clear',
6916            click_today   : 'click.bjui.datepicker.today',//日期 新增今天按钮 todayBtn  2020-07-28
6917            click_close   : 'click.bjui.datepicker.close',
6918            click_tm      : 'click.bjui.datepicker.tm',
6919            click_spinner : 'click.bjui.datepicker.spinner',
6920            mousedown_sp  : 'mousedown.bjui.datepicker.spinner',
6921            mouseup_sp    : 'mouseup.bjui.datepicker.spinner',
6922            change_ym     : 'change.bjui.datepicker.ym',
6923            click_time    : 'click.bjui.datepicker.time',
6924            keydown_time  : 'keydown.bjui.datepicker.time',
6925            keyup_time    : 'keyup.bjui.datepicker.time'
6926        }
6927    }
6928
6929    Datepicker.DEFAULTS = {
6930        pattern : 'yyyy-MM-dd',
6931        minDate : '1900-01-01',
6932        maxDate : '2099-12-31',
6933        mmStep  : 1,
6934        ssStep  : 1
6935    }
6936
6937    Datepicker.EVENTS = {
6938        afterChange : 'afterchange.bjui.datepicker'
6939    }
6940
6941    Datepicker.prototype.TOOLS = function() {
6942        var that  = this
6943        var tools = {
6944            changeTmMenu: function(sltClass) {
6945                $tm.removeClass('hh').removeClass('mm').removeClass('ss')
6946                if (sltClass) {
6947                    $tm.addClass(sltClass)
6948                    $timeinps.removeClass('slt').filter('.'+ sltClass).addClass('slt')
6949                }
6950            },
6951            clickTmMenu: function($input, type) {
6952                $tm
6953                    .find('> ul')
6954                    .hide()
6955                    .filter('.'+ type)
6956                    .show()
6957                    .find('> li')
6958                    .off(that.events.click_tm)
6959                    .on(that.events.click_tm, function() {
6960                        var $li = $(this)
6961                        var val = parseInt($li.text()) < 10 ? ('0'+ $li.text()) : $li.text()
6962
6963                        $input.val(val)
6964                    })
6965            },
6966            keydownInt: function(e) {
6967                if (!((e.keyCode >= 48 && e.keyCode <= 57) || (e.keyCode == BJUI.keyCode.DELETE || e.keyCode == BJUI.keyCode.BACKSPACE))) { return false }
6968            },
6969            changeTm: function($input, $btn) {
6970                var ivalue = parseInt($input.val()), istart = parseInt($input.data('start')) || 0, iend = parseInt($input.data('end'))
6971                var istep  = parseInt($input.data('step') || 1)
6972                var type   = $btn ? ($btn.data('add') ? $btn.data('add') : -1) : 0
6973                var newVal = ivalue
6974
6975                if (type == 1) {
6976                    if (ivalue <= iend - istep)
6977                        newVal = ivalue + istep
6978                } else if (type == -1) {
6979                    if (ivalue >= (istart + istep))
6980                        newVal = ivalue - istep
6981                } else if (ivalue > iend) {
6982                    newVal = iend
6983                } else if (ivalue < istart) {
6984                    newVal = istart
6985                }
6986                if (newVal < 10) newVal = '0'+ newVal
6987                $input.val(newVal)
6988            },
6989            closeCalendar: function(flag) {
6990                tools.changeTmMenu()
6991                if (flag) {
6992                    $(document).off(that.events.click_close)
6993                    $box.hide()
6994                }
6995            },
6996            get: function(name) {
6997                return that.options[name]
6998            },
6999            getDays: function (y, m) {
7000                return m == 2 ? (y % 4 || (!(y % 100) && y % 400) ? 28 : 29) : (/4|6|9|11/.test(m) ? 30 : 31)
7001            },
7002            minMaxDate: function(sDate) {
7003                var _count  = sDate.split('-').length - 1
7004                var _format = 'y-M-d'
7005
7006                if (_count == 1) _format = 'y-M'
7007                else if (!_count) _format = 'y'
7008
7009                return sDate.parseDate(_format)
7010            },
7011            getMinDate: function() {
7012                return this.minMaxDate(that.options.minDate)
7013            },
7014            getMaxDate: function() {
7015                var _sDate = that.options.maxDate
7016                var _count = _sDate.split('-').length - 1
7017                var _date  = this.minMaxDate(_sDate)
7018
7019                if (_count < 2) { //format:y-M、y
7020                    var _day = this.getDays(_date.getFullYear(), _date.getMonth() + 1)
7021                    _date.setDate(_day)
7022                    if (!_count)//format:y
7023                        _date.setMonth(11)
7024                }
7025
7026                return _date
7027            },
7028            getDateWrap: function(date) {
7029                if (!date) date = this.parseDate(that.sDate) || new Date()
7030
7031                var y = date.getFullYear(),
7032                    m = date.getMonth() + 1,
7033                    days = this.getDays(y, m)
7034
7035                return {
7036                    year: y, month: m, day: date.getDate(),
7037                    hour: date.getHours(), minute: date.getMinutes(), second: date.getSeconds(),
7038                    days: days, date: date
7039                }
7040            },
7041            changeDate: function(y, m, d) {
7042                var dw = this.getDateWrap(), d = d || 1, date
7043
7044                date = new Date(y, m - 1, d)
7045
7046                if (date.getMonth() + 1 != m) {
7047                    date = new Date(y, m, 1)
7048                    date.setMonth(m - 1)
7049                }
7050                that.sDate = this.formatDate(date)
7051
7052                return date
7053            },
7054            changeDateTime: function(y, M, d, H, m, s) {
7055                var date    = new Date(y, M - 1, d, H, m, s)
7056
7057                if (date.getMonth() + 1 != M) {
7058                    date = new Date(y, date.getMonth(), 0, H, m, s)
7059                    date.setMonth(M - 1)
7060                }
7061                that.sDate = this.formatDate(date)
7062                return date
7063            },
7064            changeDay: function(day, chMonth) {
7065                if (!chMonth) chMonth = 0
7066                var dw = this.getDateWrap()
7067
7068                return this.changeDate(dw.year, dw.month + parseInt(chMonth), day)
7069            },
7070            changeyyyms: function(Month) {//年+月 显示配置 2020-11-13
7071                var dw = this.getDateWrap()
7072                return this.changeDate(dw.year,parseInt(Month))
7073            },
7074            changeMonth: function(type) {
7075                var yearIndex = $year.get(0).selectedIndex,
7076                    maxYear   = $year.find('option').length,
7077                    month     = ($month.val() * 1) + type
7078
7079                if (!month) {
7080                    if (!yearIndex) {
7081                        month = 1
7082                    } else {
7083                        month = 12
7084                        yearIndex--
7085                        $year.get(0).selectedIndex = yearIndex
7086                    }
7087                } else if (month == 13) {
7088                    if (yearIndex == (maxYear - 1)) {
7089                        month = 12
7090                    } else {
7091                        month = 1
7092                        yearIndex++
7093                        $year.get(0).selectedIndex = yearIndex
7094                    }
7095                }
7096                $month.val(month).change()
7097            },
7098            parseDate: function(sDate) {
7099                if (!sDate) return null
7100                return sDate.parseDate(that.options.pattern)
7101            },
7102            formatDate: function(date) {
7103                return date.formatDate(that.options.pattern)
7104            },
7105            hasHour: function() {
7106                return that.options.pattern.indexOf('H') != -1
7107            },
7108            hasMinute: function() {
7109                return that.options.pattern.indexOf('m') != -1
7110            },
7111            hasSecond: function() {
7112                return that.options.pattern.indexOf('s') != -1
7113            },
7114            hasTime: function() {
7115                return this.hasHour() || this.hasMinute() || this.hasSecond()
7116            },
7117            hasDate: function() {
7118                var _dateKeys = ['y','M','d','E']
7119
7120                for (var i = 0; i < _dateKeys.length; i++) {
7121                    if (that.options.pattern.indexOf(_dateKeys[i]) != -1) return true
7122                }
7123                return false
7124            },
7125            afterChange: function(date) {
7126                var value = date ? this.formatDate(date) : ''
7127
7128                that.$element
7129                    .trigger(Datepicker.EVENTS.afterChange, {date:date, value:value})
7130                    .trigger('change')
7131                if(!commonBlank(date)){//date不为空,移除 2020-11-02
7132                    that.$element.blur();
7133                }
7134                that.$element.focus();
7135            }
7136        }
7137        return tools
7138    }
7139
7140    Datepicker.prototype.addBtn = function() {
7141        var that = this, $element = that.$element, fluid = $element.attr('size') ? '' : ' fluid'
7142
7143        if ($element.data('nobtn')) return
7144
7145        if (!this.$dateBtn && !this.options.addbtn && !$element.parent().hasClass('wrap_bjui_btn_box')) {
7146            this.$dateBtn = $(FRAG.dateBtn)
7147            this.$element.css({'paddingRight':'15px'}).wrap('<span class="wrap_bjui_btn_box'+ fluid +'"></span>')
7148
7149            var $box   = this.$element.parent()
7150            var height = this.$element.addClass('form-control').innerHeight()
7151
7152            $box.css({'position':'relative', 'display':'inline-block'})
7153
7154            this.$dateBtn.css({'height':height, 'lineHeight':height +'px'}).appendTo($box)
7155            this.$dateBtn.on('selectstart', function() { return false })
7156        }
7157    }
7158
7159    Datepicker.prototype.init = function() {
7160        if (!this.$element.is(':text')) return
7161        if (this.$element.val()) this.sDate = this.$element.val().trim()
7162
7163        var that      = this,
7164            options   = this.options,
7165            tools     = this.tools,
7166            dw        = tools.getDateWrap(),
7167            minDate   = tools.getMinDate(), maxDate = tools.getMaxDate(),
7168            yearstart = minDate.getFullYear(), yearend = maxDate.getFullYear()
7169
7170        if (!options.toggle || options.toggle !== 'datepicker' && !that.JSAPI)
7171            that.$element.data('JSAPI', true)
7172
7173        $year.empty()
7174        for (var y = yearstart; y <= yearend; y++) {
7175            $year.append('<option value="'+ y +'"'+ (dw.year == y ? ' selected' : '') +'>'+ y +'</option>')
7176        }
7177        $month.val(dw.month)
7178        $year.add($month).off(this.events.change_ym).on(this.events.change_ym, function() {
7179            if (tools.hasTime()) {
7180                var $day = $days.find('.slt'),
7181                    date = tools.changeDateTime($year.val(), $month.val(), $day.data('day'), dw.hour, dw.minute, dw.second)
7182
7183                that.create(tools.getDateWrap(date), minDate, maxDate)
7184            } else {
7185                var $day = $days.find('.slt'),
7186                    date = tools.changeDate($year.val(), $month.val(), $day.data('day'))
7187
7188                that.create(tools.getDateWrap(date), minDate, maxDate)
7189            }
7190        })
7191        $prev.off(this.events.click_prev).on(this.events.click_prev, function() {
7192            that.tools.changeMonth(-1)
7193        })
7194        $next.off(this.events.click_prev).on(this.events.click_prev, function() {
7195            that.tools.changeMonth(1)
7196        })
7197        $todayBtn.off(this.events.click_today).on(this.events.click_today, function() {//日期 新增今天按钮 todayBtn  2020-07-28
7198            var date=new Date();
7199            // var year = date.getFullYear();
7200            // var month = date.getMonth()+1;
7201            // var today = date.getDate();
7202
7203            tools.closeCalendar(true);
7204            that.$element.val(tools.formatDate(date)).focus()
7205            //changedEvent
7206            tools.afterChange(date)
7207        })
7208        $clearBtn.off(this.events.click_clear).on(this.events.click_clear, function() {
7209            that.$element.val('')
7210            tools.closeCalendar(true)
7211            tools.afterChange('')
7212        })
7213        $okBtn.off(this.events.click_ok).on(this.events.click_ok, function() {
7214            var $dd = $days.find('dd.slt')
7215
7216            if ($dd.hasClass('disabled')) return false
7217
7218            var date = tools.changeDay($dd.data('day'), $dd.data('month'))
7219
7220            if (tools.hasTime()) {
7221                date.setHours(parseInt($hh.val()))
7222                date.setMinutes(parseInt($mm.val()))
7223                date.setSeconds(parseInt($ss.val()))
7224            }
7225            tools.closeCalendar(true)
7226            that.$element.val(tools.formatDate(date)).focus()
7227
7228            //changedEvent
7229            tools.afterChange(date)
7230        })
7231        $close.off(this.events.click_close).on(this.events.click_close, function() {
7232            tools.closeCalendar(true)
7233        })
7234        $(document).off(this.events.click_close).on(this.events.click_close, function(e) {
7235            var $target = $(e.target)
7236
7237            if (e.target == that.$element.get(0)) return
7238            if ($target.closest('#calendar').length) return
7239            if ($target.data('toggle') == 'datepicker' || $target.parent().data('toggle') == 'datepickerbtn' || $target.data('toggle') == 'datepickerbtn' || $target.data('JSAPI'))
7240                tools.closeCalendar(false)
7241            else
7242                tools.closeCalendar(true)
7243        })
7244
7245        that.dw = dw
7246        that.minDate = minDate
7247        that.maxDate = maxDate
7248
7249        // if js API
7250        if (that.$element.data('JSAPI')) {
7251            // add btn
7252            if (!options.nobtn)
7253                that.addBtn()
7254            // event
7255            that.$element.off('click.bjui.datepicker.data-api').on('click.bjui.datepicker.data-api', $.proxy(function(e) {
7256                that.create()
7257            }, that))
7258
7259            if (!options.nobtn) {
7260                that.$element.parent('.wrap_bjui_btn_box').find('[data-toggle="datepickerbtn"]').off('click.bjui.datepicker.data-api').on('click.bjui.datepicker.data-api', $.proxy(function(e) {
7261                    that.create()
7262                }, that))
7263            }
7264        }
7265    }
7266
7267    Datepicker.prototype.create = function(dw, minDate, maxDate) {
7268        if (!dw) {
7269            this.init()
7270
7271            dw = this.dw
7272            minDate = this.minDate
7273            maxDate = this.maxDate
7274        }
7275
7276        var that       = this,
7277            options    = this.options,
7278            tools      = this.tools,
7279            monthStart = new Date(dw.year, dw.month - 1, 1),
7280            startDay   = monthStart.getDay(),
7281            dayStr     = '',
7282            //年+月 显示配置 begin 2020-11-13
7283            yyymStr    = '',
7284            onlyyStr   = '',
7285            yearstart = minDate.getFullYear(), yearend = maxDate.getFullYear(),
7286            monthstart = minDate.getMonth() + 1, monthend = maxDate.getMonth() + 1
7287        //年+月 显示配置 end 2020-11-13
7288        if (startDay > 0) {
7289            monthStart.setMonth(monthStart.getMonth() - 1)
7290            var prevDateWrap = tools.getDateWrap(monthStart)
7291
7292            for (var t = prevDateWrap.days - startDay + 1; t <= prevDateWrap.days; t++) {
7293                var _date     = new Date(dw.year, dw.month - 2, t),
7294                    _ctrClass = (_date >= minDate && _date <= maxDate) ? '' : ' disabled'
7295
7296                dayStr += '<dd class="other'+ _ctrClass +'" data-month="-1" data-day="'+ t +'">'+ t +'</dd>'
7297            }
7298        }
7299
7300        //年+月 显示配置 begin 2020-11-13
7301
7302        for (var tt = monthstart; tt <= monthend; tt++) {
7303            var _ctrClass = '';
7304            var mapobj={
7305                1:'一月',
7306                2:'二月',
7307                3:'三月',
7308                4:'四月',
7309                5:'五月',
7310                6:'六月',
7311                7:'七月',
7312                8:'八月',
7313                9:'九月',
7314                10:'十月',
7315                11:'十一月',
7316                12:'十二月',
7317            }
7318
7319            if (tt == dw.month){
7320                _ctrClass += 'slt'
7321            }
7322            yyymStr += '<dd class="'+ _ctrClass +'" data-month="'+ tt +'" style="width:25%">'+ mapobj[tt] +'</dd>'
7323        }
7324
7325        var $allyyym=$yyym.html(yyymStr).find('dd')
7326
7327        $allyyym.off(this.events.click_yyym).on(this.events.click_yyym, function() {
7328            var $yyymbox = $(this)
7329
7330            if (!tools.hasTime()) {
7331                var date = tools.changeyyyms($yyymbox.data('month'))
7332                tools.closeCalendar(true)
7333                that.$element.val(tools.formatDate(date)).focus()
7334
7335                //changedEvent
7336                tools.afterChange(date)
7337            } else {
7338                $allyyym.removeClass('slt')
7339                $yyymbox.addClass('slt')
7340
7341            }
7342        })
7343
7344        for (var ttt = yearstart; ttt <= yearend; ttt++) {
7345            var _ctrClass = ''
7346
7347            if (ttt == dw.year){
7348                _ctrClass += 'slt'
7349            }
7350            onlyyStr += '<dd style="width:25%;display:inline-block" class="'+ _ctrClass +'" data-year="'+ ttt +'">'+ ttt +'</dd>'
7351        }
7352        onlyyStr='<div style="height:120px;overflow:auto" id="onlyybody">'+onlyyStr+'</div>'
7353
7354        var $allonlyy=$onlyy.html(onlyyStr).find('dd')
7355
7356        $allonlyy.off(this.events.click_onlyy).on(this.events.click_onlyy, function() {
7357            var $onlyybox = $(this)
7358
7359            if (!tools.hasTime()) {
7360                tools.closeCalendar(true)
7361                that.$element.val($onlyybox.data('year')).focus()
7362
7363            } else {
7364                $allonlyy.removeClass('slt')
7365                $onlyybox.addClass('slt')
7366
7367
7368            }
7369        })
7370        //年+月 显示配置 end 2020-11-13
7371
7372        for (var t = 1; t <= dw.days; t++) {
7373            var _date     = new Date(dw.year, dw.month - 1, t),
7374                _ctrClass = (_date >= minDate && _date <= maxDate) ? '' : 'disabled'
7375
7376            if (t == dw.day)
7377                _ctrClass += ' slt'
7378            dayStr += '<dd class="'+ _ctrClass +'" data-day="'+ t +'">'+ t +'</dd>'
7379        }
7380        for (var t = 1; t <= 42 - startDay - dw.days; t++) {
7381            var _date     = new Date(dw.year, dw.month, t),
7382                _ctrClass = (_date >= minDate && _date <= maxDate) ? '' : ' disabled'
7383
7384            dayStr += '<dd class="other'+ _ctrClass +'" data-month="1" data-day="'+ t +'">'+ t +'</dd>'
7385        }
7386
7387        var $alldays = $days.html(dayStr).find('dd')
7388
7389        $alldays.not('.disabled').off(this.events.click_days).on(this.events.click_days, function() {
7390            var $day = $(this)
7391
7392            if (!tools.hasTime()) {
7393                var date = tools.changeDay($day.data('day'), $day.data('month'))
7394
7395                tools.closeCalendar(true)
7396                that.$element.val(tools.formatDate(date)).focus()
7397
7398                //changedEvent
7399                tools.afterChange(date)
7400            } else {
7401                $alldays.removeClass('slt')
7402                $day.addClass('slt')
7403            }
7404        })
7405
7406        //年+月 显示配置 begin 2020-11-13
7407        if(options.pattern=='yyyy-MM'){
7408            $dayNames.hide()
7409            $days.hide()
7410            $month.hide()
7411            $todayBtn.hide()
7412            $onlyy.hide()
7413
7414            $yyym.show()
7415            $year.show()
7416        }
7417        if(options.pattern=='yyyy-MM-dd' || options.pattern=='yyyy-MM-dd HH:mm:ss'){
7418            $yyym.hide()
7419            $onlyy.hide()
7420
7421            $dayNames.show()
7422            $days.show()
7423            $year.show()
7424            $month.show()
7425            $todayBtn.show()
7426        }else if(options.pattern=='HH:mm:ss'){
7427            $todayBtn.hide()
7428        }
7429        if(options.pattern=='yyyy'){
7430            $yyym.hide()
7431            $dayNames.hide()
7432            $days.hide()
7433            $year.hide()
7434            $month.hide()
7435            $todayBtn.hide()
7436
7437            $onlyy.show()
7438
7439
7440            var $ddd=$('.onlyy div dd')
7441            var selectIndex=$onlyy.find('.slt').index()
7442
7443            var curtr=parseInt(selectIndex/4)
7444            if(curtr>=3){
7445                var dis=curtr-3
7446                $('#onlyybody').animate({
7447                    scrollTop: dis*20
7448                },10)
7449
7450            }
7451
7452
7453            $prev.off(this.events.click_prev).on(this.events.click_prev, function() {
7454                if($('#onlyybody').scrollTop()==0){
7455                    return
7456                }
7457
7458                $('#onlyybody').animate({
7459                    scrollTop:$('#onlyybody').scrollTop()-120
7460                },200)
7461            })
7462            $next.off(this.events.click_prev).on(this.events.click_prev, function() {
7463
7464                var maxsctolltop= (Math.ceil($ddd.length/4)-6)*20
7465
7466                if($('#onlyybody').scrollTop()>=maxsctolltop){
7467                    return
7468                }
7469
7470                $('#onlyybody').animate({
7471                    scrollTop:$('#onlyybody').scrollTop()+120
7472                },200)
7473
7474            })
7475            $okBtn.off(this.events.click_ok).on(this.events.click_ok, function() {
7476                var yvalue=$onlyy.find('.slt').text()
7477
7478                tools.closeCalendar(true)
7479                that.$element.val(yvalue).focus()
7480            })
7481        }
7482        //年+月 显示配置 end 2020-11-13
7483
7484        if (!tools.hasDate()) {
7485            $main.addClass('nodate') // only time
7486        } else {
7487            $main.removeClass('nodate')
7488        }
7489        if (tools.hasTime()) {
7490            $time.show()
7491            $hh.val(dw.hour < 10 ? ('0'+ dw.hour) : dw.hour).off(this.events.focus_time).on(this.events.focus_time, function() {
7492                tools.changeTmMenu('hh')
7493            })
7494
7495            var iMinute = parseInt(dw.minute / options.mmStep) * options.mmStep
7496
7497            $mm.val(iMinute < 10 ? ('0'+ iMinute) : iMinute).data('step', options.mmStep).off(this.events.focus_time).on(this.events.focus_time, function() {
7498                tools.changeTmMenu('mm')
7499            })
7500            $ss.val(tools.hasSecond() ? (dw.second < 10 ? ('0'+ dw.second) : dw.second) : '00').data('step', options.ssStep).off(this.events.focus_time).on(this.events.focus_time, function() {
7501                tools.changeTmMenu('ss')
7502            })
7503            $box.off('click').on('click', function(e) {
7504                if ($(e.target).closest('.time').length) return
7505                $tm.find('> ul').hide()
7506                tools.changeTmMenu()
7507            })
7508            $timeinps.off(this.events.keydown_time).on(this.events.keydown_time, tools.keydownInt).each(function() {
7509                var $input = $(this)
7510
7511                $input.off(that.events.keyup_time).on(that.events.keyup_time, function() {
7512                    tools.changeTm($input)
7513                })
7514            }).off(this.events.click_time).on(this.events.click_time, function() {
7515                tools.clickTmMenu($(this), $(this).data('type'))
7516            })
7517
7518            var timer = null
7519
7520            $spinner.off(this.events.click_spinner).on(this.events.click_spinner, function(e) {
7521                var $btn = $(this)
7522
7523                $timeinps.filter('.slt').each(function() {
7524                    tools.changeTm($(this), $btn)
7525                })
7526
7527                e.preventDefault()
7528            }).off(this.events.mousedown_sp).on(this.events.mousedown_sp, function(e) {
7529                var $btn = $(this)
7530
7531                timer = setInterval(function() {
7532                    $timeinps.filter('.slt').each(function() {
7533                        tools.changeTm($(this), $btn)
7534                    })
7535                }, 150)
7536            }).off(this.events.mouseup_sp).on(this.events.mouseup_sp, function(e) {
7537                clearTimeout(timer)
7538            })
7539
7540            $hh.prop('disabled', !tools.hasHour())
7541            $mm.prop('disabled', !tools.hasMinute())
7542            $ss.prop('disabled', !tools.hasSecond())
7543        } else {
7544            $time.hide()
7545        }
7546        this.show()
7547    }
7548
7549    Datepicker.prototype.show = function() {
7550        var offset = this.$element.offset(),
7551            iTop   = offset.top + this.$element.get(0).offsetHeight,
7552            iLeft  = offset.left,
7553            iBoxH  = $box.outerHeight(true),// fix top
7554            iBoxW  = $box.outerWidth(true), // fix left
7555            css    = {}
7556
7557        if (iTop > iBoxH && iTop > $(window).height() - iBoxH)
7558            iTop = offset.top - iBoxH
7559
7560        css.left = iLeft
7561        css.top  = iTop
7562
7563        if (iLeft > $(window).width() - iBoxW) {
7564            $box.css('left', '')
7565
7566            delete css.left
7567            css.right = 10
7568        }
7569
7570        $box.css(css).show().click(function(e) {
7571            e.stopPropagation()
7572        })
7573    }
7574
7575    // DATEPICKER PLUGIN DEFINITION
7576    // =======================
7577
7578    function Plugin(option) {
7579        var args     = arguments
7580        var property = option
7581        return this.each(function () {
7582            var $this   = $(this)
7583            var options = $.extend({}, Datepicker.DEFAULTS, $this.data(), typeof option === 'object' && option)
7584            var data    = $this.data('bjui.datepicker')
7585            if (!data) $this.data('bjui.datepicker', (data = new Datepicker(this, options)))
7586            if (typeof property === 'string' && $.isFunction(data[property])) {
7587                [].shift.apply(args)
7588                if (!args) data[property]()
7589                else data[property].apply(data, args)
7590            } else {
7591                data.init()
7592            }
7593        })
7594    }
7595
7596    var old = $.fn.datepicker
7597
7598    $.fn.datepicker             = Plugin
7599    $.fn.datepicker.Constructor = Datepicker
7600
7601    // DATEPICKER NO CONFLICT
7602    // =================
7603
7604    $.fn.datepicker.noConflict = function () {
7605        $.fn.datepicker = old
7606        return this
7607    }
7608
7609    // DATEPICKER DATA-API
7610    // ==============
7611
7612    $(document).on(BJUI.eventType.initUI, function(e) {
7613        $(e.target).find('[data-toggle="datepicker"]').each(function() {
7614            var $this = $(this)
7615
7616            if (!$this.length) return
7617            if ($this.data('nobtn')) return
7618
7619            Plugin.call($this, 'addBtn')
7620        })
7621    })
7622
7623    $(document).on('click.bjui.datepicker.data-api', '[data-toggle="datepickerbtn"]', function(e) {
7624        var $date = $(this).prevAll('[data-toggle="datepicker"]')
7625
7626        if (!$date || !$date.is(':text')) return
7627        Plugin.call($date, 'create')
7628
7629        e.preventDefault()
7630    })
7631
7632    $(document).on('click.bjui.datepicker.data-api', '[data-toggle="datepicker"]', function(e) {
7633        var $this = $(this)
7634        if ($this.data('onlybtn')) return
7635        if (!$this.is(':text')) return
7636        Plugin.call($this, 'create')
7637
7638        e.preventDefault()
7639    })
7640
7641}(jQuery);
7642/*!
7643 * B-JUI  V1.31 (http://b-jui.com)
7644 * Git@OSC (http://git.oschina.net/xknaan/B-JUI)
7645 * Copyright 2014 K'naan.
7646 * Licensed under Apache (http://www.apache.org/licenses/LICENSE-2.0)
7647 */
7648
7649/* ========================================================================
7650 * B-JUI: bjui-ajaxtab.js  V1.31
7651 * @author K'naan
7652 * http://git.oschina.net/xknaan/B-JUI/blob/master/BJUI/js/bjui-ajaxtab.js
7653 * ========================================================================
7654 * Copyright 2014 K'naan.
7655 * Licensed under Apache (http://www.apache.org/licenses/LICENSE-2.0)
7656 * ======================================================================== */
7657
7658+function ($) {
7659    'use strict';
7660
7661    // AJAXTAB CLASS DEFINITION
7662    // ======================
7663
7664    var Ajaxtab = function(element, options) {
7665        this.$element = $(element)
7666        this.options  = options
7667    }
7668
7669    Ajaxtab.DEFAULTS = {
7670        url    : undefined,
7671        target : undefined,
7672        reload : false
7673    }
7674
7675    Ajaxtab.prototype.init = function() {
7676        var options = this.options
7677
7678        if (!(options.url)) {
7679            BJUI.debug('Ajaxtab Plugin: Error trying to open a tab, url is undefined!')
7680            return
7681        } else {
7682            options.url = decodeURI(options.url).replacePlh(this.$element.closest('.unitBox'))
7683
7684            if (!options.url.isFinishedTm()) {
7685                this.$element.alertmsg('error', (options.warn || BJUI.regional.plhmsg))
7686                BJUI.debug('Ajaxtab Plugin: The new ajaxtab\'s url is incorrect, url: '+ options.url)
7687                return
7688            }
7689
7690            options.url = encodeURI(options.url)
7691        }
7692        if (!options.target) {
7693            BJUI.debug('Ajaxtab Plugin: Attribute \'target\' is not defined!')
7694            return
7695        }
7696        if (options.reload) {
7697            this.load()
7698        } else {
7699            var reload = this.$element.data('bjui.ajaxtab.reload')
7700
7701            if (!reload) this.load()
7702            else this.$element.tab('show')
7703        }
7704    }
7705
7706    Ajaxtab.prototype.load = function() {
7707        var $element = this.$element
7708        var options  = this.options
7709
7710        $(options.target).ajaxUrl({
7711            url      : options.url,
7712            data     : {},
7713            callback : function() {
7714                $element.data('bjui.ajaxtab.reload', true).tab('show')
7715            }
7716        })
7717    }
7718
7719    // AJAXTAB PLUGIN DEFINITION
7720    // =======================
7721
7722    function Plugin(option) {
7723        var args     = arguments
7724        var property = option
7725
7726        return this.each(function () {
7727            var $this   = $(this)
7728            var options = $.extend({}, Ajaxtab.DEFAULTS, $this.data(), typeof option === 'object' && option)
7729            var data    = $this.data('bjui.ajaxtab')
7730
7731            if (!data) $this.data('bjui.ajaxtab', (data = new Ajaxtab(this, options)))
7732            if (typeof property === 'string' && $.isFunction(data[property])) {
7733                [].shift.apply(args)
7734                if (!args) data[property]()
7735                else data[property].apply(data, args)
7736            } else {
7737                data.init()
7738            }
7739        })
7740    }
7741
7742    var old = $.fn.ajaxtab
7743
7744    $.fn.ajaxtab             = Plugin
7745    $.fn.ajaxtab.Constructor = Ajaxtab
7746
7747    // AJAXTAB NO CONFLICT
7748    // =================
7749
7750    $.fn.ajaxtab.noConflict = function () {
7751        $.fn.ajaxtab = old
7752        return this
7753    }
7754
7755    // AJAXTAB DATA-API
7756    // ==============
7757
7758    $(document).on('click.bjui.ajaxtab.data-api', '[data-toggle="ajaxtab"]', function(e) {
7759        var $this   = $(this)
7760        var options = $this.data()
7761
7762        if (!options.url) options.url = $this.attr('href')
7763        Plugin.call($this, options)
7764
7765        e.preventDefault()
7766    })
7767
7768}(jQuery);
7769/*!
7770 * B-JUI  V1.31 (http://b-jui.com)
7771 * Git@OSC (http://git.oschina.net/xknaan/B-JUI)
7772 * Copyright 2014 K'naan.
7773 * Licensed under Apache (http://www.apache.org/licenses/LICENSE-2.0)
7774 */
7775
7776/* ========================================================================
7777 * B-JUI: bjui-datagrid.js  V1.31
7778 * @author K'naan
7779 * http://git.oschina.net/xknaan/B-JUI/blob/master/BJUI/js/bjui-datagrid.js
7780 * ========================================================================
7781 * Copyright 2014 K'naan.
7782 * Licensed under Apache (http://www.apache.org/licenses/LICENSE-2.0)
7783 * ======================================================================== */
7784
7785+function ($) {
7786    'use strict';
7787
7788    // DATAGRID CLASS DEFINITION
7789    // ======================
7790
7791    var Datagrid = function(element, options) {
7792        this.$element = $(element)
7793        this.options  = options
7794        this.tools    = this.TOOLS()
7795
7796        this.datanames = {
7797            tbody      : 'bjui.datagrid.tbody.dom',
7798            td_html    : 'bjui.datagrid.td.html',
7799            changeData : 'bjui.datagrid.tr.changeData'
7800        }
7801
7802        this.classnames = {
7803            s_checkbox    : 'datagrid-checkbox',
7804            s_linenumber  : 'datagrid-linenumber',
7805            s_edit        : 'datagrid-column-edit',
7806            s_lock        : 'datagrid-lock',
7807            s_menu        : 'datagrid-menu-box',
7808            s_filter      : 'datagrid-filter-box',
7809            s_showhide    : 'datagrid-showhide-box',
7810            th_cell       : 'datagrid-cell',
7811            th_menu       : 'datagrid-column-menu',
7812            btn_menu      : 'datagrid-column-menu-btn',
7813            th_col        : 'datagrid-col',
7814            th_field      : 'datagrid-col-field',
7815            th_sort       : 'datagrid-sortable',
7816            th_resize     : 'datagrid-resize-head',
7817            th_resizemark : 'datagrid-column-resizemark',
7818            tr_child      : 'datagrid-child-tr',
7819            tr_edit       : 'datagrid-edit-tr',
7820            tr_add        : 'datagrid-add-tr',
7821            tr_selected   : 'datagrid-selected-tr',
7822            td_edit       : 'datagrid-edit-td',
7823            td_changed    : 'datagrid-changed',
7824            td_child      : 'datagrid-child-td',
7825            td_linenumber : 'datagrid-linenumber-td',
7826            td_checkbox   : 'datagrid-checkbox-td',
7827            li_asc        : 'datagrid-li-asc',
7828            li_desc       : 'datagrid-li-desc',
7829            li_filter     : 'datagrid-li-filter',
7830            li_showhide   : 'datagrid-li-showhide',
7831            li_lock       : 'datagrid-li-lock',
7832            li_unlock     : 'datagrid-li-unlock'
7833        }
7834    }
7835
7836    Datagrid.DEFAULTS = {
7837        gridTitle       : '',
7838        columns         : null,     // Thead column module
7839        data            : null,     // Data source
7840        dataUrl         : null,     // Request data source URL, for processing (filtering / sorting / paging) results
7841        updateRowUrl    : null,     // Update row data URL, return JSON data
7842        postData        : null,     // Send other data to server
7843        loadType        : 'POST',   // Ajax load request type
7844        dataType        : 'json',   // Data type of data source
7845        local           : 'remote', // Optional 'local' | 'remote'
7846        fieldSortable   : true,     // Click the field to sort
7847        filterThead     : true,     // Filter in the thead
7848        sortAll         : true,     // Sort scope, false = this page, true = all
7849        filterAll       : true,     // Filter scope, false = this page, true = all
7850        filterMult      : true,     // Filter multiple fileds, false = single, true = multiple
7851        initFilter      : {},       //
7852        selectMult      : false,    // When clicked tr, multiple selected (Default need to press Ctrl or Shift or used checkbox)
7853        linenumberAll   : false,    // All data together numbers
7854        showLinenumber  : true,     // Display linenumber column, Optional 'true' | 'false' | 'lock', (Optional 'true, false' is a boolean)
7855        showCheckboxcol : false,    // Display checkbox column, Optional 'true' | 'false' | 'lock', (Optional 'true, false' is a boolean)
7856        showChildcol    : undefined,// Display child button column, Optional 'true' | 'false' | 'lock', (Optional 'true, false' is a boolean). If not set false and 'hasChild == true', showChildcol = true
7857        showEditbtnscol : false,    // Display edit buttons column, Optional 'true' | 'false' | 'edit', (Optional 'true, false' is a boolean, Optional 'edit' is custom column label)
7858        customEditbtns  : {         // Custom edit column buttons
7859            position    : 'after',  // Button inserted position, Optional 'after' | 'before' | 'replace'
7860            buttons     : null,     // Custom buttons, Set string or function
7861            width       : 0         // The edit column width, 0 = 'auto'
7862        },
7863        showTfoot       : false,    // Display the tfoot, Optional 'true' | 'false' | 'lock', (Optional 'true, false' is a boolean)
7864        showToolbar     : false,    // Display datagrid toolbar
7865        showNoDataTip   : true,     // Display 'no data' tips, Optional 'true' | 'false' | 'string', (Optional 'true, false' is a boolean, Optional 'string' is custom tips)
7866        toolbarItem     : '',       // Displayed on the toolbar elements, Optional 'all, add, edit, cancel, save, del, import, export, exportf |'
7867        toolbarCustom   : '',       // Html code || function || jQuery dom object, custom elements, displayed on the toolbar
7868        columnResize    : true,     // Allow adjust the column width
7869        columnMenu      : true,     // Display the menu button on the column
7870        columnShowhide  : true,     // On the menu display (show / hide columns)
7871        columnFilter    : false,    // On the menu display (filter form)
7872        columnLock      : true,     // On the menu display (lock / unlock columns)
7873        paging          : true,     // Display pagination component
7874        pagingAlign     : 'center', // The pagination component alignment
7875        keys            : {
7876            gridChild   : 'gridChild',
7877            gridNumber  : 'gridNumber',
7878            gridCheckbox: 'gridCheckbox',
7879            gridEdit    : 'gridEdit',
7880            gridIndex   : 'gridIndex',
7881            dropFlag    : 'dropFlag',
7882            treePTr     : 'datagrid.tree.parentTr',
7883            treePData   : 'datagrid.tree.parentData',
7884            childlen    : 'childlen',
7885            isExpand    : 'isExpand',
7886            isParent    : 'isparent'
7887        },
7888        hasChild        : false,    // It contains child data, Optional (true | false)
7889        childOptions    : {         // Child grid options
7890            width       : '100%',
7891            height      : 'auto',
7892            paging      : false,
7893            columnMenu  : false,
7894            filterThead : false,
7895            childUpdate : false     // This options only for childOptions, when the child grid data changes, update the parent row(!! The parent grid neeed option 'updateRowUrl' !!), Optional (Boolean: true | false, true = 'all') OR (String: 'all, add, edit, del')
7896        },
7897        isTree          : false,
7898        treeOptions     : {
7899            keys        : {
7900                key       : 'id',
7901                parentKey : 'pid',
7902                childKey  : 'children',
7903                childLen  : 'childlen',
7904                isParent  : 'isparent',
7905                level     : 'level',
7906                order     : 'order',
7907                isExpand  : 'isExpand'
7908            },
7909            simpleData  : true,
7910            expandAll   : false,
7911            add         : true
7912        },
7913        dropOptions     : {
7914            drop        : false,
7915            dropUrl     : null,
7916            paging      : true,     // send paging data
7917            scope       : 'drop',   // send data scope, Optional 'drop' | 'all'
7918            beforeDrag  : null,     // Function - before drag, return true can drag
7919            beforeDrop  : null,     // Function - before drop, return false cancel drop
7920            afterDrop   : 'POST'    // Post(Ajax) the current page data to server, request type = editType. Optional ('PO
7920ST' | function), If set a function, doesn't post
7921        },
7922        tdTemplate      : '',
7923        editUrl         : null,     // An action URL, for processing (update / save), return results (json)
7924        editCallback    : null,     // Callback for save
7925        editMode        : 'inline', // Editing mode, Optional 'false' | 'inline' | 'dialog', (Optional 'false' is a boolean)
7926        editDialogOp    : null,     // For dialog edit, the dialog init options
7927        editType        : 'POST',   // Ajax request method of edit, Optional 'POST' | 'GET' | 'raw', (Optional 'raw' is post raw data)
7928        inlineEditMult  : true,     // Can inline edit multiple rows
7929        saveAll         : true,     // For inline edit, true = save current row, false = save all editing rows
7930        addLocation     : 'first',  // Add rows to datagrid location, Optional 'first' | 'last' | 'prev' | 'next'
7931        delUrl          : null,     // The delete URL, return delete tr results (json)
7932        delType         : 'POST',   // Delete URL of ajax request method
7933        delPK           : null,     // Ajax delete request to send only the primary key
7934        delConfirm      : true,     // Delete confirmation message, Optional 'true' | 'false' | 'message', (Optional 'true, false' is a boolean)
7935        delCallback     : null,     // Callback for delete
7936        jsonPrefix      : '',       // JSON object key prefix, for post data
7937        contextMenuH    : true,     // Right-click on the thead, display the context menu
7938        contextMenuB    : false,    // Right-click on the tbody tr, display the context menu
7939        templateWidth   : 600,      //
7940        flowLayoutWidth : 0,        //
7941        dialogFilterW   : 360,      //
7942        hScrollbar      : false,    // Allowed horizontal scroll bar
7943        fullGrid        : false,    // If the table width below gridbox width, stretching table width
7944        importOption    : null,     // Import btn options
7945        exportOption    : null,     // Export btn options
7946        beforeEdit      : null,     // Function - before edit method, return true execute edit method
7947        beforeDelete    : null,     // Function - before delete method, return true execute delete method
7948        beforeSave      : null,     // Function - before save method, arguments($trs, datas)
7949        afterSave       : null,     // Function - after save method, arguments($trs, datas)
7950        afterDelete     : null,      // Function - after delete method
7951        cellsTitle      : true,       //单元格增加title 提示 ,true 为显示title,false为不显示 2019-10-9
7952        cellsHeight:false,//表格行高,true:固定行高30px,超出隐藏,false或不设置,行高根据内容多少自行换行显示 2020-06-10
7953        contextMenuSys: null,//配置右键方法  2020-12-01
7954        contextMenuList: [],//配置下拉菜单配置  2020-12-01
7955        dblClickSys: null//配置双击方法 2020-12-28
7956    }
7957
7958    Datagrid.renderItem = function(value, data, items, itemattr) {
7959        if (!items || !items.length) return ''
7960        var label = ''
7961
7962        $.each(items, function(i, n) {
7963            if (itemattr && itemattr.value) {
7964                if (n[itemattr.value] == value) {
7965                    label = n[itemattr.label]
7966                    return false
7967                }
7968            } else {
7969                if (typeof n[value] !== 'undefined') {
7970                    label = n[value]
7971                    return false
7972                }
7973            }
7974        })
7975
7976        return label
7977    }
7978
7979    Datagrid.renderItemMulti = function(value, data, items, itemattr) {
7980        if (!items || !items.length) return ''
7981        var label = [], val = $.type(value) === 'array' ? value : String(value).split(',')
7982
7983        $.each(items, function(i, n) {
7984            $.each(val, function(k, v) {
7985                if (itemattr && itemattr.value) {
7986                    if (n[itemattr.value] == v) {
7987                        label.push(n[itemattr.label])
7988                        return false
7989                    }
7990                } else {
7991                    if (typeof n[v] !== 'undefined') {
7992                        label.push(n[v])
7993                        return false
7994                    }
7995                }
7996            })
7997        })
7998
7999        return label.join(',')
8000    }
8001
8002    Datagrid.prototype.TOOLS = function() {
8003        var that  = this, options = that.options
8004        var tools = {
8005            getPageCount: function(pageSize, total) {
8006                return Math.ceil(total / pageSize)
8007            },
8008            getPageInterval: function(count, pageCurrent, showPageNum) {
8009                var half  = Math.ceil(showPageNum / 2), limit = count - showPageNum,
8010                    start = pageCurrent > half ? Math.max(Math.min(pageCurrent - half, limit), 0) : 0,
8011                    end   = pageCurrent > half ? Math.min((pageCurrent + half), count) : Math.min(showPageNum, count)
8012
8013                if (end - start == showPageNum) end = end + 1
8014                if (end < showPageNum) end = end + 1
8015                if (start + 1 == end) end = end + 1
8016
8017                return {start:start + 1, end:end}
8018            },
8019            getRight: function($obj) {
8020                var width = 0, index = $obj.data('index'), model = that.columnModel
8021
8022                for (var i = index; i >= 0; i--) {
8023                    width += model[i].th.outerWidth()
8024                }
8025
8026                return width
8027            },
8028            getRight4Lock: function(index) {
8029                var width = 0, $td = that.$lockTbody.find('> tr:first > td:eq('+ index +')'), $firstTds = $td && $td.prevAll().add($td)
8030
8031                if (!$firstTds || !$firstTds.length) $firstTds = that.$lockColgroupH.filter(':lt('+ (index + 1) +')')
8032                $firstTds.each(function() {
8033                    var $td = $(this), w = $td.is(':hidden') ? 0 : $td.outerWidth()
8034
8035                    width += w
8036                })
8037
8038                return width
8039            },
8040            beforeEdit: function($trs, datas) {
8041                var beforeEdit = options.beforeEdit
8042
8043                if (beforeEdit) {
8044                    if (typeof beforeEdit === 'string') beforeEdit = beforeEdit.toFunc()
8045                    if (typeof beforeEdit === 'function') {
8046                        return beforeEdit.call(that, $trs, datas)
8047                    }
8048                }
8049
8050                return true
8051            },
8052            beforeSave: function($trs, data) {
8053                var beforeSave = options.beforeSave
8054
8055                if (beforeSave) {
8056                    if (typeof beforeSave === 'string') beforeSave = beforeSave.toFunc()
8057                    if (typeof beforeSave === 'function') {
8058                        return beforeSave.call(that, $trs, data)
8059                    }
8060                }
8061
8062                return true
8063            },
8064            afterSave: function($trs, data) {
8065                var afterSave = options.afterSave, childUpdate = that.options.childUpdate, $parent = that.$element.data('bjui.datagrid.parent'),
8066                    updateParent = function($tr) {
8067                        $tr.closest('table').datagrid('updateRow', $tr)
8068                    }
8069
8070                if (afterSave) {
8071                    if (typeof afterSave === 'string') afterSave = afterSave.toFunc()
8072                    if (typeof afterSave === 'function') {
8073                        afterSave.call(that, $trs, data)
8074                    }
8075                }
8076
8077                // remove add data
8078                $trs.each(function() {
8079                    $(this).removeData('datagrid.addData')
8080                })
8081
8082                // update child parent
8083                if ($parent && childUpdate) {
8084                    if (typeof childUpdate === 'string' && childUpdate.indexOf('all') === -1) {
8085                        if (data.addFlag && childUpdate.indexOf('add') !== -1)
8086                            updateParent($parent)
8087                        else if (childUpdate.indexOf('edit') !== -1)
8088                            updateParent($parent)
8089                    } else {
8090                        updateParent($parent)
8091                    }
8092                }
8093
8094                if (that.needfixedWidth) {
8095                    that.fixedWidth()
8096                    that.needfixedWidth = false
8097                }
8098
8099                // fixedH
8100                if (options.height === 'auto') {
8101                    var scrollTop = that.$boxB.scrollTop()
8102
8103                    that.$boxB.scrollTop(5)
8104                    if (that.$boxB.scrollTop()) {
8105                        that.fixedHeight()
8106                        that.$boxB.scrollTop(scrollTop)
8107                    }
8108                }
8109
8110                that.$element.data('allData', that.allData)
8111            },
8112            afterDelete: function() {
8113                var afterDelete = options.afterDelete
8114
8115                if (afterDelete) {
8116                    if (typeof afterDelete === 'string') afterDelete = afterDelete.toFunc()
8117                    if (typeof afterDelete === 'function') {
8118                        afterDelete.call(that)
8119                    }
8120                }
8121
8122                that.$element.data('allData', that.allData)
8123            },
8124            // Correct colspan
8125            setColspan: function(column, colspanNum) {
8126                if (column.colspan) column.colspan = column.colspan + colspanNum - 1
8127                column.index = column.index + colspanNum - 1
8128                if (column.parent) this.setColspan(column.parent, colspanNum)
8129            },
8130            // set columns options
8131            setOp: function(op) {
8132                if (!op.name) {
8133                    op.menu = op.lock = op.edit = op.add = op.quickSort = op.quickfilter = false
8134                } else {
8135                    op.menu        = (typeof op.menu        === 'undefined') ? true  : op.menu
8136                    op.lock        = (typeof op.lock        === 'undefined') ? true  : op.lock
8137                    op.edit        = (typeof op.edit        === 'undefined') ? true  : op.edit
8138                    op.add         = (typeof op.add         === 'undefined') ? true  : op.add
8139                    op.quicksort   = (typeof op.quicksort   === 'undefined') ? true  : op.quicksort
8140                    op.quickfilter = (typeof op.quickfilter === 'undefined') ? true  : op.quickfilter
8141                    op.finalWidth  = (typeof op.finalWidth  === 'undefined') ? false : op.finalWidth
8142                }
8143                op.hide = (typeof op.hide === 'undefined') ? false : op.hide
8144
8145                return op
8146            },
8147            json2Array4Tree: function (options, datas, level, pid) {
8148                if (!datas) return []
8149                if (!level) level = 0
8150
8151                var k = options.key, pk = options.parentKey, childKey = options.childKey, childLen = options.childLen, levelKey = options.level, isParent = options.isParent, r = [], data
8152
8153                if (datas) {
8154                    datas.sort(function(a, b) {
8155                        return a[options.order] - b[options.order]
8156                    })
8157                }
8158
8159                if ($.isArray(datas)) {
8160                    for (var i = 0, l = datas.length; i < l; i++) {
8161                        data = $.extend({}, datas[i])
8162
8163                        data[levelKey] = level
8164                        r.push(data)
8165
8166                        if (data[childKey]) {
8167                            delete data[childKey]
8168                            data[isParent] = true
8169                            data[childLen] = datas[i][childKey].length
8170                            pid = data[k]
8171
8172                            r = r.concat(this.json2Array4Tree(options, datas[i][childKey], data[levelKey] + 1, pid))
8173
8174                            pid = null
8175                        }
8176                    }
8177                } else {
8178                    data = $.extend({}, datas)
8179
8180                    data[levelKey] = level
8181                    r.push(data)
8182
8183                    if (data[childKey]) {
8184                        delete data[childKey]
8185                        data[isParent] = true
8186                        data[childLen] = datas[childKey].length
8187                        pid = data[k]
8188
8189                        r = r.concat(this.json2Array4Tree(options, datas[childKey], data[levelKey] + 1))
8190
8191                        pid = null
8192                    }
8193                }
8194
8195                return r
8196            },
8197            array2Json4Tree: function(options, datas) {
8198                var r = [], temp = [], keys = options.keys, key = keys.key, parentKey = keys.parentKey, childKey = keys.childKey
8199
8200                if (!$.isArray(datas)) return [datas]
8201
8202                for (var i = 0, l = datas.length; i < l; i++) {
8203                    temp[datas[i][key]] = datas[i]
8204                }
8205                for (var i = 0, l = datas.length; i < l; i++) {
8206                    if (datas[i][parentKey] && datas[i][key] !== datas[i][parentKey]) {
8207                        if (!temp[datas[i][parentKey]])
8208                            temp[datas[i][parentKey]] = []
8209                        if (!temp[datas[i][parentKey]][childKey])
8210                            temp[datas[i][parentKey]][childKey] = []
8211
8212                        temp[datas[i][parentKey]][childKey].push(datas[i])
8213                    } else {
8214                        r.push(datas[i])
8215                    }
8216                }
8217
8218                return r
8219            },
8220            // create trs by data source
8221            createTrsByData: function(data, refreshFlag) {
8222                var list
8223
8224                if (!that.$tbody) that.$tbody = $('<tbody></tbody>')
8225                if (data) {
8226                    if (data.list) list = data.list
8227                    else list = data
8228
8229                    that.paging.total = list.length || 0
8230
8231                    // for tree
8232                    if (that.options.isTree) {
8233                        if (that.options.treeOptions.simpleData) {
8234                            list = this.array2Json4Tree(that.options.treeOptions, list)
8235                            list = this.json2Array4Tree(that.options.treeOptions.keys, list)
8236                        } else {
8237                            list = this.json2Array4Tree(that.options.treeOptions.keys, list)
8238                        }
8239                    }
8240
8241                    if (list && !$.isArray(list))
8242                        list = [list]
8243
8244                    that.paging.total = (list && list.length) || 0
8245
8246                    if (!that.paging.total)
8247                        list = []
8248
8249                    if (typeof data === 'object' && that.paging.total) {
8250                        if (data[BJUI.pageInfo.total]) that.paging.total = parseInt(data[BJUI.pageInfo.total], 10)
8251                        if (data[BJUI.pageInfo.pageSize]) {
8252                            if (refreshFlag && that.paging.pageSize != data[BJUI.pageInfo.pageSize]) {
8253                                that.$boxP && that.$boxP.trigger('bjui.datagrid.paging.pageSize', data[BJUI.pageInfo.pageSize])
8254                            }
8255                            that.paging.pageSize = parseInt(data[BJUI.pageInfo.pageSize], 10)
8256                        }
8257                    }
8258
8259                    that.paging.pageCount = tools.getPageCount(that.paging.pageSize, that.paging.total)
8260
8261                    if (that.paging.pageCurrent > that.paging.pageCount) that.paging.pageCurrent = that.paging.pageCount
8262                    if (!that.paging.pageCurrent) that.paging.pageCurrent = 1
8263
8264                    this.initTbody(list, refreshFlag)
8265                }
8266
8267                if (!that.init_tbody) that.$tbody.appendTo(that.$tableB)
8268                if (!that.init_thead) that.initThead()
8269            },
8270            // initTbody
8271            initTbody: function(data, refreshFlag) {
8272                var tools  = this, allData = that.allData, type = options.dataType || 'json', model = that.columnModel, hiddenFields = that.hiddenFields, regional = that.regional, newData = [], attach = that.attach, json
8273                var paging = that.paging, start = 0, end = paging.pageSize, keys = that.options.keys
8274                var doInit = function() {
8275                    type = type.toLowerCase()
8276                    if (data) allData = that.allData = data
8277
8278                    that.$element.data('allData', that.allData)
8279                    that.$element.data('options', options)
8280
8281                    if (!allData.length) {
8282                        end = 0
8283                    } else {
8284                        if (options.local === 'local') {
8285                            start = (paging.pageSize * (paging.pageCurrent - 1))
8286                            end   = start + paging.pageSize
8287                            if (paging.total != allData.length) paging.total = allData.length
8288                            if (start > allData.length) start = paging.pageSize * (paging.pageCount - 1)
8289                        } else {
8290                            if (allData.length > paging.pageSize) end = paging.pageSize
8291                        }
8292                    }
8293                    if (end > allData.length) end = allData.length
8294
8295                    // array to json
8296                    if (type === 'array' && data && data.length && $.type(data[0]) === 'array') {
8297                        var a1 = start, a2 = end, arrData = [], _index
8298
8299                        if (options.local === 'local') {
8300                            a1 = 0
8301                            a2 = allData.length
8302                        }
8303                        for (var i = a1; i < a2; i++) {
8304                            json   = {}
8305                            _index = 0
8306                            $.each(allData[i], function(k, v) {
8307                                var obj, val = v
8308
8309                                if (model[_index] && model[_index][keys.gridChild])    _index ++
8310                                if (model[_index] && model[_index][keys.gridNumber])   _index ++
8311                                if (model[_index] && model[_index][keys.gridCheckbox]) _index ++
8312                                if (typeof val === 'string') val = '"'+ val +'"'
8313
8314                                if (model[_index] && !model[_index][keys.gridEdit]) {
8315                                    obj = '{"'+ model[_index].name +'":'+ val +'}'
8316                                    $.extend(json, JSON.parse(obj))
8317                                } else { // init hidden fields
8318                                    if (model[_index] && model[_index][keys.gridEdit]) _index ++
8319                                    if (_index >= model.length && hiddenFields) {
8320                                        if (hiddenFields[k - model.length]) {
8321                                            obj = '{"'+ hiddenFields[k - model.length] +'":'+ val +'}'
8322                                            $.extend(json, JSON.parse(obj))
8323                                        }
8324                                    }
8325                                }
8326                                _index ++
8327                            })
8328
8329                            arrData.push(json)
8330                        }
8331
8332                        allData = that.allData = arrData
8333                    }
8334
8335                    // create cuttent page data
8336                    for (var i = start; i < end; i++) {
8337                        json = $.extend({}, that.allData[i], attach)
8338
8339                        /* for quickSort */
8340                        if (options.local === 'local' && !refreshFlag) {
8341                            json['bjui_local_index'] = i
8342                            that.allData[i]['bjui_local_index'] = i
8343                        }
8344
8345                        newData.push(json)
8346                    }
8347
8348                    tools.createTrs(newData, refreshFlag)
8349
8350                    that.data = newData
8351
8352                    that.$element.trigger('afterLoad.bjui.datagrid', {datas:newData})
8353                }
8354
8355                if (refreshFlag && that.$boxM) {
8356                    that.$boxM.show().trigger('bjui.ajaxStop').trigger('bjui.ajaxStart', [50, doInit])
8357                } else {
8358                    doInit()
8359                }
8360            },
8361            /*表格宽度自适应当前宽配置 - 2020-11-25*/
8362            sumWidth: function(w){
8363                var sum = 0;
8364                $.each(that.columnModel,function(index,item){
8365                    if (!item.width || item.width === 'auto'){
8366                        item.width = 50;
8367                    }
8368                    sum += item.width;
8369                })
8370                if (sum > w) {
8371                    $.each(that.columnModel, function (index, item) {
8372                        item.width = item.width / 2;
8373                    })
8374                    return this.sumWidth();
8375                } else {
8376                    return;
8377                }
8378            },
8379            // create tbody - tr
8380            createTrs: function(datas, refreshFlag) {
8381                var tools = this, keys = that.options.keys, model = that.columnModel, paging = that.paging, trs = [], editFrag = BJUI.doRegional(FRAG.gridEditBtn, that.regional), childFrag = BJUI.doRegional(FRAG.gridExpandBtn, that.regional), lockedCols = [], isRenderOnly = false,
8382                    customEditbtns = that.options.customEditbtns, editFrag2 = customEditbtns.buttons
8383
8384                // custom edit column buttons
8385                if (editFrag2) {
8386                    if (typeof editFrag2 === 'function')
8387                        editFrag2 = editFrag2.apply()
8388
8389                    if (editFrag2) {
8390                        if (customEditbtns.position === 'before')
8391                            editFrag = editFrag2 + editFrag
8392                        else if (customEditbtns.position === 'replace')
8393                            editFrag = editFrag2
8394                        else
8395                            editFrag += editFrag2
8396                    }
8397                }
8398
8399                if (refreshFlag) {
8400                    // remebered lock columns
8401                    $.each(model, function(i, n) {
8402                        if (n.locked) {
8403                            that.colLock(n.th, false)
8404                            n.lock_refresh = true
8405                        }
8406                    })
8407
8408                    if (that.$tbody.find('> tr.datagrid-nodata').length) {
8409                        that.needfixedWidth = true
8410                    }
8411
8412                    that.$tbody.empty()
8413                    that.$lockTableH && that.$lockTableH.empty()
8414                    that.$lockTableB && that.$lockTableB.empty()
8415                }
8416
8417                if (!datas.length && !refreshFlag) {
8418                    var emptyObj = {}
8419
8420                    emptyObj[model[0].name] = '0'
8421                    isRenderOnly = true
8422                    datas = []
8423                    datas.push(emptyObj)
8424                }
8425
8426                for (var i = 0, l = datas.length; i < l; i++) {
8427                    var trData = datas[i], modellength = model.length, tempcolspan = modellength, linenumber = options.linenumberAll ? ((paging.pageCurrent - 1) * paging.pageSize + (i + 1)) : (i + 1),
8428                        tds = [], n, tdHtml = BJUI.StrBuilder(), $td, name, label, _label, render_label, align, cls, display, tree, hasTree = false, treeattr = '', tdTemplate = options.tdTemplate
8429
8430                    trData[keys.gridNumber] = linenumber
8431                    trData[keys.gridIndex]  = i
8432
8433                    if (that.options.hasChild && that.options.childOptions)
8434                        tempcolspan = tempcolspan - 1
8435                    if (that.options.showLinenumber)
8436                        tempcolspan = tempcolspan - 1
8437                    if (that.options.showCheckboxcol)
8438                        tempcolspan = tempcolspan - 1
8439
8440                    var tempData = $.extend({}, trData)
8441                    var tableWidth;
8442                    for (var j = 0; j < modellength; j++) {
8443                        n       = model[j]
8444                        name    = n.name || 'datagrid-noname'
8445                        label   = trData[name]
8446                        align   = ''
8447                        cls     = []
8448                        _label  = ''
8449                        display = ''
8450                        tree    = ''
8451                        render_label = undefined
8452
8453                        if (typeof label === 'undefined' || label === 'null' || label === null) label = ''
8454                        _label = label
8455
8456                        if (n.align) align = ' align="'+ n.align +'"'
8457                        if (n[keys.gridChild]) label = childFrag
8458                        if (n[keys.gridCheckbox]) label = '<div><input type="checkbox" data-toggle="icheck" name="datagrid.checkbox" value="true"></div>'
8459                        if (n[keys.gridEdit]) {
8460                            label = editFrag
8461                            cls.push(that.classnames.s_edit)
8462                        }
8463                        /*表格宽度自适应当前宽配置 - 2020-11-25*/
8464                        if (options.hScrollbar) {
8465                            if (!n.width || n.width === 'auto'){
8466                                cls.push('nowrap')
8467                            }
8468                            tableWidth = $(n.th[0]).parents('table').parent('div').width();/*表格宽度自适应当前宽配置 - 2020-11-25*/
8469                        } else {
8470                            var thW = $(n.th[0]).width();/*表格宽度自适应当前宽配置 - 2020-11-25*/
8471                            if(thW==-4){
8472                                n.width = 50;
8473                            }
8474                        }
8475
8476                        /* for tfoot */
8477                        /*if (n.calc) {
8478                            if (!n.calc_count) n.calc_count = datas.length
8479
8480                            var number = label ? (String(label).isNumber() ? Number(label) : 0) : 0
8481
8482                            if (n.calc === 'sum' || n.calc === 'avg') n.calc_sum = (n.calc_sum || 0) + number
8483                            else if (n.calc === 'max') n.calc_max = n.calc_max ? (n.calc_max < number ? number : n.calc_max) : number
8484                            else if (n.calc === 'min') n.calc_min = n.calc_min ? (n.calc_min > number ? number : n.calc_min) : number
8485                        }*/
8486
8487                        if (n[keys.gridChild])    cls.push(that.classnames.td_child)
8488                        if (n[keys.gridNumber])   cls.push(that.classnames.td_linenumber)
8489                        if (n[keys.gridCheckbox]) cls.push(that.classnames.td_checkbox)
8490
8491                        if (cls.length) cls = cls.join(' ')
8492                        else cls = ''
8493
8494                        if (refreshFlag && n.hidden) display = ' style="display:none;"'
8495
8496                        /* render */
8497                        if (n.items && !n.render) {
8498                            if (n.attrs && n.attrs['multiple'])
8499                                n.render = $.datagrid.renderItemMulti
8500                            else
8501                                n.render = $.datagrid.renderItem
8502                        }
8503                        if (n.render && typeof n.render === 'string') n.render = n.render.toFunc()
8504                        if (n.render && typeof n.render === 'function') {
8505                            if (n.items) {
8506                                if (typeof n.items === 'string') {
8507                                    if (n.items.trim().startsWith('[')) n.items = n.items.toObj()
8508                                    else n.items = n.items.toFunc()
8509                                }
8510
8511                                if (!that.renderTds) that.renderTds = []
8512
8513                                var delayRender = function(index, label, trData, n) {
8514                                    $.when(n.items.call(that)).done(function(item) {
8515                                        n.items = item
8516
8517                                        that.delayRender --
8518                                    })
8519                                }
8520
8521                                if (typeof n.items === 'function') {
8522                                    if (!i) {
8523                                        if (!that.delayRender) that.delayRender = 0
8524                                        that.delayRender ++
8525                                        delayRender((i * j), _label, trData, n)
8526                                    }
8527                                    n.delayRender = true
8528                                    that.renderTds.push({trindex:i, tdindex:j, label:_label, data:trData, render:n.render})
8529                                } else {
8530                                    delete n.delayRender
8531                                    render_label = n.render.call(that, _label, trData, n.items, n.itemattr)
8532                                }
8533                            } else {
8534                                render_label = n.render.call(that, _label, trData)
8535                            }
8536                        }
8537
8538                        if (options.isTree && !hasTree && (!(n === that.childColumn || n === that.linenumberColumn || n === that.checkboxColumn || n === that.editBtnsColumn) || that.treeColumn)) {
8539                            if (typeof options.isTree === 'string') {
8540                                if (n.name && n.name === options.isTree)
8541                                    hasTree = true
8542                            } else {
8543                                hasTree = true
8544                            }
8545
8546                            if (hasTree) {
8547                                !that.treeColumn && (that.treeColumn = n)
8548                                n.hasTree = true
8549                                !trData[options.treeOptions.keys.level] && (trData[options.treeOptions.keys.level] = 0)
8550                                tree  = that.tools.createTreePlaceholder(trData, (render_label || label))
8551                                align = ' align="left"'
8552
8553                                if (cls) {
8554                                    cls += ' datagrid-tree-td'
8555                                } else {
8556                                    cls = 'datagrid-tree-td'
8557                                }
8558
8559                                treeattr = ' data-child="'+ (trData[options.treeOptions.keys.childLen] || 0) +'" data-level="'+ trData[options.treeOptions.keys.level] +'" class="datagrid-tree-tr datagrid-tree-level-'+ trData[options.treeOptions.keys.level] +'"'
8560                            }
8561                        }
8562
8563                        cls && (cls = ' class="'+ cls +'"')
8564
8565                        if (that.isTemplate) {
8566                            if (!n.delayRender) {
8567                                tempData[n.name] = (typeof render_label === 'undefined' ? label : render_label)
8568                            } else {
8569                                delete tempData[n.name]
8570                            }
8571                            if (!tds[0] && j == (modellength - 1)) {
8572                                if (tdTemplate && typeof tdTemplate === 'function')
8573                                    tdTemplate = tdTemplate.apply(that, [trData])
8574
8575                                tdTemplate = that.tools.replacePlh4Template(tdTemplate, tempData, true)
8576
8577                                if (that.options.hasChild && that.options.childOptions) {
8578                                    display = that.childColumn.hidden ? ' style="display:none;"' : ''
8579                                    tds[0]  = ['<td data-title="..." align="center" class="datagrid-child-td"'+ display +'><div>'+ childFrag +'</div></td>']
8580                                }
8581                                if (that.options.showLinenumber) {
8582                                    display = that.linenumberColumn.hidden ? ' style="display:none;"' : ''
8583
8584                                    var linenumbertd = ['<td data-title="No." align="center" class="datagrid-linenumber-td"'+ display +'>'+ linenumber +'</td>']
8585
8586                                    tds[tds.length] = linenumbertd
8587                                }
8588                                if (that.options.showCheckboxcol) {
8589                                    display = that.checkboxColumn.hidden ? ' style="display:none;"' : ''
8590
8591                                    var checkboxtd = ['<td data-title="Checkbox" align="center" class="datagrid-checkbox-td"'+ display +'><div><input type="checkbox" data-toggle="icheck" name="datagrid.checkbox" value="true"></div></td>']
8592
8593                                    tds[tds.length] = checkboxtd
8594                                }
8595
8596                                var temptd = ['<td class="datagrid-template-td" colspan="'+ tempcolspan +'">'+ tdTemplate +'</td>']
8597
8598                                tds[tds.length] = temptd
8599
8600                                treeattr = ' class="datagrid-template-tr"'
8601                            }
8602                        } else {
8603                            tdHtml
8604                                .add('<td data-title="'+ n.label +'"')
8605                                .add(align)
8606                                .add(cls)
8607                                .add(display)
8608                                .add('>')
8609
8610                            if (tree) {
8611                                tdHtml.add(tree)
8612                            } else {
8613
8614                                tdHtml
8615                                    .add('<div>')
8616                                    .add(typeof render_label === 'undefined' ? label : render_label)
8617                                    .add('</div>')
8618                            }
8619
8620                            tdHtml.add('</td>')
8621                            tds.push(tdHtml.toString())
8622                        }
8623                    }
8624                    /*表格宽度自适应当前宽配置 - 2020-11-25*/
8625                    if (options.hScrollbar) {
8626                        this.sumWidth(tableWidth);
8627                    }
8628
8629                    trs.push('<tr'+ treeattr +'>'+ tds.join('') +'</tr>')
8630
8631                    if (isRenderOnly) {
8632                        trs = []
8633                        trs.push(tools.createNoDataTr(true) || '')
8634                    } else {
8635                        trs.push(tools.createChildTr(null, trData))
8636                    }
8637                }
8638
8639                that.$tbody.html(trs.join(''))
8640
8641                if (refreshFlag) {
8642                    that.initEvents()
8643                    if (options.editMode) that.edit()
8644
8645                    if (!datas.length)
8646                        tools.createNoDataTr()
8647
8648                    that.$boxP && that.$boxP.trigger('bjui.datagrid.paging.jump')
8649
8650                    // locked
8651                    $.each(model, function(i, n) {
8652                        if (n.lock_refresh) {
8653                            that.colLock(n.th, true)
8654                            delete n.lock_refresh
8655                        }
8656                    })
8657
8658                    setTimeout(function() {
8659                        that.$tableB.initui()
8660                        that.$lockTableB && that.$lockTableB.initui()
8661
8662                        that.fixedHeight()
8663
8664                        if (that.needfixedWidth) {
8665                            that.fixedWidth()
8666                            that.needfixedWidth = null
8667                        }
8668
8669                        that.$boxM && that.$boxM.trigger('bjui.ajaxStop').hide()
8670
8671                        // for initFilter
8672                        if (that.doInitFilter) {
8673                            that.tools.initFilter()
8674                            that.doInitFilter = undefined
8675                        }
8676                    }, datas.length + 1)
8677                }
8678            },
8679            coverTemplate: function() {
8680                var tools = this, options = that.options, datas = that.data, model = that.columnModel, trs
8681
8682                if (that.isTemplate) {
8683                    trs = that.$grid.data('bjui.datagrid.trs.template')
8684
8685                    if (!trs)
8686                        tools.createTrs(datas, true)
8687                    else {
8688                        that.$tbody.html(trs)
8689
8690                        that.initEvents()
8691                        if (options.editMode) that.edit()
8692
8693                        if (!datas.length)
8694                            tools.createNoDataTr()
8695
8696                        that.$boxP && that.$boxP.trigger('bjui.datagrid.paging.jump')
8697
8698                        // locked
8699                        $.each(model, function(i, n) {
8700                            if (n.lock_refresh) {
8701                                that.colLock(n.th, true)
8702                                delete n.lock_refresh
8703                            }
8704                        })
8705
8706                        setTimeout(function() {
8707                            that.$tableB.initui()
8708                            that.$lockTableB && that.$lockTableB.initui()
8709
8710                            that.fixedHeight()
8711
8712                            that.$boxM && that.$boxM.trigger('bjui.ajaxStop').hide()
8713
8714                            // for initFilter
8715                            if (that.doInitFilter) {
8716                                that.tools.initFilter()
8717                                that.doInitFilter = undefined
8718                            }
8719                        }, datas.length + 1)
8720                    }
8721                } else {
8722                    trs = that.$grid.data('bjui.datagrid.trs.normal')
8723
8724                    if (!trs)
8725                        this.createTrs(datas, true)
8726                    else {
8727                        that.$tbody.html(trs)
8728
8729                        that.initEvents()
8730                        if (options.editMode) that.edit()
8731
8732                        if (!datas.length)
8733                            tools.createNoDataTr()
8734
8735                        that.$boxP && that.$boxP.trigger('bjui.datagrid.paging.jump')
8736
8737                        // locked
8738                        $.each(model, function(i, n) {
8739                            if (n.lock_refresh) {
8740                                that.colLock(n.th, true)
8741                                delete n.lock_refresh
8742                            }
8743                        })
8744
8745                        setTimeout(function() {
8746                            that.$tableB.initui()
8747                            that.$lockTableB && that.$lockTableB.initui()
8748
8749                            that.fixedHeight()
8750
8751                            that.$boxM && that.$boxM.trigger('bjui.ajaxStop').hide()
8752
8753                            // for initFilter
8754                            if (that.doInitFilter) {
8755                                that.tools.initFilter()
8756                                that.doInitFilter = undefined
8757                            }
8758                        }, datas.length + 1)
8759                    }
8760                }
8761
8762                setTimeout(function() {
8763                    that.initFixedW = false
8764                    that.hasAutoCol = true
8765                    that.fixedWidth(true)
8766                }, 300)
8767            },
8768            replacePlh: function(url, data) {
8769                return url.replace(/{\/?[^}]*}/g, function($1) {
8770                    var key = $1.replace(/[{}]+/g, ''), val = data[key]
8771
8772                    if (typeof val === 'undefined' || val === 'null' || val === null)
8773                        val = ''
8774
8775                    return val
8776                })
8777            },
8778            replacePlh4Template: function(html, data, replaceAll) {
8779                return html.replace(/{#\/?[^}]*}/g, function($1) {
8780     
8780               var key = $1.replace(/[{#}]+/g, ''), val = data[key]
8781
8782                    if (replaceAll && typeof val === 'undefined')
8783                        return $1
8784
8785                    if (typeof val === 'undefined' || val === 'null' || val === null)
8786                        val = ''
8787
8788                    return val
8789                })
8790            },
8791            createNoDataTr: function(str) {
8792                if (that.options.showNoDataTip) {
8793                    if (str) {
8794                        return '<tr class="datagrid-nodata"><td colspan="'+ that.columnModel.length +'">'+ (typeof that.options.showNoDataTip === 'string' ? that.options.showNoDataTip : BJUI.getRegional('datagrid.noData')) +'</td></tr>'
8795                    } else if (!that.$tbody.find('> tr').length) {
8796                        $('<tr class="datagrid-nodata"></tr>').html('<td colspan="'+ that.columnModel.length +'">'+ (typeof that.options.showNoDataTip === 'string' ? that.options.showNoDataTip : BJUI.getRegional('datagrid.noData')) +'</td>').appendTo(that.$tbody)
8797                    }
8798                }
8799            },
8800            createTreePlaceholder: function(data, label, isExpand) {
8801                var keys = that.options.treeOptions.keys, str = BJUI.StrBuilder()
8802                var addIndent = function(level) {
8803                    var indent = []
8804
8805                    while (level--) {
8806                        indent.push('<span class="datagrid-tree-indent"></span>')
8807                    }
8808
8809                    return indent.join('')
8810                }
8811
8812                str.add('<div class="datagrid-tree-box">')
8813
8814                if (data[keys.level])
8815                    str.add(addIndent(data[keys.level]))
8816
8817                str.add('<span class="datagrid-tree-switch'+ (typeof isExpand !== 'undefined' && !isExpand ? ' collapsed' : '') +'">')
8818
8819                if (data[keys.isParent]) {
8820                    if (typeof isExpand === 'undefined') {
8821                        if (typeof data[keys.isExpand] === 'undefined')
8822                            data[keys.isExpand] = true
8823
8824                        if (!data[keys.isExpand]) {
8825                            if (!that.collapseIndex) that.collapseIndex = []
8826                            that.collapseIndex.push(data.gridIndex)
8827                        }
8828
8829                        str.add('<i class="fa fa-minus-square-o"></i>')
8830                    } else {
8831                        str.add('<i class="fa fa-'+ (isExpand ? 'minu
8831s' : 'plus') +'-square-o"></i>')
8832                    }
8833                }
8834
8835                str
8836                    .add('</span>')
8837                    .add('<span class="datagrid-tree-'+ (data[keys.isParent] ? 'branch' : 'leaf') +'"><i class="fa fa-'+ (data[keys.isParent] ? 'folder' : 'file') +'-o"></i></span>')
8838                    .add('<span class="datagrid-tree-title">')
8839                    .add(label)
8840                    .add('</span>')
8841                    .add('</div>')
8842
8843                return str.toString()
8844            },
8845            createChildTr: function($tr, trData) {
8846                if ($tr && $tr.next() && $tr.next().hasClass(that.classnames.tr_child))
8847                    return
8848
8849                if (options.hasChild && options.childOptions && options.childOptions.dataUrl) {
8850                    that.childOptions = $.extend(true, {}, Datagrid.DEFAULTS, options.childOptions)
8851
8852                    var child = '<tr class="'+ that.classnames.tr_child +'"><td colspan="'+ that.columnModel.length +'" style="width:100%; padding:10px;"><table class="table-child"></table></td></tr>'
8853
8854                    if ($tr && $tr.length)
8855                        $tr.after(child)
8856                    else
8857                        return child
8858                }
8859
8860                return ''
8861            },
8862            // Parameters can be (jQuery Object || number)
8863            getNoChildTrIndex: function(row) {
8864                var index
8865
8866                if (isNaN(row)) {
8867                    if (!row || !row.length) return -1
8868                    index = row.index()
8869                } else {
8870                    index = parseInt(row, 10)
8871                }
8872                if (that.options.hasChild && that.options.childOptions)
8873                    index = index * 2
8874
8875                return index
8876            },
8877            // Parameters can be (jQuery Object || number)
8878            getNoChildDataIndex: function(row) {
8879                var data_index
8880
8881                if (isNaN(row))
8882                    data_index = this.getNoChildTrIndex(row)
8883                else
8884                    data_index = parseInt(row, 10)
8885
8886                if (data_index === -1) return data_index
8887                if (that.options.hasChild && that.options.childOptions)
8888                    data_index = data_index / 2
8889
8890                return data_index
8891            },
8892            // ajax load data by url
8893            loadData: function(data, refreshFlag) {
8894                var tools = this, url = options.dataUrl, dataType = options.dataType || 'json', model = that.columnModel
8895
8896                that.$boxM && that.$boxM.show().trigger('bjui.ajaxStart')
8897
8898                dataType = dataType.toLowerCase()
8899                if (dataType === 'array') dataType = 'text'
8900
8901                if (options.postData) {
8902                    if (typeof options.postData === 'string') {
8903                        if (options.postData.trim().startsWith('{')) options.postData = options.postData.toObj()
8904                        else options.postData = options.postData.toFunc()
8905                    }
8906                    if (typeof options.postData === 'function') {
8907                        options.postData = options.postData.apply()
8908                    }
8909                    if (typeof options.postData === 'object') {
8910                        if (!data) data = options.postData
8911                        else data = $.extend({}, options.postData, data)
8912                    }
8913                }
8914
8915                data = data || {}
8916                if (!data.pageSize && options.paging) {
8917                    data.pageSize = that.paging.pageSize
8918                    data.pageCurrent = that.paging.pageCurrent
8919                }
8920
8921                if (!options.paging) {
8922                    delete data.pageSize
8923                    delete data.pageCurrent
8924                }
8925
8926                BJUI.ajax('doajax', {
8927                    url       : url,
8928                    data      : data,
8929                    type      : options.loadType,
8930                    cache     : options.cache || false,
8931                    dataType  : dataType,
8932                    okCallback: function(response) {
8933                        if (dataType === 'json' || dataType === 'jsonp') {
8934                            tools.createTrsByData(response, refreshFlag)
8935                        } else if (dataType === 'text') {
8936                            if ($.type(response) !== 'array')
8937                                response = []
8938
8939                            tools.createTrsByData(response, refreshFlag)
8940                        } else if (dataType === 'xml') {
8941                            var xmlData = [], obj
8942
8943                            $(response).find('row').each(function() {
8944                                obj = {}
8945
8946                                $(this).find('cell').each(function(i) {
8947                                    var $cell = $(this), label = $cell.text(), name = $cell.attr('name')
8948
8949                                    obj[name] = label
8950                                })
8951
8952                                xmlData.push(obj)
8953                            })
8954
8955                            if (xmlData.length) tools.createTrsByData(xmlData, refreshFlag)
8956                        } else {
8957                            BJUI.debug('BJUI.Datagrid: The options \'dataType\' is incorrect!')
8958                        }
8959                    },
8960                    errCallback: function(json) {
8961                        if (json && json[BJUI.keys.statusCode]) {
8962                            BJUI.alertmsg('error', json[BJUI.keys.message] || BJUI.getRegional('datagrid.errorData'))
8963                        } else {
8964                            BJUI.alertmsg('warn', BJUI.getRegional('datagrid.errorData'))
8965                        }
8966
8967                        tools.createTrsByData([], refreshFlag)
8968                    },
8969                    failCallback: function(msg) {
8970                        BJUI.alertmsg('warn', BJUI.getRegional('datagrid.failData'))
8971
8972                        tools.createTrsByData([], refreshFlag)
8973                    }
8974                })
8975            },
8976            // append columns
8977            appendColumns: function() {
8978                that.childColumn      = {name:that.options.keys.gridChild, gridChild:true, width:30, minWidth:30, label:'...', align:'center', menu:false, edit:false, quicksort:false}
8979                that.linenumberColumn = {name:that.options.keys.gridNumber, gridNumber:true, width:'auto', minWidth:80, label:'No.', align:'center', menu:false, edit:false, quicksort:false}
8980                that.checkboxColumn   = {name:that.options.keys.gridCheckbox, gridCheckbox:true, width:30, minWidth:30, label:'Checkbox', align:'center', menu:false, edit:false, quicksort:false}
8981                that.editBtnsColumn   = {name:that.options.keys.gridEdit, gridEdit:true, width:that.options.customEditbtns.width, minWidth:110, label:(typeof options.showEditbtnscol === 'string' ? options.showEditbtnscol : 'Edit'), align:'center', menu:false, edit:false, hide:false, quicksort:false}
8982            },
8983            // setBoxb - height
8984            setBoxbH: function(height) {
8985                var boxH = height || that.boxH || options.height, topM = 0, h, $boxB, bH
8986
8987                if (boxH < 100) return
8988                if (isNaN(boxH)) {
8989                    if (boxH === 'auto') {
8990                        $boxB = that.$boxB.clone().height('').prependTo('body').find('> colgroup').remove().end()
8991                        bH = $boxB.outerHeight()
8992                        $boxB.remove()
8993
8994                        boxH = (that.$boxT ? that.$boxT.outerHeight() : 0)
8995                            + (that.$boxH ? that.$boxH.outerHeight() : 0)
8996                            + (that.$toolbar ? that.$toolbar.outerHeight() : 0)
8997                            + (that.$boxP ? that.$boxP.outerHeight() : 0)
8998                            + bH
8999                            + (that.$boxF ? that.$boxF.outerHeight() : 0)
9000
9001                        if (options.maxHeight && Number(options.maxHeight) < boxH) {
9002                            boxH = Number(options.maxHeight)
9003                        }
9004
9005                        that.$grid.height(boxH)
9006                        that.boxH = boxH
9007                    } else {
9008                        boxH = that.$grid.height()
9009                    }
9010                }
9011
9012                if (that.$boxT) {
9013                    h     = that.$boxT.outerHeight()
9014                    boxH -= h
9015                    topM += h
9016                }
9017                if (that.$toolbar) {
9018                    h     = that.$toolbar.outerHeight()
9019                    boxH -= h
9020                    topM += h
9021                }
9022                if (that.$boxP)
9023                    boxH -= that.$boxP.outerHeight()
9024                if (that.$boxF)
9025                    boxH -= that.$boxF.outerHeight()
9026
9027                topM += that.$tableH.outerHeight()
9028                boxH -= that.$boxH.outerHeight()
9029
9030                if (boxH < 0) boxH = 0
9031
9032                that.$boxB.height(boxH)
9033                that.$boxM.height(boxH).css({top:topM})
9034                that.$lockB && that.$lockB.height(boxH)
9035
9036                if (that.$element.data('bjui.datagrid.parent'))
9037                    that.$element.data('bjui.datagrid.parent').closest('table').datagrid('fixedHeight')
9038            },
9039            // column menu - toggle show submenu
9040            showSubMenu: function($li, $menu, $submenu) {
9041                var left, width = $menu.outerWidth(), submenu_width = $submenu.data('width') || $submenu.outerWidth(), wh = that.$grid.height(), mt, submenu_height = $submenu.data('height'), animate_op, boxWidth = that.$boxH.width()
9042                var hidesubmenu = function($li, $menu, $submenu) {
9043                    left       = $menu.offset().left - that.$grid.offset().left - 1
9044                    animate_op = {left:'50%'}
9045
9046                    $li.removeClass('active')
9047
9048                    if ($menu.hasClass('position-right') || (boxWidth - left < width + submenu_width)) {
9049                        $submenu.css({left:'auto', right:'100%'})
9050                        animate_op = {right:'50%'}
9051                    } else {
9052                        $submenu.css({left:'100%', right:'auto'})
9053                    }
9054                    animate_op.opacity = 0.2
9055
9056                    $submenu.stop().animate(animate_op, 'fast', function() {
9057                        $(this).hide()
9058                    })
9059                }
9060
9061                $li.hover(function() {
9062                    $submenu.appendTo($li)
9063                    if ($li.hasClass(that.classnames.li_filter) && $submenu.is(':visible')) {
9064                        return false
9065                    } else {
9066                        var $filterli = $li.siblings('.'+ that.classnames.li_filter)
9067
9068                        if ($filterli.length && $filterli.hasClass('active')) {
9069                            hidesubmenu($filterli, $menu, $filterli.find('> .'+ that.classnames.s_filter))
9070                        }
9071                    }
9072
9073                    if ($li.hasClass(that.classnames.li_showhide)) {
9074                        mt = $li.position().top + $menu.position().top
9075
9076                        if ((wh - mt) < submenu_height) {
9077                            if (submenu_height > wh) {
9078                                submenu_height = wh
9079                                $submenu.css('height', wh)
9080                            }
9081                            $submenu.css({top:(- (submenu_height - (wh - mt)))})
9082                        }
9083                    }
9084
9085                    left       = $menu.offset().left - that.$grid.offset().left - 1
9086                    animate_op = {left:'100%'}
9087
9088                    if ($menu.hasClass('position-right') || (boxWidth - left < width + submenu_width)) {
9089                        $submenu.css({left:'auto', right:'50%'})
9090                        animate_op = {right:'100%'}
9091                    } else {
9092                        $submenu.css({left:'50%', right:'auto'})
9093                    }
9094                    animate_op.opacity = 1
9095
9096                    $li.addClass('active')
9097                    $submenu.show().stop().animate(animate_op, 'fast')
9098                }, function() {
9099                    if ($li.hasClass(that.classnames.li_filter)) {
9100                        return false
9101                    }
9102                    hidesubmenu($li, $menu, $submenu)
9103                })
9104
9105                $li.on('hidesubmenu.bjui.datagrid.th', function(e, menu, submenu) {
9106                    hidesubmenu($(this), menu, submenu)
9107                })
9108            },
9109            // column menu - lock/unlock
9110            locking: function($th) {
9111                var index= $th.data('index'), columnModel = that.columnModel[index], lockFlag = columnModel.lock, locked = columnModel.locked, $menu = that.$menu, $ul = $menu.find('> ul'), $lockli = $ul.find('> li.'+ that.classnames.li_lock), $unlockli = $lockli.next()
9112
9113                if (locked) {
9114                    $lockli.addClass('disable')
9115                    $unlockli.removeClass('disable')
9116                } else {
9117                    $unlockli.addClass('disable')
9118                    $lockli.removeClass('disable')
9119                }
9120
9121                if (lockFlag) {
9122                    $lockli.show().off('click').on('click', function() {
9123                        if ($lockli.hasClass('disable')) return
9124
9125                        $menu.hide().data('bjui.datagrid.menu.btn').removeClass('active')
9126                        that.colLock($th, true)
9127                    })
9128
9129                    $unlockli.show().off('click').on('click', function() {
9130                        if ($unlockli.hasClass('disable')) return
9131
9132                        $menu.hide().data('bjui.datagrid.menu.btn').removeClass('active')
9133                        that.colLock($th, false)
9134                    })
9135                } else {
9136                    $lockli.hide().off('click')
9137                    $unlockli.hide().off('click')
9138                }
9139            },
9140            // create show/hide column panel
9141            createShowhide: function() {
9142                var $showhide, keys = that.options.keys
9143
9144                if (!that.$showhide) {
9145                    that.col_showhide_count = that.columnModel.length
9146                    $showhide = $('<ul class="'+ that.classnames.s_showhide +'" role="menu"></ul>')
9147
9148                    $.each(that.columnModel, function(i, n) {
9149                        if (that.tools.isGridModel(n))
9150                            that.col_showhide_count --
9151
9152                        var $col = $(FRAG.gridShowhide.replaceAll('#index#', n.index).replaceAll('#label#', (n.label || ''))).attr('title', (n.label || '')).toggleClass('nodisable', !!(that.tools.isGridModel(n)))
9153                        var colClick = function(n) {
9154                            $col.click(function() {
9155                                if ($(this).hasClass('disable')) return false
9156
9157                                var $this = $(this), check = !$this.find('i').hasClass('fa-check-square-o'), index = n.index
9158
9159                                $this.toggleClass('datagrid-col-check')
9160                                    .find('i').attr('class', 'fa fa'+ (check ? '-check' : '') +'-square-o')
9161
9162                                that.showhideColumn(n.th, check)
9163
9164                                if (!(that.tools.isGridModel(n))) {
9165                                    that.col_showhide_count = check ? that.col_showhide_count + 1 : that.col_showhide_count - 1
9166                                }
9167
9168                                if (that.col_showhide_count == 1) $showhide.find('> li.datagrid-col-check').addClass('disable')
9169                                else $showhide.find('> li.disable').removeClass('disable')
9170
9171                                $showhide.find('> li.nodisable').removeClass('disable')
9172                            })
9173                        }
9174
9175                        colClick(n)
9176                        $col.appendTo($showhide)
9177
9178                        if (n.hide) $col.trigger('click')
9179                    })
9180
9181                    $showhide.appendTo(that.$grid)
9182                    $showhide.data('width', $showhide.outerWidth()).data('height', $showhide.outerHeight())
9183                    that.$showhide = $showhide
9184                }
9185            },
9186            // column - display/hide
9187            showhide: function(model, showFlag) {
9188                var keys = that.options.keys, index = model.index, $th = model.th, $trs = that.$tbody.find('> tr'), display = showFlag ? '' : 'none'
9189                var setColspan = function(column) {
9190                    var _colspan = column.colspan
9191
9192                    if (showFlag) _colspan ++
9193                    else _colspan --
9194
9195                    if (!_colspan) column.th.css('display', 'none')
9196                    else column.th.css('display', '')
9197
9198                    column.th.attr('colspan', _colspan)
9199                    column.colspan = _colspan
9200
9201                    if (column.parent) setColspan(column.parent)
9202                }
9203
9204                if (typeof model.hidden === 'undefined') model.hidden = false
9205                // if (model.hidden === !showFlag) return
9206                //hidden ->hide 隐藏列一次之后reload datagrid 第二次不能隐藏列
9207                if (model.hide === !showFlag) return
9208
9209                model.hidden = !showFlag
9210
9211                $th.css('display', display)
9212
9213                if (that.options.tdTemplate && !this.isGridModel(model)) {
9214                    var colspan = $trs.eq(0).find('> td.datagrid-template-td').attr('colspan')
9215
9216                    if (colspan) {
9217                        $trs.find('> td.datagrid-template-td').attr('colspan', parseInt(colspan, 10) + (model.hidden ? -1 : 1))
9218                    }
9219                } else {
9220                    $trs.find('> td:eq('+ index +')').css('display', display)
9221                }
9222                that.$colgroupH.find('> col').eq(index).css('display', display)
9223                that.$colgroupB.find('> col').eq(index).css('display', display)
9224                that.$thead.find('> tr.datagrid-filter > th:eq('+ index +')').css('display', display)
9225                if (that.$boxF) {
9226                    that.$tableF.find('> thead > tr > th:eq('+ index +')').css('display', display)
9227                    that.$colgroupF.find('> col').eq(index).css('display', display)
9228                }
9229
9230                if (model.calc) {
9231                    that.$tfoot && that.$tfoot.trigger('resizeH.bjui.datagrid.tfoot')
9232                }
9233
9234                if (model.parent) setColspan(model.parent)
9235
9236                // fixed width && height for child datagrid
9237                that.$tbody.find('> tr.'+ that.classnames.tr_child +':visible > td table').trigger('bjui.datagrid.child.resize')
9238            },
9239            isGridModel: function(model) {
9240                var keys = that.options.keys
9241
9242                if (!model || typeof model !== 'object') return false
9243                return (model[keys.gridChild] || model[keys.gridNumber] || model[keys.gridCheckbox] || model[keys.gridEdit])
9244            },
9245            isGridData: function(name) {
9246                var keys = that.options.keys, b = false
9247
9248                for (var key in keys) {
9249                    if (keys[key] === name) {
9250                        b = true
9251
9252                        break
9253                    }
9254                }
9255
9256                return b
9257            },
9258            // jump to page
9259            jumpPage: function(pageCurrent, pageSize) {
9260                var allData = that.allData, filterDatas
9261
9262                if (pageCurrent) {
9263                    that.paging.oldPageCurrent = that.paging.pageCurrent
9264                    that.paging.pageCurrent    = pageCurrent
9265                }
9266                if (pageSize) {
9267                    that.paging.oldPageSize = that.paging.pageSize
9268
9269                    that.paging.pageSize  = pageSize
9270                    that.paging.pageCount = this.getPageCount(pageSize, that.paging.total)
9271
9272                    if (that.paging.pageCurrent > that.paging.pageCount)
9273                        that.paging.pageCurrent = that.paging.pageCount
9274                }
9275
9276                if (options.local === 'remote') {
9277                    filterDatas = this.getRemoteFilterData(true)
9278                    this.loadData(filterDatas, true)
9279                } else {
9280                    this.initTbody(allData, true)
9281                }
9282            },
9283            // column - quicksort
9284            quickSort: function(model) {
9285                if (that.isDom) {
9286                    if (options.local === 'local') return
9287                    options.sortAll = true
9288                }
9289                if (!that.sortData) {
9290                    that.sortData = {}
9291                }
9292                if (that.$tbody.find('> tr.'+ that.classnames.tr_edit).length) {
9293                    that.$tbody.alertmsg('info', BJUI.getRegional('datagrid.editMsg'))
9294                    return
9295                }
9296
9297                var $th = model.th, data = that.data, allData = that.allData, postData, direction, name = model.name, type = model.type, $ths = that.$thead.find('> tr > th.datagrid-quicksort-th')
9298
9299                if (!name) name = 'datagrid-noname'
9300
9301                var getOrders = function() {
9302                    var orders = []
9303
9304                    $.each(that.sortData, function(k, v) {
9305                        orders.push(k +' '+ v.direction)
9306                    })
9307
9308                    return orders
9309                }
9310                var sortData = function(data, orders) {
9311                    var localSort = function(a, b) {
9312                        var key_index = 0
9313
9314                        function doCompare() {
9315                            var keys = orders[key_index].split(' '), name = keys[0], direction = keys[1], typeA = (typeof a[name]), typeB = (typeof b[name])
9316
9317                            if (a[name] == b[name] && key_index < orders.length - 1) {
9318                                key_index ++
9319                                return doCompare()
9320                            }
9321
9322                            if ((typeA = typeB === 'number') || (typeA = typeB === 'boolean')) {
9323                                return direction === 'asc' ? (a[name] - b[name]) : (b[name] - a[name])
9324                            } else {
9325                                return direction === 'asc' ? String(a[name]).localeCompare(b[name]) : String(b[name]).localeCompare(a[name])
9326                            }
9327                        }
9328
9329                        if (!orders || !orders.length) {
9330                            return (a['bjui_local_index'] - b['bjui_local_index'])
9331                        }
9332                        return doCompare()
9333                    }
9334
9335                    data.sort(localSort)
9336                }
9337
9338                if (options.fieldSortable)
9339                    $th.find('> div > .datagrid-label > i').remove()
9340                else
9341                    that.$thead.find('> tr:not(.datagrid-filter) > th > div > .datagrid-label > i').remove()
9342
9343                if (model.sortDesc) {
9344                    model.sortDesc = false
9345                } else {
9346                    if (model.sortAsc) {
9347                        direction = 'desc'
9348                        model.sortAsc  = false
9349                        model.sortDesc = true
9350                    } else {
9351                        direction = 'asc'
9352                        model.sortAsc = true
9353                    }
9354                    // for thead
9355                    $th.find('> div > .datagrid-label').prepend('<i class="datagrid-sort-i fa fa-long-arrow-'+ (model.sortAsc ? 'up' : 'down') +'"></i>')
9356                }
9357
9358                if (direction) {
9359                    if (that.sortData[name]) {
9360                        that.sortData[name]['direction'] = direction
9361                    } else {
9362                        that.sortData[name] = {index:(Object.keys(that.sortData)).length, direction:direction}
9363                    }
9364                } else {
9365                    delete that.sortData[name]
9366                }
9367                if (options.sortAll) {
9368                    if (options.local === 'remote') {
9369                        postData = that.$element.data('filterDatas') || {}
9370                        postData[BJUI.pageInfo.pageSize]    = that.paging.pageSize
9371                        postData[BJUI.pageInfo.pageCurrent] = that.paging.pageCurrent
9372
9373                        if (direction) {
9374                            postData[BJUI.pageInfo.orderField]     = name
9375                            postData[BJUI.pageInfo.orderDirection] = direction
9376                        } else {
9377                            postData[BJUI.pageInfo.orderField]     = ''
9378                            postData[BJUI.pageInfo.orderDirection] = ''
9379                        }
9380
9381                        postData['orders'] = getOrders().join(',')
9382                        that.orders = {orders : postData['orders']}
9383
9384                        this.loadData(that.tools.getRemoteFilterData(true), true)
9385                    } else {
9386                        sortData(allData, getOrders())
9387                        this.initTbody(allData, true)
9388                    }
9389                } else {
9390                    sortData(data, getOrders())
9391                    this.createTrs(data, true)
9392                }
9393            },
9394            showFilterMsg: function(msgs) {
9395                var $msg = that.$boxH.find('.datagrid-thead-dialog-filter-msg'), $filter = $msg.find('> .msg-filter'), html = BJUI.StrBuilder()
9396
9397                $filter.html('')
9398
9399                if (!msgs.length) return
9400
9401                $.each(msgs, function(i, n) {
9402                    if (!n) return true
9403
9404                    var label = n.label, val = n.data.valA
9405
9406                    if (n.model.type === 'select' || n.model.type === 'boolean') {
9407                        val = n.model.render.call(that, val, {}, n.model.items, n.model.itemattr)
9408                    }
9409
9410                    html.add(';')
9411                        .add(n.model.label +':'+ val)
9412                })
9413
9414                html = html.toString()
9415                html.length > 1 && (html = html.substr(1))
9416
9417                $filter.html(html)
9418            },
9419            quickFilter: function(model, filterDatas) {
9420                if (that.isDom) {
9421                    if (options.local != 'remote') {
9422                        BJUI.debug('BJUI.Datagrid: Please change the local option is remote!')
9423                        return
9424                    }
9425                    if (!options.dataUrl) {
9426                        BJUI.debug('BJUI.Datagrid: Not Set the dataUrl option!')
9427                        return
9428                    }
9429                }
9430
9431                var tools = this, $th = model.th, data = that.data, allData = that.allData, name = model.name, postData, fDatas, msgs = []
9432                var switchOperator = function(operator, val1, val2, model) {
9433                    var compare = false
9434
9435                    switch (operator) {
9436                        case '=':
9437                            compare = String(val1) === String(val2)
9438                            break
9439                        case '!=':
9440                            compare = String(val1) !== String(val2)
9441                            break
9442                        case '>':
9443                            compare = parseFloat(val2) > parseFloat(val1)
9444                            break
9445                        case '<':
9446                            compare = parseFloat(val2) < parseFloat(val1)
9447                            break
9448                        case 'like':
9449                            if (model && model.type === 'select') {
9450                                compare = String(val1) === String(val2)
9451                                if (model.attrs && model.attrs.multiple) {
9452                                    if ($.isArray(val1) && String(val2)) {
9453                                        $.each(String(val2).split(','), function(i, n) {
9454                                            compare = $.inArray(n, val1) != -1
9455                                            if (compare) return false
9456                                        })
9457                                    }
9458                                }
9459                            } else {
9460                                compare = String(val2).indexOf(String(val1)) >= 0
9461                            }
9462                            break
9463                        default:
9464                            break
9465                    }
9466
9467                    return compare
9468                }
9469                var filterData = function(data, filterDatas) {
9470                    var grepFun = function(n) {
9471                        var count = 0
9472
9473                        $.each(filterDatas, function(name, v) {
9474                            var op = v.datas
9475
9476                            count ++
9477                            if (!op) {
9478                                count --
9479                                v.model.isFiltered = false
9480                                v.model.th.trigger('filter.bjui.datagrid.th', [false])
9481                                if (v.model.$quickfilter) v.model.$quickfilter.trigger('clearfilter.bjui.datagrid.thead')
9482
9483                                return true
9484                            }
9485
9486                            v.model.isFiltered = true
9487                            v.model.th.trigger('filter.bjui.datagrid.th', [true])
9488
9489                            if (!msgs[v.model.index])
9490                                msgs[v.model.index] = {model:v.model, data:v.datas}
9491
9492                            if (op.andor) {
9493                                if (op.andor === 'and') {
9494                                    if (switchOperator(op.operatorA, op.valA, n[name], v.model) && switchOperator(op.operatorB, op.valB, n[name], v.model)) {
9495                                        count --
9496                                    }
9497                                } else if (op.andor === 'or') {
9498                                    if (switchOperator(op.operatorA, op.valA, n[name], v.model) || switchOperator(op.operatorB, op.valB, n[name], v.model)) {
9499                                        count --
9500                                    }
9501                                }
9502                            } else {
9503                                if (op.operatorB) {
9504                                    if (switchOperator(op.operatorB, op.valB, n[name], v.model)) {
9505                                        count --
9506                                    }
9507                                } else {
9508                                    if (switchOperator(op.operatorA, op.valA, n[name], v.model)) {
9509                                        count --
9510                                    }
9511                                }
9512                            }
9513                        })
9514
9515                        return !count ? true : false
9516                    }
9517
9518                    return $.grep(data, function(n, i) {
9519                        return grepFun(n)
9520                    })
9521                }
9522
9523                if (!that.filterDatas) that.filterDatas = {}
9524                if (options.filterMult) {
9525                    that.filterDatas[name] = {datas:filterDatas, model:model}
9526                } else {
9527                    that.filterDatas = {}
9528                    that.filterDatas[name] = {datas:filterDatas, model:model}
9529                }
9530
9531                if (options.local !== 'remote' && allData) {
9532                    if (!that.oldAllData) that.oldAllData = allData.concat()
9533                    else allData = that.oldAllData.concat()
9534                }
9535
9536                if (options.filterAll) {
9537                    if (options.local === 'remote') {
9538                        tools.loadData(tools.getRemoteFilterData(false, msgs), true)
9539                    } else {
9540                        fDatas = filterData(allData, that.filterDatas)
9541
9542                        that.tools.showFilterMsg(msgs)
9543
9544                        that.paging.pageCurrent = 1
9545                        that.paging.pageCount   = this.getPageCount(that.paging.pageSize, fDatas.length)
9546
9547                        this.initTbody(fDatas, true)
9548                    }
9549                } else {
9550                    if (that.isDom) {
9551                        tools.loadData(tools.getRemoteFilterData(false, msgs), true)
9552                    } else {
9553                        if (!that.oldData) that.oldData = data.concat()
9554                        else data = that.oldData.concat()
9555
9556                        fDatas = filterData(data, that.filterDatas)
9557
9558                        that.tools.showFilterMsg(msgs)
9559
9560                        this.createTrs(fDatas, true)
9561                    }
9562                }
9563            },
9564            getRemoteFilterData: function(isPaging, msgs) {
9565                var filterDatas = {}
9566
9567                if (that.filterDatas && !$.isEmptyObject(that.filterDatas)) {
9568                    $.each(that.filterDatas, function(name, v) {
9569                        if (!v.datas) {
9570                            v.model.isFiltered = false
9571                            v.model.th.trigger('filter.bjui.datagrid.th', [false])
9572                            if (v.model.$quickfilter) v.model.$quickfilter.trigger('clearfilter.bjui.datagrid.thead')
9573                            msgs && msgs[v.model.index] && (msgs[v.model.index] = false)
9574                            return true
9575                        }
9576
9577                        v.model.isFiltered = true
9578                        v.model.th.trigger('filter.bjui.datagrid.th', [true])
9579
9580                        if (options.jsonPrefix)
9581                            name = options.jsonPrefix +'.'+ name
9582
9583                        if (v.datas.andor)
9584                            filterDatas['andor'] = v.datas.andor
9585                        if (v.datas.operatorA) {
9586                            filterDatas[name] = v.datas.valA
9587                            filterDatas[name +'.operator'] = v.datas.operatorA
9588                        }
9589                        if (v.datas.operatorB) {
9590                            if (filterDatas[name]) {
9591                                filterDatas[name] = [filterDatas[name], v.datas.valB]
9592                                filterDatas[name +'.operator'] = [filterDatas[name +'.operator'], v.datas.operatorB]
9593                            } else {
9594                                filterDatas[name] = v.datas.valB
9595                                filterDatas[name +'.operator'] = v.datas.operatorB
9596                            }
9597                        }
9598                    })
9599
9600                    if (!isPaging) that.paging.pageCurrent = 1
9601                }
9602
9603                if (that.initFilter) {
9604                    var name = options.jsonPrefix ? options.jsonPrefix +'.' : ''
9605
9606                    $.each(that.initFilter, function(k, v) {
9607                        if (!that.filterDatas || typeof that.filterDatas[k] === 'undefined')
9608                            filterDatas[name + k] = v.value
9609                    })
9610                }
9611
9612                // paging
9613                filterDatas[BJUI.pageInfo.pageSize]    = that.paging.pageSize
9614                filterDatas[BJUI.pageInfo.pageCurrent] = that.paging.pageCurrent || 1
9615
9616                $.extend(filterDatas, that.orders || {})
9617
9618                that.$element.data('filterDatas', filterDatas)
9619
9620                return filterDatas
9621            },
9622            // set data for Dom
9623            setDomData: function(tr) {
9624                var columnModel = that.columnModel, data = {}, hideDatas = tr.attr('data-hidden-datas'), attach = that.attach
9625
9626                tr.find('> td').each(function(i) {
9627                    var $td = $(this), model = columnModel[i], val = $td.attr('data-val') || $td.text()
9628
9629                    if (!model.name) data['datagrid-noname'+ i] = val
9630                    else data[model.name] = val
9631                })
9632
9633                if (hideDatas) hideDatas = hideDatas.toObj()
9634
9635                attach[that.options.keys.gridNumber] = (tr.index() + 1)
9636                $.extend(data, attach, hideDatas)
9637
9638                tr.data('initData', data)
9639
9640                return data
9641            },
9642            // update linenumber
9643            updateLinenumber: function() {
9644                if ($.inArray(that.linenumberColumn, that.columnModel) == -1)
9645                    return
9646
9647                var lock = false
9648
9649                if (that.linenumberColumn.locked) {
9650                    that.colLock(that.linenumberColumn.th, false)
9651                    lock = true
9652                }
9653
9654                that.$tbody.find('> tr:not(.'+ that.classnames.tr_child +')').each(function(i) {
9655                    var $tr = $(this)
9656
9657                    $tr.find('> td.'+ that.classnames.td_linenumber).text(i + 1)
9658                })
9659
9660                if (lock)
9661                    that.colLock(that.linenumberColumn.th, true)
9662            },
9663            // update that.data gridIndex && gridNumber
9664            updateGridIndex: function() {
9665                var paging = that.paging, options = that.options, startNumber = (paging.pageCurrent - 1) * paging.pageSize
9666
9667                $.each(that.data, function(i, data) {
9668                    var linenumber = options.linenumberAll ? (startNumber + (i + 1)) : (i + 1)
9669
9670                    data[options.keys.gridNumber] = linenumber
9671                    data[options.keys.gridIndex]  = i
9672                })
9673            },
9674            // init filter
9675            initFilter: function($input, model) {
9676                var initFilter = that.initFilter
9677                var doFilter = function($input, model) {
9678                    $input.val(String(that.options.initFilter[model.name]))
9679
9680                    if (that.$headFilterUl) {
9681                        var $headinput = that.$headFilterUl.find('> li.li-'+ model.index +'> '+ $input[0].tagName)
9682
9683                        if ($headinput.length) {
9684                            $headinput.val($input.val())
9685                            if ($headinput.isTag('select'))
9686                                $headinput.selectpicker('refresh')
9687                        }
9688                    }
9689
9690                    if (that.options.local === 'remote') {
9691                        model.isFiltered = true
9692                        model.th.trigger('filter.bjui.datagrid.th', [true])
9693                    } else {
9694                        that.tools.quickFilter(model, {operatorA:'like', valA:that.options.initFilter[model.name]})
9695                    }
9696                }
9697
9698                if (!$input && !model) {
9699                    if (initFilter) {
9700                        $.each(initFilter, function(i, n) {
9701                            doFilter(n.input, n.model)
9702                        })
9703                    }
9704                    return
9705                }
9706
9707                if (!initFilter) initFilter = {}
9708
9709                if (!model) return
9710
9711                doFilter($input, model)
9712
9713                if (!initFilter[model.name]) {
9714                    initFilter[model.name] = {}
9715                    initFilter[model.name].input = $input
9716                    initFilter[model.name].model = model
9717                    initFilter[model.name].value = that.options.initFilter[model.name]
9718                }
9719
9720                that.initFilter = initFilter
9721            },
9722            // init inputs array for edit
9723            /*新增、修改行数据,初始化编辑框 begin*/
9724            initEditInputs: function() {
9725                var columnModel = that.columnModel
9726
9727                that.inputs = []
9728
9729                $.each(columnModel, function(i, op) {
9730                    var name = op.name, rule = '', pattern = '', selectoptions = [], attrs = ''
9731
9732                    if (!op) return
9733                    if (op.attrs && typeof op.attrs === 'object') {
9734                        $.each(op.attrs, function(i, n) {
9735                            if (typeof n === 'object') n = JSON.stringify(n).replaceAll('\"', '\'')
9736                            attrs += ' '+ i +'='+ n
9737                        })
9738                    }
9739
9740                    if (op === that.childColumn || op === that.linenumberColumn || op === that.checkboxColumn || op === that.editBtnsColumn) {
9741                        that.inputs.push('')
9742                    } else if (name) {
9743                        if (op.rule) rule = ' data-rule="'+ op.label +':'+ op.rule +'"'
9744                        else if (op.type === 'date') rule = ' data-rule="pattern('+ (op.pattern || 'yyyy-MM-dd') +')"';
9745                        if (op.type) {
9746                            switch (op.type) {
9747                                case 'date':
9748                                    if (!op.pattern) op.pattern = 'yyyy-MM-dd'
9749                                    pattern = ' data-pattern="'+ op.pattern +'"'
9750                                    that.inputs.push('<input type="text" name="'+ name +'" data-toggle="datepicker"'+ pattern + rule + attrs +'>')
9751
9752                                    break
9753                                case 'select':
9754                                    if (!op.items) return
9755
9756                                    $.each(op.items, function(i, n) {
9757                                        if (op.itemattr) {
9758                                            selectoptions.push('<option value="'+ n[op.itemattr.value] +'">'+ n[op.itemattr.label] +'</option>')
9759                                        } else {
9760                                            $.each(n, function(key, value) {
9761                                                selectoptions.push('<option value="'+ key +'">'+ value +'</option>')
9762                                            })
9763                                        }
9764                                    })
9765
9766                                    that.inputs.push('<select name="'+ name +'" data-toggle="selectpicker"'+ rule + attrs +' data-width="100%">'+ selectoptions.join('') +'</select>')
9767
9768                                    break
9769                                /*可选择可输入框 2018-07-25 begin*/
9770                                case 'selectInput':
9771                                    if (!op.items) return
9772                                    $.each(op.items, function(i, n) {
9773                                        if (op.itemattr) {
9774                                            selectoptions.push('<option value="'+ n[op.itemattr.value] +'">'+ n[op.itemattr.label] +'</option>')
9775                                        } else {
9776                                            $.each(n, function(key, value) {
9777                                                selectoptions.push('<option value="'+ key +'">'+ value +'</option>')
9778                                            })
9779                                        }
9780                                    })
9781                                    that.inputs.push('<input type="text" class="allowInputT" name="'+ name +'"'+ rule + attrs +' ><select data-toggle="selectpicker" data-width="100%" onchange="selectInputChange(this)">'+ selectoptions.join('') +'</select>')
9782                                    break
9783                                /*可选择可输入框 end*/
9784                                case 'boolean':
9785                                    that.inputs.push('<input type="checkbox" name="'+ name +'" data-toggle="icheck"'+ rule + attrs +' value="true">')
9786
9787                                    break
9788                                case 'findgrid':
9789                                    that.inputs.push('<input type="text" name="'+ name +'" data-toggle="findgrid" data-custom-event="true"'+ rule + attrs +'>')
9790
9791                                    break
9792                                case 'tags':
9793                                    that.inputs.push('<input type="text" name="'+ name +'" data-toggle="tags"'+ attrs +'>')
9794
9795                                    break
9796                                case 'spinner':
9797                                    that.inputs.push('<input type="text" name="'+ name +'" data-toggle="spinner"'+ rule + attrs +'>')
9798
9799                                    break
9800                                case 'textarea':
9801                                    that.inputs.push('<textarea data-toggle="autoheight" rows="1"'+ rule + attrs +'></textarea>')
9802
9803                                    break
9804                                default:
9805                                    that.inputs.push('<input type="text" name="'+ name +'"'+ rule + attrs +'>')
9806                                    break
9807                            }
9808                        } else {
9809                            that.inputs.push('<input type="text" name="'+ name +'"'+ rule + attrs +'>')
9810                        }
9811                    } else {
9812                        that.inputs.push('')
9813                    }
9814                })
9815                return that.inputs
9816            },
9817            /*新增、修改行数据,初始化编辑框 end*/
9818            contextmenuH: function() {
9819                var tools = this
9820
9821                that.$tableH.on('contextmenu', 'tr:not(.datagrid-filter)', function(e) {
9822                    if (!that.$showhide) tools.createShowhide()
9823
9824                    var posX = e.pageX, posY = e.pageY, wh = $(window).height(), mh = that.$showhide.data('height')
9825
9826                    if ($(window).width()  < posX + that.$showhide.width())  posX -= that.$showhide.width()
9827                    if (posY < 0 || (posY + mh) > wh)
9828                        posY = 0
9829                    if (mh > wh)
9830                        that.$showhide.css({height:wh})
9831                    else
9832                        that.$showhide.css({height:''})
9833                    if (that.$menu) {
9834                        that.$grid.trigger('click.bjui.datagrid.filter')
9835                    }
9836
9837                    that.$showhide
9838                        .appendTo('body')
9839                        .css({left:posX, top:posY, opacity:1, 'z-index':9999}).show()
9840
9841                    $(document).on('click', function(e) {
9842                        var $showhide = $(e.target).closest('.'+ that.classnames.s_showhide)
9843
9844                        if (!$showhide.length)
9845                            that.$showhide.css({left:'50%', top:0, opacity:0.2, 'z-index':''}).hide().appendTo(that.$grid)
9846                    })
9847
9848                    e.preventDefault()
9849                    e.stopPropagation()
9850                })
9851            },
9852            contextmenuB: function($tr, isLock) {
9853                $tr.contextmenu('show',
9854                    {
9855                        exclude : 'input, .bootstrap-select',
9856                        items:[
9857                            {
9858                                icon  : 'refresh',
9859                                title : BJUI.getRegional('datagrid.refresh'),
9860                                func  : function(parent, menu) {
9861                                    that.refresh()
9862                                }
9863                            },
9864                            {
9865                                title : 'diver'
9866                            },
9867                            {
9868                                icon  : 'plus',
9869                                title : BJUI.getRegional('datagrid.add'),
9870                                func  : function(parent, menu) {
9871                                    that.add()
9872                                }
9873                            },
9874                            {
9875                                icon  : 'edit',
9876                                title : BJUI.getRegional('datagrid.edit'),
9877                                func  : function(parent, menu) {
9878                                    var $tr = parent
9879
9880                                    if (isLock) $tr = that.$tbody.find('> tr:eq('+ $tr.index() +')')
9881                                    that.doEditRow($tr)
9882                                }
9883                            },
9884                            {
9885                                icon  : 'undo',
9886                                title : BJUI.getRegional('datagrid.cancel'),
9887                                func  : function(parent, menu) {
9888                                    var $tr = parent
9889
9890                                    if (isLock) $tr = that.$tbody.find('> tr:eq('+ $tr.index() +')')
9891
9892                                    if (!$tr.hasClass(that.classnames.tr_edit)) {
9893                                        $tr = that.$tbody.find('> tr.'+ that.classnames.tr_edit)
9894                                    }
9895                                    that.doCancelEditRow($tr)
9896                                }
9897                            },
9898                            {
9899                                icon  : 'remove',
9900                                title : BJUI.getRegional('datagrid.del'),
9901                                func  : function(parent, menu) {
9902                                    var $tr = parent
9903
9904                                    if (isLock) $tr = that.$tbody.find('> tr:eq('+ $tr.index() +')')
9905                                    that.delRows($tr)
9906                                }
9907                            }
9908                        ]
9909                    }
9910                )
9911            },
9912            contextMenuListM: function ($tr,list) {//list:菜单列表,右键配置 2020-12-01
9913                $tr.contextmenu('show',
9914                    {
9915                        items: list,
9916                    }
9917                )
9918            }//contextMenuListM
9919        }
9920
9921        return tools
9922    }
9923
9924    Datagrid.prototype.init = function() {
9925        if (!this.$element.isTag('table')) return
9926        if (this.$element.data('bjui.datagrid.init')) return
9927
9928        this.$element.data('bjui.datagrid.init', true)
9929
9930        var that = this, options = that.options, keys = options.keys, tools = that.tools, $parent = that.$element.parent(), gridHtml = BJUI.StrBuilder()
9931
9932        options.tableWidth = options.tableWidth || ''
9933        options.width      = options.width || '100%'
9934        options.height     = options.height || 'auto'
9935        that.isDom         = false
9936        that.columnModel   = []
9937        that.inputs        = []
9938        that.regional      = BJUI.regional.datagrid
9939
9940        gridHtml
9941            .add('<div class="bjui-datagrid">')
9942            .add(options.gridTitle ? '<div class="datagrid-title">'+ options.gridTitle +'</div>' : '')
9943            .add(options.showToolbar ? '<div class="datagrid-toolbar"></div>' : '')
9944            .add('<div class="datagrid-box-h"><div class="datagrid-wrap-h"><table class="table table-bordered"><colgroup></colgroup></table></div></div>')
9945            .add('<div class="datagrid-box-b"><div class="datagrid-wrap-b"></div></div>')
9946            .add('<div class="datagrid-box-m"></div>')
9947            .add(options.paging ? '<div class="datagrid-paging-box bjui-paging-box"></div>' : '')
9948            .add('</div>')
9949
9950        that.$grid    = $(gridHtml.toString()).insertAfter(that.$element).css('height', options.height)
9951        that.$boxH    = that.$grid.find('> div.datagrid-box-h')
9952        that.$boxB    = that.$boxH.next()
9953        that.$boxM    = that.$boxB.next().css('height', options.height)
9954        that.$boxP    = options.paging ? that.$boxM.next() : null
9955        that.$boxT    = options.gridTitle ? that.$grid.find('> div.datagrid-title') : null
9956        that.$toolbar = options.showToolbar ? that.$boxH.prev() : null
9957        that.$tableH  = that.$boxH.find('> div > table')
9958        that.$tableB  = that.$element
9959        // tdtemplate
9960        that.isTemplate = (options.tdTemplate && options.templateWidth) && options.templateWidth > that.$grid.width() || (options.tdTemplate && !options.templateWidth)
9961
9962        that.$grid.data('bjui.datagrid.table', that.$element.clone())
9963        that.$boxB.find('> div').append(that.$element)
9964
9965        that.initTop()
9966
9967        if (typeof options.paging === 'string') options.paging = options.paging.toObj()
9968        that.paging = $.extend({}, {pageSize:4000, selectPageSize:'30,60,90', pageCurrent:1, total:0, showPagenum:5}, (typeof options.paging === 'object') && options.paging)
9969        that.$thead = that.$element.find('> thead')
9970        that.$tbody = that.$element.find('> tbody')
9971        that.attach = {}
9972
9973        that.attach[keys.gridNumber]   = 0
9974        that.attach[keys.gridCheckbox] = '#checkbox#'
9975        that.attach[keys.gridEdit]     = '#edit#'
9976
9977        if (that.$tbody && that.$tbody.find('> tr').length) {
9978            that.isDom = true
9979
9980            that.setColumnModel()
9981
9982            that.$tbody.find('> tr > td').each(function() {
9983                var $td = $(this), html = $td.html()
9984
9985                $td.html('<div>'+ html +'</div>')
9986            })
9987
9988            if (!that.paging.total) {
9989                that.paging.total = that.$tbody.find('> tr').length
9990                that.paging.pageCount = 1
9991            } else {
9992                that.paging.pageCount = tools.getPageCount(that.paging.pageSize, that.paging.total)
9993            }
9994
9995            that.paging.pageCurrent = 1
9996            that.initThead()
9997        } else {
9998            that.$tbody = null
9999            that.$element.find('> tbody').remove()
10000
10001            if (options.columns) {
10002                if (typeof options.columns === 'string') {
10003                    if (options.columns.trim().startsWith('[')) {
10004                        options.columns = options.columns.toObj()
10005                    } else {
10006                        options.columns = options.columns.toFunc()
10007                    }
10008                }
10009                if (typeof options.columns === 'function') {
10010                    options.columns = options.columns.call()
10011                }
10012
10013                that.$thead = null
10014                that.$element.find('> thead').remove()
10015                that.createThead()
10016            } else {
10017                if (that.$thead && that.$thead.length && that.$thead.find('> tr').length) {
10018                    that.setColumnModel()
10019                } else {
10020                    BJUI.debug('BJUI.Datagrid: No set options \'columns\' !')
10021                    that.destroy()
10022                    return
10023                }
10024            }
10025            if (options.data || options.dataUrl) {
10026                that.createTbody()
10027            } else {
10028                BJUI.debug('BJUI.Datagrid: No options \'data\' or \'dataUrl\'!')
10029                that.destroy()
10030            }
10031        }
10032    }
10033
10034    // DOM to datagrid - setColumnModel
10035    Datagrid.prototype.setColumnModel = function() {
10036        var that = this, options = that.options, $trs = that.$thead.find('> tr'), rows = [], ths = [], trLen = $trs.length;
10037        if (!that.isDom) {
10038            that.tools.appendColumns()
10039
10040            var $th, _rowspan = trLen > 1 ? ' rowspan="'+ trLen +'"' : ''
10041            if (options.showCheckboxcol) {
10042                that.columnModel.push(that.checkboxColumn)
10043                if (options.showCheckboxcol === 'lock') that.checkboxColumn.initLock = true
10044
10045                $th = $('<th class="'+ that.classnames.td_checkbox +'"'+ _rowspan +'><input type="checkbox" data-toggle="icheck"></th>')
10046                $th.prependTo($trs.first())
10047                if (_rowspan) $th.data('datagrid.column', that.checkboxColumn)
10048            }
10049            if (options.showLinenumber) {
10050                that.columnModel.unshift(that.linenumberColumn)
10051                if (options.showLinenumber === 'lock') that.linenumberColumn.initLock = true
10052
10053                $th = $('<th class="'+ that.classnames.td_linenumber +'"'+ _rowspan +'>No.</th>')
10054                $th.prependTo($trs.first())
10055                if (_rowspan) $th.data('datagrid.column', that.linenumberColumn)
10056            }
10057            if (options.showChildcol || (options.showChildcol === undefined && options.hasChild && options.childOptions)) {
10058                that.columnModel.unshift(that.childColumn)
10059
10060                $th = $('<th class="'+ that.classnames.td_child +'"'+ _rowspan +'>...</th>')
10061                $th.prependTo($trs.first())
10062                if (_rowspan) $th.data('datagrid.column', that.childColumn)
10063            }
10064            if (options.showEditbtnscol) {
10065                $th = $('<th'+ _rowspan +'>'+ that.editBtnsColumn.label +'</th>')
10066                $th.appendTo($trs.first())
10067                if (_rowspan) $th.data('datagrid.column', that.editBtnsColumn)
10068                that.columnModel[$th.index()] = that.editBtnsColumn
10069            }
10070        }
10071
10072        if ($trs.length && trLen == 1) {
10073            $trs.find('> th').each(function(i) {
10074                var $th = $(this).addClass('single-row').data('index', i), op = $th.data('options'), oW = $th.attr('width') || 'auto', label = $th.html()
10075
10076                if (that.columnModel.length && that.columnModel[i]) {
10077                    op = that.columnModel[i]
10078                    op.index = i
10079                } else {
10080                    if (op && typeof op === 'string') op = op.toObj()
10081                    if (typeof op !== 'object') op = {}
10082
10083                    op.index = i
10084                    op.label = label
10085                    op.width = (typeof op.width === 'undefined') ? oW : op.width
10086
10087                    op = that.tools.setOp(op)
10088
10089                    that.columnModel[i] = op
10090                }
10091
10092                that.columnModel[i].th = $th
10093
10094                $th.html('<div><div class="datagrid-space"></div><div class="datagrid-label">'+ label +'</div><div class="'+ that.classnames.th_cell +'"><div class="'+ that.classnames.th_resizemark +'"></div></div></div>')
10095                if (op.menu && options.columnMenu) $th.addClass(that.classnames.th_menu)
10096                if (options.fieldSortable && op.quicksort) $th.addClass('datagrid-quicksort-th')
10097                if (op.align) $th.attr('align', op.align)
10098            })
10099        } else { // multi headers
10100            $trs.each(function(len) {
10101                var next_rows = [], next_ths = [], index = -1, next_index = 0
10102
10103                if (rows.length) {
10104                    next_rows = rows.concat()
10105                    next_ths  = ths.concat()
10106                }
10107                rows = []
10108                ths  = []
10109
10110                $(this).find('> th').each(function(i) {
10111                    var $th = $(this), op = $th.data('options') || $th.data('datagrid.column') || {}
10111, colspan = parseInt(($th.attr('colspan') || 0), 10), rowspan = parseInt(($th.attr('rowspan') || 0), 10), oW = $th.attr('width') || 'auto', label = $th.html()
10112
10113                    if (op && typeof op === 'string') op = op.toObj()
10114                    if (typeof op !== 'object') op = {}
10115                    if (BJUI.isIE(8) && colspan === 1) colspan = 0
10116
10117                    op.label = label
10118                    op.th    = $th
10119                    if (op[options.keys.gridCheckbox]) op.label = 'Checkbox'
10120
10121                    index++
10122                    if (colspan) {
10123                        op.colspan = colspan
10124                        for (var start_index = (next_rows.length ? next_rows[index] : index), k = start_index; k < (start_index + colspan); k++) {
10125                            rows[next_index++]  = k
10126                            ths[next_index - 1] = op
10127                        }
10128                        index += (colspan - 1)
10129
10130                        $th.data('index', index)
10131
10132                        if (next_rows.length) {
10133                            op.parent = next_ths[index]
10134                        }
10135                    }
10136                    if (!rowspan || rowspan == 1) $th.addClass('single-row')
10137                    if (!colspan) {
10138                        op.width = (typeof op.width === 'undefined') ? oW : op.width
10139
10140                        op = that.tools.setOp(op)
10141                        $th.html('<div><div class="datagrid-space"></div><div class="datagrid-label">'+ label +'</div><div class="'+ that.classnames.th_cell +'"><div class="'+ that.classnames.th_resizemark +'"></div></div></div>')
10142
10143                        if (op.menu && options.columnMenu) $th.addClass(that.classnames.th_menu)
10144                        if (options.fieldSortable && op.quicksort) $th.addClass('datagrid-quicksort-th')
10145                        if (op.align) $th.attr('align', op.align)
10146                        if (!next_rows.length) {
10147                            op.index = index
10148                            that.columnModel[index] = op
10149                        } else {
10150                            op.index  = next_rows[index]
10151                            op.parent = next_ths[index]
10152                            that.columnModel[next_rows[index]] = op
10153                        }
10154
10155                        $th.data('index', op.index)
10156                    } else {
10157                        $th.html('<div><div class="datagrid-space"></div><div class="datagrid-label">'+ label +'</div><div class="'+ that.classnames.th_cell +'"><div class="'+ that.classnames.th_resizemark +'"></div></div></div>')
10158                    }
10159                })
10160            })
10161        }
10162    }
10163
10164    // create thead by columns
10165    Datagrid.prototype.createThead = function() {
10166        var that = this, options = that.options, keys = options.keys, columns = options.columns.concat(), rowArr = [], rows = [], label, align, width, colspan, rowspan, resize, menu,
10167            columns2Arr = function(columns, rowArr, index, parent) {
10168                if (!rowArr) rowArr = []
10169                if (!index)   index = 0
10170                if (!rowArr[index]) rowArr[index] = []
10171
10172                $.each(columns, function(i, n) {
10173                    var len = rowArr[index].length, colspan
10174
10175                    if (parent) n.parent = parent
10176                    if (n.columns) {
10177                        colspan = n.columns.length
10178                        if (index && n.parent) {
10179                            that.tools.setColspan(n.parent, colspan)
10180                        }
10181
10182                        n.index     = that.columnModel.length + colspan - 1
10183                        n.colspan   = colspan
10184                        n.quicksort = false
10185                        n.columns[0].style="border-left:1px solid #c3ced5 !important;"
10186                        n.columns[colspan-1].style="border-right:1px solid #c3ced5 !important;"
10187                        rowArr[index][len++] = n
10188
10189                        return columns2Arr(n.columns, rowArr, index + 1, n)
10190                    } else {
10191                        n.rowspan = index
10192                        n.index   = that.columnModel.length
10193
10194                        n = that.tools.setOp(n)
10195
10196                        rowArr[index][len++] = n
10197                        that.columnModel.push(n)
10198                    }
10199                })
10200
10201                return rowArr
10202            }
10203
10204        that.tools.appendColumns()
10205
10206        if (options.showCheckboxcol) {
10207            columns.unshift(that.checkboxColumn)
10208            if (options.showCheckboxcol === 'lock') that.checkboxColumn.initLock = true
10209        }
10210        if (options.showLinenumber) {
10211            columns.unshift(that.linenumberColumn)
10212            if (options.showLinenumber === 'lock') that.linenumberColumn.initLock = true
10213        }
10214        if (options.showChildcol || (options.showChildcol === undefined && options.hasChild && options.childOptions)) {
10215            columns.unshift(that.childColumn)
10216        }
10217        if (options.showEditbtnscol) columns.push(that.editBtnsColumn)
10218        rowArr = columns2Arr(columns, rowArr)
10219        // the last model can't lock
10220        that.columnModel[that.columnModel.length - (options.showEditbtnscol ? 2 : 1)].lock = false
10221        // hidden fields
10222        if (options.hiddenFields) that.hiddenFields = options.hiddenFields
10223        // create thead
10224        that.$thead  = $('<thead></thead>')
10225        $.each(rowArr, function(i, arr) {
10226            var $tr = $('<tr style="height:25px;"></tr>'), $num = '<th class="datagrid-number"></th>', $th
10227
10228            $.each(arr, function(k, n) {
10229                label   = n.label || n.name
10230                align   = n.align ? (' align="'+ n.align +'"') : ''
10231                width   = n.width ? (' width="'+ n.width +'"') : ''
10232                colspan = n.colspan ? ' colspan="'+ n.colspan +'"' : ''
10233                rowspan = (rowArr.length - n.rowspan > 1) ? ' rowspan="'+ (rowArr.length - n.rowspan) +'"' : ''
10234                resize  = '<div class="'+ that.classnames.th_resizemark +'"></div>'
10235                menu    = ''
10236                var style   = n.style ? ' style="'+ n.style +'"' : ''
10237
10238                if (n[keys.gridCheckbox]) label = '<input type="checkbox" data-toggle="icheck">'
10239                if (n.colspan) align = ' align="center"'
10240                if (n.thalign) align = ' align="'+ n.thalign +'"'
10241                if (n.menu && options.columnMenu) menu = ' class="'+ that.classnames.th_menu +'"'
10242
10243                $th = $('<th'+ menu + width + align + colspan + rowspan+ style +'><div><div class="datagrid-space"></div><div class="datagrid-label">'+ label +'</div><div class="'+ that.classnames.th_cell +'">'+ resize +'</div></div></th>')
10244                $th.data('index', n.index).appendTo($tr)
10245
10246                if (!rowspan) $th.addClass('single-row')
10247                if (n[keys.gridChild]) $th.addClass(that.classnames.td_child)
10248                if (n[keys.gridNumber]) $th.addClass(that.classnames.td_linenumber)
10249                if (n[keys.gridCheckbox]) $th.addClass(that.classnames.td_checkbox)
10250                if (options.fieldSortable && n.quicksort) $th.addClass('datagrid-quicksort-th')
10251
10252                n.th = $th
10253            })
10254
10255            $tr.appendTo(that.$thead)
10256        })
10257
10258        that.$thead.appendTo(that.$element).initui()
10259    }
10260
10261    Datagrid.prototype.createTbody = function() {
10262        var that = this, options = that.options, data = options.data, model = that.columnModel, cols = []
10263
10264        if (data) {
10265            if (typeof data === 'string') {
10266                if (data.trim().startsWith('[') || data.trim().startsWith('{')) {
10267                    data = data.toObj()
10268                } else {
10269                    data = data.toFunc()
10270                }
10271            }
10272            if (typeof data === 'function') {
10273                data = data.call()
10274            }
10275
10276            // 过滤dom 格式化,如果当前返回数据为存在 <> 全部进行转译
10277            if(typeof data=='object'){
10278                for(var itemF in data){
10279                    if(typeof data[itemF] == 'string'){
10280                        data[itemF] = data[itemF].replaceAll('<', '&lt')
10281                        data[itemF] = data[itemF].replaceAll('>', '&gt')
10282                    }
10283                }
10284            }else {
10285                data.forEach(function(item){
10286                    for(var itemF in item){
10287                        if(typeof item[itemF] == 'string'){
10288                            item[itemF] = item[itemF].replaceAll('<', '&lt')
10289                            item[itemF] = item[itemF].replaceAll('>', '&gt')
10290                        }
10291                    }
10292                })
10293            }
10294
10295            options.data = data
10296            that.tools.createTrsByData(data)
10297        } else if (options.dataUrl) {
10298            var data = {}
10299
10300            if (typeof options.initFilter === 'object' && options.initFilter && options.jsonPrefix) {
10301                $.each(options.initFilter, function(k, v) {
10302                    data[options.jsonPrefix +'.'+ k] = v
10303                })
10304            }
10305
10306            that.$element.data('filterDatas', data)
10307
10308            that.tools.loadData(data)
10309        }
10310    }
10311
10312    Datagrid.prototype.refresh = function(filterFlag) {
10313        var that = this, options = that.options, tools = that.tools, isDom = that.isDom, pageInfo = BJUI.pageInfo, paging = that.paging, postData = {}
10314
10315        if (!options.dataUrl) {
10316            if (options.data && options.data.length) {
10317                tools.initTbody(that.allData, true)
10318                return
10319            }
10320
10321            BJUI.debug('BJUI.Datagrid: Not Set the dataUrl option!')
10322            return
10323        }
10324
10325        if (!options.postData || !options.postData[pageInfo.pageSize]) {
10326            postData[pageInfo.pageSize]    = paging.pageSize
10327            postData[pageInfo.pageCurrent] = paging.pageCurrent
10328        }
10329        if (options.initFilter && typeof options.initFilter === 'object') {
10330            if (typeof options.initFilter === 'object' && options.initFilter && options.jsonPrefix) {
10331                $.each(options.initFilter, function(k, v) {
10332                    postData[options.jsonPrefix +'.'+ k] = v
10333                })
10334            }
10335            that.doInitFilter = true
10336        }
10337        if (filterFlag)
10338            $.extend(postData, that.$element.data('filterDatas') || {})
10339
10340        tools.loadData(postData, true)
10341
10342        // clear fiter
10343        if (!filterFlag) {
10344            that.filterDatas = null
10345            $.each(that.columnModel, function(i, n) {
10346                n.th.trigger('filter.bjui.datagrid.th', [false])
10347                n.isFiltered = false
10348                if (n.$quickfilter) n.$quickfilter.trigger('clearfilter.bjui.datagrid.thead')
10349            })
10350            // clear sort
10351            that.orders = {}
10352            that.$thead.find('> tr > th.datagrid-quicksort-th').find('> div > .datagrid-label > i').remove()
10353        }
10354    }
10355
10356    Datagrid.prototype.refreshParent = function(filterFlag) {
10357        var that = this, $parent = that.$element.data('bjui.datagrid.parent')
10358
10359        if ($parent && $parent.length)
10360            $parent.closest('table').datagrid('refresh', filterFlag)
10361    }
10362
10363    Datagrid.prototype.refreshChild = function(row, filterFlag) {
10364        var that = this, $trs = that.$tbody.find('> tr'), $table,
10365            refresh = function(obj) {
10366                $table = obj.data('bjui.datagrid.child')
10367
10368                if ($table && $table.length && $table.isTag('table'))
10369                    $table.datagrid('refresh', filterFlag)
10370            }
10371
10372        if (row instanceof jQuery) {
10373            row.each(function() {
10374                refresh($(this))
10375            })
10376        } else if (isNaN(row)) {
10377            $.each(row.split(','), function(i, n) {
10378                if (n * 2 < $trs.length)
10379                    refresh($trs.eq(n * 2))
10380            })
10381        } else {
10382            if (row * 2 < $trs.length)
10383                refresh($trs.eq(row * 2))
10384        }
10385    }
10386
10387    // api
10388    Datagrid.prototype.showChild = function(row, flag, func) {
10389        if (typeof flag === 'undefined')
10390            flag = 'toggle'
10391
10392        var that   = this, options = that.options, $child, $td, $table, index, trData, childOptions, dataUrl, $trs = that.$tbody.find('> tr:not(.'+ that.classnames.tr_child +')'),
10393            fixedH = function() {
10394                //if (!options.fullGrid)
10395                that.fixedWidth()
10396
10397                that.fixedHeight()
10398            },
10399            fixedL = function(index, showorhide, height) {
10400                if (that.$lockTableB) {
10401                    var $locktr = that.$lockTableB.find('> tbody > tr:eq('+ index +')')
10402
10403                    $locktr.toggle(showorhide)
10404
10405                    if (height)
10406                        $locktr.height(height)
10407                    else if (!$locktr.height())
10408                        $locktr.height($child.height())
10409                }
10410            },
10411            show = function($tr, $child, $table) {
10412                $td.find('> div').html(BJUI.doRegional(FRAG.gridShrinkBtn, that.regional))
10413
10414                $child.fadeIn('normal', function() {
10415                    if (!$table.data('bjui.datagrid.init')) {
10416                        childOptions = $.extend(true, {}, that.childOptions), dataUrl = childOptions.dataUrl
10417
10418                        if (that.isDom) trData = $tr.data('initData') || that.tools.setDomData($tr)
10419                        else {
10420                            trData = that.data[that.tools.getNoChildDataIndex($tr.index())]
10421                        }
10422
10423                        if (dataUrl && !dataUrl.isFinishedTm()) {
10424                            dataUrl = that.tools.replacePlh(dataUrl, trData)
10425
10426                            if (!dataUrl.isFinishedTm()) {
10427                                BJUI.debug('BJUI.Datagrid: The datagrid options \'childOptions\' in the \'dataUrl\' options is incorrect: '+ dataUrl)
10428                            } else {
10429                                childOptions.dataUrl = dataUrl
10430                            }
10431                        }
10432
10433                        $table
10434                            .datagrid(childOptions)
10435                            .data('bjui.datagrid.parent', $tr)
10436                            .on('completed.bjui.datagrid', $.proxy(function() {
10437                                fixedH()
10438                                fixedL(index, true, $child.outerHeight())
10439
10440                                if (func)
10441                                    func.apply(that, [$table])
10442                            }, that))
10443                            .on('bjui.datagrid.child.resize', function() {
10444                                $table
10445                                    .datagrid('fixedWidth')
10446                                    .datagrid('fixedHeight')
10447                            })
10448
10449                        $tr.data('bjui.datagrid.child', $table)
10450                    } else {
10451                        fixedH()
10452                        fixedL(index, true)
10453
10454                        if (func)
10455                            func.apply(that, [$table])
10456                    }
10457                })
10458            },
10459            hide = function($tr, $child, $table) {
10460                $child.fadeOut('normal', function() {
10461                    $td.find('> div').html(BJUI.doRegional(FRAG.gridExpandBtn, that.regional))
10462
10463                    fixedH()
10464                    fixedL(index, false)
10465
10466                    if (func)
10467                        func.apply(that, [$table])
10468                })
10469            },
10470            showhide = function($tr) {
10471                $child = $tr.next('.'+ that.classnames.tr_child)
10472
10473                if ($child && $child.length) {
10474                    $td    = $tr.find('> td.'+ that.classnames.td_child)
10475                    index  = $child.index()
10476                    $table = $child.find('> td').find('table.table-child')
10477
10478                    if ($table && $table.length) {
10479                        if (flag && flag === 'toggle') {
10480                            $child.is(':hidden') ? show($tr, $child, $table) : hide($tr, $child, $table)
10481                        } else {
10482                            flag ? show($tr, $child, $table) : hide($tr, $child, $table)
10483                        }
10484                    }
10485                }
10486            }
10487
10488        if (func) {
10489            if (typeof func === 'string')
10490                func = func.toFunc()
10491            if (typeof func !== 'function')
10492                func = false
10493        }
10494
10495        if (row instanceof jQuery) {
10496            row.each(function() {
10497                showhide($(this))
10498            })
10499        } else if (isNaN(row)) {
10500            $.each(row.split(','), function(i, n) {
10501                var tr = $trs.eq(parseInt(n.trim(), 10))
10502
10503                if (tr && tr.length)
10504                    showhide(tr)
10505            })
10506        } else if (!isNaN(row)) {
10507            var tr = $trs.eq(row)
10508
10509            if (tr && tr.length)
10510                showhide(tr)
10511        }
10512    }
10513
10514    // api
10515    Datagrid.prototype.updateRow = function(row, updateData) {
10516        var that = this, options = that.options, data_index, data, url, $tr,
10517            doUpdate = function(tr, updateData) {
10518                $.extend(data, typeof updateData === 'object' && updateData)
10519
10520                that.dialogEditComplete(tr, data)
10521
10522                // refresh child
10523                if (data['refresh.datagrid.child']) {
10524                    var $child = tr.data('bjui.datagrid.child')
10525
10526                    if ($child && $child.length)
10527                        $child.datagrid('refresh')
10528                    else
10529                        that.showChild(row)
10530                }
10531
10532                // fixedH
10533                if (options.height === 'auto') {
10534                    var scrollTop = that.$boxB.scrollTop()
10535
10536                    that.$boxB.scrollTop(5)
10537                    if (that.$boxB.scrollTop()) {
10538                        that.fixedHeight()
10539                        that.$boxB.scrollTop(scrollTop)
10540                    }
10541                }
10542            }
10543
10544        if (row instanceof jQuery) {
10545            $tr = row
10546        } else if (!isNaN(row)) {
10547            $tr = that.$tbody.find('> tr:not(.'+ that.classnames.tr_child +')').eq(parseInt(row, 10))
10548        } else {
10549            BJUI.debug('BJUI.Datagrid: Func \'updateRow\', Parameter \'row\' is 
10549incorrect!')
10550            return
10551        }
10552
10553        if (that.isDom) data = $tr.data('initData') || that.tools.setDomData($tr)
10554        else {
10555            data_index = that.tools.getNoChildDataIndex($tr.index())
10556            data = that.data[data_index]
10557        }
10558
10559        if (updateData) {
10560            if (typeof updateData === 'string') {
10561                if (updateData.trim().startsWith('{'))
10562                    updateData = updateData.toObj()
10563                else
10564                    updateData = updateData.toFunc()
10565            }
10566            if (typeof updateData === 'function')
10567                updateData = updateData.apply()
10568
10569            if (typeof updateData !== 'object' && !options.updateRowUrl) {
10570                BJUI.debug('BJUI.Datagrid: Func \'updateRow\', Parameter \'updateData\' is incorrect!')
10571                return
10572            }
10573
10574            doUpdate($tr, updateData)
10575        } else if (options.updateRowUrl) {
10576            url = that.tools.replacePlh(options.updateRowUrl, data)
10577
10578            if (!url.isFinishedTm()) {
10579                BJUI.debug('BJUI.Datagrid: The datagrid options \'updateRowUrl\' is incorrect!')
10580            } else {
10581                BJUI.ajax('doajax', {
10582                    url       : url,
10583                    type      : options.loadType,
10584                    okCallback: function(json) {
10585                        doUpdate($tr, json)
10586                    }
10587                })
10588            }
10589        } else {
10590            BJUI.debug('BJUI.Datagrid: The datagrid options \'updateRowUrl\' is not set!')
10591        }
10592    }
10593
10594    // api
10595    Datagrid.prototype.doAjaxRow = function(row, opts) {
10596        var that = this, options = that.options, $tr, data, data_index, url
10597
10598        if (row instanceof jQuery) {
10599            $tr = row
10600        } else if (!isNaN(row)) {
10601            $tr = that.$tbody.find('> tr:not(.'+ that.classnames.tr_child +')').eq(parseInt(row, 10))
10602        } else {
10603            BJUI.debug('BJUI.Datagrid: Func \'doAjaxRow\', Parameter \'row\' is incorrect!')
10604            return
10605        }
10606        if (typeof opts === 'object' && opts.url) {
10607            if (typeof opts.reload === 'undefined')
10608                opts.reload = false
10609            if (!opts.callback && !opts.okCallback) {
10610                opts.okCallback = function(json, options) {
10611                    that.updateRow($tr, typeof json === 'object' && !json[BJUI.keys.statusCode] && json)
10612                }
10613            }
10614
10615            if (that.isDom) data = $tr.data('initData') || that.tools.setDomData($tr)
10616            else {
10617                data_index = that.tools.getNoChildDataIndex($tr.index())
10618                data = that.data[data_index]
10619            }
10620
10621            url = opts.url
10622
10623            if (!data || data.addFlag)
10624                url = url.replace(/{\/?[^}]*}/g, '')
10625            else
10626                url = that.tools.replacePlh(url, data)
10627
10628            if (!url.isFinishedTm()) {
10629                BJUI.debug('BJUI.Datagrid: Func \'doAjaxRow\', options \'url\' is incorrect: '+ url)
10630            }
10631
10632            opts.url = url
10633            opts.loadingmask = true
10634            opts.target = that.$boxB
10635
10636            BJUI.ajax('doajax', opts)
10637        } else {
10638            BJUI.debug('BJUI.Datagrid: Func \'doAjaxRow\', options is incorrect or the property \'url\' is not set!')
10639        }
10640    }
10641
10642    Datagrid.prototype.filter = function(data) {
10643        var that = this, options = that.options, nodatatr = that.$tbody.find('> tr.datagrid-nodata').length
10644
10645        if (data && typeof data === 'object') {
10646            if (data.clearOldPostData || !options.postData)
10647                options.postData = {}
10648
10649            $.extend(options.postData, data)
10650        }
10651
10652        // reset pageCurrent
10653        that.paging.pageCurrent = 1
10654
10655        that.refresh()
10656
10657        if (nodatatr) {
10658            that.$element.one('afterLoad.bjui.datagrid', function() {
10659                that.needfixedWidth = true
10660                that.fixedWidth()
10661                that.needfixedWidth = null
10662            })
10663        }
10664    }
10665
10666    Datagrid.prototype.reload = function(option) {
10667        var that = this, options = that.options, data, $element
10668
10669        if (option && typeof option === 'object') {
10670            if (option.clearOldPostData)
10671                delete options.postData
10672
10673            if (option.columns)
10674                delete options.columns
10675
10676            $.extend(true, options, option)
10677        }
10678
10679        that.destroy()
10680
10681        $element = that.$element
10682        $element.data('bjui.datagrid', (data = new Datagrid($element, options)))
10683
10684        if (data)
10685            data.init()
10686    }
10687
10688    Datagrid.prototype.reloadData = function(option) {/*重载表内容,不包含表å
10688¤´--2018-11-13*/
10689        var that = this, options = that.options
10690
10691        if (option && typeof option === 'object') {
10692            if (option.clearOldPostData)
10693                delete options.postData
10694
10695            if (option.columns)
10696                delete options.columns
10697
10698            $.extend(true, options, option)
10699        }
10700        //that.$tbody.find('> tr').remove()
10701        that.createTbody()
10702        that.initEvents()
10703        BJUI.init({})
10704    }
10705    Datagrid.prototype.destroy = function() {
10706        var that = this, $element = that.$grid.data('bjui.datagrid.table')
10707
10708        if ($element) {
10709            that.$element
10710                .html($element.html())
10711                .removeData()
10712                .insertBefore(that.$grid)
10713
10714            that.$grid.remove()
10715        }
10716    }
10717
10718    Datagrid.prototype.initTop = function() {
10719        var that = this, options = that.options, regional = that.regional, hastoolbaritem = false, $group, groupHtml = '<div class="btn-group" role="group"></div>', btnHtml = '<button type="button" class="btn" data-icon=""></button>'
10720
10721        if (options.showToolbar) {
10722            if (options.toolbarItem || options.toolbarCustom) {
10723                if (options.toolbarItem) {
10724                    var itemFunc = options.toolbarItem.toFunc()
10725
10726                    if (typeof itemFunc === 'function') {
10727                        options.toolbarItem = itemFunc.apply()
10728                    }
10729
10730                    hastoolbaritem = true
10731                    if (options.toolbarItem.indexOf('all') >= 0) options.toolbarItem = 'add, edit, cancel, save, |, del, |, refresh, |, import, export, exportf'
10732                    $.each(options.toolbarItem.split(','), function(i, n) {
10733                        n = n.trim().toLocaleLowerCase()
10734                        if (!$group || n === '|') {
10735                            $group = $(groupHtml).appendTo(that.$toolbar)
10736                            if (n === '|') return true
10737                        }
10738
10739                        if (n === 'add') {
10740                            that.$toolbar_add = $(btnHtml).attr('data-icon', 'plus').addClass('btn-blue').text(options.addName || BJUI.getRegional('datagrid.add'))
10741                                .appendTo($group)
10742                                .on('click', function(e) {
10743                                    that.add()
10744                                })
10745                        } else if (n === 'edit') {
10746                            that.$toolbar_edit = $(btnHtml).attr('data-icon', 'edit').addClass('btn-green').text(options.editName || BJUI.getRegional('datagrid.edit'))
10747                                .appendTo($group)
10748                                .on('click', function(e) {
10749                                    var $selectTrs = that.$tbody.find('> tr.'+ that.classnames.tr_selected)
10750
10751                                    if (!options.editMode) return false
10752                                    if (!$selectTrs.length) {
10753                                        $(this).alertmsg('info', BJUI.getRegional('datagrid.selectMsg'))
10754                                    } else {
10755                                        if (options.inlineEditMult) {
10756                                            that.doEditRow($selectTrs)
10757                                        } else {
10758                                            if (that.$lastSelect) that.doEditRow(that.$lastSelect)
10759                                            else that.doEditRow($selectTrs.first())
10760                                        }
10761                                    }
10762                                })
10763                        } else if (n === 'cancel') {
10764                            that.$toolbar_calcel = $(btnHtml).attr('data-icon', 'undo').addClass('btn-orange').text(options.cancelName || BJUI.getRegional('datagrid.cancel'))
10765                                .appendTo($group)
10766                                .on('click', function(e) {
10767                                    that.doCancelEditRow(that.$tbody.find('> tr.'+ that.classnames.tr_edit))
10768                                })
10769                        } else if (n === 'save') {
10770                            that.$toolbar_save = $(btnHtml).attr('data-icon', 'save').addClass('btn-default').text(options.saveName || BJUI.getRegional('datagrid.save'))
10771                                .appendTo($group)
10772                                .on('click', function(e) {
10773                                    that.doSaveEditRow()
10774                                })
10775                        } else if (n === 'del') {
10776                            that.$toolbar_del = $(btnHtml).attr('data-icon', 'times').addClass('btn-red').text(options.delName || BJUI.getRegional('datagrid.del'))
10777                                .appendTo($group)
10778                                .on('click', function(e) {
10779                                    var $selectTrs = that.$tbody.find('> tr.'+ that.classnames.tr_selected)
10780
10781                                    if ($selectTrs.length) {
10782                                        that.delRows($selectTrs)
10783                                    } else {
10784                                        $(this).alertmsg('info', BJUI.getRegional('datagrid.selectMsg'))
10785                                    }
10786                                })
10787                        } else if (n === 'refresh') {
10788                            that.$toolbar_refresh = $(btnHtml).attr('data-icon', 'refresh').addClass('btn-green').text(options.refreshName || BJUI.getRegional('datagrid.refresh'))
10789                                .appendTo($group)
10790                                .on('click', function(e) {
10791                                    that.refresh()
10792                                })
10793                        }
10793 else if (n === 'import') {
10794                            that.$toolbar_add = $(btnHtml).attr('data-icon', 'sign-in').addClass('btn-blue').text(options.importName || BJUI.getRegional('datagrid.import'))
10795                                .appendTo($group)
10796                                .on('click', function(e) {
10797                                    if (options.importOption) {
10798                                        var opts = options.importOption
10799
10800                                        if (typeof opts === 'string')
10801                                            opts = opts.toObj()
10802
10803                                        if (opts.options && opts.options.url) {
10804                                            if (opts.type === 'dialog') {
10805                                                that.$grid.dialog(opts.options)
10806                                            } else if (opts.type === 'navtab') {
10807                                                that.$grid.navtab(opts.options)
10808                                            } else {
10809                                                that.$grid.bjuiajax('doajax', opts.options)
10810                                            }
10811                                        }
10812                                    }
10813                                })
10814                        } else if (n === 'export') {
10815                            that.$toolbar_add = $(btnHtml).attr('data-icon', 'sign-out').addClass('btn-green').text(options.exportName || BJUI.getRegional('datagrid.export'))
10816                                .appendTo($group)
10817                                .on('click', function(e) {
10818                                    if (options.exportOption) {
10819                                        var opts = options.exportOption
10820
10821                                        if (typeof opts === 'string')
10822                                            opts = opts.toObj()
10823
10824                                        if (opts.options && opts.options.url) {
10825                                            if (!opts.options.data)
10826                                                opts.options.data = {}
10827
10828                                            $.extend(opts.options.data, that.$element.data('filterDatas') || {}, that.sortData || {})
10829                                            opts.options.type = 'POST'
10830
10831                                            if (opts.type === 'dialog') {
10832                                                BJUI.dialog(opts.options)
10833                                            } else if (opts.type === 'navtab') {
10834                                                BJUI.navtab(opts.options)
10835                                            } else if (opts.type === 'file') {
10836                                                opts.options.target = that.$boxB
10837                                                BJUI.ajax('ajaxdownload', opts.options)
10838                                            } else {
10839                                                BJUI.ajax('doajax', opts.options)
10840                                            }
10841                                        }
10842                                    }
10843                                })
10844                        } else if (n === 'exportf') {
10845                            that.$toolbar_add = $(btnHtml).attr('data-icon', 'filter').addClass('btn-green').text(options.exportfName || BJUI.getRegional('datagrid.exportf'))
10846                                .appendTo($group)
10847                                .on('click', function(e) {
10848                                    if (options.exportOption) {
10849                                        var opts = options.exportOption, filterDatas = that.tools.getRemoteFilterData(true)
10850
10851                                        if (typeof opts === 'string')
10852                                            opts = opts.toObj()
10853
10854                                        if (opts.options && opts.options.url) {
10855                                            if (!opts.options.data)
10856                                                opts.options.data = {}
10857
10858                                            $.extend(opts.options.data, filterDatas, that.sortData || {})
10859
10860                                            opts.options.type = 'POST'
10861
10862                                            if (opts.type === 'dialog') {
10863                                                BJUI.dialog(opts.options)
10864                                            } else if (opts.type === 'navtab') {
10865                                                BJUI.navtab(opts.options)
10866                                            } else if (opts.type === 'file') {
10867                                                opts.options.target = that.$boxB
10868                                                BJUI.ajax('ajaxdownload', opts.options)
10869                                            } else {
10870                                                BJUI.ajax('doajax', opts.options)
10871                                            }
10872                                        }
10873                                    }
10874                                })
10875                        }
10876                    })
10877                }
10878
10879                if (options.toolbarCustom) {
10880                    var $custom, $custombox = $('<div style="display:inline-block;"></div>')
10881
10882                    if (typeof options.toolbarCustom === 'string') {
10883                        var custom = $(options.toolbarCustom)
10884
10885                        if (custom && custom.length) {
10886                            $custom = custom
10887                        } else {
10888                            custom = custom.toFunc()
10889                            if (custom) {
10890                                $custom = custom.call(that)
10891                                if (typeof $custom === 'string') $custom = $($custom)
10892                            }
10893                        }
10894                    } else if (typeof options.toolbarCustom === 'function') {
10895                        $custom = options.toolbarCustom.call(that)
10896                        if (typeof $custom === 'string') $custom = $($custom)
10897                    } else {
10898                        $custom = options.toolbarCustom
10899                    }
10900
10901                    if ($custom && $custom.length && typeof $custom !== 'string') {
10902                        if (hastoolbaritem) {
10903                            $custombox.css('margin-left', '5px')
10904                        }
10905                        $custombox.appendTo(that.$toolbar)
10906                        $custom.appendTo($custombox)
10907                    }
10908                }
10909
10910                that.$toolbar.initui()
10911            }
10912        }
10913    }
10914
10915    Datagrid.prototype.initThead = function() {
10916        var that = this, options = that.options, tools = that.tools, columnModel = that.columnModel, width, cols = []
10917
10918        that.$tableH.append(that.$thead)
10919
10920        that.init_thead    = true
10921        that.$trsH         = that.$thead.find('> tr')
10922        that.table_width   = 0
10923        that.$colgroupH    = that.$tableH.find('> colgroup')
10924        that.fixtedColumnWidthCount = 0
10925
10926        $.each(that.columnModel, function(i, n) {
10927            var lockWidth = ''
10928
10929            if (n === that.checkboxColumn || n === that.childColumn || n === that.editBtnsColumn || n.finalWidth)
10930                lockWidth = ' class="datagrid_col_lockwidth"'
10931
10932            width = n.width
10933
10934            if ((!width || width === 'auto') && !that.hasAutoCol) {
10935                that.hasAutoCol = true
10936            }
10937
10938            cols.push('<col style="width:'+ (width && width !== 'auto' ? width +'px' : 'auto') +'"'+ lockWidth +'>')
10939            n.width = width
10940        })
10941
10942        that.table_width = that.$grid.width()
10943
10944        that.$colgroupH.html(cols.join(''))
10945
10946        // thead - events
10947        var $ths = that.$trsH.find('> th')
10948        // events - quicksort
10949        $ths.filter('.datagrid-quicksort-th')
10950            .on('click.bjui.datagrid.quicksort', function(e) {
10951                var $target = $(e.target)
10952
10953                if (!$target.closest('.'+ that.classnames.th_cell).length && !that.isResize)
10954                    tools.quickSort(columnModel[$(this).data('index')])
10955            })
10956
10957        // events - filter
10958        $ths.filter('.datagrid-column-menu')
10959            .on('filter.bjui.datagrid.th', function(e, flag) {
10960                var $th = $(this), $btn = $th.find('> div > .'+ that.classnames.th_cell +'> .'+ that.classnames.btn_menu +'> .btn')
10961
10962                if (flag) {
10963                    $th.addClass('filter-active')
10964                    $btn.find('> i').attr('class', 'fa fa-filter')
10965                } else {
10966                    $th.removeClass('filter-active')
10967                    $btn.find('> i').attr('class', 'fa fa-bars')
10968                }
10969            })
10970
10971        // events - contextmenu
10972        if (options.contextMenuH) {
10973            tools.contextmenuH()
10974        }
10975
10976        that.initTbody()
10977
10978        if (options.columnResize) that.colResize()
10979        if (options.columnMenu)   that.colMenu()
10980        if (options.paging)       that.initPaging()
10981        if (options.editMode)     that.edit()
10982        if (options.cellsTitle)   that.cellTitle() //单元格增加title 提示 2019-10-9
10983        if (options.cellsHeight) that.cellsHeight() //表格行高配置 提示 2020-06-10
10984
10985        var delayFunc = function() {
10986            if (options.showTfoot) that.initTfoot()
10987
10988            /* render */
10989            if (that.renderTds && that.renderTds.length) {
10990                var $trs = that.$tbody.find('> tr:not(.'+ that.classnames.tr_child +', .datagrid-nodata)'), j = that.renderTds && that.renderTds.length, fixedWidthModel = {}
10991                var $tempTrs = $(), tempDatas = []
10992
10993                for (var i = 0; i < j; i++) {
10994                    var obj = that.renderTds[i], label = obj.render.call(that, obj.label, obj.data, that.columnModel[obj.tdindex].items, that.columnModel[obj.tdindex].itemattr)
10995                    var tempData = $.extend({}, obj.data)
10996
10997                    if (!fixedWidthModel[obj.tdindex] && that.columnModel[obj.tdindex].fixedWidth)
10998                        fixedWidthModel[obj.tdindex] = that.columnModel[obj.tdindex]
10999
11000                    if (that.isTemplate) {
11001                        var tempData = {}, tempIndex = $.inArray($trs.eq(obj.trindex)[0], $tempTrs)
11002
11003                        if (tempIndex == -1) {
11004                            $tempTrs = $tempTrs.add($trs.eq(obj.trindex))
11005
11006                            tempData = $.extend({}, obj.data)
11007                            tempData[that.columnModel[obj.tdindex]['name']] = label
11008
11009                            tempDatas.push(tempData)
11010                        } else {
11011                            tempDatas[tempIndex][that.columnModel[obj.tdindex]['name']] = label
11012                        }
11013                    } else {
11014                        $trs.eq(obj.trindex).find('> td:eq('+ obj.tdindex +') > div:last').html(label)
11015                    }
11016                }
11017
11018                // for tdTemplate
11019                $.each($tempTrs, function(i) {
11020                    var $td = $(this).find('> td.datagrid-template-td'), html = $td.html()
11021
11022                    if ($td.length) {
11023                        $td.html(tools.replacePlh4Template(html, tempDatas[i]))
11024                    }
11025                })
11026            }
11027
11028            if (that.isTemplate)
11029                that.$grid.data('bjui.datagrid.trs.template', that.$tbody.html())
11030            else
11031                that.$grid.data('bjui.datagrid.trs.normal', that.$tbody.html())
11032
11033            that.initEvents()
11034            that.$tableB.initui()
11035            that.$lockTableB && that.$lockTableB.initui()
11036
11037            tools.setBoxbH()
11038
11039            /* tree - collapse */
11040            if (that.collapseIndex && that.collapseIndex.length) {
11041                that.expand(that.collapseIndex.join(','), false)
11042                that.collapseIndex = null
11043            }
11044
11045            setTimeout(function() {
11046                that.fixedWidth('init')
11047                that.initLock()
11048                that.$element.trigger('completed.bjui.datagrid', {datas:that.data})
11049                that.$boxM && that.$boxM.trigger('bjui.ajaxStop').hide()
11050
11051                if ((that.options.width.endsWith('%') &&
11052                    (that.options.flowLayoutWidth && that.$grid.width() < that.options.flowLayoutWidth)
11053                    || that.options.dialogFilterW && that.$grid.width() < that.options.dialogFilterW)
11054                    || that.options.dialogFilterW === 0) {
11055                    $(window).resize()
11056                }
11057
11058                that.resizeGrid()
11059            }, 50)
11060
11061            that.delayFilterTimeout && clearInterval(that.delayFilterTimeout)
11062        }
11063
11064        if (options.filterThead) {
11065            if (that.delayRender) {
11066                that.delayFilterTimeout = setInterval(function() {
11067                    if (!that.delayRender) {
11068                        that.filterInThead()
11069                        delayFunc()
11070                    }
11071                }, 100)
11072            } else {
11073                that.filterInThead()
11074                delayFunc()
11075            }
11076        } else {
11077            delayFunc()
11078        }
11079    }
11080
11081    Datagrid.prototype.fixedWidth = function(isInit) {
11082        var that = this, options = that.options, bW, excludeW = 0, fixedW, columnModel = that.columnModel, length = columnModel.length
11083
11084        if (isInit && that.initFixedW) return
11085        that.initFixedW = true
11086
11087        var setNewWidth = function() {
11088            if (String(that.options.width).endsWith('%'))
11089                that.$grid.css('width', '')
11090
11091            that.$boxH.find('> div').css('width', '')
11092            that.$boxB.find('> div').css('width', '')
11093            that.$boxF && that.$boxF.find('> div').css('width', '')
11094            that.$boxP && that.$boxP.find('> div.paging-content').css('width', '')
11095
11096            bW = (that.$boxB.find('> div'))[0].clientWidth
11097
11098            if (that.options.hasChild) {
11099                var scrollTop = that.$boxB.scrollTop()
11100
11101                that.$boxB.scrollTop(1)
11102
11103                if (that.$boxB.scrollTop()) {
11104                    that.$boxB.scrollTop(scrollTop)
11105                }
11106            }
11107            if (that.$element.hasClass('table-child'))
11108                bW = bW - 18
11109
11110            that.$boxB.find('> div').width(bW)
11111            that.$boxH.find('> div').width(bW)
11112            that.$boxF && that.$boxF.find('> div').width(bW)
11113
11114            if (that.table_width > bW || options.fullGrid)
11115                that.$boxP && that.$boxP.find('> div.paging-content').width(bW)
11116            else
11117                that.$boxP && that.$boxP.find('> div.paging-content').width(that.table_width)
11118
11119            if (options.fullGrid || that.isTemplate || that.needfixedWidth || (that.hasAutoCol && isInit)) {
11120                $('body').find('> .bjui-datagrid').remove()
11121
11122                var oldTheight = that.$tableH.height(),
11123                    $grid = $('<div class="bjui-datagrid forwidth"></div>'),
11124                    $tableB = that.$element.clone().addClass('table table-bordered').appendTo($grid)
11125
11126                $tableB.find('> tbody').before(that.$thead.clone())
11127
11128                $tableB.find('> colgroup > col').each(function(i) {
11129                    var $col = $(this), dataLength = that.data.length ? String(that.data[that.data.length - 1].gridNumber).length : 2
11130
11131                    if ($col.hasClass('datagrid_col_lockwidth')) return true
11132                    if (columnModel[i] === that.linenumberColumn) {
11133                        dataLength == 1 && (dataLength = 2)
11134                        $col.width(dataLength * 15)
11135                    } else if (!columnModel[i].width || columnModel[i].width === 'auto' || that.isTemplate)
11136                        $col.width('')
11137                })
11138
11139                $grid.width(bW + 17).height(that.$boxB.height()).prependTo($('body'))
11140
11141                if (!(options.fullGrid || that.isTemplate) && options.hScrollbar) {
11142                    $grid.width('')
11143                }
11144
11145                if (that.isTemplate)
11146                    options.tableWidth = '100%'
11147
11148                $tableB.attr('style', 'width:'+ (options.tableWidth || 'auto') +' !important;')
11149                $tableB.find('thead th > div').height('')
11150
11151                var $tr = $tableB.find('> tbody > tr:first')
11152
11153                if (!$tr.length || that.isTemplate || $tr.hasClass('datagrid-nodata')) {
11154                    var trHtml = BJUI.StrBuilder()
11155
11156                    t
11156rHtml.add('<tr>')
11157
11158                    for (var i = 0, j = $tableB.find('colgroup > col').length; i < j; i++) {
11159                        trHtml.add('<td></td>')
11160                    }
11161
11162                    trHtml.add('</tr>')
11163
11164                    $tableB.find('> tbody').prepend(trHtml.toString())
11165                    $tr = $tableB.find('> tbody > tr:first')
11166                }
11167
11168                if (that.isTemplate) {
11169                    that.$boxP && that.$boxP.find('> div.paging-content').width('100%')
11170                }
11171
11172                var $ths = that.$thead.find('th')
11173
11174                $tableB.find('thead > tr:not(.datagrid-filter) > th').each(function(i) {
11175                    var $this = $(this), v = $this.is(':hidden')
11176
11177                    if (v) $this.show()
11178                    $ths.eq(i).find('> div').height($this.find('> div').height())
11179                    if (v) $this.hide()
11180                })
11181
11182                that.$boxB.height(that.$boxB.height() + (oldTheight - $tableB.find('> thead').height()))
11183                that.$boxM && that.$boxM.height(that.$boxB.height()).css('top', that.$boxB.position().top)
11184                that.$lockB && that.$lockB.height(that.$boxB.height())
11185
11186                $tr.find('> td').each(function(i) {
11187                    var $col = that.$colgroupB.find('> col:eq('+ i +')')
11188
11189                    !($col.hasClass('datagrid_col_lockwidth')) && $col.width($(this).outerWidth())
11190                })
11191
11192                that.$colgroupH.html(that.$colgroupB.html())
11193
11194                if (!that.options.noremove)
11195                    $grid.remove()
11196            }
11197        }
11198
11199        setNewWidth()
11200    }
11201
11202    Datagrid.prototype.fixedHeight = function(height) {
11203        var that = this, options = that.options
11204
11205        if (options.height === 'auto') {
11206            that.boxH = 'auto'
11207            that.$grid.css('height', '')
11208            that.$boxB.css('height', '')
11209            that.tools.setBoxbH()
11210        } else
11211            that.tools.setBoxbH(height)
11212
11213        // if scrollLeft
11214        var scrollLeft = that.$boxB.scrollLeft()
11215
11216        that.$boxB.scrollLeft(5)
11217
11218        if (that.$boxB.scrollLeft()) {
11219            that.fixedWidth()
11220            that.$boxB.scrollLeft(scrollLeft)
11221        }
11222    }
11223
11224    Datagrid.prototype.initTbody = function() {
11225        var that = this, options = that.options, tools = that.tools, $trs = that.$tbody.find('> tr'), $tds = $trs.find('> td'), width = options.tableWidth || '0'
11226
11227        that.init_tbody = true
11228        that.$colgroupB = that.$colgroupH.clone()
11229
11230        that.$tableB.prepend(that.$colgroupB)
11231
11232        if (options.fullGrid || that.isTemplate) width = '100%'
11233
11234        that.$tableH.css('width', width)
11235        that.$tableB.css('width', width)
11236
11237        // add class
11238        that.$tableB.removeAttr('data-toggle width').addClass('table table-bordered').removeClass('table-hover')
11239
11240        that.$boxB
11241            .scroll(function() {
11242                that.$boxH.find('> div').prop('scrollLeft', this.scrollLeft)
11243                that.$boxF && that.$boxF.find('> div').prop('scrollLeft', this.scrollLeft)
11244                that.$lockB && that.$lockB.prop('scrollTop', this.scrollTop)
11245            })
11246
11247        // if DOM to datagrid
11248        if (that.isDom) {
11249            if (options.showLinenumber) {
11250                that.showLinenumber(options.showLinenumber)
11251            }
11252            if (options.showCheckboxcol) {
11253                that.showCheckboxcol(options.showCheckboxcol)
11254            }
11255            if (options.showEditbtnscol) {
11256                that.showEditCol(options.showEditbtnscol)
11257            }
11258
11259            that.$grid.data(that.datanames.tbody, that.$tbody.clone())
11260        }
11261    }
11262
11263    // init events(only tbody)
11264    Datagrid.prototype.initEvents = function($trs) {
11265        var that = this, options = that.options, trs = that.$tbody.find('> tr')
11266
11267        if (!$trs) $trs = trs;
11268        $trs.on('click.bjui.datagrid.tr', function(e, checkbox) {
11269            var $tr = $(this), index = $tr.index(), data, $selectedTrs = that.$tbody.find('> tr.'+ that.classnames.tr_selected), $last = that.$lastSelect, checked, $lockTrs = that.$lockTbody && that.$lockTbody.find('> tr');
11270            if (that.options.isTree) {//树结构选择 2021-02-18
11271                that.selectedChildrens($tr,index,e,checkbox);
11272            }
11273            // else{
11274            if (checkbox) {
11275                checked = checkbox.is(':checked')
11276                if (!checked) that.$lastSelect = $tr
11277                that.selectedRows($tr, !checked)
11278            } else {
11279                if ($tr.hasClass(that.classnames.tr_edit)) return
11280                if (options.selectMult) {
11281                    that.selectedRows($tr)
11282                } else {
11283                    // if (!BJUI.KeyPressed.ctrl && !BJUI.KeyPressed.shift) {// 删除 Datagrid中选中行时的 shift、ctrl配置 2020-04-14
11284                    if (true) {
11285                        if ($selectedTrs.length > 1 && $tr.hasClass(that.classnames.tr_selected)) {
11286                            that.selectedRows($selectedTrs.not($tr))
11287                            that.$lastSelect = $tr
11288                        } else {
11289                            if ($selectedTrs.length && $selectedTrs[0] != this) that.selectedRows(null)
11290                            if (!$tr.hasClass(that.classnames.tr_selected)) that.$lastSelect = $tr
11291                            that.selectedRows($tr)
11292                        }
11293                    } else {
11294                        //window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty() //clear selection
11295
11296                        if (BJUI.KeyPressed.ctrl) {
11297                            if (!$tr.hasClass(that.classnames.tr_selected)) that.$lastSelect = $tr
11298                            that.selectedRows($tr)
11299                        } else if (BJUI.KeyPressed.shift) {
11300                            if (!$last) $last = that.$lastSelect = $tr
11301                            if ($last.length) {
11302                                that.selectedRows(null)
11303                                if ($last.index() != index) {
11304                                    if ($last.index() > index) {
11305                                        that.selectedRows($tr.nextUntil($last).add($tr).add($last), true)
11306                                    } else {
11307                                        that.selectedRows($tr.prevUntil($last).add($tr).add($last), true)
11308                                    }
11309                                } else {
11310                                    that.selectedRows(index)
11311                                }
11312                            }
11313                        }
11314                    }
11315                }
11316            }
11317
11318            if (that.isDom)
11319                data = that.tools.setDomData($tr)
11320            else
11321                data = that.data[that.tools.getNoChildDataIndex(index)]
11322
11323            that.$element.trigger('clicked.bjui.datagrid.tr', {target:e.target, tr:$tr, data:data})
11324            // }
11325        })
11326            .on('contextmenu.bjui.datagrid.tr', function (e) {//右键行方法配置 2020-12-01
11327                var $tr = $(this), index = $tr.index(), data;
11328                data = that.data[that.tools.getNoChildDataIndex(index)];
11329                // that.tools.contextMenuSys($tr, data);
11330                var contextMenuSys = options.contextMenuSys;
11331                if (contextMenuSys) {
11332                    if (typeof contextMenuSys === 'string') contextMenuSys = contextMenuSys.toFunc()
11333                    if (typeof contextMenuSys === 'function') {
11334                        contextMenuSys.call(that, $tr, data)
11335                    }
11336                }
11337                e.preventDefault();
11338                e.stopPropagation();
11339            })
11340            .on('dblclick.bjui.datagrid.tr', function (e) {//双击行方法配置 2020-12-28
11341                var $tr = $(this), index = $tr.index(), data;
11342                data = that.data[that.tools.getNoChildDataIndex(index)];
11343                var dblClickSys = options.dblClickSys;
11344                if (dblClickSys) {
11345                    if (typeof dblClickSys === 'string') dblClickSys = dblClickSys.toFunc()
11346                    if (typeof dblClickSys === 'function') {
11347                        dblClickSys.call(that, $tr, data)
11348                    }
11349                }
11350            })
11351            .on('mouseenter.bjui.datagrid', function(e) {
11352                var $tr = $(this), index = $tr.index()
11353
11354                if (that.isDrag) return false
11355
11356                $tr.addClass('datagrid-hover')
11357                that.$lockTbody && that.$lockTbody.find('> tr:eq('+ index +')').addClass('datagrid-hover')
11358            })
11359            .on('mouseleave.bjui.datagrid', function(e) {
11360                var $tr = $(this), index = $tr.index()
11361
11362                if (that.isDrag) return false
11363
11364                $tr.removeClass('datagrid-hover')
11365                that.$lockTbody && that.$lockTbody.find('> tr:eq('+ index +')').removeClass('datagrid-hover')
11366            })
11367            // custom event - delete
11368            .on('delete.bjui.datagrid.tr', function(e) {
11369                e.stopPropagation()
11370
11371                var $tr = $(this), tr_index = $tr.index(), data_index = tr_index, data = that.data, gridIndex, allData = that.allData, $lockTrs = that.$lockTbody && that.$lockTbody.find('> tr')
11372
11373                if ($tr.hasClass('datagrid-nodata')) return false
11374
11375                if (that.options.hasChild && that.options.childOptions) {
11376                    data_index = data_index / 2
11377
11378                    // remove child dom
11379                    $tr.next().remove()
11380                    $lockTrs && $lockTrs.eq(tr_index).next().remove()
11381                }
11382
11383                /* remove tree - child */
11384                if (that.options.isTree) {
11385                    var $childrens = that.getChildrens($tr, null, true), len = $childrens.length
11386
11387                    if (that.options.hasChild && that.options.childOptions)
11388                        len = len / 2
11389
11390                    $childrens.remove()
11391
11392                    if (!that.isDom) {
11393                        gridIndex    = data[data_index].gridIndex
11394
11395                        that.data.splice(data_index + 1, len)
11396                        that.allData.splice(gridIndex + 1, len)
11397                    }
11398                }
11399
11400                if (!that.isDom) {
11401                    gridIndex    = data[data_index].gridIndex
11402                    that.data    = data.remove(data_index)     // remove data in the current page data
11403                    that.allData = allData.remove(gridIndex)   // remove data in allData
11404                    that.tools.updateGridIndex()
11405                }
11406
11407                /* update gridNumber */
11408                if ($.inArray(that.linenumberColumn, that.columnModel) != -1) {
11409                    $tr.nextAll(':not(.'+ that.classnames.tr_child +')').each(function() {
11410                        var $td = $(this).find('> td.'+ that.classnames.td_linenumber), num = parseInt($td.text(), 10)
11411
11412                        $td.text(num - 1)
11413                    })
11414
11415                    $lockTrs && $lockTrs.eq(tr_index).trigger('delete.bjui.datagrid.tr', [tr_index])
11416                }
11417
11418                // remove dom
11419                $tr.remove()
11420                $lockTrs && $lockTrs.eq(tr_index).remove()
11421
11422                // no data
11423                that.tools.createNoDataTr()
11424            })
11425
11426        // child
11427        that.$grid.off('click.bjui.datagrid.tr.child').on('click.bjui.datagrid.tr.child', 'td.'+ that.classnames.td_child, function(e) {
11428            e.stopPropagation()
11429
11430            var $this = $(this), $tr = $this.closest('tr'), $child = $tr.next('.'+ that.classnames.tr_child)
11431
11432            if ($child && $child.length)
11433                that.showChild($tr, !$child.is(':visible'))
11434        })
11435            // td checkbox
11436            .off('ifClicked').on('ifClicked', 'td.'+ that.classnames.td_checkbox +' input', function(e) {
11437            e.stopPropagation()
11438
11439            var $this = $(this), $tr = $this.closest('tr'), tr_index = $tr.index()
11440
11441            that.$tbody.find('> tr:eq('+ tr_index +')').trigger('click.bjui.datagrid.tr', [$this])
11442        })
11443            // th checkbox - check all
11444            .off('ifChanged').on('ifChanged', 'th.'+ that.classnames.td_checkbox +' input', function(e) {
11445            e.stopPropagation()
11446
11447            var checked = $(this).is(':checked'), $trs = that.$tbody.find('> tr:not(".'+ that.classnames.tr_child +'")')
11448
11449            that.selectedRows($trs, checked)
11450        })
11451
11452
11453        //contextmenu
11454        if (options.contextMenuB) {
11455            $trs.each(function() {
11456                that.tools.contextmenuB($(this))
11457            })
11458        }
11459
11460        if (!commonBlank(options.contextMenuList)) {//开启右键菜单配置 2020-12-01
11461            var mentList=[];
11462            $.each(options.contextMenuList, function (i, item) {
11463                mentList[i] = {'title':item.title,'func':item.method,'icon':item.icon}
11464            })
11465            $trs.each(function () {
11466                that.tools.contextMenuListM($(this),mentList)
11467            })
11468        }
11469
11470        // custom update
11471        that.$tableB.off('click.bjui.datagrid.refresh').on('click.bjui.datagrid.refresh', 'tbody > tr > td [data-toggle="update.datagrid.tr"]', function(e) {
11472            e.stopPropagation()
11473            e.preventDefault()
11474
11475            that.updateRow($(this).closest('tr'))
11476        })
11477            // custom edit
11478            .off('click.bjui.datagrid.edit').on('click.bjui.datagrid.edit', 'tbody > tr > td [data-toggle="edit.datagrid.tr"]', function(e) {
11479            e.stopPropagation()
11480            e.preventDefault()
11481
11482            var $this = $(this), opts = $this.data('options'), $tr = $this.closest('tr')
11483
11484            if (opts && typeof opts === 'string') opts = opts.toObj()
11485
11486            if (typeof opts === 'object')
11487                that.externalEdit($tr, opts)
11488            else
11489                that.doEditRow($tr)
11490        })
11491            // custom ajax
11492            .off('click.bjui.datagrid.ajax').on('click.bjui.datagrid.ajax', 'tbody > tr > td [data-toggle="ajax.datagrid.tr"]', function(e) {
11493            e.stopPropagation()
11494            e.preventDefault()
11495
11496            var $this = $(this), opts = $this.data()
11497
11498            if (opts.options && typeof opts.options === 'string') opts.options = opts.options.toObj()
11499            $.extend(opts, typeof opts.options === 'object' && opts.options)
11500
11501            if (!opts.url && $this.attr('href'))
11502                opts.url = $this.attr('href')
11503
11504            that.doAjaxRow($this.closest('tr'), opts)
11505        })
11506            // custom addChild
11507            .off('click.bjui.datagrid.addchild').on('click.bjui.datagrid.addchild', 'tbody > tr > td [data-toggle="addchild.datagrid.tr"]', function(e) {
11508            e.stopPropagation()
11509            e.preventDefault()
11510
11511            var $this = $(this), $tr = $this.closest('tr'), $table = $tr.data('bjui.datagrid.child'), $child = $tr.next('.'+ that.classnames.tr_child), trData, data = $this.data('addData'), addData,
11512                replaceData = function(data) {
11513                    return data.replace(/#\/?[^#]*#/g, function($1) {
11514                        var key = $1.replace(/[##]+/g, ''), val = trData[key]
11515
11516                        if (typeof val === 'undefined' || val === 'null' || val === null)
11517                            val = ''
11518
11519                        return val
11520                    })
11521                },
11522                doAdd = function($table) {
11523                    if (data) {
11524                        if (typeof data === 'string') {
11525                            data = replaceData(data)
11526
11527                            if (data.trim().startsWith('{'))
11528                                data = data.toObj()
11529                            else
11530                                data = data.toFunc()
11531                        } else {
11532                            if (typeof data === 'function') {
11533                                data = data.toFunc()
11534                            }
11535                            if (typeof data === 'object') {
11536                                data = JSON.stringify(data)
11537                            }
11538
11539                            data = replaceData(data).toObj()
11540                        }
11541
11542                        if (typeof data === 'object') {
11543                            addData = data
11544                        }
11545                    }
11546
11547                    $table.datagrid('add', false, addData)
11548                }
11549
11550            if ($child && $child.length) {
11551                if (that.isDom) trData = $tr.data('initData') || tools.setDomData($tr)
11552                else trData = that.data[that.tools.getNoChildDataIndex($tr.index())]
11553
11554                if ($table && $table.length) {
11555                    doAdd($table)
11556                } else {
11557                    that.showChild($tr, true, doAdd)
11558                }
11559            }
11560        })
11561            // custom delete
11562            .off('click.bjui.datagrid.del').on('click.bjui.datagrid.del', 'tbody > tr > td [data-toggle="del.datagrid.tr"]', function(e) {
11563            e.stopPropagation()
11564            e.preventDefault()
11565
11566            that.delRows($(this).closest('tr'))
11567        })
11568            // tree expand || collapse
11569            .off('click.bjui.datagrid.tree').on('click.bjui.datagrid.tree', 'tbody > tr > td .datagrid-tree-switch', function(e) {
11570            e.stopPropagation()
11571            e.preventDefault()
11572
11573            var $t = $(this), $tr = $t.closest('tr'), childLen = $tr.data('child'), level = $tr.data('level'), isExpand = !$t.hasClass('collapsed')
11574
11575            if (childLen) {
11576                $tr.data('isExpand', !isExpand)
11577                    .nextAll('.datagrid-tree-level-'+ (level + 1)).slice(0, childLen).toggleClass('collapsed', isExpand).trigger('switch.child.bjui.datagrid.tree', {isExpand:isExpand})
11578                $t.toggleClass('collapsed', isExpand).find('> i').attr('class', 'fa '+ (isExpand ? 'fa-plus-square-o' : 'fa-minus-square-o'))
11579            }
11580
11581            if (options.height === 'auto') {
11582                that.fixedHeight()
11583            }
11584        })
11585            .off('switch.child.bjui.datagrid.tree').on('switch.child.bjui.datagrid.tree', 'tbody > tr', function(e, data) {
11586            e.stopPropagation()
11587            e.preventDefault()
11588
11589            var $tr = $(this), childLen = $tr.data('child'), level = $tr.data('level')
11590
11591            if (childLen) {
11592                $tr.nextAll('.datagrid-tree-level-'+ (level + 1)).slice(0, childLen)
11593                    .toggleClass('collapsed-child', data[that.options.treeOptions.isExpand])
11594                    .trigger('switch.child.bjui.datagrid.tree', {isExpand:data[that.options.treeOptions.isExpand]})
11595            }
11596        })
11597            .off('expand.bjui.datagrid.tree').on('expand.bjui.datagrid.tree', 'tbody > tr', function(e) {
11598            e.stopPropagation()
11599            e.preventDefault()
11600
11601            var $tr = $(this).data('isExpand', true), $t = $tr.find('> td.datagrid-tree-td .datagrid-tree-switch')
11602
11603            if (!$t || !$t.length || !$t.hasClass('collapsed')) return false
11604
11605            $t.trigger('click.bjui.datagrid.tree')
11606
11607            if (options.height === 'auto') {
11608                that.fixedHeight()
11609            }
11610        })
11611            .off('collapse.bjui.datagrid.tree').on('collapse.bjui.datagrid.tree', 'tbody > tr', function(e) {
11612            e.stopPropagation()
11613            e.preventDefault()
11614
11615            var $tr = $(this).data('isExpand', false), $t = $tr.find('> td.datagrid-tree-td .datagrid-tree-switch')
11616
11617            if (!$t || !$t.length || $t.hasClass('collapsed')) return false
11618
11619            $t.trigger('click.bjui.datagrid.tree')
11620
11621            if (options.height === 'auto') {
11622                that.fixedHeight()
11623            }
11624        })
11625            // tree add btn
11626            .off('mouseover.bjui.datagrid.tree').on('mouseover.bjui.datagrid.tree', 'tbody > tr > td.datagrid-tree-td', function(e) {
11627            e.stopPropagation()
11628            e.preventDefault()
11629
11630            if (!options.treeOptions.add || that.isDrag)
11631                return false
11632
11633            var $td = $(this), $tr = $td.closest('tr'), $add = $td.find('.datagrid-tree-add')
11634
11635            if (!$add || !$add.length)
11636                $td.find('> div').append('<a href="javascript:;" class="datagrid-tree-add" data-toggle="add.datagrid.tree" title="添加"><i class="fa fa-plus-circle"></i></a>')
11637            else
11638                $add.show()
11639        })
11640            .off('mouseout.bjui.datagrid.tree').on('mouseout.bjui.datagrid.tree', 'tbody > tr > td.datagrid-tree-td', function(e) {
11641            e.stopPropagation()
11642            e.preventDefault()
11643
11644            if (!options.treeOptions.add || that.isDrag)
11645                return false
11646
11647            var $td = $(this), $add = $td.find('.datagrid-tree-add')
11648
11649            if ($add && $add.length)
11650                $add.hide()
11651        })
11652            // tree add
11653            .off('click.bjui.datagrid.tree.add').on('click.bjui.datagrid.tree.add', 'tbody > tr > td.datagrid-tree-td [data-toggle="add.datagrid.tree"]', function(e) {
11654            e.stopPropagation()
11655            e.preventDefault()
11656
11657            var $add = $(this), $tr = $add.closest('tr'), opts = $add.data()
11658
11659            if (opts.addData) {
11660                if (typeof opts.addData === 'string')
11661                    opts.addData = opts.addData.toObj()
11662            }
11663
11664            that.addTree($tr, opts.addLocation || '', opts.addData || {})
11665        })
11666
11667        if (options.dropOptions.drop) {
11668            var $trs = that.$tbody.find('> tr:not(.'+ that.classnames.tr_child +')'), beforeDrag = options.dropOptions.beforeDrag
11669
11670            if (typeof beforeDrag === 'string')
11671                beforeDrag = beforeDrag.toFunc()
11672
11673            if (typeof beforeDrag !== 'function')
11674                beforeDrag = false
11675
11676            $trs
11677                .basedrag('destroy')
11678                .basedrag({
11679                    exclude: 'input, button, a, .bjui-lookup, .datagrid-tree-switch, .datagrid-tree-add, .datagrid-child-td',
11680                    drop: $trs,
11681                    container : that.$boxB,
11682                    beforeDrag: beforeDrag,
11683                    treeData: that.data,
11684                    drag: function() {
11685                        that.isDrag = true
11686                    },
11687                    stop: function() {
11688                        that.isDrag = false
11689
11690                        $(this).find('> td.datagrid-tree-td').trigger('mouseout.bjui.datagrid.tree')
11691                    }
11692                })
11693                .off('dropover.bjui.basedrag').on('dropover.bjui.basedrag', function(e, x, y, target) {
11694                trs.removeClass('datagrid-hover datagrid-drop-over-after datagrid-drop-over-before').find('.datagrid-tree-box').removeClass('datagrid-drop-over-append')
11695
11696                if (this === target[0] || target.hasClass(that.classnames.tr_edit)) {
11697                    return false
11698                }
11699                if (that.options.isTree) {
11700                    var $childrens = that.getChildrens(target)
11701
11702                    if ($.inArray(this, $childrens) !== -1)
11703                        return false
11704                }
11705
11706                var $this = $(this).addClass('datagrid-hover'), height = $this.outerHeight() / 2, top = $this.offset().top
11707
11708                if (that.options.isTree)
11709                    height = 5
11710
11711                if (y < (top + height)) {
11712                    $this.addClass('datagrid-drop-over-before').prevAll(':visible:first').addClass('datagrid-drop-over-after')
11713                } else {
11714                    if (!that.options.isTree || (that.options.isTree && y > (top + $this.outerHeight() - height)))
11715                        $this.addClass('datagrid-drop-over-after')
11716                    else if (that.options.isTree) {
11717                        $this.find('.datagrid-tree-box').addClass('datagrid-drop-over-append')
11718                    }
11719                }
11720            })
11721                .off('dropout.bjui.basedrag').on('dropout.bjui.basedrag', function(e, data) {
11722                $trs.removeClass('datagrid-hover datagrid-drop-over-after datagrid-drop-over-before')
11723                $trs.find('div.datagrid-drop-over-append').removeClass('datagrid-drop-over-append')
11724            })
11725                .off('drop.bjui.basedrag').on('drop.bjui.basedrag', function(e, target) {
11726                var $this = $(this), position, beforeDrop = options.dropOptions.beforeDrop, afterDrop = options.dropOptions.afterDrop
11727
11728                that.afterDrop = false
11729
11730                if ($this.hasClass('datagrid-drop-over-before'))
11731                    position = 'top'
11732                else if ($this.hasClass('datagrid-drop-over-after'))
11733                    position = 'bottom'
11734                else if (that.options.isTree && $this.find('.datagrid-tree-box').hasClass('datagrid-drop-over-append'))
11735                    position = 'append'
11736
11737                if (position) {
11738                    if (position != 'append')
11739                        that.insertTr(target, $this, position)
11740                    else {
11741                        var $parents = that.getParents(target, null, true)
11742
11743                        if ($.inArray(this, $parents) !== -1) {
11744                            $this.find('.datagrid-tree-box').removeClass('datagrid-drop-over-append')
11745
11746                            return false
11747                        }
11748
11749                        that.appendTr(target, $this)
11750                    }
11751                }
11752
11753                $trs.removeClass('datagrid-drop-over-after datagrid-drop-over-before').find('.datagrid-tree-box').removeClass('datagrid-drop-over-append')
11754
11755                if (afterDrop && that.afterDrop) {
11756                    if (typeof afterDrop === 'function') {
11757                        afterDrop.apply(that, [target, $this])
11758                    } else if (options.dropOptions.dropUrl) {
11759                        var postData = {pageSize:that.paging.pageSize, pageCurrent:that.paging.pageCurrent}, type = options.editType, opts = {url:options.dropOptions.dropUrl, type:'POST', reload:false}
11760
11761                        postData['list'] = []
11762
11763                        $.each(that.data, function(i, data) {
11764                            var _data = $.extend({}, data)
11765
11766                            if (options.dropOptions.scope !== 'drop' || data[options.keys.dropFlag]) {
11767                                for (var key in options.keys)
11768                                    delete _data[options.keys[key]]
11769                            }
11770                            if (options.dropOptions.scope === 'drop') {
11771                                if (data[options.keys.dropFlag]) {
11772                                    postData['list'].push(_data)
11773                                }
11774                            } else {
11775                                postData['list'].push(_data)
11776                            }
11777                        })
11778
11779                        if (postData) {
11780                          
11780  postData = JSON.stringify(options.dropOptions.paging && options.paging ? postData : postData['list'])
11781
11782                            if (type && type === 'raw') {
11783                                opts.data = postData
11784                                opts.contentType = 'application/json'
11785                            } else {
11786                                opts.data = {json:postData}
11787                                type && (opts.type = type)
11788                            }
11789
11790                            BJUI.ajax('doajax', opts)
11791                        }
11792                    }
11793                }
11794            })
11795        }
11796    }
11797    /**
11798     * 表格树的行选中 2021-02-18
11799     * @param $tr:当前行
11800     * @param index:当选行索引
11801     * @param checkbox: 是否为复选*/
11802    Datagrid.prototype.selectedChildrens=function($tr,index,e,checkbox){
11803        var that = this, options = that.options, trs = that.$tbody.find('> tr');
11804        var data, checked, $childrens;
11805        if (that.isDom){
11806            data = that.tools.setDomData($tr)
11807        }else {
11808            data = that.data[that.tools.getNoChildDataIndex(index)];
11809        }
11810        if(data.isparent!=undefined && data.isparent!=null && data.isparent!=false && checkbox){
11811            checked = checkbox.is(':checked');
11812            $childrens = that.getChildrens($tr, null, true);
11813
11814            $.each($childrens,function(index,item){
11815                var childData= that.getChildrens($(item), null, true);
11816                if(childData.length>0){//存在子节点
11817                    that.selectedChildrensAll(childData, !checked);
11818                }
11819            })
11820            that.selectedRows($childrens, !checked);
11821        }
11822        that.$element.trigger('clicked.bjui.datagrid.tr', {target:e.target, tr:$tr, data:data})
11823    }
11824    /**
11825     * 表格树的行选中 2021-02-18
11826     * 选中子节点*/
11827    Datagrid.prototype.selectedChildrensAll=function(childData,checked){
11828        var that=this;
11829        this.selectedRows(childData, checked);
11830        $.each(childData,function(index,item){
11831            var childData= that.getChildrens($(item), null, true);//获取子节点
11832            if(childData.length>0){
11833                that.selectedChildrensAll(childData,checked);
11834            }
11835        })
11836
11837    }
11838    //取某行数据 rows为行数,从0开始 修改于-2018-05-31 begin
11839    Datagrid.prototype.dataRows = function(rows) {
11840        var that = this
11841        var $trs = that.$tbody.find('> tr').eq(rows), datas = []
11842
11843        $trs.each(function() {
11844            var $tr = $(this), data_index = $tr.index(), data
11845
11846            data_index = that.tools.getNoChildDataIndex(data_index)
11847
11848            if (that.isDom) data = $tr.data('initData') || that.tools.setDomData($tr)
11849            else data = that.data[data_index]
11850
11851            datas.push(data)
11852        })
11853        //取某行数据
11854        that.$element.data('trs', $trs).data("dataRow",datas)
11855    }
11856    //取某行数据 rows为行数,从0开始 修改于-2018-05-31 end
11857
11858    //取新增、修改编辑行的值  -- 2020-08-17
11859    Datagrid.prototype.getEditData = function($trs) {
11860        var that = this, options = that.options, keys = options.keys, callback = options.editCallback, $tr, data,
11861            data_index, datas = [], changeData, tempData, postData = [], returnData = [], len = $trs && $trs.length
11862
11863        if (!$trs || $trs.length) {
11864            $trs = that.$tbody.find('> tr.' + that.classnames.tr_edit)
11865            len = $trs.length
11866        }
11867
11868        if (!len) return
11869
11870        $trs.each(function () {
11871            $tr = $(this)
11872
11873            data_index = that.tools.getNoChildDataIndex($tr.index())
11874            data = that.isDom ? $tr.data('initData') : that.data[data_index]
11875            datas.push(data)
11876            that.$element.data('trs', $trs).data('getEditData', datas)
11877            $tr.isValid(function (v) {
11878                if (v) {
11879                    // Update data
11880                    changeData = $tr.data(that.datanames.changeData)
11881                    $.extend(data, changeData)
11882                    // Specification post data
11883                    if (options.jsonPrefix) {
11884                        tempData = {}
11885
11886                        $.each(data, function (name, value) {
11887                            if (!that.tools.isGridData(name))
11888                                tempData[options.jsonPrefix + '.' + name] = value
11889                        })
11890                    } else {
11891                        tempData = $.extend({}, data)
11892
11893                        for (var key in keys)
11894                            delete tempData[keys[key]]
11895                    }
11896
11897                    len--
11898                    postData.push(tempData)
11899                } else {
11900                    postData = []
11901                    return false
11902                }
11903            })
11904        })
11905    }
11906    //取删除行的值 -- 2020-08-17
11907    Datagrid.prototype.getDelData = function($trs) {
11908        var that = this, options = that.options, keys = options.keys, callback = options.editCallback, $tr, data,
11909            data_index, datas = [], changeData, tempData, postData = [], returnData = [], len = $trs && $trs.length
11910
11911        if (!$trs || $trs.length) {
11912            $trs = that.$tbody.find('> tr.datagrid-del-tr')
11913            len = $trs.length
11914        }
11915        if (!len) return
11916
11917        $trs.each(function () {
11918            $tr = $(this)
11919            data_index = that.tools.getNoChildDataIndex($tr.index())
11920            data = that.isDom ? $tr.data('initData') : that.data[data_index]
11921            datas.push(data)
11922            that.$element.data('trs', $trs).data('getDelData', datas)
11923        })
11924        $tr.isValid(function (v) {
11925            if (v) {
11926                // Update data
11927                changeData = $tr.data(that.datanames.changeData)
11928                $.extend(data, changeData)
11929                // Specification post data
11930                if (options.jsonPrefix) {
11931                    tempData = {}
11932
11933                    $.each(data, function (name, value) {
11934                        if (!that.tools.isGridData(name))
11935                            tempData[options.jsonPrefix + '.' + name] = value
11936                    })
11937                } else {
11938                    tempData = $.extend({}, data)
11939
11940                    for (var key in keys)
11941                        delete tempData[keys[key]]
11942                }
11943
11944                len--
11945                postData.push(tempData)
11946            } else {
11947                postData = []
11948                return false
11949            }
11950        })
11951    }
11952    Datagrid.prototype.getChildrens = function(tr, childrens, hasChild, maxLevel) {
11953        var that = this, childLen = tr.data('child'), level = tr.data('level')
11954
11955        if (maxLevel) maxLevel --
11956        if (!childrens) childrens = $()
11957        if (childLen) {
11958            tr.nextAll('.datagrid-tree-level-'+ (level + 1)).slice(0, childLen).each(function() {
11959                childrens = childrens.add(this)
11960
11961                if (hasChild && $(this).next().hasClass(that.classnames.tr_child))
11962                    childrens = childrens.add($(this).next())
11963
11964                if (maxLevel)
11965                    childrens = childrens.add(that.getChildrens($(this), childrens, hasChild, maxLevel))
11966            })
11967        }
11968
11969        return childrens
11970    }
11971
11972    Datagrid.prototype.getParents = function(tr, parents, onlyParent, hasChild) {
11973        var that = this, level = tr.data('level'), prev
11974
11975        if (!parents) parents = $()
11976        if (level) {
11977            prev = tr.prevAll('.datagrid-tree-level-'+ (level - 1) +':first')
11978            if (prev.length) {
11979                parents = parents.add(prev)
11980
11981                if (hasChild && prev.next().hasClass(that.classnames.tr_child))
11982                    parents = parents.add(prev.next())
11983
11984                if (!onlyParent)
11985                    parents = parents.add(that.getParents(prev, parents, hasChild))
11986            }
11987        }
11988
11989        return parents
11990    }
11991
11992    // only for tree
11993    Datagrid.prototype.appendTr = function(sTr, dTr, option) {
11994        if (!this.options.isTree)
11995            return
11996
11997        var that = this, options = that.options, sData, dData, sIndex = that.tools.getNoChildDataIndex(sTr.index()), dIndex = that.tools.getNoChildDataIndex(dTr.index()), hasChild = sTr.next().hasClass(that.classnames.tr_child),
11998            keys = options.treeOptions.keys,
11999            sParent, sParentData, sLevel = sTr.data('level'), dLevel = (dTr.data('level') + 1) || 0, dChildLen = dTr.data('child') + 1,
12000            dParent, dTd = dTr.find('> td.datagrid-tree-td'), moveIndex, len,
12001            _lastDTr
12002        var beforeDrop = options.dropOptions.beforeDrop
12003
12004        if (hasChild) {
12005            sTr = sTr.add(sTr.next())
12006            dTr = dTr.add(dTr.next())
12007        }
12008
12009        sData = that.data[sIndex]
12010        dData = that.data[dIndex]
12011        /* beforeDrop */
12012        if (beforeDrop && typeof beforeDrop === 'string')
12013            beforeDrop = beforeDrop.toFunc()
12014        if (beforeDrop && typeof beforeDrop === 'function') {
12015            if (!beforeDrop.apply(this, [sData, dData, 'append'])) {
12016                return
12017            }
12018        }
12019
12020        sParent = that.getParents(sTr, null, true)
12021        if (sParent.length) {
12022            sParentData = that.data[that.tools.getNoChildDataIndex(sParent.index())]
12023
12024            sParentData[keys.childLen] = sParentData[keys.childLen] - 1
12025            sParent.data('child', sParentData[keys.childLen]).attr('data-child', sParentData[keys.childLen])
12026
12027            if (!sParentData[keys.childLen]) {
12028                delete sParentData[keys.isParent]
12029                delete sParentData[keys.isExpand]
12030
12031                var sParentTd = sParent.find('> td.datagrid-tree-td')
12032
12033                sParentTd.html(that.tools.createTreePlaceholder(sParentData, sParentTd.find('.datagrid-tree-title').html()), sParent.data('isExpand'))
12034            }
12035        }
12036
12037        if (dTr.length) {
12038            dTr   = that.getChildrens(dTr, dTr, true)
12039            _lastDTr = that.getChildrens(dTr.last(), dTr.last(), true, true).last()
12040            //dData = that.data[dIndex]
12041            that.expand(dTr.first(), true)
12042
12043            dData[keys.isParent] = true
12044            dData[keys.childLen] = dChildLen
12045
12046            dTr.first().data('child', dChildLen).attr('data-child', dChildLen)
12047            dTd.html(that.tools.createTreePlaceholder(dData, dTd.find('.datagrid-tree-title').html(), dTr.first().data('isExpand')))
12048        }
12049
12050        sTr = that.getChildrens(sTr, sTr, true)
12051        sTr.filter(':not(.'+ that.classnames.tr_child +')').each(function() {
12052            var $tr = $(this), level = $tr.data('level'), newLevel = level + (dLevel - sLevel), $td = $tr.find('> td.datagrid-tree-td'), label = $td.find('.datagrid-tree-title').html(),
12053                trIndex = $tr.index(), trData = that.data[that.tools.getNoChildDataIndex(trIndex)]
12054
12055            if (option && option.isUp) {
12056                newLevel = dData[keys.level]
12057            }
12058            trData[keys.level] = newLevel
12059
12060            $tr.removeClass('datagrid-tree-level-'+ level).addClass('datagrid-tree-level-'+ newLevel)
12061                .data('level', newLevel).attr('data-level', newLevel)
12062
12063            $td.html(that.tools.createTreePlaceholder(trData, label, $tr.data('isExpand')))
12064        })
12065
12066        if (option && option.dIndex)
12067            moveIndex = option.dIndex
12068        else {
12069            moveIndex = dTr.last().index() + 1
12070            if (hasChild)
12071                moveIndex = moveIndex / 2
12072        }
12073
12074        //sData = that.data[sIndex]
12075        len   = (hasChild ? sTr.length / 2 : sTr.length)
12076
12077        that.data.moveItems(sIndex, moveIndex, len)
12078        that.allData.moveItems(sData.gridIndex, (sData.gridIndex + (moveIndex - sIndex)), len)
12079
12080        that.tools.updateGridIndex()
12081
12082        if (option && option._dTr) {
12083            dParent = that.getParents(option._dTr, null, true, false)
12084            if (option.isBefore)
12085                sTr.insertBefore(option._dTr)
12086            else if (option.isUp) {
12087                sTr.insertAfter(_lastDTr)
12088            } else {
12089                sTr.insertAfter(option._dTr)
12090            }
12091        } else {
12092            sTr.insertAfter(_lastDTr)
12093        }
12094
12095        // update the source seq
12096        if (sParent) {
12097            var _childs = that.getChildrens(sParent, null, false)
12098
12099            _childs.each(function(i) {
12100                var _trData = that.data[that.tools.getNoChildDataIndex($(this).index())]
12101
12102                if (_trData) {
12103                    _trData[keys.order] = i
12104                    _trData[options.keys.dropFlag] = true
12105                }
12106            })
12107        }
12108
12109        // update this seq and parentid
12110        if (!dParent)
12111            dParent = dTr.first()
12112
12113        if (dParent && dParent.length) {
12114            var _childs = that.getChildrens(dParent, null, false), dParentData = that.data[that.tools.getNoChildDataIndex(dParent.index())]
12115
12116            sData[keys.parentKey] = dParentData[keys.key]
12117
12118            _childs.each(function(i) {
12119                var _trData = that.data[that.tools.getNoChildDataIndex($(this).index())]
12120
12121                if (_trData) {
12122                    _trData[keys.order] = i
12123                    _trData[options.keys.dropFlag] = true
12124                }
12125            })
12126        } else {
12127            var _trs = sTr.siblings('.datagrid-tree-level-'+ sData[keys.level]).addBack()
12128
12129            sData[keys.parentKey] = null
12130
12131            _trs.each(function(i) {
12132                var _trData = that.data[that.tools.getNoChildDataIndex($(this).index())]
12133
12134                if (_trData) {
12135                    _trData[keys.order] = i
12136                    _trData[options.keys.dropFlag] = true
12137                }
12138            })
12139        }
12140
12141        that.tools.updateLinenumber()
12142
12143        that.afterDrop = true
12144    }
12145
12146    Datagrid.prototype.insertTr = function(sTr, dTr, position) {
12147        var that = this, point, options = that.options, keys = options.treeOptions.keys, sData, dData, moveIndex,
12148            sIndex = that.tools.getNoChildDataIndex(sTr.index()), dIndex = that.tools.getNoChildDataIndex(dTr.index()), hasChild = sTr.next().hasClass(that.classnames.tr_child),
12149            _start, _end
12150        var beforeDrop = options.dropOptions.beforeDrop
12151        var insertTr = function(sTr, dTr, point) {
12152            if (position === 'bottom') {
12153                if (hasChild)
12154                    dTr = dTr.next()
12155                sTr.insertAfter(dTr)
12156            } else {
12157                sTr.insertBefore(dTr)
12158            }
12159        }
12160
12161        sData = that.data[sIndex]
12162        dData = that.data[dIndex]
12163
12164        /* beforeDrop */
12165        if (beforeDrop && typeof beforeDrop === 'string')
12166            beforeDrop = beforeDrop.toFunc()
12167        if (beforeDrop && typeof beforeDrop === 'function') {
12168            if (!beforeDrop.apply(this, [sData, dData, position])) {
12169                return
12170            }
12171        }
12172
12173        if (sIndex > dIndex) {
12174            point = position === 'top' ? 0 : 1
12175        } else {
12176            point = position === 'top' ? -1 : 0
12177        }
12178
12179        moveIndex = dIndex + point
12180
12181        if (moveIndex == sIndex && !options.isTree) return
12182
12183        if (hasChild)
12184            sTr = sTr.add(sTr.next())
12185
12186        if (that.isDom) {
12187            insertTr(sTr, dTr, point)
12188        } else {
12189            sData = that.data[sIndex]
12190            dData = that.data[dIndex]
12191
12192            if (options.isTree) {
12193                var len, option = {}, append = false, sParent = that.getParents(sTr.first(), null, true), dParent = that.getParents(dTr, null, true)
12194
12195                if (dData[keys.level] === sData[keys.level] && dData[keys.order] == sData[keys.order] + (position === 'bottom' ? -1 : 1)) {
12196                    return
12197                }
12198
12199                /* to append */
12200                // if bottom
12201                if (position === 'bottom' && dData[keys.isParent]) {
12202                    append        = true
12203                    option._dTr   = dTr
12204                    option.dIndex = dIndex + 1
12205                    option.isUp   = true
12206                }
12207                // if different level or not the same parent
12208                else if (sTr.data('level') != dTr.data('level') || sParent[0] !== dParent[0]) {
12209                    append        = true
12210                    option._dTr   = dTr
12211                    option.dIndex = moveIndex
12212                    dTr           = dParent
12213
12214                    if (position === 'top')
12215                        option.isBef
12215ore = true
12216
12217                    if (sIndex < dIndex) {
12218                        option.dIndex ++
12219                    }
12220                }
12221                if (append) {
12222                    that.appendTr(sTr, dTr, option)
12223
12224                    return
12225                }
12226
12227                sTr = that.getChildrens(sTr, sTr, true)
12228                len = (hasChild ? sTr.length / 2 : sTr.length)
12229
12230                that.data.moveItems(sIndex, moveIndex, len)
12231                that.allData.moveItems(sData.gridIndex, (dData.gridIndex + point), len)
12232
12233                _start = (sIndex > dIndex ? dIndex : sIndex)
12234                _end = (sIndex > dIndex ? sIndex : dIndex) + (len - 1)
12235            } else {
12236                that.data.move(sIndex, moveIndex)
12237                that.allData.move(sData.gridIndex, (dData.gridIndex + point))
12238
12239                _start = sIndex > dIndex ? dIndex : sIndex
12240                _end = sIndex > dIndex ? sIndex : dIndex
12241            }
12242
12243            that.tools.updateGridIndex()
12244
12245            insertTr(sTr, dTr, point)
12246
12247            // update the seqs
12248            if (sParent) {
12249                var _childs = that.getChildrens(sParent, null, false, 1)
12250
12251                _childs.each(function(i) {
12252                    var _trData = that.data[that.tools.getNoChildDataIndex($(this).index())]
12253
12254                    if (_trData && (_trData[options.keys.gridIndex] >= _start && _trData[options.keys.gridIndex] <= _end)) {
12255                        _trData[keys.order] = i
12256                        _trData[options.keys.dropFlag] = true
12257                    }
12258                })
12259            } else {
12260                for (var i = _start; i <= _end; i++) {
12261                    var _trData = that.data[i]
12262
12263                    _trData[options.keys.dropFlag] = true
12264                }
12265            }
12266
12267            that.tools.updateLinenumber()
12268
12269            that.afterDrop = true
12270        }
12271    }
12272
12273    Datagrid.prototype.addTree = function(row, addLocation, addData) {
12274        var that = this, options = that.options, $tr, data, tr_index, index
12275
12276        if (options.isTree) {
12277            if (!addData || typeof addData !== 'object') {
12278                addData = {}
12279            }
12280
12281            if (row instanceof jQuery) {
12282                $tr = row.first()
12283            } else {
12284                $tr = that.$tbody.find('> tr:not(.'+ that.classnames.tr_child +')').eq(parseInt(row, 10))
12285            }
12286
12287            if ($tr && $tr.length) {
12288                that.$lastSelect = $tr
12289                that.add(addLocation, addData)
12290            }
12291        }
12292    }
12293
12294    Datagrid.prototype.expand = function(rows, expandFlag) {
12295        var that = this, options = that.options, $trs = that.$tbody.find('> tr:not(.'+ that.classnames.tr_child +')'), event
12296
12297        if (typeof expandFlag === 'undefined') expandFlag = true
12298
12299        event = (expandFlag ? 'expand' : 'collapse') +'.bjui.datagrid.tree'
12300
12301        if (options.isTree) {
12302            if (rows instanceof jQuery) {
12303                rows.trigger(event)
12304            } else if (isNaN(rows)) {
12305                $.each(rows.split(','), function(i, n) {
12306                    var tr = $trs.eq(parseInt(n.trim(), 10))
12307
12308                    if (tr && tr.length)
12309                        tr.trigger(event)
12310                })
12311            } else if (!isNaN(rows)) {
12312                var tr = $trs.eq(rows)
12313
12314                if (tr && tr.length)
12315                    tr.trigger(event)
12316            }
12317        }
12318    }
12319
12320    Datagrid.prototype.initTfoot = function() {
12321        var that = this, options = that.options, tools = that.tools, columnModel = that.columnModel, $tr = $('<tr></tr>')
12322
12323        that.$boxF      = $('<div class="datagrid-box-f"></div>')
12324        that.$colgroupF = that.$colgroupH.clone()
12325        that.$tableF    = that.$tableH.clone().empty()
12326        that.$tableF.append(that.$colgroupF)
12327        that.$boxF.append($('<div class="datagrid-wrap-h"></div>').append(that.$tableF))
12328        that.$boxF.insertAfter(that.$boxB)
12329
12330        that.$tfoot = $('<thead></thead>')
12331        $.each(columnModel, function(i, n) {
12332            var $th = $('<th><div></div></th>')
12333
12334            if (n.calc) {
12335                var calc_html = '<div><div class="datagrid-calcbox">#tit#</div>#number#</div>'
12336
12337                if (n.calc === 'avg')
12338                    $th.html(calc_html.replace('#tit#', (n.calcTit || 'AVG')).replace('#number#', (n.calc_sum / n.calc_count).toFixed(n.calcDecimal || 2)))
12339                else if (n.calc === 'count')
12340                    $th.html(calc_html.replace('#tit#', (n.calcTit || 'COUNT')).replace('#number#', (n.calc_count)))
12341                else if (n.calc === 'sum')
12342                    $th.html(calc_html.replace('#tit#', (n.calcTit || 'SUM')).replace('#number#', (n.calc_sum)))
12343                else if (n.calc === 'max')
12344                    $th.html(calc_html.replace('#tit#', (n.calcTit || 'MAX')).replace('#number#', (n.calc_max)))
12345                else if (n.calc === 'min')
12346                    $th.html(calc_html.replace('#tit#', (n.calcTit || 'MIN')).replace('#number#', (n.calc_min)))
12347            }
12348
12349            if (n.hidden) $th.css('display', 'none')
12350
12351            $th.appendTo($tr)
12352        })
12353
12354        that.$tfoot.append($tr).appendTo(that.$tableF)
12355
12356        // events
12357        that.$tfoot.on('resizeH.bjui.datagrid.tfoot', function() {
12358            tools.setBoxbH(options.height)
12359        })
12360    }
12361
12362    // selected row
12363    Datagrid.prototype.selectedRows = function(rows, selected) {
12364        var that = this, $lockTrs = that.$lockTbody && that.$lockTbody.find('> tr'), $trs = that.$tbody.find('> tr')
12365        var selectedTr = function(n) {
12366            if (typeof selected === 'undefined') selected = true
12367            if ($trs.eq(n).hasClass(that.classnames.tr_child)) return
12368
12369            $trs.eq(n)
12370                .toggleClass(that.classnames.tr_selected, selected)
12371                .find('> td.'+ that.classnames.td_checkbox +' input').iCheck(selected ? 'check' : 'uncheck')
12372
12373            $lockTrs && $lockTrs.eq(n)
12374                .toggleClass(that.classnames.tr_selected, selected)
12375                .find('> td.'+ that.classnames.td_checkbox +' input').iCheck(selected ? 'check' : 'uncheck')
12376        }
12377
12378        if (rows === null) {
12379            $trs.removeClass(that.classnames.tr_selected)
12380                .find('> td.'+ that.classnames.td_checkbox +' input').iCheck('uncheck')
12381
12382            $lockTrs && $lockTrs.removeClass(that.classnames.tr_selected)
12383                .find('> td.'+ that.classnames.td_checkbox +' input').iCheck('uncheck')
12384        } else if (typeof rows === 'object') {
12385            rows.each(function() {
12386                var $row = $(this), index = $row.index()
12387
12388                if ($row.hasClass(that.classnames.tr_child)) return true
12389
12390                if (typeof selected !== 'undefined') {
12391                    selectedTr(index)
12392                } else {
12393                    // $row.toggleClass(that.classnames.tr_selected)
12394                    //去掉了再次单击取消选中功能 修改于-2018-05-31
12395                    $row.addClass(that.classnames.tr_selected)
12396                        .trigger('bjui.datagrid.tr.selected')
12397                        .find('> td.'+ that.classnames.td_checkbox +' input').iCheck(($row.hasClass(that.classnames.tr_selected) ? 'check' : 'uncheck'))
12398                    $lockTrs && $lockTrs.eq(index)
12399                        .toggleClass(that.classnames.tr_selected)
12400                        .trigger('bjui.datagrid.tr.selected')
12401                        .find('> td.'+ that.classnames.td_checkbox +' input').iCheck(($row.hasClass(that.classnames.tr_selected) ? 'check' : 'uncheck'))
12402                }
12403            })
12404        } else if (isNaN(rows)) {
12405            $.each(rows.split(','), function(i, n) {
12406                selectedTr(parseInt(n.trim(), 10))
12407            })
12408        } else if (!isNaN(rows)) {
12409            selectedTr(parseInt(rows, 10))
12410        }
12411
12412        if (that.$lastSelect && !that.$lastSelect.hasClass(that.classnames.tr_selected)) {
12413            that.$lastSelect = null
12414        }
12415
12416        // selectedTrs
12417        var $selectedTrs = that.$tbody.find('> tr.'+ that.classnames.tr_selected), datas = []
12418
12419        $selectedTrs.each(function() {
12420            var $tr = $(this), data_index = $tr.index(), data
12421
12422            data_index = that.tools.getNoChildDataIndex(data_index)
12423
12424            if (that.isDom) data = $tr.data('initData') || that.tools.setDomData($tr)
12425            else data = that.data[data_index]
12426
12427            datas.push(data)
12428        })
12429
12430        that.$element.data('selectedTrs', $selectedTrs).data('selectedDatas', datas)
12431    }
12432
12433    //lock
12434    Datagrid.prototype.initLock = function() {
12435        var that = this, columnModel = that.columnModel
12436
12437        that.col_lock_count = 0
12438        $.each(that.columnModel, function(i, n) {
12439            if (n.initLock) that.col_lock_count ++
12440        })
12441
12442        if (that.col_lock_count) that.doLock()
12443    }
12444
12445    //api - colLock
12446    Datagrid.prototype.colLock = function(column, lockFlag) {
12447        var that = this, $th, index, columnModel
12448
12449        if (that.isTemplate)
12450            return
12451        if ($.type(column) === 'number') {
12452            index = parseInt(column, 10)
12453            if (index < 0 || index > that.columnModel.length - 1) return
12454            columnModel = that.columnModel[index]
12455            $th         = columnModel.th
12456        } else {
12457            $th         = column
12458            index       = $th.data('index')
12459            columnModel = that.columnModel[index]
12460        }
12461
12462        if (columnModel === that.editBtnsColumn) return // edit btn column
12463        else if (columnModel.index === that.columnModel.length - 1) return // last column
12464        if (typeof columnModel.locked === 'undefined') columnModel.locked = false
12465        if (columnModel.locked === lockFlag) return
12466
12467        columnModel.initLock = lockFlag
12468
12469        if (lockFlag) {
12470            that.col_lock_count ++
12471        } else {
12472            that.col_lock_count --
12473        }
12474        if (that.col_lock_count < 0) that.col_lock_count = 0
12475
12476        that.doLock()
12477    }
12478
12479    Datagrid.prototype.fixedLockItem = function(type) {
12480        var that = this, columnModel = that.columnModel, $filterThs = that.$thead.find('> tr.datagrid-filter > th'), $lockTrs = that.$lockTbody && that.$lockTbody.find('> tr')
12481
12482        // out
12483        if (!type) {
12484            var fixedTh = function($th, $lockTh) {
12485                $lockTh.clone().insertAfter($lockTh)
12486                $lockTh.hide().insertAfter($th)
12487                $th.remove()
12488            }
12489
12490            // filterThead
12491            if ($filterThs && $filterThs.length) {
12492                that.$lockThead && that.$lockThead.find('> tr.datagrid-filter > th:visible').each(function() {
12493                    var $lockTh = $(this), index = $lockTh.index(), $th = $filterThs.eq(index)
12494
12495                    fixedTh($th, $lockTh)
12496                })
12497            }
12498
12499            //thead checkbox
12500            if (that.$lockThead) {
12501                // checkbox
12502                if ($.inArray(that.checkboxColumn, columnModel) != -1 && that.checkboxColumn.locked) {
12503                    var $lockTh = that.$lockThead.find('> tr:first > th.'+ that.classnames.td_checkbox), index = that.checkboxColumn.index, $th = that.$thead.find('> tr:first > th:eq('+ index +')')
12504
12505                    fixedTh($th, $lockTh)
12506                }
12507            }
12508
12509            // inline edit && checkbox td
12510            if ($lockTrs && $lockTrs.length) {
12511                $lockTrs.each(function() {
12512                    var $lockTr = $(this), tr_index = $lockTr.index(), $tr, $td,
12513                        fixedTd = function($lockTd, tr_index, td_index) {
12514                            $tr = that.$tbody.find('> tr:eq('+ tr_index +')')
12515                            $td = $tr.find('> td:eq('+ td_index +')')
12516                            $lockTd.clone().insertAfter($lockTd)
12517                            $lockTd.hide().insertAfter($td)
12518                            $td.remove()
12519                        }
12520
12521                    if ($lockTr.hasClass(that.classnames.tr_edit)) {
12522                        var $lockTd = $lockTr.find('> td:eq('+ columnModel.lockIndex +')'), td_index = $lockTd.index()
12523
12524                        if ($lockTd.hasClass(that.classnames.td_edit)) {
12525                            fixedTd($lockTd, tr_index, td_index)
12526                        }
12527                    }
12528
12529                    if ($.inArray(that.checkboxColumn, columnModel) != -1 && that.checkboxColumn.locked) {
12530                        $lockTr.find('> td.'+ that.classnames.td_checkbox).each(function() {
12531                            var $lockTd = $(this), td_index = that.checkboxColumn.index
12532
12533                            fixedTd($lockTd, tr_index, td_index)
12534                        })
12535                    }
12536                })
12537            }
12538        } else { //in
12539            var fixedTh = function($th, $lockTh) {
12540                $th.clone().html('').insertAfter($th)
12541                $th.show().insertAfter($lockTh)
12542                $lockTh.remove()
12543            }
12544
12545            // filterThead
12546            if ($filterThs && $filterThs.length) {
12547                that.$lockThead.find('> tr.datagrid-filter > th:visible').each(function() {
12548                    var $lockTh = $(this), index = $lockTh.index(), $th = $filterThs.eq(index)
12549
12550                    fixedTh($th, $lockTh)
12551                })
12552            }
12553
12554            //thead checkbox
12555            if (that.$lockThead) {
12556                // checkbox
12557                if ($.inArray(that.checkboxColumn, columnModel) != -1 && that.checkboxColumn.locked) {
12558                    var $lockTh = that.$lockThead.find('> tr:first > th.'+ that.classnames.td_checkbox), index = that.checkboxColumn.index, $th = that.$thead.find('> tr:first > th:eq('+ index +')')
12559
12560                    fixedTh($th, $lockTh)
12561                }
12562            }
12563
12564            // inline edit && checkbox td
12565            if ($lockTrs && $lockTrs.length) {
12566                $lockTrs.each(function() {
12567                    var $lockTr = $(this), tr_index = $lockTr.index(), $tr, $td,
12568                        fixedTd = function($lockTd, tr_index, td_index) {
12569                            $tr = that.$tbody.find('> tr:eq('+ tr_index +')')
12570                            $td = $tr.find('> td:eq('+ td_index +')')
12571                            $td.clone().insertAfter($td)
12572                            $td.show().insertAfter($lockTd)
12573                            $lockTd.remove()
12574                        }
12575
12576                    if ($lockTr.hasClass(that.classnames.tr_edit)) {
12577                        $lockTr.find('> td.'+ that.classnames.td_edit +':visible').each(function() {
12578                            var $lockTd = $(this), td_index = $lockTd.index(), model = columnModel[td_index]
12579
12580                            if (model.locked) {
12581                                fixedTd($lockTd, tr_index, td_index)
12582                            }
12583                        })
12584                    }
12585                    if ($.inArray(that.checkboxColumn, columnModel) != -1 && that.checkboxColumn.locked) {
12586                        $lockTr.find('> td.'+ that.classnames.td_checkbox).each(function() {
12587                            var $lockTd = $(this), td_index = that.checkboxColumn.index
12588
12589                            fixedTd($lockTd, tr_index, td_index)
12590                        })
12591                    }
12592                })
12593            }
12594        }
12595    }
12596
12597    //locking
12598    Datagrid.prototype.doLock = function() {
12599        var that = this, options = that.options, tools = that.tools, columnModel = that.columnModel, tableW = that.$tableH.width(), width = 0, $trs, $lockTrs, lockedLen = 0
12600        var hasFoot = that.$boxF && true, top = 0
12601
12602        if (!that.$lockBox || !that.$lockBox.length) {
12603            that.$lockBox = $('<div class="datagrid-box-l"></div>')
12604            that.$lockH   = $('<div class="datagrid-box-h"></div>')
12605            that.$lockB   = $('<div class="datagrid-box-b"></div>')
12606            that.$lockF   = $('<div class="datagrid-box-f"></div>')
12607
12608            that.$lockTableH = $('<table class="table table-bordered"></table>')
12609            that.$lockTableB = $('<table></table>').addClass(that.$tableB.attr('class'))
12610            that.$lockTableF = $('<table class="table table-bordered"></table>')
12611
12612            that.$lockH.append(that.$lockTableH)
12613            that.$lockB.append(that.$lockTableB)
12614            that.$lockF.append(that.$lockTableF)
12615
12616            that.$lockBox.append(that.$lockH).append(that.$lockB).prependTo(that.$grid)
12617            if (hasFoot) {
12618                that.$lockBox.append(that.$lockF)
12619                that.$lockF.css('margin-top', (that.$boxB.outerHeight() - that.$boxB[0].clientHeight)).height(that.$boxF.outerHeight())
12620            }
12621        } else {
12622            that.fixedLockItem()
12623            that.$lockTableH.empty()
12624            that.$lockTableB.empty()
12625            that.$lockTableF && that.$lockTableF.empty()
12626        }
12627
12628        if (that.$boxT)    top += that.$boxT.outerHeight()
12629        if (that.$toolbar) top += that.$toolbar.outerHeight()
12630        if (top) that.$lockBox.css({top:top})
12631
12632        // display initLock columns, hide other
12633        $.each(columnModel, function(i, n) {
12634            n.lockShow = false
12635            n.lockHide = false
12636            if (n.initLock) {
12637                if (n.hidden) tools.showhide(n, true)
12638                n.lockHide  = true
12639                n.locked    = true
12640                n.lockIndex = lockedLen ++
12641                width      += n.width
12642            } else {
12643                n.lockShow = true
12644                if (!n.hidden) tools.showhide(n, false)
12645                else n.lockShow = false
12646                if (n.locked) n.lockShow = true
12647                n.locked   = false
12648            }
12649        })
12650
12651        that.$lockThead     = that.$thead.clone(true)
12652        that.$lockTbody     = that.$tbody.clone()
12653        that.$lockColgroupH = that.$colgroupH.clone()
12654        that.$lockColgroupB = that.$colgroupB.clone()
12655
12656        that.$lockTableH.append(that.$lockColgroupH).append(that.$lockThead).css('width', width)
12657        that.$lockTableB.append(that.$lockColgroupB).append(that.$lockTbody).css('width', width)
12658
12659        if (hasFoot) {
12660            that.$lockTfoot     = that.$tableF.find('> thead').clone()
12661            that.$lockColgroupF = that.$colgroupF.clone()
12662            that.$lockTableF.append(that.$lockColgroupF).append(that.$lockTfoot).css('width', width)
12663        }
12664
12665        // display unlock columns, hide locked columns
12666        $.each(that.columnModel, function(i, n) {
12667            if (n.lockShow) tools.showhide(n, true)
12668            if (n.lockHide) tools.showhide(n, false)
12669        })
12670
12671        that.$boxH.find('> div').css('width', '')
12672        that.$boxB.find('> div').css('width', '')
12673        that.$boxF && that.$boxF.find('> div').css('width', '')
12674
12675        setTimeout(function() {
12676            var bw = that.$boxB.find('> div').width()
12677
12678            that.$boxB.find('> div').width(bw)
12679            that.$boxH.find('> div').width(bw)
12680            that.$boxF && that.$boxF.find('> div').width(bw)
12681        }, 50)
12682
12683        if (!that.col_lock_count) that.$lockBox.hide()
12684        else that.$lockBox.show()
12685
12686        // colspan for child tr && nodata tr
12687        that.$tbody.find('> .'+ that.classnames.tr_child +', .datagrid-nodata').each(function() {
12688            $(this).find('> td').attr('colspan', that.columnModel.length - that.col_lock_count)
12689        })
12690
12691        if (width > 1) width = width - 1
12692        that.$boxH.css('margin-left', width)
12693        that.$boxB.css('margin-left', width)
12694        if (hasFoot) that.$boxF.css('margin-left', width)
12695
12696        // fixed height
12697        that.$lockB.height(that.$boxB[0].clientHeight)
12698        that.$lockB.prop('scrollTop', that.$boxB[0].scrollTop)
12699
12700        var lockH = that.$lockTableH.height(), H = that.$thead.height(), lockFH = that.$lockTableF && that.$lockTableF.height(), HF = that.$tableF && that.$tableF.height()
12701
12702        if (lockH != H) {
12703            if (lockH < H) that.$lockTableH.height(H)
12704            else that.$tableH.height(lockH)
12705        }
12706
12707        if (lockFH && HF && (lockFH != HF)) {
12708            if (lockFH < HF) that.$lockTableF.find('> thead > tr:first-child > th:visible:first').height(HF)
12709            else that.$tableF.find('> thead > tr:first-child > th:visible:first').height(lockFH)
12710        }
12711
12712        $lockTrs = that.$lockTbody.find('> tr')
12713        $trs     = that.$tbody.find('> tr')
12714
12715        setTimeout(function() {
12716            var lockBH = that.$lockTableB.height(), HB = that.$tableB.height()
12717
12718            if (lockBH != HB) {
12719                if (lockBH > HB) {
12720                    $lockTrs.each(function(tr_index) {
12721                        var $lockTr = $(this), $lockTd = $lockTr.find('> td:visible:first'), newH = $lockTd.outerHeight()
12722
12723                        if (newH > 30) {
12724                            $lockTr.height(newH)
12725                            $trs.eq(tr_index).height(newH)
12726                        }
12727                    })
12728                } else {
12729                    $trs.each(function(tr_index) {
12730                        var $tr = $(this), $td = $tr.find('> td:visible:first'), newH = $td.outerHeight()
12731
12732                        if (newH > 30) {
12733                            $tr.height(newH)
12734                            $lockTrs.eq(tr_index).height(newH)
12735                        }
12736                    })
12737                }
12738            }
12739        }, 20)
12740
12741        that.fixedLockItem(1)
12742
12743        // remove hidden tds
12744        $lockTrs.find('> td:hidden').remove()
12745
12746        // events
12747        that.initLockEvents($lockTrs)
12748    }
12749
12750    // init lockTr Events
12751    Datagrid.prototype.initLockEvents = function($locktrs) {
12752        if (!this.$lockTbody) return
12753
12754        var that = this, options = that.options
12755
12756        if (!$locktrs) $locktrs = that.$lockTbody.find('> tr')
12757
12758        $locktrs
12759            .on('click.bjui.datagrid.tr', function(e) {
12760                var index = $(this).index(), $td = $(e.target).closest('td')
12761
12762                that.$tbody.find('> tr:eq('+ index +')').trigger('click.bjui.datagrid.tr')
12763            })
12764            .on('delete.bjui.datagrid.tr', function(e, index) {
12765                var $tr = $(this)
12766
12767                if (that.linenumberColumn && that.linenumberColumn.locked) {
12768                    $tr.nextAll(':not(.'+ that.classnames.tr_child +')').each(function() {
12769                        var $td = $(this).find('> td.'+ that.classnames.td_linenumber), num = parseInt($td.text(), 10)
12770
12771                        $td.text(num - 1)
12772                    })
12773                }
12774            })
12775            .on('mouseenter.bjui.datagrid', function(e) {
12776                var $tr = $(this), index = $tr.index()
12777
12778                $tr.addClass('datagrid-hover')
12779                that.$tbody.find('> tr:eq('+ index +')').addClass('datagrid-hover')
12780            })
12781            .on('mouseleave.bjui.datagrid', function(e) {
12782                var $tr = $(this), index = $tr.index()
12783
12784                $tr.removeClass('datagrid-hover')
12785                that.$tbody.find('> tr:eq('+ index +')').removeClass('datagrid-hover')
12786            })
12787
12788        //contextmenu
12789        if (options.contextMenuB) {
12790            $locktrs.each(function() {
12791                that.tools.contextmenuB($(this), true)
12792            })
12793        }
12794    }
12795
12796    //api - filterInThead
12797    Datagrid.prototype.filterInThead = function(isDialog) {
12798        var that = this, options = that.options, tools = that.tools, regional = that.regional, columnModel = that.columnModel, filterData = {}
12799        var $tr = isDialog ? $('<ul class="datagrid-thead-dialog-view-ul"></ul>') : $('<tr class="datagrid-filter"></tr>')
12800        var onFilter = function($input, model, $th) {
12801            var type = model.type, $others
12802
12803            if ($th.isTag('th')) {
12804                $others = that.$headFilterUl && that.$headFilterUl.find('> li.li-'+ model.index)
12805            } else if ($th.isTag('li')) {
12806                $others = that.$thead.find('> tr.datagrid-filter > th:eq('+ model.index +')')
12807            }
12808
12809            if ($others) {
12810                $input.val($others.find('input').val())
12811                // if ($input.isTag('select'))
12812                //     $input.val($others.find('select').val()).selectpicker('refresh')
12813            }
12814
12815            if (type === 'date') {
12816                $input.change(function() {
12817                    doFilter(model, $input.val())
12818                })
12819            } else if (type === 'findgrid') {
12820                $input.change(function() {
12821                    doFilter(model, $input.val())
12822                })
12823            } else if (type === 'tags') {
12824                $th.on('aftercreated.bjui.tags', '[data-toggle="tags"]', function(e, data) {
12825                    doFilter(model, data.value)
12826                })
12827
12828                $input.change(function() {
12829                    doFilter(model, $input.val())
12830                })
12831            } else {
12832                $input.change(function() {
12833                    doFilter(model, $input.val())
12834                })
12835            }
12836
12837            $input.change(function() {
12838                if ($th.isTag('th') && !$others) {
12839                    $others = that.$headFilterUl && that.$headFilterUl.find('> li.li-'+ model.index)
12840                }
12841
12842                $others && $others.find('input').val($input.val())
12843                if ($input.isTag('select'))
12844                    $others && $others.find('select').val($input.val()).selectpicker('refresh')
12845            })
12846        }
12847        var doFilter = function(model, val) {
12848            tools.quickFilter(model, val ? {operatorA:'like', valA:val} : null)
12849        }
12850        var initFilter = (typeof options.initFilter === 'object') && options.initFilter
12851
12852        if (!that.inputs || !that.inputs.length) tools.initEditInputs()
12853
12854        $.each(columnModel, function(i, n) {
12855            if (isDialog) {
12856                if (n === that.linenumberColumn || n === that.checkboxColumn || n === that.editBtnsColumn || n === that.childColumn)
12857                    return true
12858            }
12859
12860            var $input = $(that.inputs[i]), $th = isDialog ? $('<li></li>') : $('<th></th>'), attrs = ''
12861
12862            if (!n.quickfilter) {
12863                $th.appendTo($tr)
12864                return true
12865            }
12866            else if (n.type === 'findgrid') $input.data('context', $tr)
12867            else if (n.type === 'spinner') $input = $('<input type="text" name="'+ n.name +'">')
12868            else if (n.type === 'boolean') $input = $(BJUI.doRegional('<select name="'+ n.name +'" data-toggle="selectpicker"><option value="">#all#</option><option value="true">#true#</option><option value="false">#false#</option></select>', regional))
12869            else if (n.type === 'select') {
12870                if (n.attrs && typeof n.attrs === 'object') {
12871                    $.each(n.attrs, function(i, n) {
12872                        attrs += ' '+ i +'='+ n
12873                    })
12874                }
12875                if ($input.find('> option:first-child').val() && (!n.attrs || !n.attrs.multiple)) {
12876                    $input = $('<select name="'+ n.name +'" data-toggle="selectpicker"'+ attrs +'></select>')
12877                        .append(BJUI.doRegional('<option value="">#all#</option>', regional))
12878                        .append($input.html())
12879
12880                    $input.val('') // for IE8
12881                }
12882            }
12883
12884            if (isDialog)
12885                $th.data('index', i).addClass('li-'+ i).append('<a href="javascript:;" class="datagrid-thead-dialog-sort" title="'+ BJUI.getRegional('datagrid.asc') +'/'+ BJUI.getRegional('datagrid.desc') +'">'+ n.label +'</a>')
12886
12887            $th.append($input)
12888
12889            if (n.hidden) $th.hide()
12890            if (n.type === 'boolean' && !isDialog) $th.attr('align', 'center')
12891            $th.appendTo($tr)
12892
12893            $input.data('clearFilter', false)
12894
12895            onFilter($input, n, $th)
12896
12897            // events - clear filter
12898            $input.on('clearfilter.bjui.datagrid.thead', function() {
12899                $input.val('')
12900                if (n.type === 'boolean' || n.type === 'select') $input.selectpicker('refresh')
12901            })
12902
12903            n.$quickfilter = $input
12904
12905            // init filter
12906            if (initFilter && typeof initFilter[n.name] !== 'undefined') {
12907                that.tools.initFilter($input, n)
12908            }
12909        })
12910
12911        if (isDialog) {
12912            $tr.prepend('<li><label>'+ BJUI.getRegional('datagrid.asc') +'/'+ BJUI.getRegional('datagrid.desc') +'</label><span class="quicksort-title">'+ BJUI.getRegional('datagrid.filter') +'</span></li>')
12913            $tr.hide().appendTo(that.$grid).initui()
12914
12915            that.$headFilterUl = $tr
12916            // for thead
12917            that.sortModels = !that.sortModels ? [] : that.sortModels
12918
12919            $tr.off('click.datagrid.thead.quicksort').on('click.datagrid.thead.quicksort', 'a.datagrid-thead-dialog-sort', function(e) {
12920                var $this = $(this), model = that.columnModel[$this.closest('li').data('index')], html = []
12921
12922                $this.find('> i').remove()
12923
12924                that.tools.quickSort(model)
12925
12926                if (model.sortDesc) {
12927                    $this.append('<i class="fa fa-long-arrow-down"></i>')
12928                    that.sortModels[model.index] = model
12929                } else if (model.sortAsc) {
12930                    $this.append('<i class="fa fa-long-arrow-up"></i>')
12931                    that.sortModels[model.index] = model
12932                } else {
12933                    delete that.sortModels[model.index]
12934                }
12935
12936                if (!that.sortData || $.isEmptyObject(that.sortData))
12937                    that.sortModels = []
12938
12939                $.each(that.sortModels, function(i, n) {
12940                    if (n)
12941                        html.push('<i class="datagrid-sort-i fa fa-long-arrow-'+ (n.sortAsc ? 'up' : 'down') +'"></i> '+ n.label)
12942                })
12943
12944                that.$boxH.find('.datagrid-thead-dialog-filter-msg > .msg-sort')
12945                    .html(html.length > 0 ? html.join('<em>&nbsp;&gt;&nbsp;</em>') : '')
12946            })
12947        } else
12948            $tr.appendTo(that.$thead).initui()
12949    }
12950
12951    //api - showhide linenumber column
12952    Datagrid.prototype.showLinenumber = function(flag) {
12953        var that = this, options = that.options, model = that.columnModel, numberModel, modelOrder = -1, data = that.data, numberModel_index = $.inArray(that.linenumberColumn, model)
12954
12955        if (numberModel_index != -1)
12956            numberModel = model[numberModel_index]
12957
12958        if (numberModel) {
12959            if (typeof flag === 'string' && (flag === 'lock' || flag === 'unlock')) {
12960                that.colLock(numberModel.th, flag === 'lock' ? true : false)
12961            } else {
12962                that.showhideColumn(numberModel.th, flag ? true : false)
12963            }
12964        } else if (flag) {
12965            modelOrder = $.inArray(that.childColumn, model)
12966
12967            modelOrder ++
12968            numberModel = that.linenumberColumn
12969            numberModel.index = modelOrder
12970            model.splice(modelOrder, 0, numberModel)
12971
12972            if (that.inputs && that.inputs.length)
12973                that.inputs = that.inputs.splice(modelOrder, 0, '')
12974
12975            var $trsH = that.$thead.find('> tr'), col = '<col style="width:30px;">', $th, $filterTr = $trsH.filter('.datagrid-filter'), rowspan = $trsH.length - $filterTr.length
12976
12977            $th = $('<th align="center"'+ (rowspan > 1 ? ' rowspan="'+ rowspan +' "' : '') +'class="'+ that.classnames.td_linenumber + (rowspan == 1 ? ' single-row' : '') +'"><div><div class="datagrid-space"></div><div class="datagrid-label">'+ that.linenumberColumn.label +'</div></div></th>')
12978
12979            that.$colgroupH.find('> col:eq('+ modelOrder +')').before(col)
12980            that.$colgroupB.find('> col:eq('+ modelOrder +')').before(col)
12981            that.$colgroupF && that.$colgroupF.find('> col:eq('+ modelOrder +')').before(col)
12982            $filterTr.length && $filterTr.find('> th:eq('+ modelOrder +')').before('<th></th>')
12983            $trsH.first().find('> th:eq('+ modelOrder +')').before($th)
12984            that.$tableF && that.$tableF.find('> thead > tr > th:eq('+ modelOrder +')').before('<th></th>')
12985
12986            numberModel.th    = $th
12987            numberModel.width = 30
12988
12989            that.$tbody.find('> tr').each(function(i) {
12990                var $tr = $(this), colspan = that.columnModel.length, linenumber = i, paging = that.paging
12991
12992                if ($tr.hasClass(that.classnames.tr_child) || $tr.hasClass('datagrid-nodata'))
12993                    $tr.find('> td').attr('colspan', colspan)
12994                else {
12995                    linenumber = that.tools.getNoChildDataIndex(linenumber)
12996                    if (options.linenumberAll)
12997                        linenumber = ((paging.pageCurrent - 1) * paging.pageSize + (linenumber))
12998
12999                    $tr.find('> td:eq('+ modelOrder +')').before('<td align="center" class="'+ that.classnames.td_linenumber +'">'+ (linenumber + 1) +'</td>')
13000                }
13001            })
13002
13003            that.$tableF && that.$tableF.find('> thead > tr > th:eq('+ modelOrder +')').before('<th></th>')
13004
13005            $.each(model, function(i, n) {
13006                n.index = i
13007                if (n.th) n.th.data('index', i)
13008            })
13009
13010            $th.find('> div').height($th.outerHeight())
13011
13012            if (flag === 'lock') {
13013                that.colLock($th, true)
13014            }
13015            if (that.$showhide) {
13016                that.$showhide.remove()
13017                that.colShowhide(options.columnShowhide)
13018            }
13019        }
13020    }
13021
13022    //api - showhide checkbox column
13023    Datagrid.prototype.showCheckboxcol = function(flag) {
13024        var that = this, options = that.options, model = that.columnModel, numberModel = model[0], checkModel, modelOrder = -1, checkModel_index = $.inArray(that.checkboxColumn, model)
13025
13026        if (checkModel_index != -1)
13027            checkModel = that.columnModel[checkModel_index]
13028
13029        if (checkModel) {
13030            if (typeof flag === 'string' && (flag === 'lock' || flag === 'unlock')) {
13031                that.colLock(checkModel.th, flag === 'lock' ? true : false)
13032            } else {
13033                that.showhideColumn(checkModel.th, flag)
13034            }
13035        } else if (flag) {
13036            modelOrder = $.inArray(that.linenumberColumn, model)
13037            if (modelOrder == -1)
13038                modelOrder = $.inArray(that.childColumn, model)
13039
13040            modelOrder ++
13041            checkModel = that.checkboxColumn
13042            checkModel.index = modelOrder
13043            model.splice(modelOrder, 0, checkModel)
13044
13045            if (that.inputs && that.inputs.length)
13046                that.inputs = that.inputs.splice(modelOrder, 0, '')
13047
13048            var $trsH = that.$thead.find('> tr'), col = '<col style="width:30px;">', $th, $td, $filterTr = $trsH.filter('.datagrid-filter'), rowspan = $trsH.length - $filterTr.length
13049
13050            $th = $('<th align="center"'+ (rowspan > 1 ? ' rowspan="'+ rowspan +' "' : '') +'class="'+ that.classnames.td_checkbox + (rowspan == 1 ? ' single-row' : '') +'"><div><div class="datagrid-space"></div><div class="datagrid-label"><input type="checkbox" data-toggle="icheck"></div></th>')
13051
13052            that.$colgroupH.find('> col:eq('+ modelOrder +')').before(col)
13053            that.$colgroupB.find('> col:eq('+ modelOrder +')').before(col)
13054            that.$colgroupF && that.$colgroupF.find('> col:eq('+ modelOrder +')').before(col)
13055            $filterTr.length && $filterTr.find('> th:eq('+ modelOrder +')').before('<th></th>')
13056            $trsH.first().find('> th:eq('+ modelOrder +')').before($th)
13057            that.$tableF && that.$tableF.find('> thead > tr > th:eq('+ modelOrder +')').before('<th></th>')
13058            $th.initui()
13059
13060            checkModel.th    = $th
13061            checkModel.width = 30
13062
13063            that.$tbody.find('> tr').each(function(i) {
13064                var $tr = $(this), colspan = that.columnModel.length
13065
13066                if ($tr.hasClass(that.classnames.tr_child) || $tr.hasClass('datagrid-nodata'))
13067                    $tr.find('> td').attr('colspan', colspan)
13068                else {
13069                    $td = $('<td align="center" class="'+ that.classnames.td_checkbox +'"><input type="checkbox" data-toggle="icheck" name="datagrid.checkbox"></td>')
13070                    $tr.find('> td:eq('+ modelOrder +')').before($td)
13071                    $td.initui()
13072                }
13073            })
13074
13075            $.each(model, function(i, n) {
13076                n.index = i
13077                if (n.th) n.th.data('index', i)
13078            })
13079
13080            $th.find('> div').height($th.outerHeight())
13081
13082            if (flag === 'lock') {
13083                that.colLock($th, true)
13084            }
13085            if (that.$showhide) {
13086                that.$showhide.remove()
13087                that.colShowhide(options.columnShowhide)
13088            }
13089        }
13090    }
13091
13092    //api - showhide checkbox column
13093    Datagrid.prototype.showEditCol = function(flag) {
13094        var that = this, options = that.options, model = that.columnModel, editModel = model[model.length - 1], data = that.data
13095
13096        if (editModel === that.editBtnsColumn) {
13097            that.showhideColumn(editModel.th, flag ? true : false)
13098        } else if (flag) {
13099            var $trsH = that.$thead.find('>
13099 tr'), col = '<col style="width:110px;">', $th, $td, $filterTr = $trsH.filter('.datagrid-filter'), rowspan = $trsH.length - $filterTr.length
13100
13101            editModel = that.editBtnsColumn
13102            model.push(editModel)
13103
13104            that.$colgroupH.append(col)
13105            that.$colgroupB.append(col)
13106            that.$colgroupF && that.$colgroupF.append(col)
13107            $th = $('<th align="center" rowspan="'+ rowspan +'">'+ that.editBtnsColumn.label +'</th>')
13108            $trsH.first().append($th)
13109            $filterTr.length && $filterTr.append('<th></th>')
13110            $th.initui().data('index', model.length - 1)
13111            editModel.th    = $th
13112            editModel.width = 110
13113            editModel.index = model.length - 1
13114
13115            that.$tbody.find('> tr').each(function(i) {
13116                var $tr = $(this), colspan = that.columnModel.length
13117
13118                if ($tr.hasClass(that.classnames.tr_child) || $tr.hasClass('datagrid-nodata'))
13119                    $tr.find('> td').attr('colspan', colspan)
13120                else {
13121                    $td = $('<td align="center" class="'+ that.classnames.s_edit +'">'+ BJUI.doRegional(FRAG.gridEditBtn, that.regional) +'</td>')
13122                    $tr.append($td)
13123                    $td.initui()
13124                }
13125            })
13126
13127            that.edit(that.$tbody.find('> tr'))
13128
13129            that.$tableF && that.$tableF.find('> thead > tr').append('<th></th>')
13130
13131            if (that.$showhide) {
13132                that.$showhide.remove()
13133                that.colShowhide(options.columnShowhide)
13134            }
13135        }
13136    }
13137
13138    //resize
13139    Datagrid.prototype.colResize = function() {
13140        var that        = this,
13141            tools       = that.tools,
13142            columnModel = that.columnModel,
13143            $thead      = that.$thead,
13144            $resizeMark = that.$grid.find('> .resizeProxy')
13145
13146        if (!$resizeMark.length) {
13147            $resizeMark = $('<div class="resizeProxy" style="left:0; display:none;"></div>')
13148            $resizeMark.appendTo(that.$grid)
13149        }
13150
13151        $thead.find('> tr > th').each(function(i) {
13152            var $th = $(this),  $resize = $th.find('> div > .'+ that.classnames.th_cell +'> .'+ that.classnames.th_resizemark)
13153
13154            $resize.on('mousedown.bjui.datagrid.resize', function(e) {
13155                var ofLeft = that.$boxH.scrollLeft(), marginLeft = parseInt(that.$boxH.css('marginLeft') || 0, 10), left, index = $th.data('index'), model = columnModel[index],
13156                    // width = model.width
13157                    width = (commonBlank(model.width)) ? model.th.width() : model.width //配置列拖动时的宽度 2020-11-02
13158                    , $trs = that.$tbody.find('> tr'), $lockTrs = that.$lockTbody && that.$lockTbody.find('> tr'), lockH = that.$lockTableB && that.$lockTableB.height(), H = that.$tableB.height(), lockH_new, H_new
13159                if (isNaN(marginLeft)) marginLeft = 0
13160                left = tools.getRight($th) - ofLeft + marginLeft
13161                that.isResize = true
13162
13163                if (model.locked) {
13164                    left = tools.getRight4Lock(model.lockIndex)
13165                    if (model.lockWidth) width = model.lockWidth
13166                }
13167
13168                $resizeMark
13169                    .show()
13170                    .css({
13171                        left   : left,
13172                        bottom : (that.$boxP ? that.$boxP.outerHeight() : 0),
13173                        cursor : 'col-resize'
13174                    })
13175                    .basedrag({
13176                        scop  : true, cellMinW:20, relObj:$resizeMark,
13177                        move  : 'horizontal',
13178                        event : e,
13179                        stop  : function() {
13180                            var new_left = $resizeMark.position().left,
13181                                move     = new_left - left,
13182                                newWidth = Number(move) + Number(width),
13183                                tableW   = that.$tableH.width() + move,
13184                                lockW    = that.$lockTableH && that.$lockTableH.width() + move
13185                            if (newWidth < 5) newWidth = 20
13186                            if (model.minWidth && newWidth < model.minWidth) newWidth = model.minWidth
13187                            if (newWidth != width + move) {
13188                                tableW   = tableW - move + (newWidth - width)
13189                                lockW    = lockW - move + (newWidth - width)
13190                            }
13191                            model.width = newWidth
13192
13193                            if (model.locked) {
13194                                if (lockW < (that.$grid.width() * 0.75
13194)) {
13195                                    model.lockWidth = newWidth
13196                                    that.$lockColgroupH.find('> col:eq('+ index +')').width(newWidth)
13197                                    that.$lockColgroupB.find('> col:eq('+ index +')').width(newWidth)
13198                                    that.$lockColgroupF && that.$lockColgroupF.find('> col:eq('+ index +')').width(newWidth)
13199
13200                                    that.$lockTableH.width(lockW)
13201                                    that.$lockTableB.width(lockW)
13202                                    that.$lockTableF && that.$lockTableF.width(lockW)
13203
13204                                    var margin = that.$lockBox.width()
13205
13206                                    that.$boxH.css('margin-left', margin - 1)
13207                                    that.$boxB.css('margin-left', margin - 1)
13208                                    that.$boxH.find('> div').width(that.$boxH.width())
13209                                    that.$boxB.find('> div').width(that.$boxH.width())
13210                                    that.$boxF && that.$boxF.css('margin-left', margin - 1)
13211
13212                                    that.$colgroupH.find('> col:eq('+ index +')').width(newWidth)
13213                                    that.$colgroupB.find('> col:eq('+ index +')').width(newWidth)
13214                                    that.$colgroupF && that.$colgroupF.find('> col:eq('+ index +')').width(newWidth)
13215                                }
13216                            } else {
13217                                setTimeout(function() {
13218                                    that.$colgroupH.find('> col:eq('+ index +')').width(newWidth)
13219                                    that.$colgroupB.find('> col:eq('+ index +')').width(newWidth)
13220                                    that.$colgroupF && that.$colgroupF.find('> col:eq('+ index +')').width(newWidth)
13221                                }, 1) //setTimeout for chrome
13222                            }
13223
13224                            /* fixed height */
13225                            setTimeout(function() {
13226                                $trs.css('height', '')
13227                                H_new = that.$tableB.height()
13228
13229                                if (that.$lockTbody) {
13230                                    $lockTrs.css('height', '')
13231                                    lockH_new = that.$lockTableB.height()
13232                                    if (lockH_new != lockH || H_new != H) {
13233                                        if (lockH_new > H_new) {
13234                                            $lockTrs.each(function(tr_index) {
13235                                                var $lockTr = $(this), $lockTd = $lockTr.find('> td:eq('+ model.lockIndex +')'), newH = $lockTd.outerHeight()
13236
13237                                                if (newH > 30) {
13238                                                    $lockTr.height(newH)
13239                                                    $trs.eq(tr_index).height(newH)
13240                                                }
13241                                            })
13242                                        } else {
13243                                            $trs.each(function(tr_index) {
13244                                                var $tr = $(this), $td = $tr.find('> td:eq('+ index +')'), newH = $td.outerHeight()
13245
13246                                                if (newH > 30) {
13247                                                    $tr.height(newH)
13248                                                    $lockTrs.eq(tr_index).height(newH)
13249                                                }
13250                                            })
13251                                        }
13252                                    }
13253
13254                                    that.$lockB.height(that.$boxB[0].clientHeight)
13255                                }
13256
13257                                if (model.calc) that.$tfoot && that.$tfoot.trigger('resizeH.bjui.datagrid.tfoot')
13258
13259                                that.isResize = false
13260                            }, 10)
13261
13262                            $resizeMark.hide()
13263                            that.resizeFlag = true
13264                        }
13265                    })
13266            })
13267        })
13268    }
13269
13270    //column - add menu button
13271    Datagrid.prototype.colMenu = function() {
13272        var that = this, options = that.options, tools = that.tools, regional = that.regional, $ths = that.$trsH.find('> th.'+ that.classnames.th_menu), $menu = that.$grid.find('> .'+ that.classnames.s_menu)
13273
13274        if (!$menu.legnth) {
13275            $menu = $(BJUI.doRegional(FRAG.gridMenu, regional))
13276            $menu.hide().appendTo(that.$grid)
13277            that.$menu = $menu
13278        }
13279        that.colShowhide(options.columnShowhide)
13280
13281        $ths.each(function() {
13282            var $th     = $(this),
13283                index   = $th.data('index'),
13284                model   = that.columnModel[index],
13285                $cell   = $th.find('> div > .'+ that.classnames.th_cell),
13286                $btnBox = $cell.find('> .'+ that.classnames.btn_menu),
13287                $btn
13288
13289            if (!$btnBox.length) {
13290                $btn    = $('<button type="button" class="btn btn-default"><i class="fa fa-bars"></button>'),
13291                    $btnBox = $('<div class="'+ that.classnames.btn_menu +'"></div>').append($btn)
13292
13293                $btnBox.appendTo($cell)
13294
13295                $btn.click(function() {
13296                    var $tr = $th.closest('tr'), rowspan = parseInt(($th.attr('rowspan') || 1), 10), left = $(this).offset().left - that.$grid.offset().left - 1, top = (that.$trsH.length - rowspan) * 25 + (13 * rowspan) + 11, $showhide = $menu.find('> ul > li.datagrid-li-showhide'), menu_width, submenu_width
13297                    var $otherBtn = $menu.data('bjui.datagrid.menu.btn')
13298
13299                    if ($otherBtn && $otherBtn.length) $otherBtn.removeClass('active')
13300                    $(this).addClass('active')
13301                    if ($showhide.length && that.$showhide) {
13302                        that.$showhide.appendTo($showhide)
13303                        submenu_width = that.$showhide.data('width')
13304                    }
13305                    $menu
13306                        .css({position:'absolute', top:top, left:left})
13307                        .show()
13308                        .data('bjui.datagrid.menu.btn', $btn)
13309                        .siblings('.'+ that.classnames.s_menu).hide()
13310
13311                    menu_width = $menu.outerWidth()
13312
13313                    var position = function(left) {
13314                        if (that.$boxH.width() - left < menu_width) {
13315                            $menu.css({left:left - menu_width + 18}).addClass('position-right')
13316                        } else {
13317                            $menu.css({left:left}).removeClass('position-right')
13318                        }
13319                    }
13320                    var fixedLeft = function($btn) {
13321                        that.$boxB.scroll(function() {
13322                            var left = $btn.offset().left - that.$grid.offset().left - 1
13323
13324                            position(left)
13325                        })
13326                    }
13327
13328                    position(left)
13329                    fixedLeft($btn)
13330
13331                    if (options.columnFilter) that.colFilter($th)
13332                    else $menu.find('> ul > li.'+ that.classnames.li_filter).hide()
13333
13334                    tools.locking($th)
13335
13336                    // quick sort
13337                    var $asc  = $menu.find('> ul > li.'+ that.classnames.li_asc),
13338                        $desc = $asc.next()
13339
13340                    $asc.off('click.bjui.datagrid.sort').on('click.bjui.datagrid.sort', function() {
13341                        if (model.sortDesc)
13342                            model.sortDesc = false
13343                        else {
13344                            model.sortAsc  = false
13345                        }
13346                        tools.quickSort(model)
13347                    })
13348
13349                    $desc.off('click.bjui.datagrid.sort').on('click.bjui.datagrid.sort', function() {
13350                        if (model.sortAsc) {
13351                            model.sortDesc = false
13352                        } else {
13353                            model.sortAsc  = true
13354                        }
13355                        tools.quickSort(model)
13356                    })
13357
13358                    $menu.on('sort.bjui.datagrid.th', function(e, asc) {
13359                        $asc.toggleClass('sort-active', asc)
13360                        $desc.toggleClass('sort-active', !asc)
13361                    })
13362                })
13363            }
13364        })
13365
13366        /* hide filterbox */
13367        that.$grid.on('click.bjui.datagrid.filter', function(e) {
13368            var $target = $(e.target), $menu = that.$grid.find('.'+ that.classnames.s_menu +':visible')
13369
13370            if ($menu.length && !$target.closest('.'+ that.classnames.btn_menu).length) {
13371                if (!$target.closest('.'+ that.classnames.s_menu).length) {
13372                    $menu.hide().data('bjui.datagrid.menu.btn').removeClass('active')
13373                }
13374            }
13375        })
13376    }
13377
13378    // show or hide columns on btn menu
13379    Datagrid.prototype.colShowhide = function(showFlag) {
13380        var that = this, options = that.options, tools = that.tools, $menu = that.$menu, $ul = $menu.find('> ul'), $showhideli = $ul.find('> li.'+ that.classnames.li_showhide)
13381
13382        if (showFlag) {
13383            if (!that.$showhide) {
13384                tools.createShowhide()
13385                tools.showSubMenu($showhideli, $menu, that.$showhide)
13386            }
13387        } else {
13388            $showhideli.hide()
13389        }
13390    }
13391
13392    // api - show or hide column
13393    Datagrid.prototype.showhideColumn = function(column, showFlag) {
13394        var that = this, tools = that.tools, index, model
13395
13396        if ($.type(column) === 'number') {
13397            index = parseInt(column, 10)
13398            if (index < 0) return
13399        } else {
13400            index = column.data('index')
13401        }
13402
13403        model = that.columnModel[index]
13404
13405        if (model) {
13406            if (model.locked) {
13407                if (showFlag) return
13408                else that.colLock(model.th, showFlag)
13409            }
13410            tools.showhide(model, showFlag)
13411        }
13412    }
13413
13414    // filter
13415    Datagrid.prototype.colFilter = function($th, filterFlag) {
13416        var that  = this, options = that.options, tools = that.tools, regional = that.regional, $filter = $th.data('bjui.datagrid.filter'), $menu = that.$menu, $filterli = $menu.find('> ul > li.'+ that.classnames.li_filter)
13417        var model = that.columnModel[$th.data('index')]
13418
13419        if (!that.inputs || !that.inputs.length) tools.initEditInputs()
13420        if (model.quickfilter) {
13421            $filterli.show().find('.'+ that.classnames.s_filter).addClass('hide')
13422
13423            if (!$filter || !$filter.length) {
13424                $filter = $(BJUI.doRegional(FRAG.gridFilter.replaceAll('#label#', $th.text()), regional)).hide().appendTo(that.$grid)
13425
13426                var index = $th.data('index'), model = that.columnModel[index], type = model.type || 'string', operator = model.operator || [],
13427                    $filterA = $filter.find('span.filter-a'),
13428                    $filterB = $filter.find('span.filter-b'),
13429                    $select  = $('<select data-toggle="selectpicker" data-container="true"></select>'),
13430                    $input   = $(that.inputs[index]),
13431                    $valA, $valB
13432
13433                $input.removeAttr('data-rule').attr('size', 10).addClass('filter-input')
13434
13435                if (type === 'string' || type === 'findgrid' || type === 'tags') {
13436                    if (!operator.length) operator = ['=', '!=', 'like']
13437                    if (type === 'findgrid') {
13438                        $input.data('context', $filter)
13439                    }
13440                } else if (type === 'number' || type === 'int' || type === 'spinner') {
13441                    if (type === 'spinner') $input.removeAttr('data-toggle')
13442                    if (!operator.length) operator = ['=', '!=', '>', '<', '>=', '<=']
13443                } else if (type === 'date') {
13444                    if (!operator.length) operator = ['=', '!=']
13445                } else if (type === 'boolean') {
13446                    if (!operator.length) operator = ['=', '!=']
13447                    $input = $(BJUI.doRegional('<select name="'+ model.name +'" data-toggle="selectpicker"><option value="">#all#</option><option value="true">#true#</option><option value="false">#false#</option></select>', regional))
13448                } else if (type === 'select') {
13449                    if (!operator.length) operator = ['=', '!=']
13450                    $input.attr('data-width', '80')
13451                    if ($input.find('> option:first-child').val()) {
13452                        $input = $('<select name="'+ model.name +'" data-toggle="selectpicker" data-width="80"></select>')
13453                            .append(BJUI.doRegional('<option value="">#all#</option>', regional))
13454                            .append($input.html())
13455                    }
13456                }
13457
13458                for (var i = 0, l = operator.length; i < l; i++) {
13459                    $select.append('<option value="'+ (operator[i]) +'">'+ (operator[i]) +'</option>')
13460                }
13461
13462                $valA = $input
13463                $valB = $valA.clone()
13464
13465                $filterA.append($select).append($input)
13466                $filterB.append($select.clone()).append($valB)
13467
13468                $th.data('bjui.datagrid.filter', $filter)
13469
13470                $filter.appendTo($filterli)
13471                $filter.data('width', $filter.outerWidth()).hide().initui()
13472
13473                /* events */
13474                var $ok      = $filter.find('button.ok'),
13475                    $clear   = $filter.find('button.clear'),
13476                    $selects = $filter.find('select'),
13477                    $selA    = $selects.first(),
13478                    $selB    = $selects.last(),
13479                    $andOr   = $selects.eq(1)
13480
13481                $ok.click(function() {
13482                    var operatorA = $selA.val(), valA = $valA.val().trim(), operatorB = $selB.val(), valB = $valB.val().trim(), andor = $andOr.val()
13483                    var filterDatas = {}
13484
13485                    if (valA.length) {
13486                        $.extend(filterDatas, {operatorA:operatorA, valA:valA})
13487                    }
13488                    if (valB.length) {
13489                        if (valA.length) $.extend(filterDatas, {andor:andor})
13490                        $.extend(filterDatas, {operatorB:operatorB, valB:valB})
13491                    }
13492                    if (!$.isEmptyObject(filterDatas)) {
13493                        tools.quickFilter(that.columnModel[$th.data('index')], filterDatas)
13494                        that.$grid.trigger('click')
13495                        $filterli.trigger('hidesubmenu.bjui.datagrid.th', [$menu, $filter])
13496                    } else {
13497                        $clear.trigger('click')
13498                    }
13499                })
13500
13501                $clear.click(function() {
13502                    var model = that.columnModel[$th.data('index')]
13503
13504                    $selects.find('> option:first').prop('selected', true)
13505                    $selects.selectpicker('refresh')
13506                    $valA.val('')
13507                    $valB.val('')
13508                    if (model.isFiltered) {
13509                        tools.quickFilter(model, null)
13510                        that.$grid.trigger('click')
13511                        $filterli.trigger('hidesubmenu.bjui.datagrid.th', [$menu, $filter])
13512                    }
13513                })
13514            }
13515
13516            tools.showSubMenu($filterli, $menu, $filter.removeClass('hide'))
13517
13518            $menu.find('> ul > li:not(".'+ that.classnames.li_filter +'")').on('mouseover', function() {
13519                if ($filterli.hasClass('active'))
13520                    $filterli.trigger('hidesubmenu.bjui.datagrid.th', [$menu, $filter])
13521            })
13522        } else {
13523            $filterli.hide()
13524        }
13525    }
13526
13527    // paging
13528    Datagrid.prototype.initPaging = function() {
13529        var that = this, tools = that.tools, options = that.options, paging = that.paging, pr = BJUI.regional.pagination, btnpaging = FRAG.gridPaging, pageNums = [], pageCount = paging.pageCount, interval, selectPages = [], pagingHtml = BJUI.StrBuilder()
13530
13531        interval = tools.getPageInterval(pageCount, paging.pageCurrent, paging.showPagenum)
13532
13533        for (var i = interval.start; i < interval.end; i++) {
13534            pageNums.push(FRAG.gridPageNum.replace('#num#', i).replace('#active#', (paging.pageCurrent == i ? ' active' : '')))
13535        }
13536
13537        btnpaging = BJUI.doRegional(btnpaging.replaceAll('#pageCurrent#', paging.pageCurrent).replaceAll('#count#', paging.total +'/'+ parseInt((pageCount || 0), 10)), pr)
13538
13539        pagingHtml
13540            .add('<div class="paging-content" style="width:'+ that.$boxB.width() +'px;">')
13541            .add('<span></span><div class="paging-pagesize"><button type="button" class="btn-default btn-refresh" title="'+ pr.refresh +'" data-icon="refresh"></button>')
13542            .add('<select data-toggle="selectpicker"></select>')
13543            .add('</div>')
13544            .add('<div class="paging-box">')
13545            .add(btnpaging.replace('#pageNumFrag#', pageNums.join('')))
13546            .add('</div>')
13547            .add('</div>')
13548
13549        that.$boxP.html(pagingHtml.toString())
13550        that.$boxP.initui()
13551
13552        //events
13553        var $select    = that.$boxP.find('div.paging-pagesize > select'),
13554            $pagenum   = that.$boxP.find('ul.pagination'),
13555            $pagetotal = $pagenum.find('> li.page-total'),
13556            $jumpto    = $pagetotal.next(),
13557            $first     = $jumpto.next(),
13558            $prev      = $first.next(),
13559            $next      = $prev.nextAll('.page-next'),
13560            $last      = $next.next()
13561
13562        var disablePrev = function() {
13563            $first.addClass('disabled')
13564            $prev.addClass('disabled')
13565        }
13566        var enablePrev = function() {
13567            $first.removeClass('disabled')
13568            $prev.removeClass('disabled')
13569        }
13570        var disableNext = function() {
13571            $next.addClass('disabled')
13572            $last.addClass('disabled')
13573        }
13574        var enableNext = function() {
13575            $next.removeClass('disabled')
13576            $last.removeClass('disabled')
13577        }
13578        var pageFirst = function() {
13579            disablePrev()
13580            enableNext()
13581        }
13582        var pageLast = function() {
13583            enablePrev()
13584            disableNext()
13585        }
13586        var setPageSize = function(pageSize) {
13587            $select.empty()
13588
13589            if (!pageSize) pageSize = that.paging.pageSize
13590
13591            selectPages = paging.selectPageSize.split(',')
13592            selectPages.push(String(pageSize))
13593
13594            $.unique(selectPages).sort(function(a, b) { return a - b })
13595
13596            var opts = []
13597
13598            $.each(selectPages, function(i, n) {
13599                opts.push('<option value="'+ n +'"'+ (n == paging.pageSize && 'selected') +'>'+ n +'/'+ pr.page +'</option>')
13600            })
13601
13602            $select.html(opts.join('')).selectpicker('refresh')
13603        }
13604
13605        if (paging.pageCurrent == 1) pageFirst()
13606        if (paging.pageCurrent == paging.pageCount) {
13607            pageLast()
13608            if (paging.pageCurrent == 1) disablePrev()
13609        }
13610        if (!paging.total) disableNext()
13611        setPageSize()
13612
13613        that.$boxP.on('click.datagrid.pagenum', 'li.page-num', function(e) {
13614            var $num = $(this)
13615
13616            if (!$num.hasClass('active')) {
13617                that.jumpPage($num.text())
13618            }
13619
13620            e.preventDefault()
13621        }).on('click.datagrid.refresh', 'button.btn-refresh', function() {
13622            that.refresh()
13623        }).on('bjui.datagrid.paging.jump', function(e) {
13624            var pageCurrent = that.paging.pageCurrent, interval = tools.getPageInterval(that.paging.pageCount, pageCurrent, paging.showPagenum), pageNums = []
13625
13626            for (var i = interval.start; i < interval.end; i++) {
13627                pageNums.push(FRAG.gridPageNum.replace('#num#', i).replace('#active#', (pageCurrent == i ? ' active' : '')))
13628            }
13629
13630            $pagenum.find('> li.page-num').remove()
13631            $prev.after(pageNums.join(''))
13632
13633            if (pageCurrent == 1) {
13634                pageFirst()
13635                if (pageCurrent == that.paging.pageCount) disableNext()
13636                if (!that.paging.total) disableNext()
13637            } else if (pageCurrent == that.paging.pageCount) {
13638                pageLast()
13639            } else {
13640                enablePrev()
13641                enableNext()
13642            }
13643
13644            $jumpto.find('input').val(pageCurrent)
13645            $pagetotal.find('> span').html(that.paging.total +'/'+ that.paging.pageCount)
13646        }).on('bjui.datagrid.paging.pageSize', function(e, pageSize) {
13647            setPageSize(pageSize)
13648        }).on('change', 'div.paging-pagesize > select', function() {
13649            var pageSize = $(this).val()
13650
13651            that.jumpPage(null, pageSize)
13652        })
13653
13654        $jumpto.find('input').on('keyup', function(e) {
13655            if (e.which === BJUI.keyCode.ENTER) {
13656                var page = $(this).val()
13657
13658                if (page) that.jumpPage(page)
13659            }
13660        })
13661
13662        $first.on('click', function() {
13663            if (that.paging.pageCurrent > 1)
13664                that.jumpPage(1)
13665        })
13666
13667        $prev.on('click', function() {
13668            if (that.paging.pageCurrent > 1)
13669                that.jumpPage(that.paging.pageCurrent - 1)
13670        })
13671
13672        $next.on('click', function() {
13673            if (that.paging.pageCurrent < that.paging.pageCount)
13674                that.jumpPage(that.paging.pageCurrent + 1)
13675        })
13676
13677        $last.on('click', function() {
13678            if (that.paging.pageCurrent < that.paging.pageCount)
13679                that.jumpPage(that.paging.pageCount)
13680        })
13681    }
13682
13683    Datagrid.prototype.jumpPage = function(pageCurrent, pageSize) {
13684        var that = this, paging = that.paging, pageCount = paging.pageCount
13685
13686        if (pageCurrent && isNaN(pageCurrent)) return
13687        if (pageSize && isNaN(pageSize))       return
13688        if (pageCurrent) {
13689            pageCurrent = parseInt(pageCurrent, 10)
13690
13691            if (pageCurrent < 1)         pageCurrent = 1
13692            if (pageCurrent > pageCount) pageCurrent = pageCount
13693            if (pageCurrent == paging.pageCurrent) return
13694        }
13695        if (pageSize) {
13696            pageSize = parseInt(pageSize, 10)
13697
13698            if (that.options.local != 'remote') {
13699                if (paging.pageSize > paging.total) return
13700            }
13701        }
13702
13703        that.tools.jumpPage(pageCurrent, pageSize)
13704    }
13705
13706    // api - add
13707    Datagrid.prototype.add = function(addLocation, addData, noEdit,moreadd) {
13708        if(moreadd){
13709            this.moreadd=true;
13710
13711        }else{
13712            this.moreadd=false;
13713        }
13714        if (!this.tools.beforeEdit() && !noEdit) return
13715
13716        if (!this.options.editUrl && !noEdit) {
13717            BJUI.debug('BJUI.Datagrid: Edit url is not set!')
13718            return
13719        }
13720
13721        if (!this.options.editMode && !noEdit) return
13722        if (!this.options.inlineEditMult) {
13723            this.doCancelEditRow(this.$tbody.find('> tr.'+ this.classnames.tr_edit))
13724        } else if (!noEdit && this.options.editMode != 'inline' && this.$tbody.find('> tr.'+ this.classnames.tr_add).length) {
13725            return
13726        }
13727
13728        if (!addData) {
13729            addData = {}
13730        } else {
13731            if (typeof addData === 'string') {
13732                addData = addData.toObj()
13733            }
13734            if (typeof addData !== 'object') {
13735                addData = {}
13736            }
13737        }
13738
13739        var that = this, options = that.options, keys = options.keys, tools = that.tools, paging = that.paging, trs, obj = {}, data = [], addObj, startNumber = (paging.pageCurrent - 1) * paging.pageSize, linenumber
13740
13741        var addTr = function() {
13742            var $tr = $('<tr></tr>').addClass(that.classnames.tr_add), $lockTr = $tr.clone()
13743
13744            if (that.isTemplate) {
13745                var tdTemplate = options.tdTemplate, tempcolspan = that.columnModel.length
13746
13747                if (typeof tdTemplate === 'function')
13748                    tdTemplate = tdTemplate.apply(that, [{}])
13749
13750                if (that.options.hasChild && that.options.childOptions) {
13751                    $tr.append('<td data-title="..." align="center" class="datagrid-child-td"><div>'+ BJUI.doRegional(FRAG.gridExpandBtn, that.regional) +'</div></td>')
13752                    tempcolspan --
13753                }
13754                if (that.options.showLinenumber) {
13755                    $tr.append('<td data-title="No." align="center" class="datagrid-linenumber-td">0</td>')
13756                    tempcolspan --
13757                }
13758                if (that.options.showCheckboxcol) {
13759                    $tr.append('<td data-title="Checkbox" align="center" class="datagrid-checkbox-td"><div><input type="checkbox" data-toggle="icheck" name="datagrid.checkbox" value="true"></div></td>')
13760                    tempcolspan --
13761                }
13762
13763                $tr.append('<td class="datagrid-template-td" colspan="'+ tempcolspan +'">'+ tdTemplate +'</td>')
13764            } else {
13765                $.each(that.columnModel, function(i, n) {
13766                    var label = '', $td = $('<td></td>')
13767
13768                    if (n[keys.gridChild])
13769                        $td.addClass(that.classnames.td_child).html('<div>'+ BJUI.doRegional(FRAG.gridExpandBtn, that.regional) +'</div>')
13770                    else if (n[keys.gridNumber])
13771                        $td.addClass(that.classnames.td_linenumber).text(0)
13772                    else if (n[keys.gridCheckbox])
13773                        $td.addClass(that.classnames.td_checkbox).html('<div><input type="checkbox" data-toggle="icheck" name="datagrid.checkbox" value="true"></div>')
13774                    else if (n[keys.gridEdit])
13775                        $td.addClass(that.classnames.s_edit).data('isAdd', true).html(BJUI.doRegional(FRAG.gridEditBtn, that.regional))
13776                    else $td.text('')
13777
13778                    if (n.hidden) $td.css('display', 'none')
13779                    if (n.align)  $td.attr('align', n.align)
13780
13781                    if (n.name) obj[n.name] = ''
13782
13783                    if (n.locked) {
13784                        if (n[keys.gridCheckbox]) {
13785                            $td.clone().hide().appendTo($tr)
13786                            $td.show().appendTo($lockTr)
13787                        } else {
13788                            $td.clone().show().appendTo($lockTr)
13789                            $td.hide().appendTo($tr)
13790                        }
13791                    } else {
13792                        $td.appendTo($tr)
13793                    }
13794                })
13795            }
13796
13797            obj = $.extend({}, that.attach, obj)
13798            if (!that.emptyData) that.emptyData = obj
13799
13800            return {tr:$tr, lockTr:$lockTr.find('> td').length ? $lockTr : null}
13801        }
13802
13803        if (!addLocation) addLocation = options.addLocation || 'first'
13804        if (!that.$lastSelect) {
13805            if (addLocation === 'prev') addLocation = 'first'
13806            else if (addLocation === 'next') addLocation = 'last'
13807        }
13808        if ($.inArray(addLocation, ['first', 'last', 'prev', 'next']) === -1)
13809            addLocation = 'first'
13810
13811        if (options.isTree && that.$lastSelect) {
13812            if (!(addLocation === 'first' || addLocation === 'last'))
13813                addLocation = 'first'
13814
13815            var parentData = that.data[that.tools.getNoChildDataIndex(that.$lastSelect.index())]
13816
13817            if (parentData) {
13818                addData[options.treeOptions.keys.level]     = parentData[options.treeOptions.keys.level] + 1
13819                addData[options.treeOptions.keys.parentKey] = parentData[options.treeOptions.keys.key]
13820                addData[options.keys.treePTr]               = that.$lastSelect
13821                addData[options.keys.treePData]             = parentData
13822            } else {
13823                addData['level'] = 0
13824            }
13825        }
13826
13827        if (addLocation === 'first') {
13828            linenumber = 0
13829            trs = addTr()
13830
13831            if (options.isTree && that.$lastSelect) {
13832                linenumber = that.tools.getNoChildDataIndex(that.$lastSelect.index()) + 1
13833
13834                if (that.$lastSelect.next().hasClass(that.classnames.tr_child)) {
13835                    trs.tr.insertAfter(that.$lastSelect.next())
13836                    if (trs.lockTr) trs.lockTr.insertAfter(that.$lockTbody.find('> tr:eq('+ that.$lastSelect.next().index() +')'))
13837                } else {
13838                    trs.tr.insertAfter(that.$lastSelect)
13839                    if (trs.lockTr) trs.lockTr.insertAfter(that.$lockTbody.find('> tr:eq('+ that.$lastSelect.index() +')'))
13840                }
13841            } else {
13842                trs.tr.prependTo(that.$tbody)
13843                if (trs.lockTr) trs.lockTr.prependTo(that.$lockTbody)
13844            }
13845        } else if (addLocation === 'last') {
13846            linenumber = that.$tbody.find('> tr').length
13847            trs = addTr()
13848
13849            if (options.isTree && that.$lastSelect) {
13850                var child = that.$lastSelect.data('child') || 0, level = that.$lastSelect.data('level'), $lastTr, hasChild = that.$lastSelect.next().hasClass(that.classnames.tr_child)
13851
13852                $lastTr = that.getChildrens(that.$lastSelect, that.$lastSelect).last()
13853
13854                if (hasChild) {
13855                    trs.tr.insertAfter($lastTr.next())
13856                    if (trs.lockTr) trs.lockTr.insertAfter(that.$lockTbody.find('> tr:eq('+ $lastTr.next().index() +')'))
13857                } else {
13858                    trs.tr.insertAfter($lastTr)
13859                    if (trs.lockTr) trs.lockTr.insertAfter(that.$lockTbody.find('> tr:eq('+ $lastTr.index() +')'))
13860                }
13861
13862                linenumber = that.tools.getNoChildDataIndex($lastTr.index()) + 1
13863
13864                addData[options.treeOptions.keys.order] = child
13865            } else {
13866                trs.tr.appendTo(that.$tbody)
13867                if (trs.lockTr) trs.lockTr.appendTo(that.$lockTbody)
13868            }
13869        } else if (addLocation === 'prev') {
13870            linenumber = that.tools.getNoChildDataIndex(that.$lastSelect.index())
13871            tr
13871s = addTr()
13872
13873            trs.tr.insertBefore(that.$lastSelect)
13874            if (trs.lockTr) trs.lockTr.insertBefore(that.$lockTbody.find('> tr:eq('+ that.$lastSelect.index() +')'))
13875        } else if (addLocation === 'next') {
13876            linenumber = that.tools.getNoChildDataIndex(that.$lastSelect.index()) + 1
13877            trs = addTr()
13878
13879            if (that.$lastSelect.next().hasClass(that.classnames.tr_child)) {
13880                trs.tr.insertAfter(that.$lastSelect.next())
13881                if (trs.lockTr) trs.lockTr.insertAfter(that.$lockTbody.find('> tr:eq('+ that.$lastSelect.next().index() +')'))
13882            } else {
13883                trs.tr.insertAfter(that.$lastSelect)
13884                if (trs.lockTr) trs.lockTr.insertAfter(that.$lockTbody.find('> tr:eq('+ that.$lastSelect.index() +')'))
13885            }
13886        }
13887
13888        addData = $.extend({}, that.emptyData, addData, {addFlag:true})
13889
13890        if (!that.data) that.data = []
13891        if (!that.allData) that.allData = []
13892        if (that.allData.length) {
13893            that.allData.splice(linenumber + startNumber, 0, addData)
13894        } else {
13895            that.allData.push(addData)
13896        }
13897
13898        if (that.data.length) {
13899            that.data.splice(linenumber, 0, addData)
13900        } else {
13901            that.data.push(addData)
13902        }
13903
13904        that.tools.updateGridIndex()
13905
13906        trs.tr.initui()
13907        trs.lockTr && trs.lockTr.initui()
13908
13909        if (addData[options.keys.treePTr])
13910            trs.tr.data(options.keys.treePTr, addData[options.keys.treePTr])
13911        if (options.showNoDataTip)
13912            that.$tbody.find('> tr.datagrid-nodata').remove()
13913        if (options.height === 'auto')
13914            that.fixedHeight()
13915
13916        setTimeout(function() {
13917            that.initEvents(trs.tr)
13918        }, 20)
13919
13920        if (trs.lockTr) that.initLockEvents(trs.lockTr)
13921        that.edit(trs.tr)
13922
13923        if (options.hasChild && options.childOptions)
13924            trs.tr.after('<tr class="'+ that.classnames.tr_child +'"></tr>')
13925
13926        if (noEdit) {
13927            that.inlineEditComplete(trs.tr, addData)
13928            if (that.data.length == 1)
13929                that.needfixedWidth = true
13930            that.tools.afterSave(trs.tr, addData)
13931        } else {
13932            if (options.editMode != 'dialog') {
13933                that.doEditRow(trs.tr, 'inline', true)
13934            } else {
13935                that.dialogEdit(trs.tr, true)
13936            }
13937        }
13938    }
13939
13940    // edit
13941    Datagrid.prototype.edit = function($trs) {
13942        var that = this, options = that.options, tools = that.tools, type = options.editMode, columnModel = that.columnModel, $editTd
13943
13944        that.editInit = false
13945
13946        if (!type) return
13947        if (typeof type === 'object') {
13948            var editOptions = {}, types = ['dialog', 'navtab', 'div'], editFlag = false
13949
13950            that.editOptions = null
13951
13952            for (var key in type) {
13953                if ($.inArray(key, types) != -1) {
13954                    editOptions.type    = key
13955                    editOptions.options = type[key]
13956
13957                    editFlag = true
13958
13959                    break
13960                }
13961            }
13962
13963            if (!editFlag) {
13964                BJUI.debug('Dialog Plugn: The options \'editModel\' set error!')
13965                return
13966            }
13967
13968            if (!$.isEmptyObject(editOptions))
13969                that.editOptions = editOptions
13970
13971        } else {
13972            if (that.options.editUrl)
13973                that.options.editUrl = that.options.editUrl.replace(/{\/?[^}]*}/g, '')
13974
13975            if (type != 'dialog')
13976                type = 'inline'
13977        }
13978
13979        if (!$trs) $trs = that.$tbody.find('> tr')
13980
13981        $editTd = $trs.find('> td.'+ that.classnames.s_edit)
13982
13983        that.editInit = true
13984
13985        /* events */
13986        $editTd.each(function() {
13987            var $td = $(this), $btns = $td.find('button.bjui-datagrid-btn'), $edit = $btns.first(), $update = $edit.next(), $save = $update.next(), $cancel = $
13987save.next(), $delete = $cancel.next()
13988
13989            $edit.on('click', function(e, data) {
13990                var $btn = $(this), $tr = $btn.closest('tr'), data_index = $tr.index(), isAdd = $td.data('isAdd')
13991
13992                data_index = that.tools.getNoChildDataIndex(data_index)
13993
13994                if (!data) {
13995                    if (that.isDom) data = $tr.data('initData') || tools.setDomData($tr)
13996                    else data = that.data[data_index]
13997                }
13998                if (!tools.beforeEdit($tr, data)) {
13999                    return false
14000                }
14001                if (that.editOptions) {
14002                    that.externalEdit($tr, null, data)
14003                    return false
14004                }
14005                if (type != 'dialog') {
14006                    that.inlineEdit($tr, isAdd)
14007
14008                    $btns.hide()
14009                    $update.show()
14010                    $cancel.show()
14011
14012                    if (isAdd) {
14013                        $update.hide()
14014                        $save.show()
14015                    }
14016                } else {
14017                    that.dialogEdit($tr, isAdd)
14018                }
14019
14020                e.stopPropagation()
14021            })
14022
14023            $save.on('click', function(e) {
14024                var $btn = $(this), $tr = $btn.closest('tr')
14025
14026                that.updateEdit($tr, $btn)
14027
14028                e.stopPropagation()
14029            }).on('bjui.datagrid.update.tr', function() {
14030                $btns.hide()
14031                $edit.show()
14032                $delete.show()
14033            })
14034
14035            $update.on('click', function(e) {
14036                var $btn = $(this), $tr = $btn.closest('tr')
14037
14038                that.updateEdit($tr, $btn)
14039
14040                e.stopPropagation()
14041            }).on('bjui.datagrid.update.tr', function() {
14042                $btns.hide()
14043                $edit.show()
14044                $delete.show()
14045            })
14046
14047            $cancel.on('click', function(e) {
14048                var $btn = $(this), $tr = $btn.closest('tr')
14049
14050                that.cancelEdit($tr)
14051
14052                $btns.hide()
14053                $edit.show()
14054                $delete.show()
14055
14056                e.stopPropagation()
14057            })
14058
14059            $delete.on('click', function(e) {
14060                var $btn = $(this), $tr = $btn.closest('tr')
14061
14062                that.delRows($tr)
14063
14064                e.stopPropagation()
14065            })
14066        })
14067    }
14068
14069    Datagrid.prototype.externalEdit = function(row, editOpts, data) {
14070        var that = this, options = that.options, editOptions = {}, $tr, data_index, editUrl, type, types = ['dialog', 'navtab', 'div']
14071
14072        if (editOpts && typeof editOpts === 'object') {
14073            for (var key in editOpts) {
14074                if ($.inArray(key, types) != -1) {
14075                    editOptions.type    = key
14076                    editOptions.options = editOpts[key]
14077
14078                    break
14079                }
14080            }
14081        } else
14082            editOptions = $.extend({}, that.editOptions)
14083
14084        if (row instanceof jQuery) {
14085            $tr = row
14086        } else if (!isNaN(row)) {
14087            $tr = that.$tbody.find('> tr:not(.'+ that.classnames.tr_child +')').eq(parseInt(row, 10))
14088        } else {
14089            BJUI.debug('BJUI.Datagrid: Func \'externalEdit\', Parameter \'row\' is incorrect!')
14090            return
14091        }
14092
14093        if (typeof editOptions === 'undefined') {
14094            BJUI.debug('BJUI.Datagrid: Func \'externalEdit\', Parameter \'editOptions\' is incorrect!')
14095            return
14096        }
14097
14098        if (!$.isEmptyObject(editOptions)) {
14099            if (!data) {
14100                if (that.isDom) data = $tr.data('initData') || that.tools.setDomData($tr)
14101                else {
14102                    data_index = that.tools.getNoChildDataIndex($tr.index())
14103                    data = that.data[data_index]
14104                }
14105            }
14106            if (!editOptions.options.url || editOptions.options['datagrid.nourl']) {
14107                editOptions.options['datagrid.nourl'] = true
14108                editOptions.options.url = options.editUrl
14109            }
14110
14111            editUrl = editOptions.options.url
14112
14113            if (editUrl && !editUrl.isFinishedTm()) {
14114                if (!data || data.addFlag)
14115                    editUrl = editUrl.replace(/{\/?[^}]*}/g, '')
14116                else
14117                    editUrl = that.tools.replacePlh(editUrl, data)
14118
14119                if (!editUrl.isFinishedTm()) {
14120                    BJUI.debug('BJUI.Datagrid: Func \'externalEdit\', the property \'url\' of options \'editOptions\' is 
14120incorrect: '+ editUrl)
14121                } else {
14122                    editUrl = editUrl
14123                }
14124            }
14125
14126            if (editUrl) {
14127                editOptions.options.url = editUrl
14128                type = editOptions.type
14129
14130                if (typeof data === 'object' && data) {
14131                    if (editOptions.options.data)
14132                        $.extend(editOptions.options.data, data)
14133                    else
14134                        editOptions.options.data = $.extend({}, data)
14135                }
14136
14137                for (var key in options.keys)
14138                    delete editOptions.options.data[key]
14139
14140                if (!editOptions.options.id)
14141                    editOptions.options.id = 'datagrid-external-edit'+ (new Date().getTime())
14142                if (!editOptions.options.type)
14143                    editOptions.options.type = options.editType
14144
14145                // onClose
14146                if (typeof options.extOnClose === 'undefined') {
14147                    options.extOnClose = (editOptions.options.onClose && editOptions.options.onClose.toFunc()) || false
14148                }
14149                // for dialog && navtab (if not save)
14150                editOptions.options.onClose = function() {
14151                    if ($tr.hasClass(that.classnames.tr_add))
14152                        that.cancelEdit($tr)
14153
14154                    if (typeof options.extOnClose !== 'undefined') {
14155                        if (options.extOnClose) {
14156                            options.extOnClose.apply(that)
14157                        }
14158                    }
14159                }
14160
14161                var okCallback = function(json) {
14162                    var complete = false, returnData, fixedWidth = false
14163
14164                    if (editOptions.options.data['addFlag'] && that.data.length == 1)
14165                        that.needfixedWidth = true
14166                    if ($.type(json) === 'array') {
14167                        complete   = true
14168                        returnData = json[0]
14169                    } else if (typeof json === 'object') {
14170                        complete = true
14171                        returnData = json
14172                    }
14173
14174                    if (complete) {
14175                        $.extend(data, typeof returnData === 'object' && returnData)
14176
14177                        if (that.allData && that.allData[data.gridIndex]) {
14178                            $.extend(that.allData[data.gridIndex], data)
14179                        }
14180
14181                        // update allData for filter
14182                        if (that.oldAllData) that.oldAllData = that.allData.concat()
14183
14184                        if (data.addFlag) data.addFlag = false
14185
14186                        that.dialogEditComplete($tr, data)
14187
14188                        if (type === 'dialog') {
14189                            if (editOptions.options.message)
14190                                BJUI.alertmsg('ok', editOptions.options.message)
14191                            if (typeof editOptions.options.closeCurrent === 'undefined' || editOptions.options.closeCurrent)
14192                                BJUI.dialog('close', editOptions.options.id)
14193                        }
14194                        else if (type === 'navtab')
14195                            BJUI.navtab('closeTab', editOptions.options.id)
14196
14197                        that.tools.afterSave($tr, data)
14198
14199                        // refresh child
14200                        if (data['refresh.datagrid.child']) {
14201                            var $child = $tr.data('bjui.datagrid.child')
14202
14203                            if ($child && $child.length)
14204                                $child.datagrid('refresh')
14205                            else
14206                                that.showChild($tr)
14207                        }
14208                    }
14209                }
14210
14211                editOptions.options.onLoad = function($box) {
14212                    var $form = $box.find('form.datagrid-edit-form')
14213
14214                    if ($form && $form.length) {
14215                        $form = $form.first()
14216
14217                        $form
14218                            .removeAttr('okCallback')
14219                            .data('okCallback', $.proxy(okCallback, that))
14220                    }
14221                }
14222
14223                if (type === 'dialog')
14224                    BJUI.dialog(editOptions.options)
14225                else if (type === 'navtab')
14226                    BJUI.navtab(editOptions.options)
14227                else if (type === 'div')
14228                    BJUI.ajax('doload', editOptions.options)
14229
14230            }
14231        }
14232    }
14233
14234    // Api - inline edit tr
14235    Datagrid.prototype.doEditRow = function(rows, type, isAdd,editOpts) {
14236        if (!this.editInit) return
14237        var editOpts = editOpts || [];
14238        //修改attrs disabled属性
14239        if(!editOpts.length==0){
14240            this.options.columns.forEach(function(item,index){
14241                item.attrs=editOpts[index]
14242            })
14243        }
14244
14245        var that = this, $trs, $editBtn, datas = []
14246
14247        type = type || that.options.editMode
14248
14249        if (typeof rows === 'object') {
14250            $trs = rows
14251        } else if (isNaN(rows)) {
14252            var $myTrs = that.$tbody.find('> tr:not(.'+ that.classnames.tr_child +')'), $editTrs, rows = rows.split(',')
14253
14254            rows = rows.unique()
14255            rows.sort(function(a, b) {return a.trim() - b.trim()})
14256
14257            $.each(rows, function(i, n) {
14258                var row = parseInt(n.trim(), 10), tr
14259
14260                tr = $myTrs.eq(row)
14261
14262                if (tr && tr.length) {
14263                    if (!$editTrs) $editTrs = tr
14264                    else $editTrs = $editTrs.add(tr)
14265                }
14266            })
14267
14268            $trs = $editTrs
14269        } else if (!isNaN(rows)) {
14270            $trs = that.$tbody.find('> tr:not(.'+ that.classnames.tr_child +')').eq(rows)
14271        }
14272
14273        if (!$trs.length) return
14274
14275        $trs.each(function() {
14276            var $tr = $(this), data_index = $tr.index(), data
14277
14278            data_index = that.tools.getNoChildDataIndex(data_index)
14279
14280            if (that.isDom) data = $tr.data('initData') || tools.setDomData($tr)
14281            else data = that.data[data_index]
14282
14283            datas.push(data)
14284        })
14285
14286        if (!that.tools.beforeEdit($trs, datas)) {
14287            return
14288        }
14289
14290        if (!that.options.editUrl) {
14291            BJUI.debug('BJUI.Datagrid: Edit url is not set!')
14292            return
14293        }
14294
14295        if (that.editOptions) {
14296            that.externalEdit($trs.last(), null, datas[$trs.length - 1])
14297        } else {
14298            $trs.each(function(i) {
14299                var $tr = $(this)
14300
14301                $editBtn = $tr.find('> td.'+ that.classnames.s_edit +' button.bjui-datagrid-btn.edit')
14302
14303                if (type != 'dialog') {
14304                    if ($editBtn.length) $editBtn.trigger('click', [datas[i]])
14305                    else that.inlineEdit($tr, isAdd, datas[i])
14306                } else {
14307                    that.dialogEdit($tr, isAdd, datas[i])
14308                    return false
14309                }
14310            })
14311        }
14312    }
14313
14314    // Api - cancel edit
14315    Datagrid.prototype.doCancelEditRow = function(row) {
14316        var that = this, $trs
14317
14318        if ($.type(row) === 'number') {
14319            $trs = this.$tbody.find('> tr').eq(row)
14320        } else {
14321            $trs = row
14322        }
14323
14324        $trs.each(function() {
14325            var $tr = $(this), $cancelBtn = $tr.find('> td.'+ that.classnames.s_edit +' > button.bjui-datagrid-btn.cancel')
14326
14327            if ($cancelBtn.length) {
14328                $cancelBtn.trigger('click')
14329            } else {
14330                that.cancelEdit($tr)
14331            }
14332        })
14333    }
14334
14335    // Api - save edit tr
14336    Datagrid.prototype.doSaveEditRow = function(row) {
14337        var that = this, options = that.options, $tr
14338
14339        if ($.type(row) === 'number') {
14340            $tr = this.$tbody.find('> tr').eq(row)
14341        } else if (row) {
14342            $tr = row
14343        } else {
14344            $tr = that.$tbody.find('> tr.'+ that.classnames.tr_edit)
14345        }
14346
14347        if (!$tr.length) {
14348            that.$grid.alertmsg('info', BJUI.getRegional('datagrid.saveMsg'))
14349            return
14350        }
14351        if ($tr.length == 1) {
14352            if ($tr.hasClass(that.classnames.tr_edit))
14353                this.updateEdit($tr)
14354        } else {
14355            if (options.saveAll) {
14356                that.saveAll($tr)
14357            } else {
14358                $tr.each(function() {
14359                    that.updateEdit($(this))
14360                })
14361            }
14362        }
14363    }
14364
14365    // Api - del tr
14366    Datagrid.prototype.delRows = function(rows) {
14367        var that  = this, options = that.options, keys = options.keys, beforeDelete = options.beforeDelete, confirmMsg = options.delConfirm, $trs
14368
14369        if (beforeDelete) {
14370            if (typeof beforeDelete === 'string') beforeDelete = beforeDelete.toFunc()
14371            if (typeof beforeDelete === 'function') {
14372                if (!beforeDelete.call(this)) {
14373                    return
14374                }
14375            }
14376        }
14377
14378        if (typeof rows === 'object') {
14379            $trs = rows
14380        } else if (isNaN(rows)) {
14381            var $myTrs = that.$tbody.find('> tr:not(.'+ that.classnames.tr_child +')'), $delTrs, rows = rows.split(',')
14382
14383            rows = rows.unique()
14384            rows.sort(function(a, b) {return a.trim() - b.trim()})
14385
14386            $.each(rows, function(i, n) {
14387                var tr = $myTrs.eq(parseInt(n.trim(), 10))
14388
14389                if (tr && tr.length) {
14390                    if (!$delTrs) $delTrs = tr
14391                    else $delTrs = $delTrs.add(tr)
14392                }
14393            })
14394
14395            $trs = $delTrs
14396        } else if (!isNaN(rows)) {
14397            $trs = this.$tbody.find('> tr:not(.'+ that.classnames.tr_child +')').eq(rows)
14398        }
14399
14400        if (!$trs || !$trs.length) return
14401
14402        var delEnd = function() {
14403            $trs.each(function() {
14404                var $tr = $(this), childUpdate = that.options.childUpdate, $parent = that.$element.data('bjui.datagrid.parent'),
14405                    updateParent = function($parent) {
14406                        $parent.closest('table').datagrid('updateRow', $parent)
14407                    }
14408                // update child parent
14409                if ($parent && childUpdate) {
14410                    if (typeof childUpdate === 'string') {
14411                        if (childUpdate.indexOf('all') !== -1 || childUpdate.indexOf('del') !== -1)
14412                            updateParent($parent)
14413                    } else {
14414                        updateParent($parent)
14415                    }
14416                }
14417
14418                $tr.trigger('delete.bjui.datagrid.tr')
14419            })
14420
14421            that.tools.afterDelete()
14422
14423            if (options.height === 'auto')
14424                that.fixedHeight()
14425        }
14426
14427        var doDel = function() {
14428            var $addTrs = $trs.filter('.'+ that.classnames.tr_add)
14429
14430            if ($addTrs.length) {
14431                that.cancelEdit($addTrs)
14432
14433                if (!$trs.not($addTrs).length)
14434                    return
14435            }
14436
14437            // remote delete
14438            if (options.delUrl) {
14439                var postData = [], callback = options.delCallback
14440
14441                $trs.not($addTrs).each(function() {
14442                    var $tr = $(this), index = $tr.index(), data, delData
14443
14444                    if (that.isDom) data = $tr.data('initData') || that.tools.setDomData($tr)
14445                    else data = that.data[that.tools.getNoChildDataIndex(index)]
14446
14447                    if (options.delPK) {
14448                        postData.push(data[options.delPK])
14449                    } else {
14450                        if (options.jsonPrefix) {
14451                            delData = {}
14452
14453                            $.each(data, function(name, value) {
14454                                if (!that.tools.isGridData(name))
14455                                    delData[options.jsonPrefix +'.'+ name] = value
14456                            })
14457                        } else {
14458                            delData = $.extend({}, data)
14459                            for (var key in keys)
14460                                delete delData[keys[key]]
14461                        }
14462
14463                        postData.push(delData)
14464                    }
14465                })
14466
14467                if (typeof callback === 'string') callback = callback.toFunc()
14468
14469                var type = options.delType, opts = {url:options.delUrl, data:(options.delPK ? [{ name:options.delPK, value:postData.join(',') }] : JSON.stringify(postData)), type:'POST', okCallback:callback || function(json) { delEnd() }}
14470
14471                if (type && type === 'raw' && !options.delPK) {
14472                    opts.contentType = 'application/json'
14473                } else {
14474                    !options.delPK && (opts.data = {json:opts.data})
14475                    type && type !== 'raw' && (opts.type = type)
14476                }
14477
14478                BJUI.ajax('doajax', opts)
14479            } else { // local delete
14480                delEnd()
14481            }
14482        }
14483
14484        if (confirmMsg) {
14485            if (typeof confirmMsg !== 'string') confirmMsg = $trs.length == 1 ? BJUI.getRegional('datagrid.delMsg') : BJUI.getRegional('datagrid.delMsgM')
14486
14487            that.$grid.alertmsg('confirm', confirmMsg, {
14488                okCall:function() {
14489                    doDel()
14490                }
14491            })
14492        } else {
14493            doDel()
14494        }
14495    }
14496
14497    // inline edit
14498    Datagrid.prototype.inlineEdit = function($tr, isAdd, data) {
14499        if (!this.tools.beforeEdit($tr, data)) {
14500            return false
14501        }
14502
14503        var that = this, options = that.options, tools = that.tools, columnModel = that.columnModel, $tds = $tr.find('> td'), tds_length = $tds.length, tr_index = $tr.index(), data_index = tr_index
14504
14505        data_index = tools.getNoChildDataIndex(data_index)
14506
14507        if (!data) {
14508            if (that.isDom) data = $tr.data('initData') || tools.setDomData($tr)
14509            else data = that.data[data_index]
14510        }
14511
14512        if ($tr.hasClass(that.classnames.tr_edit)) return false
14513        if (!that.inputs || !that.inputs.length) tools.initEditInputs()
14514
14515        $tr.addClass(that.classnames.tr_edit).data(that.datanames.changeData, {})
14516        if ($tr.data('validator')) $tr.validator('destroy') //remove old validate
14517
14518        if (!options.inlineEditMult) {
14519            that.doCancelEditRow($tr.siblings('.'+ that.classnames.tr_edit))
14520        }
14521
14522        that.$lastEditTr = $tr
14523
14524        $tds.each(function(i) {
14525            var $td = $(this), op = columnModel[i], val = op && op.name && data[op.name], html = $td.html(), input = that.inputs[i], $input
14526            var onChange = function($el, $td, val) {
14527                var changeData = $tr.data(that.datanames.changeData), jsontype = op.jsontype, defaultVal = (typeof op.defaultVal === 'undefined') ? null : op.defaultVal
14528
14529                switch (op.type) {
14530                    case 'date':
14531                        $el
14532                            .change(function() {
14533                                $td.addClass(that.classnames.td_changed)
14534                                if ($el.val() == val) $td.removeClass(that.classnames.td_changed)
14535                                changeData[op.name] = $el.val()
14536                            })
14537
14538                        break
14539                    case 'select':
14540                        var value = $el.val();
14541                        var text = $el.find('option:selected').text();//选中行text -- 2020-10-20
14542                        // console.log(value);
14543
14544                        // console.log(text);
14545
14546                        $td.addClass(that.classnames.td_changed)
14547                        if (value == String(val)) $td.removeClass(that.classnames.td_changed)
14548                        if ($el.prop('multiple')) {
14549                            $.isArray(value) && (value = value.join(','))
14550                        } else if (jsontype) {
14551                            if (jsontype === 'boolean') {
14552                                value = Boolean(value)
14553                            } else if (jsontype === 'number') {
14554                                if (value.length)
14555                                    !isNaN(Number(value)) && (value = Number(value))
14556                                else
14557                                    value = null
14558                            }
14559                        }
14560
14561                        changeData[op.name] = value;
14562                        $el.change(function() {
14563                            var value = $(this).val();
14564                            var text = $(this).find('option:selected').text();//选中行text -- 2020-10-20
14565
14566                            $td.addClass(that.classnames.td_changed)
14567
14568                            if (value == String(val)) $td.removeClass(that.classnames.td_changed)
14569
14570                            if ($el.prop('multiple')) {
14571                                $.isArray(value) && (value = value.join(','))
14572                            } else if (jsontype) {
14573                                if (jsontype === 'boolean') {
14574                                    value = Boolean(value)
14575                                } else if (jsontype === 'number') {
14576                                    if (value.length)
14577                                        !isNaN(Number(value)) && (value = Number(value))
14578                                    else
14579                                        value = null
14580                                }
14581                            }
14582
14583                            changeData[op.name] = value;
14584
14585                            //增加: 切换下拉框值后调用的方法 -- 2020-10-20
14586                            if(!commonBlank(op.change)){
14587                                op.change(value,text,$el);
14588                            }
14589
14590                        })
14591
14592                        break
14593                    case 'boolean':
14594                        $el.on('ifChanged', function() {
14595                            $td.toggleClass(that.classnames.td_changed)
14596
14597                            var checked = $(this).is(':checked')
14598
14599                            if (checked == val)
14600                                $td.removeClass(that.classnames.td_changed)
14601
14602                            changeData[op.name] = checked
14603                        })
14604
14605                        break
14606                    case 'findgrid':
14607                        changeData[op.name] = $el.val()
14608
14609                        $el.change(function() {
14610                            var value = $(this).val()
14611
14612                            $td.addClass(that.classnames.td_changed)
14613
14614                            if (value == val)
14615                                $td.removeClass(that.classnames.td_changed)
14616                            if (jsontype && jsontype === 'number') {
14617                                if (value.length)
14618                                    !isNaN(Number(value)) && (value = Number(value))
14619                                else
14620                                    value = null
14621                            }
14622
14623                            changeData[op.name] = value
14624                        })
14625
14626                        $td.off('afterchange.bjui.findgrid').on('afterchange.bjui.findgrid', '[data-toggle="findgrid"]', function(e, data) {
14627                            var include = op.attrs && op.attrs['data-options'] && op.attrs['data-options']['include']
14628
14629                            if (include) {
14630                                $.each(include.split(','), function(i, n) {
14631                                    var obj = n.trim().split(':'), name = obj[0], key = obj.length > 1 ? obj[1] : obj[0]
14632
14633                                    data['data'] && (changeData[name] = data['data'][key])
14634                                })
14635                            }
14636                        })
14637
14638                        break
14639                    case 'spinner':
14640                        $el.change(function() {
14641                            $td.addClass(that.classnames.td_changed)
14642                            if ($el.val() == val) $td.removeClass(that.classnames.td_changed)
14643                            changeData[op.name] = Number($el.val())
14644                        })
14645
14646                        break
14647                    default:
14648                        $el.change(function() {
14649                            var value = $(this).val()
14650
14651                            $td.addClass(that.classnames.td_changed)
14652
14653                            if (value == val)
14654                                $td.removeClass(that.classnames.td_changed)
14655                            if (jsontype && jsontype === 'number') {
14656                                if (value.length)
14657                                    !isNaN(Number(value)) && (value = Number(value))
14658                                else
14659                                    value = null
14660                            }
14661
14662                            changeData[op.name] = value
14663                        })
14664
14665                        break
14666                }
14667
14668                if (isAdd) {
14669                    if (op.type === 'boolean') {
14670                        defaultVal = Boolean(defaultVal)
14671                        changeData[op.name] = defaultVal
14672                        $el.prop('checked', defaultVal)
14673                    } else {
14674                        if (defaultVal != null) {
14675                            if ($el.isTag('select') && $el.prop('multiple')) {
14676                                $el.val($.isArray(defaultVal) ? defaultVal : defaultVal.split(','))
14677                            } else {
14678                                $el.val(String(defaultVal))
14679                            }
14680                            if (jsontype) {
14681                                if (jsontype === 'number') {
14682                                    if (defaultVal.length)
14683                                        !isNaN(Number(defaultVal)) && (defaultVal = Number(defaultVal))
14684                                    else
14685                                        defaultVal = null
14686                                }
14687                                else if (jsontype === 'boolean')
14688                                    defaultVal = Boolean(defaultVal)
14689                            }
14690
14691                            changeData[op.name] = defaultVal
14692                        } else {
14693                            if(!that.moreadd){
14694                                if (($el.isTag('select') && !$el.prop('multiple'))) {
14695                                    var $clone = $el.clone().appendTo('body'), val = $clone.val()
14696
14697                                    changeData[op.name] = val
14698                                    $clone.remove()
14699                                }
14700
14701                            }
14702                        }
14703                    }
14704                } else if (jsontype) {
14705                    $el.trigger('change')
14706                }
14707            }
14708
14709            $td.data(that.datanames.td_html, html)
14710
14711            if (isAdd) {
14712                if (!op.add) input = ''
14713            } else {
14714                if (data.addFlag) data.addFlag = false
14715                if (!op.edit) input = ''
14716            }
14717
14718            if (input) {
14719                $input = $(input)
14720
14721                if (typeof val === 'undefined' || val === 'null' || val === null)
14722                    val = ''
14723
14724                if (op.type === 'boolean')
14725                    $input.prop('checked', val)
14726                else if (op.type === 'findgrid')
14727                    $input.data('context', $tr).val(String(val))
14728                else {
14729                    $input.val(String(val))
14730
14731                    if ($input.isTag('select') && $input.prop('multiple') && val && !$.isArray(val)) {
14732                        $input.val(val.split(','))
14733                    }
14734                }
14735
14736                if (isAdd) {
14737                    if (op.addAttrs && typeof op.addAttrs === 'object') {
14738                        $.each(op.addAttrs, function(i, n) {
14739                            $input.attr(i, n)
14740                        })
14741                    }
14742                } else {
14743                    if (op.editAttrs && typeof op.editAttrs === 'object') {
14744                        $.each(op.editAttrs, function(i, n) {
14745                            $input.attr(i, n)
14746                        })
14747                    }
14748                }
14749
14750                $td
14751                    .empty()
14752                    .append($input)
14753                    .addClass(that.classnames.td_edit)
14754
14755                if (that.treeColumn && that.treeColumn === op) {
14756                    var treeInput = that.tools.createTreePlaceholder(data, '')
14757
14758                    $td.attr('align', 'left').html(treeInput)
14759
14760                    $input.appendTo($td.find('.datagrid-tree-title'))
14761                }
14762
14763                onChange($input, $td, val)
14764
14765                if (op.locked) {
14766                    var $lockTr = that.$lockTbody.find('tr:eq('+ tr_index +')')
14767                    var $lockTd = $lockTr.find('> td:eq('+ op.lockIndex +')')
14768
14769                    $td.clone().html(html).insertAfter($td)
14770                    $td.show().insertAfter($lockTd).initui()
14771                    $lockTd.remove()
14772                }
14773            }
14774
14775            if (!--tds_length) {
14776                $tr
14777                    .initui()
14778                    .validator({
14779                        msgClass : 'n-bottom',
14780                        theme    : 'red_bottom_effect_grid'
14781                    })
14782            }
14783        })
14784    }
14785
14786    Datagrid.prototype.saveAll = function($trs) {
14787        var that = this, options = that.options, keys = options.keys, callback = options.editCallback, $tr, data, data_index, datas = [], changeData, tempData, postData = [], returnData = [], len = $trs && $trs.length
14788
14789        if (!$trs || $trs.length) {
14790            $trs = that.$tbody.find('> tr.'+ that.classnames.tr_edit)
14791            len  = $trs.length
14792        }
14793
14794        if (!len) return
14795
14796        $trs.each(function() {
14797            $tr = $(this)
14798
14799            data_index = that.tools.getNoChildDataIndex($tr.index())
14800            data = that.isDom ? $tr.data('initData') : that.data[data_index]
14801            datas.push(data)
14802
14803            $tr.isValid(function(v) {
14804                if (v) {
14805                    // Update data
14806                    changeData = $tr.data(that.datanames.changeData)
14807                    $.extend(data, changeData)
14808                    // Specification post data
14809                    if (options.jsonPrefix) {
14810                        tempData = {}
14811
14812                        $.each(data, function(name, value) {
14813                            if (!that.tools.isGridData(name))
14814                                tempData[options.jsonPrefix +'.'+ name] = value
14815                        })
14816                    } else {
14817                        tempData = $.extend({}, data)
14818
14819                        for (var key in keys)
14820                            delete tempData[keys[key]]
14821                    }
14822
14823                    len --
14824                    postData.push(tempData)
14825                } else {
14826                    postData = []
14827
14828                    return false
14829                }
14830            })
14831        })
14832
14833        // do save
14834        if (!len) {
14835            // Callback
14836            if (callback) {
14837                callback = callback.toFunc()
14838            } else {
14839                callback = function(json) {
14840                    if ($.type(json) === 'array') {
14841                        returnData = json
14842                    } else if (typeof json === 'object') {
14843                        returnData.push(json)
14844                    }
14845
14846                    $trs.each(function(i) {
14847                        $tr = $(this)
14848                        data_index = $tr.index()
14849
14850                        if (that.columnModel[0] === that.childColumn)
14851                            data_index = data_index / 2
14852
14853                        data = that.isDom ? $tr.data('initData') : that.data[data_index]
14854
14855                        $.extend(data, typeof returnData[i] === 'object' && returnData[i])
14856
14857                        if (that.allData && that.allData[data.gridIndex]) {
14858                            $.extend(that.allData[data.gridIndex], data)
14859                        }
14860
14861                        // update allData for filter
14862                        if (that.oldAllData) that.oldAllData = that.allData.concat()
14863
14864                        that.inlineEditComplete($tr, data)
14865                    })
14866
14867                    that.tools.afterSave($trs, postData)
14868                }
14869            }
14870            if (that.options.saveLocal) {
14871                callback(postData)
14872            } else {
14873                // Do ajax
14874                if (that.tools.beforeSave($trs, datas)) {
14875                    var type = options.editType, opts = {url:options.editUrl, data:JSON.stringify(postData), type:'POST', okCallback:callback}
14876
14877                    if (type && type === 'raw') {
14878                        opts.contentType = 'application/json'
14879                    } else {
14880                        opts.data = {json:opts.data}
14881                        type && (opts.type = type)
14882                    }
14883
14884                    BJUI.ajax('doajax', opts)
14885                }
14886            }
14887        }
14888    }
14889
14890    // update - inline edit
14891    Datagrid.prototype.updateEdit = function($tr, $btn) {
14892        var that = this, options = that.options, keys = options.keys, callback = options.editCallback, data, datas = [], changeData, tempData, postData = [], returnData, data_index = $tr.index()
14893
14894        data_index = that.tools.getNoChildDataIndex(data_index)
14895
14896        if (that.isDom) data = $tr.data('initData')
14897        else data = that.data[data_index]
14898
14899        if ($tr.hasClass(that.classnames.tr_edit)) {
14900            // validate
14901            $tr.isValid(function(v) {
14902                if (v) {
14903                    // Update data
14904                    changeData = $tr.data(that.datanames.changeData)
14905                    $.extend(data, changeData)
14906                    // Specification post data
14907                    if (options.jsonPrefix) {
14908                        tempData = {}
14909                        $.each(data, function(name, value) {
14910                            if (!that.tools.isGridData(name))
14911                                tempData[options.jsonPrefix +'.'+ name] = value
14912                        })
14913                    } else {
14914                        tempData = $.extend({}, data)
14915
14916                        for (var key in keys) {
14917                            delete tempData[keys[key]]
14918                        }
14919                    }
14920                    // Callback
14921                    if (callback) {
14922                        callback = callback.toFunc()
14923                    } else {
14924                        callback = function(json) {
14925                            if ($.type(json) === 'array') {
14926                                returnData = json[0]
14927                            } else if (typeof json === 'object') {
14928                                returnData = json
14929                            }
14930
14931                            $.extend(data, typeof returnData === 'object' && returnData)
14932
14933                            if (that.allData && that.allData[data.gridIndex]) {
14934                                $.extend(that.allData[data.gridIndex], data)
14935                            }
14936
14937                            // update allData for filter
14938                            if (that.oldAllData) that.oldAllData = that.allData.concat()
14939
14940                            that.inlineEditComplete($tr, data, $btn)
14941                            that.tools.afterSave($tr, data)
14942                        }
14943                    }
14944                    // Do ajax
14945                    datas.push(data)
14946                    if (that.tools.beforeSave($tr, datas)) {
14947                        postData.push(tempData)
14948
14949                        var type = options.editType, opts = {url:options.editUrl, data:JSON.stringify(postData), type:'POST', okCallback:callback}
14950
14951                        if (type && type === 'raw') {
14952                            opts.contentType = 'application/json'
14953                        } else {
14954                            opts.data = {json:opts.data}
14955                            type && (opts.type = type)
14956                        }
14957
14958                        BJUI.ajax('doajax', opts)
14959                    }
14960                }
14961            })
14962        }
14963    }
14964
14965    /* cancel - inline edit */
14966    Datagrid.prototype.cancelEdit = function($trs) {
14967        var that = this, columnModel = that.columnModel
14968
14969        $trs.each(function() {
14970            var $tr = $(this), tr_index = $tr.index(), data_index = tr_index
14971
14972            if ($tr.hasClass(that.classnames.tr_edit)) {
14973                $tr
14974                    .removeClass(that.classnames.tr_edit)
14975                    .find('> td.'+ that.classnames.td_edit).each(function() {
14976                    var $td = $(this), td_index = $td.index(), model = columnModel[td_index], html = $td.data(that.datanames.td_html)
14977
14978                    $td.removeClass(that.classnames.td_edit).removeClass(that.classnames.td_changed).html(html)
14979                    if (model.locked) {
14980                        var $lockTr = that.$lockTbody.find('tr:eq('+ tr_index +')')
14981                        var $lockTd = $lockTr.find('> td:eq('+ model.lockIndex +')')
14982
14983                        html = $lockTd.data(that.datanames.td_html)
14984
14985                        $lockTr.removeClass(that.classnames.tr_edit)
14986                        $lockTd.removeClass(that.classnames.td_edit).removeClass(that.classnames.td_changed).html(html)
14987                    }
14988                })
14989            }
14990
14991            if ($tr.hasClass(that.classnames.tr_add)) {
14992                data_index = that.tools.getNoChildDataIndex(data_index)
14993
14994                if (!that.isDom) {
14995                    that.allData = that.allData.remove(that.data[data_index].gridIndex)   // remove data in allData
14996                    that.data    = that.data.remove(data_index)
14997
14998                    that.tools.updateGridIndex()
14999                    that.$element.data('allData', that.allData)
15000                }
15001
15002                if ($tr.next().hasClass(that.classnames.tr_child)) {
15003                    $tr.next().remove()
15004                    that.$lockTbody && that.$lockTbody.find('> tr:eq('+ tr_index +')').next().remove()
15005                }
15006
15007                that.$lockTbody && that.$lockTbody.find('> tr:eq('+ tr_index +')').remove()
15008                $tr.remove()
15009
15010                that.tools.createNoDataTr()
15011
15012                if (that.options.height === 'auto')
15013                    that.fixedHeight()
15014            }
15015        })
15016    }
15017
15018    // inline editComplete
15019    Datagrid.prototype.inlineEditComplete = function($tr, trData, $btn) {
15020        var that = this, columnModel = that.columnModel, tr_index = $tr.index(), $tds = $tr.find('> td'), hasLinenumber = false, $lockTr = that.$lockTbody && that.$lockTbody.find('> tr:eq('+ tr_index +')')
15021        var tdTemplate = that.options.tdTemplate, tempData = $.extend({}, trData)
15022
15023        $.each(columnModel, function(i, n) {
15024            if (n === that.linenumberColumn) hasLinenumber = true
15025            if (that.tools.isGridModel(n)) return true
15026
15027            var label = n.name ? trData[n.name] : '', render_label, $td = $tds.eq(n.index)
15028
15029            if (that.isTemplate)
15030                $td = null
15031            if (typeof label === 'undefined' || label === 'null' || label === null)
15032                label = ''
15033
15034            $td && ($td.text(label).removeClass(that.classnames.td_edit).removeClass(that.classnames.td_changed))
15035
15036            if (n.render && typeof n.render === 'function') {
15037                if (n.items) {
15038                    render_label = n.render.call(that, label, trData, n.items, n.itemattr)
15039                    tempData[n.name] = render_label
15040                    $td && $td.html(render_label)
15041                } else {
15042                    render_label = n.render.call(that, label, trData)
15043                    tempData[n.name] = render_label
15044                    $td && $td.html(render_label)
15045                }
15046            } else if (n.items) {
15047                render_label = Datagrid.renderItem.call(that, label, trData, n.items, n.itemattr)
15048                tempData[n.name] = render_label
15049                $td && $td.html(render_label)
15050            }
15051
15052            if (that.options.isTree && n.hasTree) {
15053                $td && ($td.attr('align', 'left').addClass('datagrid-tree-td').html(that.tools.createTreePlaceholder(trData, (render_label || label))))
15054            }
15055
15056            if (n.locked && $lockTr) {
15057                var $lockTd = $lockTr.find('> td:eq('+ n.lockIndex +')')
15058
15059                $lockTd.removeClass(that.classnames.td_changed).html($td.html())
15060            }
15061        })
15062
15063        if (that.isTemplate) {
15064            if (typeof tdTemplate === 'function')
15065                tdTemplate = tdTemplate.apply(that, [trData])
15066
15067            tdTemplate = that.tools.replacePlh4Template(tdTemplate, tempData)
15068
15069            $tr.find('> td.datagrid-template-td').html(tdTemplate)
15070        }
15071
15072        $tr.removeClass(that.classnames.tr_edit).initui()
15073        if ($lockTr)
15074            $lockTr.removeClass(that.classnames.tr_edit).initui()
15075
15076        if (!$btn) $btn = $tds.filter('.'+ that.classnames.s_edit).find('button.update')
15077        if ($btn && $btn.length)
15078            $btn.trigger('bjui.datagrid.update.tr')
15079
15080        if ($tr.hasClass(that.classnames.tr_add)) {
15081            $tr.removeClass(that.classnames.tr_add)
15082            $tr.find('> td.'+ that.classnames.s_edit).removeData('isAdd')
15083
15084            // update linenumber
15085            if (hasLinenumber) {
15086                that.tools.updateLinenumber()
15087            }
15088
15089            // tree
15090            if (that.options.isTree) {
15091                var $parentTr = trData[that.options.keys.treePTr], parentData = trData[that.options.keys.treePData], keys = that.options.treeOptions.keys, $treePTd
15092
15093                if ($parentTr && parentData) {
15094                    if (!parentData[keys.isParent]) {
15095                        parentData[keys.isParent] = true
15096                        $treePTd = $parentTr.find('> td.datagrid-tree-td')
15097                        $treePTd.html(that.tools.createTreePlaceholder(parentData, $treePTd.find('span.datagrid-tree-title').html()))
15098                    }
15099                    if (!parentData[keys.childLen]) {
15100                        parentData[keys.childLen] = 1
15101                    } else {
15102                        parentData[keys.childLen] ++
15103                    }
15104
15105                    $tr.data(that.options.keys.treePTr).data('child', parentData[keys.childLen]).attr('data-child', parentData[keys.childLen])
15106                }
15107
15108                $tr.addClass('datagrid-tree-tr datagrid-tree-level-'+ trData[keys.level]).attr('data-child', 0).attr('data-level', trData[keys.level])
15109            }
15110
15111            // child
15112            $tr.next('.'+ that.classnames.tr_child).remove()
15113            that.tools.createChildTr($tr, trData)
15114        }
15115    }
15116
15117    // inline edit
15118    Datagrid.prototype.dialogEdit = function($tr, isAdd, data) {
15119        if (!this.tools.beforeEdit($tr, data)) {
15120            return false
15121        }
15122
15123        var that = this, options = that.options, tools = that.tools, columnModel = that.columnModel, tr_index = $tr.index(), data_index = tr_index, $dialog, $form, html = '', title
15124
15125        if (!data) {
15126            data_index = tools.getNoChildDataIndex(data_index)
15127
15128            if (that.isDom) data = $tr.data('initData') || tools.setDomData($tr)
15129            else data = that.data[data_index]
15130        }
15131
15132        if (!that.inputs || !that.inputs.length) tools.initEditInputs()
15133
15134        title = options.gridTitle || 'datagrid'
15135
15136        if (isAdd) {
15137            title += ' - '+ BJUI.getRegional('datagrid.add')
15138        } else {
15139            if (data.addFlag) data.addFlag = false
15140            title += ' - '+ BJUI.getRegional('datagrid.edit')
15141        }
15142
15143        $dialog = $('<div><div class="bjui-pageContent"></div><div class="bjui-pageFooter"></div></div>')
15144        $form   = $('<form class="datagrid-dialog-edit-form"></form>')
15145
15146        var onChange = function($tr, $form, $el, model) {
15147            var changeData = $tr.data(that.datanames.changeData), jsontype = model.jsontype, defaultVal = (typeof model.defaultVal === 'undefined') ? null : model.defaultVal
15148
15149            switch (model.type) {
15150                case 'date':
15151                    $el.change(function() {
15152                        changeData[model.name] = $(this).val()
15153                    })
15154
15155                    break
15156                case 'select':
15157                    $el.change(function() {
15158                        var $element = $(this), val = $element.val(), multiple = $element.prop('multiple')
15159
15160                        if (multiple && $.isArray(val)) {
15161                            val = val.join(',')
15162                        }
15163                        if (!multiple && jsontype) {
15164                            if (jsontype === 'boolean') {
15165                                val = Boolean(val)
15166                            } else if (jsontype === 'number') {
15167                                if (val.length)
15168                                    !isNaN(Number(val)) && (val = Number(val))
15169                                else
15170                                    val = null
15171                            }
15172                        }
15173
15174                        changeData[model.name] = val
15175                    })
15176
15177                    break
15178                case 'boolean':
15179                    $el.on('ifChanged', function() {
15180                        changeData[model.name] = $(this).is(':checked')
15181                    })
15182
15183                    break
15184                case 'findgrid':
15185                    $el.change(function() {
15186                        var val = data.value
15187
15188                        if (jsontype && jsontype === 'number') {
15189                            if (val.length)
15190                                !isNaN(Number(val)) && (val = Number(val))
15191                            else
15192                                val = null
15193                        }
15194
15195                        changeData[model.name] = $(this).val()
15196                    })
15197
15198                    $form.off('afterchange.bjui.findgrid').on('afterchange.bjui.findgrid', '[data-toggle="findgrid"]', function(e, data) {
15199                        var include = model.attrs && model.attrs['data-options'] && model.attrs['data-options']['include']
15200
15201                        if (include) {
15202                            $.each(include.split(','), function(i, n) {
15203                                var obj = n.trim().split(':'), name = obj[0], key = obj.length > 1 ? obj[1] : obj[0]
15204
15205                                data['data'] && (changeData[name] = data['data'][key])
15206                            })
15207                        }
15208                    })
15209
15210                    break
15211                case 'spinner':
15212                    $el.change(function() {
15213                        changeData[model.name] = Number($(this).val())
15214                    })
15215
15216                    break
15217                default:
15218                    $el.change(function() {
15219                        var val = $(this).val()
15220
15221                        if (jsontype && jsontype === 'number') {
15222                            if (val.length)
15223                                !isNaN(Number(val)) && (val = Number(val))
15224                            else
15225                                val = null
15226                        }
15227
15228                        changeData[model.name] = val
15229                    })
15230
15231                    break
15232            }
15233
15234            if (isAdd) {
15235                if (model.type === 'boolean') {
15236                    defaultVal = Boolean(defaultVal)
15237                    changeData[model.name] = defaultVal
15238                    $el.prop('checked', defaultVal)
15239                } else {
15240                    if (defaultVal != null) {
15241                        if ($el.isTag('select') && $el.prop('multiple')) {
15242                            $el.val($.isArray(defaultVal) ? defaultVal : defaultVal.split(','))
15243                        } else {
15244                            $el.val(String(defaultVal))
15245                        }
15246                        if (jsontype) {
15247                            if (jsontype === 'number')
15248                                !isNaN(Number(defaultVal)) && (defaultVal = Number(defaultVal))
15249                            else if (jsontype === 'boolean')
15250                                defaultVal = Boolean(defaultVal)
15251                        }
15252
15253                        changeData[model.name] = defaultVal
15254                    } else {
15255                        //($el.isTag('select') && !$el.prop('multiple')) && (changeData[model.name] = $el.val())
15256                        if (($el.isTag('select') && !$el.prop('multiple'))) {
15257                            var $clone = $el.clone().appendTo('body'), val = $clone.val()
15258
15259                            changeData[model.name] = val
15260                            $clone.remove()
15261                        }
15262                    }
15263                }
15264            } else if (jsontype) {
15265                $el.trigger('change')
15266            }
15267        }
15268
15269        var onLoad = function($dialog) {
15270            var $form   = $dialog.find('form.datagrid-dialog-edit-form'),
15271                $btns   = $dialog.find('div.bjui-pageFooter button'),
15272                $prev   = $btns.first(),
15273                $next   = $btns.eq(1),
15274                $cancel = $btns.eq(2),
15275                $save   = $btns.last(),
15276                trindex, dataindex
15277
15278            var createForm = function(data, $form, $tr) {
15279                $form.empty()
15280                if (!$tr.data(that.datanames.changeData)) $tr.data(that.datanames.changeData, {})
15281
15282                if ($form.data('validator')) $form.validator('destroy')
15283
15284                $.each(columnModel, function(i, n) {
15285                    if (!n.name || that.tools.isGridModel(n)) return true
15286
15287                    var input = that.inputs[i], $input, $p = $('<p></p>'), id = 'datagrid-dialog-edit-column-'+ i, val = data[n.name]
15288
15289                    if (n.hide) $p.addClass('hide')
15290                    if (isAdd) {
15291                        if (!n.add) input = ''
15292                    } else {
15293                        if (!n.edit) input = ''
15294                    }
15295
15296                    if (typeof val === 'undefined' || val === 'null' || val === null)
15297                        val = ''
15298
15299                    if (input) {
15300                        $input = $(input).attr('id', id)
15301                        if ($input.isTag('select')) $input.attr('data-width', 'auto')
15302                        else if (!$input.isTag('checkbox')) $input.attr('size', 30)
15303
15304                        if (n.type === 'boolean') {
15305                            $input.prop('checked', val)
15306                        } else if (n.type === 'findgrid') {
15307                            $input.val(String(val)).data('context', $form)
15308                        } else {
15309                            $input.val(String(val))
15310                        }
15311
15312                        if ($input.isTag('select') && $input.prop('multiple') && val && !$.isArray(val)) {
15313                            $input.val(val.split(','))
15314                        }
15315
15316                        if (isAdd) {
15317                            if (n.addAttrs && typeof n.addAttrs === 'object') {
15318                                $.each(n.addAttrs, function(k, v) {
15319                                    $input.attr(k, v)
15320                                })
15321                            }
15322                        } else {
15323                            if (n.editAttrs && typeof n.editAttrs === 'object') {
15324                                $.each(n.editAttrs, function(k, v) {
15325                                    $input.attr(k, v)
15326                                })
15327                            }
15328                        }
15329                    } else if (!isAdd) {
15330                        if (!n.edit)
15331                            input = val
15332                    }
15333
15334                    $p
15335                        .append('<label class="control-label x120" for="'+ id +'">'+ n.label +':</label>')
15336                        .append($('<span class="datagrid-dialog-column-span"></span>').append($input || input))
15337                        .appendTo($form)
15338
15339                    if ($input)
15340                        onChange($tr, $form, $input, n)
15341                })
15342
15343                $form
15344                    .initui()
15345                    .validator({
15346                        msgClass : 'n-bottom',
15347                        theme    : 'red_bottom_effect_grid'
15348                    })
15349            }
15350
15351            if ($form.is(':empty')) createForm(data, $form, $tr)
15352
15353            trindex = $tr.index()
15354
15355            if (that.columnModel[0] === that.childColumn)
15356                trindex = trindex * 2
15357
15358            if (!trindex) $prev.addClass('disabled')
15359            if (trindex == that.data.length - 1) $next.addClass('disabled')
15360
15361            $prev.click(function() {
15362                var $tr_prev = $tr.prev(), data
15363
15364                if (that.options.hasChild && that.options.childOptions)
15365                    $tr_prev = $tr_prev.prev()
15366                if ($tr_prev.length) {
15367                    dataindex = that.tools.getNoChildDataIndex($tr_prev.index())
15368
15369                    if (that.isDom) {
15370                        data = $tr_prev.data('initData') || tools.setDomData($tr_prev)
15371                    } else {
15372                        data = that.data[dataindex]
15373                    }
15374
15375                    $tr = $tr_prev
15376                    createForm(data, $form, $tr)
15377                    $next.removeClass('disabled')
15378
15379                    if (!$tr_prev.prev().length) $prev.addClass('disabled')
15380                } else {
15381                    $prev.addClass('disabled')
15382                }
15383            })
15384
15385            $next.click(function() {
15386                var $tr_next = $tr.next(), data, $next_next
15387
15388                if (that.options.hasChild && that.options.childOptions)
15389                    $tr_next = $tr_next.next()
15390                if ($tr_next.length) {
15391                    $next_next = $tr_next.next()
15392                    dataindex  = that.tools.getNoChildDataIndex($tr_next.index())
15393
15394                    if (that.options.hasChild && that.options.childOptions)
15395                        $next_next = $next_next.length && $next_next.next()
15396                    if (that.isDom) {
15397                        data = $tr_next.data('initData') || tools.setDomData($tr_next)
15398                    } else {
15399                        data = that.data[dataindex]
15400                    }
15401
15402                    $tr = $tr_next
15403                    createForm(data, $form, $tr)
15404                    $form.initui()
15405                    $prev.removeClass('disabled')
15406
15407                    if (!$next_next || !$next_next.length) $next.addClass('disabled')
15408                } else {
15409                    $next.addClass('disabled')
15410                }
15411            })
15412
15413            $save.click(function() {
15414                var changeData, data, datas = [], postData, returnData, callback = options.editCallback
15415
15416                dataindex = that.tools.getNoChildDataIndex($tr.index())
15417
15418                if (that.isDom) data = $tr.data('initData')
15419                else data = that.data[dataindex]
15420
15421                $form.isValid(function(v) {
15422                    if (v) {
15423                        changeData = $tr.data(that.datanames.changeData)
15424                        $.extend(data, changeData)
15425
15426                        if (options.jsonPrefix) {
15427                            postData = {}
15428                            $.each(data, function(name, value) {
15429                                if (!that.tools.isGridData(name))
15430                                    postData[options.jsonPrefix +'.'+ name] = value
15431                            })
15432                        } else {
15433                            postData = $.extend({}, data)
15434
15435                            for (var key in that.options.keys)
15436                                delete postData[that.options.keys[key]]
15437                        }
15438
15439                        // Callback
15440                        if (callback) {
15441                            callback = callback.toFunc()
15442                        } else {
15443                            callback = function(json) {
15444                                if ($.type(json) === 'array') {
15445                                    returnData = json[0]
15446                                } else if (typeof json === 'object') {
15447                                    returnData = json
15448                                }
15449
15450                                $.extend(data, typeof returnData === 'object' && returnData)
15451
15452                                that.dialogEditComplete($tr, data)
15453                                that.$grid.dialog('close', 'datagrid-dialog-edit')
15454                                that.tools.afterSave($tr, data)
15455                            }
15456                        }
15457
15458                        // Do ajax
15459                        datas.push(data)
15460                        if (that.tools.beforeSave($tr, datas)) {
15461                            var type = options.editType, opts = {url:options.editUrl, data:JSON.stringify(postData), type:'POST', okCallback:callback}
15462
15463                            if (type && type === 'raw') {
15464                                opts.contentType = 'application/json'
15465                            } else {
15466                                opts.data = {json:opts.data}
15467                                type && (opts.type = type)
15468                            }
15469
15470                            BJUI.ajax('doajax', opts)
15471                        }
15472                    }
15473                })
15474            })
15475
15476            $cancel.click(function() {
15477                that.$grid.dialog('close', 'datagrid-dialog-edit')
15478            })
15479        }
15480
15481        var onClose = function() {
15482            var addRemove = false
15483
15484            that.$tbody.find('> tr.'+ that.classnames.tr_add).each(function() {
15485                var $tr = $(this), trindex = $tr.index(), dataindex = trindex
15486
15487                dataindex = that.tools.getNoChildDataIndex(dataindex)
15488
15489                that.data = that.data.remove(dataindex)
15490
15491                if ($tr.next().hasClass(that.classnames.tr_child)) {
15492                    $tr.next().remove()
15493                    that.$lockTbody && that.$lockTbody.find('> tr:eq('+ trindex +')').next().remove()
15494                }
15495
15496                that.$lockTbody && that.$lockTbody.find('> tr:eq('+ trindex +')').remove()
15497                $tr.remove()
15498
15499                addRemove = true
15500            })
15501
15502            if (addRemove && that.options.height === 'auto')
15503                that.fixedHeight()
15504        }
15505
15506        $dialog.find('> div:first')
15507            .append($form)
15508            .next().append(BJUI.doRegional(FRAG.gridDialogEditBtns, that.regional))
15509
15510        var dialog_options = $.extend({}, {id:'datagrid-dialog-edit', fresh:true, target:$dialog[0], width:520, height:400, mask:true, title:title, onLoad:onLoad, onClose:onClose}, (typeof options.editDialogOp === 'object' && options.editDialogOp))
15511
15512        that.$grid.dialog(dialog_options)
15513    }
15514
15515    // dialog editComplete
15516    Datagrid.prototype.dialogEditComplete = function($tr, trData) {
15517        var that = this, columnModel = that.columnModel, tr_index = $tr.index(), $tds = $tr.find('> td'), hasLinenumber = false, $trs = that.$tbody.find('> tr'), $lockTr = that.$lockTbody && that.$lockTbody.find('> tr:eq('+ tr_index +')')
15518        var tdTemplate = that.options.tdTemplate, tempData = $.extend({}, trData), treeOptions = that.options.treeOptions, treePData, treePTr, treePTd
15519
15520        $.each(columnModel, function(i, n) {
15521            if (n === that.linenumberColumn) hasLinenumber = true
15522            if (that.tools.isGridModel(n)) return true
15523
15524            var label = n.name ? trData[n.name] : '', render_label, $td = $tds.eq(n.index)
15525
15526            if (that.isTemplate)
15527                $td = null
15528            if (typeof label === 'undefined' || label === 'null' || label === null)
15529                label = ''
15530
15531            $td && ($td.text(label).removeClass(that.classnames.td_edit).removeClass(that.classnames.td_changed))
15532
15533            if (n.render && typeof n.render === 'function') {
15534                if (n.items) {
15535                    render_label = n.render.call(that, label, trData, n.items, n.itemattr)
15536                    tempData[n.name] = render_label
15537                    $td && $td.html(render_label)
15538                } else {
15539                    render_label = n.render.call(that, label, trData)
15540                    tempData[n.name] = render_label
15541                    $td && $td.html(render_label)
15542                }
15543            } else if (n.items) {
15544                render_label = Datagrid.renderItem.call(that, label, trData, n.items, n.itemattr)
15545                tempData[n.name] = render_label
15546                $td && $td.html(render_label)
15547            }
15548
15549            if (that.options.isTree && n.hasTree) {
15550                $td && ($td.attr('align', 'left').addClass('datagrid-tree-td').html(that.tools.createTreePlaceholder(trData, (render_label || label))))
15551            }
15552
15553            if (n.locked && $lockTr && $td) {
15554                var $lockTd = $lockTr.find('> td:eq('+ n.lockIndex +')')
15555
15556                $lockTd.removeClass(that.classnames.td_edit).removeClass(that.classnames.td_changed).html($td.html())
15557            }
15558        })
15559
15560        if (that.isTemplate) {
15561            if (typeof tdTemplate === 'function')
15562                tdTemplate = tdTemplate.apply(that, [trData])
15563
15564            tdTemplate = that.tools.replacePlh4Template(tdTemplate, tempData)
15565
15566            $tr.find('> td.datagrid-template-td').html(tdTemplate)
15567        }
15568
15569        $tr.initui()
15570        if ($lockTr)
15571            $lockTr.initui()
15572
15573        if ($tr.hasClass(that.classnames.tr_add)) {
15574            $tr.removeClass(that.classnames.tr_add)
15575
15576            // update linenumber
15577            if (hasLinenumber) {
15578                that.tools.updateLinenumber()
15579            }
15580
15581            // tree
15582            if (that.options.isTree) {
15583                var $parentTr = trData[that.options.keys.treePTr], parentData = trData[that.options.keys.treePData], keys = that.options.treeOptions.keys, $treePTd
15584
15585                if ($parentTr && parentData) {
15586                    if (!parentData[keys.isParent]) {
15587                        parentData[keys.isParent] = true
15588                        $treePTd = $parentTr.find('> td.datagrid-tree-td')
15589                        $treePTd.html(that.tools.createTreePlaceholder(parentData, $treePTd.find('span.datagrid-tree-title').html()))
15590                    }
15591                    if (!parentData[keys.childLen]) {
15592                        parentData[keys.childLen] = 1
15593                    } else {
15594                        parentData[keys.childLen] ++
15595                    }
15596
15597                    $tr.data(that.options.keys.treePTr).data('child', parentData[keys.childLen]).attr('data-child', parentData[keys.childLen])
15598                }
15599
15600                $tr.addClass('datagrid-tree-tr datagrid-tree-level-'+ trData[keys.level]).attr('data-child', 0).attr('data-level', trData[keys.level])
15601            }
15602
15603            // child
15604            $tr.next('.'+ that.classnames.tr_child).remove()
15605            that.tools.createChildTr($tr, trData)
15606        }
15607    }
15608
15609    /* resize */
15610    Datagrid.prototype.resizeGrid = function() {
15611        var that = this, $target = that.$grid.getPageTarget(), parentW, parentH
15612        var _resizeGrid = function() {
15613            var ww = that.$grid.width(), $headDiv = that.$tableH.next('.datagrid-thead-dialog-div');
15614            //     newTemplate = ((that.options.tdTemplate && that.options.templateWidth) && that.options.templateWidth > ww) || that.options.templateWidth === 0
15615
15616            // // tdtemplate
15617            // if (newTemplate !== that.isTemplate) {
15618            //     that.isTemplate = newTemplate
15619            //     that.tools.coverTemplate()
15620            //     return
15621            // }
15622            if ((that.options.dialogFilterW && ww < that.options.dialogFilterW)
15623                || that.options.dialogFilterW === 0) {
15624
15625                that.$tableH.hide()
15626
15627                if (!$headDiv.length) {
15628                    that.$tableH.after('<div class="datagrid-thead-dialog-div" style="padding:5px;"><button type="button" class="btn btn-orange datagrid-thead-dialog-view">'+ BJUI.getRegional('datagrid.fAndS') +'</button><span class="datagrid-thead-dialog-filter-msg"><span class="msg-sort"></span><span class="msg-filter"></span></span></div>')
15629                } else {
15630                    $headDiv.show()
15631                }
15632
15633                if (!that.$headFilterUl)
15634                    that.filterInThead(true)
15635
15636                that.$grid.off('click.datagrid.thead.view').on('click.datagrid.thead.view', '.datagrid-thead-dialog-view', function(e) {
15637                    BJUI.dialog({id:'datagrid-thead-view', html:'<div class="bjui-pageContent"></div><div class="bjui-pageFooter"><ul><li><button type="button" class="btn btn-close">关闭</button></li></ul></div>', width:360, height:300, title:'datagrid - thead - columns',
15638                        onLoad: function($dialog) {
15639                            that.$headFilterUl.show().appendTo($dialog.find('.bjui-pageContent'))
15640                        },
15641                        beforeClose:function($dialog) {
15642                            that.$headFilterUl.hide().appendTo(that.$grid)
15643                            return true
15644                        }
15645                    })
15646                })
15647            } else {
15648                that.$grid.removeClass('datagrid-flowlayout')
15649                that.$tableH.show()
15650                $headDiv.hide()
15651
15652                if (that.$colgroupB.is(':hidden')) {
15653                    that.$colgroupB.show()
15654                }
15655            }
15656
15657            if (that.initFixedW && String(that.options.width).endsWith('%')) {
15658                parentW = that.$grid.parent().width()
15659                that.fixedWidth()
15660
15661                if (that.options.hasChild && that.options.childOptions) {
15662                    that.$tbody.find('> tr.'+ that.classnames.tr_child +':visible').each(function() {
15663                        var $child = $(this), $tr = $child.prev(), $table = $tr.data('bjui.datagrid.child')
15664
15665                        if ($table && $table.length) {
15666                            $table.datagrid('fixedWidth')
15667                        }
15668                    })
15669                }
15670            }
15671
15672            if (String(that.options.height).endsWith('%')) {
15673                that.tools.setBoxbH()
15674            }
15675        }
15676
15677        // for tab
15678        $('a[data-toggle="tab"]').on('shown.bs.tab', $.proxy(function(e) {
15679            if (!that.$element.data('bjui.datagrid.init.tab')) {
15680                var $target = $(e.target), $box = $target.data('target'), href = $target.attr('href')
15681
15682                if (!$box)
15683                    $box = $(href)
15684
15685                if ($box && $box.length) {
15686                    if ($box.find(that.$element).length) {
15687                        that.$element.data('bjui.datagrid.init.tab', true)
15688                        that.$element.datagrid('fixedHeight')
15689                    }
15690                }
15691            }
15692        }, that))
15693
15694        $(window).on(BJUI.eventType.resizeGrid, $.proxy(_resizeGrid, that))
15695    }
15696
15697    //cellTitle 单元格增加title 提示 2019-10-09
15698    Datagrid.prototype.cellTitle=function(){
15699        var that = this;
15700        that.$tbody.find('td').each(function(index,item){
15701            $(this).attr('title',$(this).text()); //取当前单元格信息,赋值给title显示
15702        })
15703    }
15704    /*cellsHeight 表格行高配置 2020-06-10*/
15705    Datagrid.prototype.cellsHeight=function(){
15706        var that = this;
15707        that.$tbody.find('td').css({
15708            'white-space':'nowrap',
15709            'overflow':'hidden'
15710        })
15711        that.$tbody.find('td div').css({
15712            'white-space':'nowrap',
15713            'overflow':'hidden',
15714            'text-overflow':'ellipsis'
15715        })
15716    }
15717
15718    // DATAGRID PLUGIN DEFINITION
15719    // =======================
15720
15721    function Plugin(option) {
15722        var args     = arguments,
15723            property = option
15724
15725        return this.each(function () {
15726            var $this   = $(this),
15727                options = $.extend(true, {}, Datagrid.DEFAULTS, typeof option === 'object' && option),
15728                data    = $this.data('bjui.datagrid')
15729
15730            if (!data) $this.data('bjui.datagrid', (data = new Datagrid(this, options)))
15731            if (typeof property === 'string' && $.isFunction(data[property])) {
15732                [].shift.apply(args)
15733                if (!args) data[property]()
15734                else data[property].apply(data, args)
15735            } else {
15736                data.init()
15737            }
15738        })
15739    }
15740
15741    var old = $.fn.datagrid
15742
15743    $.fn.datagrid             = Plugin
15744    //$.fn.datagrid.Constructor = Datagrid
15745    $.datagrid                = Datagrid
15746
15747    // DATAGRID NO CONFLICT
15748    // =================
15749
15750    $.fn.datagrid.noConflict = function () {
15751        $.fn.datagrid = old
15752        return this
15753    }
15754
15755    // DATAGRID DATA-API
15756    // ==============
15757
15758    $(document).on(BJUI.eventType.initUI, function(e) {
15759        $(e.target).find('table[data-toggle="datagrid"]').each(function() {
15760            var $this = $(this), options = $this.data()
15761
15762            if (!$this.length) return
15763
15764            if (options.options && typeof options.options === 'string') options.options = options.options.toObj()
15765            $.extend(options, typeof options.options === 'object' && options.options)
15766
15767            Plugin.call($this, options)
15768        })
15769    })
15770
15771}(jQuery);
15772/*!
15773 * B-JUI  V1.31 (http://b-jui.com)
15774 * Git@OSC (http://git.oschina.net/xknaan/B-JUI)
15775 * Copyright 2014 K'naan.
15776 * Licensed under Apache (http://www.apache.org/licenses/LICENSE-2.0)
15777 */
15778
15779/* ========================================================================
15780 * B-JUI: bjui-spinner.js  V1.31
15781 * @author K'naan
15782 * http://git.oschina.net/xknaan/B-JUI/blob/master/BJUI/js/bjui-spinner.js
15783 * ========================================================================
15784 * Copyright 2014 K'naan.
15785 * Licensed under Apache (http://www.apache.org/licenses/LICENSE-2.0)
15786 * ======================================================================== */
15787
15788+function ($) {
15789    'use strict';
15790
15791    // SPINNER CLASS DEFINITION
15792    // ======================
15793    var Spinner = function(element, options) {
15794        this.$element = $(element)
15795        this.options  = options
15796        this.tools    = this.TOOLS()
15797        this.$spinner = null
15798        this.height   = this.$element.addClass('form-control').innerHeight()
15799        this.ivalue   = Number(this.$element.val()) || 0
15800    }
15801
15802    Spinner.DEFAULTS = {
15803        min: 0,
15804        max: 100,
15805        step: 1,
15806        decimalPlace: 0
15807    }
15808
15809    Spinner.EVENTS = {
15810        afterChange : 'afterchange.bjui.spinner'
15811    }
15812
15813    Spinner.prototype.TOOLS = function() {
15814        var that  = this
15815        var tools = {
15816            changeVal: function($btn) {
15817                var $input = that.$element
15818                var ivalue = Number($input.val()) || Number(that.ivalue)
15819                var type   = $btn.data('add') || -1
15820                var istart = that.options.min, iend = that.options.max, istep = that.options.step
15821
15822                if (type == 1) {
15823                    if (ivalue <= iend - istep)
15824                        ivalue = ivalue + istep
15825                } else if (type == -1) {
15826                    if (ivalue >= (istart + istep))
15827                        ivalue = ivalue - istep
15828                } else if (ivalue > iend) {
15829                    ivalue = iend
15830                } else if (ivalue < istart) {
15831                    ivalue = istart
15832                }
15833                if (that.options.decimalPlace)
15834                    ivalue = new String(ivalue.toFixed(that.options.decimalPlace))
15835
15836                that.ivalue = ivalue
15837
15838                $input
15839                    .val(ivalue)
15840                    .trigger(Spinner.EVENTS.afterChange, {value:ivalue})
15841                    .trigger('change')
15842            }
15843        }
15844
15845        return tools
15846    }
15847
15848    Spinner.prototype.init = function() {
15849        var that     = this
15850        var $element = this.$element
15851        var options  = this.options
15852
15853        if (isNaN(this.options.min) || isNaN(this.options.max) || isNaN(this.options.step)) {
15854            BJUI.debug('BJUI.Spinner: Parameter is non-numeric type!')
15855            return
15856        }
15857
15858        this.addBtn()
15859    }
15860
15861    Spinner.prototype.addBtn = function() {
15862        var that = this, $element = that.$element, fluid = $element.attr('size') ? '' : ' fluid'
15863
15864        if (!this.$lookBtn && !$element.parent().hasClass('wrap_bjui_btn_box')) {
15865            this.$spinner = $(FRAG.spinnerBtn)
15866
15867            $element.css({'paddingRight':'13px'}).wrap('<span class="wrap_bjui_btn_box'+ fluid +'"></span>')
15868
15869            var $box = $element.parent()
15870            $box.css('position', 'relative')
15871            this.$spinner.css({'height':this.height}).appendTo($box)
15872            this.$spinner.on('selectstart', function() { return false })
15873
15874            var timer = null
15875            /*spinner数据递增递减,当readonly时,不允许操作按钮 2021-01*/
15876            if(commonBlank($element.attr('readonly'))){
15877                that.$spinner.find('li').on('click', function(e) {
15878                    // 当disabled时,不允许操作输入框和按钮 2021-12-3
15879                    if(commonBlank($element.attr('disabled'))){
15880                        that.tools.changeVal($(this))
15881                    }
15882                }).on('mousedown', function() {
15883                    var $btn = $(this)
15884
15885                    timer = setInterval(function() {
15886                        that.tools.changeVal($btn)
15887                    }, 150)
15888                }).on('mouseup', function() { clearTimeout(timer) })
15889            }
15890        }
15891    }
15892
15893    Spinner.prototype.destroy = function() {
15894        if (this.$element.parent().hasClass('wrap_bjui_btn_box')) {
15895            this.$element.parent().find('.bjui-spinner').remove()
15896            this.$element.unwrap()
15897        }
15898    }
15899
15900    // SPINNER PLUGIN DEFINITION
15901    // =======================
15902
15903    function Plugin(option) {
15904        var args     = arguments
15905        var property = option
15906
15907        return this.each(function () {
15908            var $this   = $(this)
15909            var options = $.extend({}, Spinner.DEFAULTS, $this.data(), typeof option === 'object' && option)
15910            var data    = $this.data('bjui.spinner')
15911
15912            if (!data) $this.data('bjui.spinner', (data = new Spinner(this, options)))
15913            if (typeof property === 'string' && $.isFunction(data[property])) {
15914                [].shift.apply(args)
15915                if (!args) data[property]()
15916                else data[property].apply(data, args)
15917            } else {
15918                data.init()
15919            }
15920        })
15921    }
15922
15923    var old = $.fn.spinner
15924
15925    $.fn.spinner             = Plugin
15926    $.fn.spinner.Constructor = Spinner
15927
15928    // SPINNER NO CONFLICT
15929    // =================
15930
15931    $.fn.spinner.noConflict = function () {
15932        $.fn.spinner = old
15933        return this
15934    }
15935
15936    // SPINNER DATA-API
15937    // ==============
15938
15939    $(document).on(BJUI.eventType.initUI, function(e) {
15940        var $this = $(e.target).find('input[data-toggle="spinner"]')
15941
15942        if (!$this.length) return
15943
15944        Plugin.call($this)
15945    })
15946
15947}(jQuery);
15948/*!
15949 * B-JUI  V1.31 (http://b-jui.com)
15950 * Git@OSC (http://git.oschina.net/xknaan/B-JUI)
15951 * Copyright 2014 K'naan.
15952 * Licensed under Apache (http://www.apache.org/licenses/LICENSE-2.0)
15953 */
15954
15955/* ========================================================================
15956 * B-JUI: bjui-findgrid.js  V1.31
15957 * @author K'naan
15958 * http://git.oschina.net/xknaan/B-JUI/blob/master/BJUI/js/bjui-findgrid.js
15959 * ========================================================================
15960 * Copyright 2014 K'naan.
15961 * Licensed under Apache (http://www.apache.org/licenses/LICENSE-2.0)
15962 * ======================================================================== */
15963
15964+function ($) {
15965    'use strict';
15966
15967    // FINDGRID GLOBAL ELEMENTS
15968    // ======================
15969
15970    var group, suffix, pk, include, exclude, append, oldData, beforeSelect, onSelect, afterSelect, $box, $currentFindGrid
15971
15972    // FINDGRID CLASS DEFINITION
15973    // ======================
15974
15975    var FindGrid = function(element, options) {
15976        this.$element = $(element)
15977        this.options  = options
15978        this.$findBtn = null
15979    }
15980
15981    FindGrid.DEFAULTS = {
15982        pk           : null,
15983        oldData      : null,
15984        group        : null,
15985        suffix       : null,
15986        include      : null,
15987        exclude      : null,
15988        multiple     : false,
15989        append       : false,
15990        empty        : true,
15991        dialogOptions: {
15992            id        : null,
15993            mask      : true,
15994            width     : 600,
15995            height    : 400,
15996            title     : 'FindGrid',
15997            maxable   : true,
15998            resizable : true
15999        },
16000        gridOptions : {
16001            width      : '100%',
16002            height     : '100%',
16003            tableWidth : '100%',
16004            columnMenu : false
16005        },
16006        context     : null,
16007        beforeSelect: null,
16008        onSelect    : null,
16009        afterSelect : null
16010    }
16011
16012    FindGrid.EVENTS = {
16013        afterChange : 'afterchange.bjui.findgrid'
16014    }
16015
16016    FindGrid.getField = function(key) {
16017        return (group ? (group +'.') : '') + (key) + (suffix ? suffix : '')
16018    }
16019
16020    FindGrid.empty = function() {
16021        if (!include) {
16022            BJUI.debug('BJUI.FindGrid: No set options \'include\' !')
16023            return
16024        }
16025
16026        var that = this, includes = include.split(','), $inputs = $box.find(':text, :input:hidden, textarea, select'), includeKeys = {}
16027
16028        for (var i = 0; i < includes.length; i++) {
16029            var arr = includes[i].split(':'), key, fieldKey
16030
16031            if (arr.length == 2) {
16032                fieldKey = arr[0].trim()
16033                key      = arr[1].trim()
16034            } else {
16035                fieldKey = includes[i].trim()
16036                key      = fieldKey
16037            }
16038
16039            includeKeys[that.getField(fieldKey)] = true
16040        }
16041
16042        for (key in includeKeys) {
16043            $inputs.filter('[name="'+ key +'"]')
16044                .val('')
16045                .trigger(FindGrid.EVENTS.afterChange, {value:'', data:''})
16046                .trigger('focus')
16047                .trigger('change')
16048        }
16049    }
16050
16051    FindGrid.setSingle = function(data) {
16052        if (typeof onSelect === 'function') {
16053            onSelect.call(this, data)
16054            return
16055        }
16056
16057        var that   = this
16058        var setVal = function($input, fieldKey, value) {
16059            var name = that.getField(fieldKey)
16060
16061            if (name == $input.attr('name')) {
16062                $input
16063                    .val(value)
16064                    .trigger(FindGrid.EVENTS.afterChange, {value:value, data:data})
16065                    .trigger('focus')
16066                    .trigger('change')
16067
16068                if ($input.isTag('select') && $input.data('toggle') && $input.data('toggle') === 'selectpicker') {
16069                    $input.selectpicker('refresh')
16070                }
16071            }
16072        }
16073
16074        $box.find('input:text, input:hidden, textarea, select').each(function() {
16075            var $input = $(this), fieldKey, excludeKeys = []
16076
16077            if (include) {
16078                var includes = include.split(',')
16079
16080                for (var i = 0; i < includes.length; i++) {
16081                    var arr = includes[i].split(':'), key
16082
16083                    if (arr.length == 2) {
16084                        fieldKey = arr[0].trim()
16085                        key      = arr[1].trim()
16086                    } else {
16087                        fieldKey = includes[i].trim()
16088                        key      = fieldKey
16089                    }
16090
16091                    if (data && typeof data[key] !== 'undefined')
16092                        setVal($input, fieldKey, data[key])
16093                }
16094            } else {
16095                for (var key in data) {
16096                    if (exclude) {
16097                        $.each(exclude.split(','), function(i, n) {
16098                            excludeKeys.push(n.trim())
16099                        })
16100
16101                        if ($.inArray(key, excludeKeys) != -1) {
16102                            continue
16103                        }
16104                    }
16105
16106                    setVal($input, key, data[key])
16107                }
16108            }
16109        })
16110
16111        if (typeof afterSelect === 'function') {
16112            afterSelect.call(that, data)
16113            return
16114        }
16115    }
16116
16117    FindGrid.setMult = function(gridId) {
16118        var datas = $('#'+ gridId).data('selectedDatas')
16119
16120        if (typeof beforeSelect === 'function') {
16121            if (!beforeSelect.apply(that, [datas])) {
16122                return false
16123            }
16124        }
16125        if (typeof onSelect === 'function') {
16126            onSelect.call(that, datas)
16127            return
16128        }
16129
16130        var that = this, data, inputLen = 0, newVal
16131        var refreshSelect = function($input) {
16132            if ($input.isTag('select') && $input.data('toggle') && $input.data('toggle') === 'selectpicker') {
16133                $input.selectpicker('refresh')
16134            }
16135        }
16136
16137        if (datas && datas.length) {
16138            var $inputs = $box.find('input:text, input:hidden, textarea, select'), fieldKey, includeKeys = {}, okObj = {}, excludeKeys = [], v
16139
16140            if (!append && oldData)
16141                oldData = []
16142
16143            if (include) {
16144                var includes = include.split(',')
16145
16146                for (var i = 0; i < includes.length; i++) {
16147                    var arr = includes[i].split(':'), key, obj
16148
16149                    if (arr.length == 2) {
16150                        fieldKey = arr[0].trim()
16151                        key      = arr[1].trim()
16152                    } else {
16153                        fieldKey = includes[i].trim()
16154                        key      = fieldKey
16155                    }
16156
16157                    includeKeys[that.getField(fieldKey)] = key
16158                }
16159            } else {
16160                for (var key in datas[0]) {
16161                    if (exclude) {
16162                        $.each(exclude.split(','), function(i, n) {
16163                            excludeKeys.push(n.trim())
16164                        })
16165                        if ($.inArray(key, excludeKeys) === -1) {
16166                            includeKeys[that.getField(key)] = key
16167                        }
16168                    } else {
16169                        includeKeys[that.getField(key)] = key
16170                    }
16171                }
16172            }
16173
16174            $inputs = $($.map($inputs, function(n) {
16175                var $n = $(n), name = $n.attr('name')
16176
16177                if (!name) return null
16178                if (!includeKeys[name]) return null
16179
16180                okObj[name] = includeKeys[name]
16181
16182                return n
16183            }))
16184
16185            for (var j = 0; j < datas.length; j++) {
16186                data = datas[j]
16187
16188                if (oldData && $.inArray(data[pk], oldData) != -1 && !append)
16189                    continue
16190
16191                $inputs.each(function(k) {
16192                    var $input = $(this), name = $input.attr('name'), value = $input.val()
16193
16194                    if (!newVal) newVal = new Array()
16195                    if (!newVal[k]) newVal[k] = []
16196
16197                    if (!append) {
16198                        $input.val('')
16199                        refreshSelect($input)
16200                    } else {
16201                        if (value) {
16202                            newVal[k].push(value)
16203
16204                            if ($input.isTag('select') && $input.prop('multiple')) {
16205                                newVal[k] = $.type(value) === 'array' ? value : []
16206                            }
16207                        }
16208                    }
16209
16210                    newVal[k].push(data[okObj[name]])
16211
16212                    if (oldData && $.inArray(data[pk], oldData) === -1)
16213                        oldData.push(data[pk])
16214                })
16215            }
16216
16217            if (newVal) {
16218                $inputs.each(function(k) {
16219                    var $input = $(this)
16220
16221                    v = newVal[k].join(',')
16222
16223                    if ($input.isTag('select') && $input.prop('multiple'))
16224                        v = newVal[k]
16225
16226                    $input
16227                        .val(v)
16228                        .trigger(FindGrid.EVENTS.afterChange, {value:v, data:datas})
16229                        .trigger('change')
16230
16231                    $currentFindGrid.data('oldData', oldData)
16232
16233                    refreshSelect($input)
16234                })
16235            }
16236
16237            if (typeof afterSelect === 'function') {
16238                afterSelect.call(that, data.data)
16239                return
16240            }
16241
16242            BJUI.dialog('closeCurrent')
16243        }
16244    }
16245
16246    FindGrid.prototype.init = function() {
16247        var that = this, options = this.options, gridOptions = options.gridOptions, tools = this.tools
16248
16249        group            = options.group  || null
16250        suffix           = options.suffix || null
16251        $currentFindGrid = that.$element
16252        oldData          = options.oldData
16253        pk               = options.pk || null
16254        include          = options.include || null
16255        exclude          = options.exclude || null
16256        $box             = null
16257
16258        if (options.context) {
16259            if (options.context instanceof jQuery)
16260                $box = options.context
16261            else
16262                $box = $(options.context)
16263        }
16264        if (!$box || !$box.length) {
16265            if (that.$element[0] === $('body')[0]) {
16266                $box = $.CurrentDialog || $.CurrentNavtab
16267            } else {
16268                $box = that.$element.closest('.unitBox')
16269            }
16270        }
16271        if (suffix)
16272            suffix = suffix.trim()
16273
16274        if (pk) {
16275            if ($currentFindGrid.data('oldData')) {
16276                oldData = $currentFindGrid.data('oldData')
16277            } else {
16278                if (typeof oldData !== 'undefined') {
16279                    if (typeof oldData === 'string')
16280                        oldData = oldData.split(',')
16281                    else if (!$.isArray(oldData))
16282                        oldData = []
16283                } else {
16284                    oldData = []
16285                }
16286            }
16287        } else {
16288            oldData = null
16289        }
16290
16291        if (gridOptions.dataUrl) {
16292            gridOptions.dataUrl = decodeURI(gridOptions.dataUrl).replacePlh($box)
16293
16294            if (!gridOptions.dataUrl.isFinishedTm()) {
16295                BJUI.alertmsg('error', (options.warn || BJUI.regional.plhmsg))
16296                BJUI.debug('Findgrid Plugin: gridOptions -> dataUrl is incorrect: '+ gridOptions.dataUrl)
16297                return
16298            }
16299
16300            gridOptions.dataUrl = encodeURI(gridOptions.dataUrl)
16301        }
16302
16303        this.open(that.$element)
16304    }
16305
16306    FindGrid.prototype.addBtn = function() {
16307        var that = this, $element = that.$element, options = $element.data('bjui.findgrid.options'), fluid = $element.attr('size') ? '' : ' fluid'
16308
16309        if (!this.$findBtn && !$element.parent().hasClass('wrap_bjui_btn_box')) {
16310            this.$findBtn = $(FRAG.findgridBtn)
16311            this.$element.css({'paddingRight':'15px'}).wrap('<span class="wrap_bjui_btn_box'+ fluid +'"></span>')
16312
16313            var $box   = this.$element.parent()
16314            var height = this.$element.addClass('form-control').innerHeight()
16315
16316            $box.css({'position':'relative', 'display':'inline-block'})
16317
16318            delete options.toggle
16319
16320            that.$findBtn.data('bjui.findgrid.options', options)
16321
16322            this.$findBtn.css({'height':height, 'lineHeight':height +'px'}).appendTo($box)
16323            this.$findBtn.on('selectstart', function() { return false })
16324        }
16325    }
16326
16327    FindGrid.prototype.open = function($obj) {
16328        var that = this, options = this.options, dialogOptions = options.dialogOptions, gridOptions = options.gridOptions, timestamp = (new Date().getTime())
16329
16330        if (!dialogOptions.id)
16331            dialogOptions.id = 'dialog_findgrid_'+ timestamp
16332        if (!options.gridId)
16333            options.gridId = 'datagrid_findgrid_'+ timestamp
16334
16335        gridOptions.showToolbar = false
16336
16337        if (options.empty) {
16338            if (!gridOptions.toolbarCustom) gridOptions.toolbarCustom = ''
16339            gridOptions.showToolbar = true
16340        }
16341        if (options.multiple) {
16342            gridOptions.showToolbar = true
16343
16344            if (typeof gridOptions.showCheckboxcol === 'undefined') {
16345                gridOptions.showCheckboxcol = true
16346            }
16347            if (!gridOptions.toolbarCustom) gridOptions.toolbarCustom = ''
16348
16349            gridOptions.selectMult  = true
16350
16351            // set multiple
16352            gridOptions.toolbarCustom += ' <button type="button" class="btn-blue" onclick="$.fn.findgrid.Constructor.setMult(\''+ options.gridId +'\')">'+ (BJUI.getRegional('findgrid.choose')) +'</button>'
16353            gridOptions.toolbarCustom += ' <label class="ilabel"><input type="checkbox" data-toggle="icheck" id="checkbox_findgrid_'+ timestamp +'" '+ (options.append ? 'checked' : '') +'>&nbsp;'+ (BJUI.getRegional('findgrid.append')) +'</label>'
16354
16355            append = options.append
16356        }
16357
16358        if (options.empty)
16359            gridOptions.toolbarCustom += ' <button type="button" class="btn-orange" onclick="$.fn.findgrid.Constructor.empty(\''+ options.gridId +'\')">'+ (BJUI.getRegional('findgrid.empty')) +'</button>'
16360
16361        delete dialogOptions.url
16362        delete dialogOptions.target
16363
16364        if (options.onSelect) {
16365            onSelect = options.onSelect
16366            if (typeof onSelect === 'string') onSelect = onSelect.toFunc()
16367        } else {
16368            onSelect = null
16369        }
16370        if (options.beforeSelect) {
16371            beforeSelect = options.beforeSelect
16372            if (typeof beforeSelect === 'string') beforeSelect = beforeSelect.toFunc()
16373        } else {
16374            beforeSelect = null
16375        }
16376        if (options.afterSelect) {
16377            afterSelect = options.afterSelect
16378            if (typeof afterSelect === 'string') afterSelect = afterSelect.toFunc()
16379        } else {
16380            afterSelect = null
16381        }
16382
16383        dialogOptions.html = '<div class="bjui-pageContent tableContent"><table id="'+ options.gridId +'"></table></div>'
16384        dialogOptions.onLoad = function($dialog) {
16385            var gridId = '#'+ options.gridId, $grid = $(gridId)
16386
16387            $grid.datagrid(gridOptions)
16388
16389            // after load - selected row by (oldData && pk)
16390            if ($.isArray(oldData) && oldData.length && pk) {
16391                $(document).on('afterLoad.bjui.datagrid', gridId, function(e, data) {
16392                    if (data.datas) {
16393                        $.each(data.datas, function(i, data) {
16394                            if (data[pk]) {
16395                                if ($.inArray(data[pk], oldData) != '-1') {
16396                                    $grid.datagrid('selectedRows', i, true)
16397                                }
16398                            }
16399                        })
16400                    }
16401                })
16402            }
16403
16404            // set single
16405            if (!options.multiple) {
16406                $(document).on('clicked.bjui.datagrid.tr', gridId, function(e, data) {
16407                    if (typeof beforeSelect === 'function') {
16408                        if (!beforeSelect.apply(that, [data.data])) {
16409                            return false
16410                        }
16411                    }
16412                    if (typeof onSelect === 'function') {
16413                        onSelect.call(that, data.data)
16414                    } else {
16415                        FindGrid.setSingle(data.data)
16416                        BJUI.dialog('closeCurrent')
16417                    }
16418                })
16419            }
16420
16421            // append checkbox
16422            $(document).on('ifChanged', '#checkbox_findgrid_'+ timestamp, function(e) {
16423                append = $(this).is(':checked')
16424            })
16425        }
16426
16427        BJUI.dialog(dialogOptions)
16428    }
16429
16430    // FINDGRID PLUGIN DEFINITION
16431    // =======================
16432
16433    function Plugin(option) {
16434        var args     = arguments
16435        var property = option
16436
16437        return this.each(function () {
16438            var $this   = $(this),
16439                options = {},
16440                data
16441
16442            $.extend(true, options, FindGrid.DEFAULTS, typeof option === 'object' && option)
16443
16444            data = new FindGrid(this, options)
16445
16446            if (typeof property === 'string' && $.isFunction(data[property])) {
16447                [].shift.apply(args)
16448                if (!args) data[property]()
16449                else data[property].apply(data, args)
16450            } else {
16451                data.init()
16452            }
16453        })
16454    }
16455
16456    var old = $.fn.findgrid
16457
16458    $.fn.findgrid             = Plugin
16459    $.fn.findgrid.Constructor = FindGrid
16460
16461    // FINDGRID NO CONFLICT
16462    // =================
16463
16464    $.fn.findgrid.noConflict = function () {
16465        $.fn.findgrid = old
16466        return this
16467    }
16468
16469    // NOT SELECTOR
16470    // ==============
16471
16472    BJUI.findgrid = function(option) {
16473        Plugin.apply($('body'), [option])
16474    }
16475
16476    // FINDGRID DATA-API
16477    // ==============
16478
16479    $(document).on(BJUI.eventType.initUI, function(e) {
16480        $(e.target).find('input[data-toggle="findgrid"]').each(function() {
16481            var $this = $(this), data = $this.data(), options = data.options
16482
16483            if (options) {
16484                if (typeof options === 'string') {
16485                    if (options.trim().startsWith('{'))
16486                        options = options.toObj()
16487                    else
16488                        options = options.toFunc()
16489                }
16490                if (typeof options === 'function') {
16491                    options = options.apply()
16492                }
16493                if (typeof options === 'object') {
16494                    delete data.options
16495
16496                    $.extend(data, options)
16497                }
16498            }
16499
16500            $this.data('bjui.findgrid.options', data)
16501            Plugin.call($this, 'addBtn')
16502        })
16503    })
16504
16505    $(document).on('click.bjui.findgrid.data-api', '[data-toggle="findgridbtn"]', function(e) {
16506        var $this = $(this), opts = $this.data('bjui.findgrid.options')
16507
16508        if (!opts) {
16509            var data = $this.data(), options = data.options
16510
16511            if (options) {
16512                if (typeof options === 'string') {
16513                    if (options.trim().startsWith('{'))
16514                        options = options.toObj()
16515                    else
16516                        options = options.toFunc()
16517                }
16518                if (typeof options === 'function') {
16519                    options = options.apply()
16520                }
16521                if (typeof options === 'object') {
16522                    delete data.options
16523
16524                    $.extend(data, options)
16525                }
16526            }
16527            opts = data
16528        }
16529
16530        delete opts['bjui.findgrid.options']
16531
16532        Plugin.call($this, opts)
16533
16534        e.preventDefault()
16535    })
16536
16537}(jQuery);
16538/*!
16539 * B-JUI  V1.31 (http://b-jui.com)
16540 * Git@OSC (http://git.oschina.net/xknaan/B-JUI)
16541 * Copyright 2014 K'naan.
16542 * Licensed under Apache (http://www.apache.org/licenses/LICENSE-2.0)
16543 */
16544
16545/* ========================================================================
16546 * B-JUI: bjui-suggest.js  V1.31
16547 * @author K'naan
16548 * http://git.oschina.net/xknaan/B-JUI/blob/master/BJUI/js/bjui-suggest.js
16549 * ========================================================================
16550 * Copyright 2014 K'naan.
16551 * Licensed under Apache (http://www.apache.org/licenses/LICENSE-2.0)
16552 * ======================================================================== */
16553
16554+function ($) {
16555    'use strict';
16556
16557    // FINDGRID GLOBAL ELEMENTS
16558    // ======================
16559
16560    var group, suffix, keys, include, autofill, onSelect, $box, $currentSuggest
16561
16562    // FINDGRID CLASS DEFINITION
16563    // ======================
16564
16565    var Suggest = function(element, options) {
16566        this.$element = $(element)
16567        this.options  = options
16568        this.$findBtn = null
16569    }
16570
16571    Suggest.DEFAULTS = {
16572        keys      : null,
16573        group     : null,
16574        suffix    : null,
16575        include   : null,
16576        context   : null,
16577        eventType : 'change',
16578        autofill  : false
16579    }
16580
16581    Suggest.EVENTS = {
16582        afterChange : 'afterchange.bjui.suggest'
16583    }
16584
16585    Suggest.getField = function(key) {
16586        return (group ? (group +'.') : '') + (key) + (suffix ? suffix : '')
16587    }
16588
16589    Suggest.setSingle = function(datas) {
16590        var that   = this, items, menus = [], $parents, inputs = []
16591        var replacePlh = function(val, data) {
16592            return val.replace(/#\/?[^#]*#/g, function($1) {
16593                var key = $1.replace(/[##]+/g, ''), val = data[key]
16594
16595                if (typeof val === 'undefined')
16596                    return $1
16597
16598                if (typeof val === 'undefined' || val === 'null' || val === null)
16599                    val = ''
16600
16601                return val
16602            })
16603        }
16604        var createMenu = function($input, value, label) {
16605            items = []
16606
16607            var $suggest = $input.data('suggest.menu'), val, lab
16608
16609            if (!$suggest || !$suggest.length) {
16610                $suggest = $('<ul class="bjui-suggest-menu"></ul>')
16611            }
16612
16613            $.each(datas, function(i, n) {
16614                val = value
16615                lab = label
16616                val = replacePlh(val, n)
16617                lab = replacePlh(lab, n)
16618
16619                if (val || lab)
16620                    items.push('<li data-value="'+ val +'">'+ lab +'</li>')
16621            })
16622
16623            if (items.length) {
16624                $suggest
16625                    .html(items.join(''))
16626                    .appendTo('body').css({position:'absolute', top:$input.offset().top + $input.outerHeight(), left:$input.offset().left})
16627                    .on('click.bjui.suggest', 'li', function() {
16628                        $input.val($(this).attr('data-value'))
16629                    })
16630                    .on('mouseover.bjui.suggest', 'li', function() {
16631                        $(this).addClass('menu-highlight')
16632                    })
16633                    .on('mouseout.bjui.suggest', 'li', function() {
16634                        $(this).removeClass('menu-highlight')
16635                    })
16636
16637                $input.addClass('bjui-suggest-input').attr('autocomplete', false).data('suggest.menu', $suggest).off('focus.bjui.suggest').on('focus.bjui.suggest', function() {
16638                    $suggest.css({top:$input.offset().top + $input.outerHeight(), left:$input.offset().left}).show()
16639                }).off('destroy.bjui.suggest').on('destroy.bjui.suggest', function() {
16640                    $suggest.remove()
16641                })
16642
16643                menus.push($suggest)
16644            }
16645        }
16646
16647        $.each(keys, function(k, v) {
16648            var name = that.getField(k), $input = $box.find('input[name="'+ name +'"], select[name="'+ name +'"], textarea[name="'+ name +'"]'), arr = v ? v.split('/') : ['#'+ k +'#'], item, value, label
16649
16650            if ($input && $input.length) {
16651                if (arr.length > 1) {
16652                    value = arr[0]
16653                    label = arr[1]
16654                } else {
16655                    value = label = arr[0]
16656                }
16657
16658                if (($input.isTag('select') || $input.isTag('textarea')) && autofill) {
16659                    $input.val(datas[0] ? datas[0][k] : '')
16660                    if ($input.isTag('select')) {
16661                        $input.selectpicker('refresh')
16662                    }
16663                }
16664                else {
16665                    createMenu($input, value, label)
16666                    if (autofill)
16667                        $input.val(datas[0] ? datas[0][k] : '')
16668                }
16669
16670                inputs.push($input)
16671
16672                if (!$parents)
16673                    $parents = $input.parents()
16674            }
16675        })
16676
16677        $(document).on('click.bjui.suggest', function(e) {
16678            var $suggest = $(e.target).data('suggest.menu')
16679
16680            if (!$suggest || !$suggest.length)
16681                $('body').find('> .bjui-suggest-menu').hide()
16682            else
16683                $suggest.siblings('.bjui-suggest-menu').hide()
16684        })
16685
16686        $parents.on('scroll.bjui.suggest', function() {
16687            $.each(inputs, function(i, n) {
16688                var $suggest = n.data('suggest.menu')
16689
16690                if ($suggest && $suggest.is(':visible')) {
16691                    $suggest.css({top:n.offset().top + n.outerHeight(), left:n.offset().left})
16692                }
16693            })
16694        })
16695
16696        $currentSuggest.data('menus', menus)
16697    }
16698
16699    Suggest.prototype.init = function() {
16700        var that = this, options = this.options, tools = this.tools
16701
16702        keys            = options.keys     || null
16703        group           = options.group    || null
16704        suffix          = options.suffix   || null
16705        autofill        = options.autofill || false
16706        $currentSuggest = that.$element
16707        $box            = null
16708
16709        if (options.context) {
16710            if (options.context instanceof jQuery)
16711                $box = options.context
16712            else
16713                $box = $(options.context)
16714        }
16715        if (!$box || !$box.length)
16716            $box = that.$element.closest('.unitBox')
16717        if (suffix)
16718            suffix = suffix.trim()
16719
16720        if (!options.keys) {
16721            BJUI.debug('BJUI.Suggest: options -> keys is not defined!')
16722            return
16723        }
16724        if (!options.url) {
16725            BJUI.debug('BJUI.Suggest: options -> url is not defined!')
16726            return
16727        } else {
16728            options.url = decodeURI(options.url).replacePlh($box)
16729
16730            if (!options.url.isFinishedTm()) {
16731                BJUI.alertmsg('error', (options.warn || BJUI.regional.plhmsg))
16732                BJUI.debug('BJUI.Suggest: options -> url is incorrect: '+ options.url)
16733                return
16734            }
16735
16736            options.url = encodeURI(options.url)
16737        }
16738
16739        that.$element.on(options.eventType || 'change', function() {
16740            var val = $(this).val()
16741
16742            if (val)
16743                that.load(val)
16744        })
16745    }
16746
16747    Suggest.prototype.load = function(value) {
16748        var that = this, options = this.options, url = options.url
16749
16750        if (url.indexOf('#val#') != -1) {
16751            url = url.replaceAll('#val#', value)
16752        }
16753
16754        BJUI.ajax('doajax', {
16755            url   : url,
16756            data  : {value : value},
16757            type  : options.type,
16758            cache : options.cache,
16759            okCallback: function(json) {
16760                Suggest.setSingle(json)
16761            }
16762        })
16763    }
16764
16765    Suggest.prototype.destroyMenu = function() {
16766        var menus = $currentSuggest.data('menus') || []
16767
16768        if (menus.length) {
16769            $.each(menus, function(i, n) {
16770                n.remove()
16771            })
16772        }
16773    }
16774
16775    // FINDGRID PLUGIN DEFINITION
16776    // =======================
16777
16778    function Plugin(option) {
16779        var args     = arguments
16780        var property = option
16781
16782        return this.each(function () {
16783            var $this   = $(this),
16784                options = {},
16785                data
16786
16787            $.extend(true, options, Suggest.DEFAULTS, typeof option === 'object' && option)
16788
16789            data = new Suggest(this, options)
16790
16791            if (typeof property === 'string' && $.isFunction(data[property])) {
16792                [].shift.apply(args)
16793                if (!args) data[property]()
16794                else data[property].apply(data, args)
16795            } else {
16796                data.init()
16797            }
16798        })
16799    }
16800
16801    var old = $.fn.suggest
16802
16803    $.fn.suggest             = Plugin
16804    $.fn.suggest.Constructor = Suggest
16805
16806    // FINDGRID NO CONFLICT
16807    // =================
16808
16809    $.fn.suggest.noConflict = function () {
16810        $.fn.suggest = old
16811        return this
16812    }
16813
16814    // FINDGRID DATA-API
16815    // ==============
16816
16817    $(document).on(BJUI.eventType.initUI, function(e) {
16818        $(e.target).find('input[data-toggle="suggest"]').each(function() {
16819            var $this = $(this), data = $this.data(), options = data.options
16820
16821            if (options) {
16822                if (typeof options === 'string') {
16823                    if (options.trim().startsWith('{'))
16824                        options = options.toObj()
16825                    else
16826                        options = options.toFunc()
16827                }
16828                if (typeof options === 'function') {
16829                    options = options.apply()
16830                }
16831                if (typeof options === 'object') {
16832                    delete data.options
16833
16834                    $.extend(data, options)
16835                }
16836            }
16837
16838            Plugin.call($this, data)
16839        })
16840    })
16841
16842    $(document).on('click.bjui.suggest.data-api', '[data-toggle="suggestbtn"]', function(e) {
16843        var $this = $(this), opts = $this.data('bjui.suggest.options')
16844
16845        if (!opts) {
16846            var data = $this.data(), options = data.options
16847
16848            if (options) {
16849                if (typeof options === 'string') {
16850                    if (options.trim().startsWith('{'))
16851                        options = options.toObj()
16852                    else
16853                        options = options.toFunc()
16854                }
16855                if (typeof options === 'function') {
16856                    options = options.apply()
16857                }
16858                if (typeof options === 'object') {
16859                    delete data.options
16860
16861                    $.extend(data, options)
16862                }
16863            }
16864            opts = data
16865        }
16866
16867        delete opts['bjui.suggest.options']
16868
16869        Plugin.call($this, opts)
16870
16871        e.preventDefault()
16872    })
16873
16874}(jQuery);
16875/*!
16876 * B-JUI  V1.31 (http://b-jui.com)
16877 * Git@OSC (http://git.oschina.net/xknaan/B-JUI)
16878 * Copyright 2014 K'naan.
16879 * Licensed under Apache (http://www.apache.org/licenses/LICENSE-2.0)
16880 */
16881
16882/* ========================================================================
16883 * B-JUI: bjui-tags.js  V1.31
16884 * @author K'naan
16885 * http://git.oschina.net/xknaan/B-JUI/blob/master/BJUI/js/bjui-tags.js
16886 * ========================================================================
16887 * Copyright 2014 K'naan.
16888 * Licensed under Apache (http://www.apache.org/licenses/LICENSE-2.0)
16889 * ======================================================================== */
16890
16891+function ($) {
16892    'use strict';
16893
16894    // TAGS CLASS DEFINITION
16895    // ======================
16896    var Tags = function(element, options) {
16897        this.$element = $(element)
16898        this.options  = options
16899        this.tools    = this.TOOLS()
16900        this.$box     = $('<div></div>')
16901        this.timeout  = null
16902        this.$tagsArr = {}
16903        this.tags     = []
16904
16905        if (options.istag) {
16906            this.$element.addClass('tag-input')
16907            this.$box.addClass('bjui-tags')
16908        } else {
16909            this.$box.addClass('bjui-autocomplete')
16910            if (!this.$element.attr('size'))
16911                this.$box.addClass('fluid')
16912        }
16913
16914        this.$element.after(this.$box)
16915        this.$element.appendTo(this.$box)
16916    }
16917
16918    Tags.DEFAULTS = {
16919        width     : 300,
16920        url       : '',
16921        global    : false,
16922        type      : 'GET',
16923        term      : 'term',
16924        tagname   : 'tag',     // Appended "<input type='hidden'>" name attribute
16925        max       : 0,         // The maximum allowable number of tags(0=unlimited)
16926        clear     : false,     // If not found, clear the input characters
16927        lightCls  : 'tags-highlight',
16928        istag     : true,      // If only need auto complete, set false
16929        data      : {},
16930        container : '',
16931        keys      : {
16932            value : 'value',
16933            label : 'label'
16934        }
16935    }
16936
16937    Tags.EVENTS = {
16938        afterCreated : 'aftercreated.bjui.tags'
16939    }
16940
16941    Tags.prototype.TOOLS = function() {
16942        var that  = this, options = this.options
16943        var tools = {
16944            keyDown: function(e) {
16945                if (e.which == 13) {
16946                    return false
16947                }
16948            },
16949            keyUp: function(e) {
16950                switch(e.which) {
16951                    case BJUI.keyCode.BACKSPACE:
16952                        if (!$.trim(that.$element.val()).length) {
16953                            that.tools.removeMenu()
16954                            return false
16955                        }
16956                        break
16957                    case BJUI.keyCode.ESC:
16958                        that.tools.removeMenu()
16959                        break
16960                    case BJUI.keyCode.DOWN:
16961                        if (!that.$menu || !that.$menu.length) return
16962
16963                        var $highlight = that.$menu.find('> .'+ options.lightCls),
16964                            $first     = that.$menu.find('> li:first-child')
16965
16966                        if (!$highlight.length) {
16967                            $first.addClass(options.lightCls)
16968                        } else {
16969                            var $hight_next = $highlight.removeClass(options.lightCls).next()
16970
16971                            if ($hight_next.length) {
16972                                $hight_next.addClass(options.lightCls)
16973                            } else {
16974                                $first.addClass(options.lightCls)
16975                            }
16976                        }
16977                        return false
16978                        break
16979                    case BJUI.keyCode.UP:
16980                        if (!that.$menu || !that.$menu.length) return
16981                        var $highlight = that.$menu.find('> .'+ options.lightCls),
16982                            $last      = that.$menu.find('> li:last-child')
16983
16984                        if (!$highlight.length) {
16985                            $last.addClass(options.lightCls)
16986                        } else {
16987                            var $hight_prev = $highlight.removeClass(options.lightCls).prev()
16988
16989                            if ($hight_prev.length) {
16990                                $hight_prev.addClass(options.lightCls)
16991                            } else {
16992                                $last.addClass(options.lightCls)
16993                            }
16994                        }
16995                        return false
16996                        break
16997                    case BJUI.keyCode.ENTER:
16998                        if (options.max > 0 && that.$tagsArr.length >= options.max) return false
16999
17000                        var label = false, value = false, item = null
17001                        var $selectedItem = that.$menu && that.$menu.find('> .'+ options.lightCls)
17002
17003                        if ($selectedItem && $selectedItem.length) {
17004                            label = $selectedItem.text()
17005                            item  = $selectedItem.data('item')
17006                            value = item[options.keys.value]
17007                        } else {
17008                            label = $.trim(that.$element.val())
17009
17010                            if (!label.length) return false
17011                            if (options.clear) {
17012                                if ($.inArray(label, that.tags) == -1) {
17013                                    options.istag && (that.$element.val(''))
17014                                    return false
17015                                }
17016                            }
17017                            value = label
17018                        }
17019                        if (!label) return
17020
17021                        /* Check the repeatability */
17022                        var isRepeat = false
17023
17024                        that.$tagsArr.length && that.$tagsArr.each(function() {
17025                            if ($(this).val() == value) {
17026                                isRepeat = true
17027                                return
17028                            }
17029                        })
17030
17031                        if (isRepeat) {
17032                            options.istag && (that.$element.val(''))
17033                            return false
17034                        }
17035
17036                        that.tools.createTag(label, value)
17037                        that.tools.removeMenu()
17038                        options.istag && (that.$element.val(''))
17039
17040                        //events
17041                        $.proxy(that.tools.onAfterCreated(item, value), that)
17042
17043                        return false
17044                        break
17045                }
17046            },
17047            query: function() {
17048                if (that.timeout) clearTimeout(that.timeout)
17049
17050                that.timeout = setTimeout(that.tools.doQuery, 300)
17051            },
17052            doQuery: function() {
17053                var options = that.options
17054
17055                if (options.max > 0 && that.$tagsArr.length >= options.max) return
17056
17057                var term = that.$element.val(), $menu = that.$menu, tags = [], $item = null
17058                var $parentBox = that.$element.closest('.navtab-panel').length ? $.CurrentNavtab : $.CurrentDialog
17059                var postData = {}
17060
17061                if (that.$element.closest('.bjui-layout').length) $parentBox = that.$element.closest('.bjui-layout')
17062                if (!term.length) return
17063
17064                that.$element.one('ajaxStart', function() {
17065                    $parentBox.trigger('bjui.ajaxStart')
17066                }).one('ajaxStop', function() {
17067                    $parentBox.trigger('bjui.ajaxStop')
17068                })
17069
17070                postData[options.term] = term
17071                $.extend(postData, typeof options.data === 'object' && options.data)
17072
17073                options.url = decodeURI(options.url).replacePlh(that.$element.closest('.unitBox'))
17074
17075                if (!options.url.isFinishedTm()) {
17076                    BJUI.alertmsg('error', (options.warn || BJUI.regional.plhmsg))
17077                    BJUI.debug('BJUI.Tags: The query tags url is incorrect, url: '+ options.url)
17078                    return
17079                }
17080
17081                options.url = encodeURI(options.url)
17082
17083                $.ajax({
17084                    url      : options.url,
17085                    global   : options.global,
17086                    type     : options.type,
17087                    data     : postData,
17088                    dataType : 'json',
17089                    success  : function(json) {
17090                        if (json.length != 0) {
17091                            if (!$menu || !$menu.length) $menu = $('<ul class="bjui-tags-menu"></ul>')
17092
17093                            $menu.empty().hide();
17094
17095                            if (options.container)
17096                                $menu.css('position', 'absolute').appendTo(options.container)
17097                            else
17098                                $menu.appendTo(that.$box)
17099
17100                            for (var i = 0; i < json.length; i++) {
17101                                var obj = json[i]
17102
17103                                if (typeof obj === 'string') {
17104                                    obj = {}
17105                                    obj[options.keys.label] = json[i]
17106                                    obj[options.keys.value] = json[i]
17107                                }
17108
17109                                $item = $('<li class="tags-item">'+ obj[options.keys.label] + '</li>').data('item', obj)
17110                                $item.appendTo($menu)
17111
17112                                tags.push(obj[options.keys.label])
17113                            }
17114
17115                            that.tags = tags
17116
17117                            var h = $(window).height() - that.$element.offset().top - 50, top = 0, left = 0
17118
17119                            if (options.container) {
17120                                top  = that.$element.offset().top + that.$element.outerHeight()
17121                                left = that.$element.offset().left
17122                            } else {
17123                                top  = that.$element.position().top + that.$element.outerHeight()
17124                                left = that.$element.position().left
17125                            }
17126
17127                            $menu
17128                                .css({'top':top, 'left':left})
17129                                .fadeIn()
17130                                .find('> li')
17131                                .hover(function() {
17132                                    $(this).addClass(options.lightCls).siblings().removeClass(options.lightCls)
17133                                }, function() {
17134                                    $(this).removeClass(options.lightCls)
17135                                })
17136                                .click(function() {
17137                                    var label    = $(this).text()
17138                                    var item     = $(this).data('item')
17139                                    var value    = item[options.keys.value]
17140                                    var isRepeat = false
17141
17142                                    that.$box.find('input:hidden').each(function() {
17143                                        if ($(this).val() == value) {
17144                                            isRepeat = true
17145                                            return
17146                                        }
17147                                    })
17148
17149                                    if (isRepeat) {
17150                                        options.istag && (that.$element.val(''))
17151                                        $menu.remove()
17152                                        return
17153                                    }
17154
17155                                    $.proxy(that.tools.createTag(label, value), that)
17156
17157                                    $menu.remove()
17158                                    options.istag && (that.$element.val(''))
17159
17160                                    //events
17161                                    $.proxy(that.tools.onAfterCreated(item, value), that)
17162                                })
17163
17164                            if ($menu.height() > h) {
17165                                $menu.height(h - 10).css('overflow-y', 'scroll')
17166                            }
17167
17168                            that.$menu = $menu
17169                        }
17170                    }
17171                })
17172            },
17173            createTag: function(label, value) {
17174                if (!that.options.istag) {
17175                    that.$element.val(label)
17176
17177                    return
17178                }
17179                var $btn = $('<span class="label label-tag" data-value="' + value +'" style="margin-left: 1px;
17179 margin-top: 1px;"><i class="fa fa-tag"></i> ' + label + '&nbsp;&nbsp;<a href="#" class="close">&times;</a></span>')
17180
17181                $btn
17182                    .insertBefore(that.$element)
17183                    .find('a.close')
17184                    .click(function() {
17185                        var value = $btn.data('value')
17186
17187                        that.$box.find('input:hidden').each(function() {
17188                            if ($(this).val() == value) {
17189                                $(this).remove()
17190                            }
17191                        })
17192
17193                        $btn.remove()
17194                        that.$tagsArr = that.$box.find('input[name="'+ that.options.tagname +'"]')
17195                    })
17196
17197                var $hidden = $('<input type="hidden" name="'+ that.options.tagname +'">').val(value)
17198
17199                $hidden.appendTo(that.$box)
17200                that.$tagsArr = that.$box.find('input[name="'+ that.options.tagname +'"]')
17201            },
17202            removeMenu: function() {
17203                if (that.$menu) that.$menu.remove()
17204            },
17205            onAfterCreated: function(item, value) {
17206                var alltags = []
17207
17208                that.$tagsArr.length && that.$tagsArr.each(function() {
17209                    alltags.push($(this).val())
17210                })
17211
17212                that.$element.trigger(Tags.EVENTS.afterCreated, {item:item, value:value, tags:alltags.join(',')})
17213            }
17214        }
17215
17216        return tools
17217    }
17218
17219    Tags.prototype.init = function() {
17220        var that     = this
17221        var $element = this.$element
17222        var options  = this.options
17223
17224        if (!(options.url)) {
17225            BJUI.debug('BJUI.Tags: Do query tags, url is undefined!')
17226            return
17227        }
17228        if (isNaN(this.options.max)) {
17229            BJUI.debug('BJUI.Tags: Parameter \'max\' is non-numeric type!')
17230            return
17231        }
17232
17233        that.$box.on('click', function() {
17234            $element.focus()
17235        })
17236
17237        if (options.istag)
17238            that.$box.css('width', options.width)
17239
17240        $element
17241            //.on('blur', $.proxy(this.tools.removeMenu, this))
17242            .on('keydown', $.proxy(this.tools.keyDown, this))
17243            .on('keyup', $.proxy(this.tools.keyUp, this))
17244
17245        if (!$.support.leadingWhitespace) { // for ie8
17246            $element.on('propertychange', $.proxy(this.tools.query, this))
17247        } else {
17248            $element.on('input', $.proxy(this.tools.query, this))
17249        }
17250
17251        $(document).on('click.bjui.tags', $.proxy(function(e) {
17252            if (!$(e.target).closest(this.$box).length) this.tools.removeMenu()
17253        }, this))
17254    }
17255
17256    Tags.prototype.destroy = function() {
17257        if (this.$tags) {
17258            this.$element.upwrap()
17259            $tags.remove()
17260        }
17261    }
17262
17263    // TAGS PLUGIN DEFINITION
17264    // =======================
17265
17266    function Plugin(option) {
17267        var args     = arguments,
17268            property = option
17269
17270        return this.each(function () {
17271            var $this   = $(this),
17272                options = {},
17273                data
17274
17275            $.extend(true, options, Tags.DEFAULTS, typeof option === 'object' && option)
17276
17277            data = new Tags(this, options)
17278
17279            if (typeof property === 'string' && $.isFunction(data[property])) {
17280                [].shift.apply(args)
17281                if (!args) data[property]()
17282                else data[property].apply(data, args)
17283            } else {
17284                data.init()
17285            }
17286        })
17287    }
17288
17289    var old = $.fn.tags
17290
17291    $.fn.tags             = Plugin
17292    $.fn.tags.Constructor = Tags
17293
17294    // TAGS NO CONFLICT
17295    // =================
17296
17297    $.fn.tags.noConflict = function () {
17298        $.fn.tags = old
17299        return this
17300    }
17301
17302    // TAGS DATA-API
17303    // ==============
17304
17305    $(document).on(BJUI.eventType.initUI, function(e) {
17306        $(e.target).find('input[data-toggle="tags"]').each(function() {
17307            var $this = $(this), data = $this.data(), options = data.options
17308
17309            if (options) {
17310                if (typeof options === 'string') {
17311                    if (options.trim().startsWith('{'))
17312                        options = options.toObj()
17313                    else
17314                        options = options.toFunc()
17315                }
17316                if (typeof options === 'function') {
17317                    options = options.apply()
17318                }
17319                if (typeof options === 'object') {
17320                    delete data.options
17321
17322                    $.extend(data, options)
17323                }
17324            } else {
17325                if (data.keys)
17326                    data.keys = data.keys.toObj()
17327                if (data.data)
17328                    data.data = data.data.toObj()
17329            }
17330
17331            Plugin.call($this, data)
17332        })
17333    })
17334
17335}(jQuery);
17336/*!
17337 * B-JUI  V1.31 (http://b-jui.com)
17338 * Git@OSC (http://git.oschina.net/xknaan/B-JUI)
17339 * Copyright 2014 K'naan.
17340 * Licensed under Apache (http://www.apache.org/licenses/LICENSE-2.0)
17341 */
17342
17343/* ========================================================================
17344 * B-JUI: bjui-theme.js  V1.31
17345 * @author K'naan
17346 * http://git.oschina.net/xknaan/B-JUI/blob/master/BJUI/js/bjui-theme.js
17347 * ========================================================================
17348 * Copyright 2014 K'naan.
17349 * Licensed under Apache (http://www.apache.org/licenses/LICENSE-2.0)
17350 * ======================================================================== */
17351
17352+function ($) {
17353    'use strict';
17354
17355    // THEME GLOBAL ELEMENTS
17356    // ======================
17357
17358    var $themeLink, $themeLis, $fontLis
17359    $(function() {
17360        var INIT_THEME = function() {
17361            $themeLink = $('#bjui-link-theme')
17362            $themeLis  = $('#bjui-themes')
17363            $fontLis   = $('#bjui-fonts')
17364
17365            if ($.cookie) {
17366                var themeName = $.cookie('bjui_theme') || 'blue'
17367                var $li = $themeLis.find('a.theme_'+ themeName)
17368
17369                $li.theme({})
17370
17371                /* font */
17372                var fontSize = $.cookie('bjui_font') || 'bjui-font-c'
17373                var $fontLi  = $fontLis.find('a.'+ fontSize)
17374
17375                $fontLi.theme('setFont', fontSize)
17376            }
17377        }
17378
17379        INIT_THEME()
17380    })
17381    // THEME CLASS DEFINITION
17382    // ======================
17383    var Theme = function(element, options) {
17384        this.$element = $(element)
17385        this.options  = options
17386    }
17387
17388    Theme.DEFAULTS = {
17389        theme: 'purple'
17390    }
17391
17392    //换肤设置 2020-10-09
17393    Theme.prototype.init = function() {
17394        if (!$themeLink.length) return
17395        var themeHref = $themeLink.attr('href')
17396        themeHref = themeHref.substring(0, themeHref.lastIndexOf('/'))
17397        // themeHref = themeHref.substring(0, themeHref.lastIndexOf('/'))
17398        // themeHref += '/'+ this.options.theme +'/core.css'
17399        themeHref += '/'+ this.options.theme +'.css?v=sun1.0'
17400        $themeLink.attr('href', themeHref)
17401
17402        var $themeA = this.$element.closest('li').filter('.active')
17403        var classA  = $themeA.data('theme') || 'default'
17404
17405        classA      = classA.replace(/(theme[\s][a-z]*)/g, '')
17406        $themeA.removeClass().addClass(classA).addClass('theme').addClass(this.options.theme)
17407        $themeLis.find('li').removeClass('active')
17408        this.$element.parent().addClass('active')
17409        this.cookie()
17410    }
17411
17412    Theme.prototype.setTheme = function(themeName) {
17413        $themeLink = $('#bjui-link-theme');
17414        if (!$themeLink.length) return
17415        var themeHref = $themeLink.attr('href')
17416        themeHref = themeHref.substring(0, themeHref.lastIndexOf('/'))
17417        themeHref += '/'+ themeName +'.css?v=sun1.0'
17418        $themeLink.attr('href', themeHref)
17419        // $themeLis.find('a.theme_'+ themeName).trigger('click')
17420    }
17421
17422    Theme.prototype.setFont = function(fontSize) {
17423        $('html').removeClass().addClass(fontSize)
17424
17425        this.$element.closest('ul').prev().html(this.$element.html()).removeClass().addClass('dropdown-toggle bjui-fonts-tit '+ fontSize)
17426
17427        $('body').find('table').each(function() {
17428            var $table = $(this), datagrid = $table.data('bjui.datagrid')
17429
17430            if (datagrid) {
17431                datagrid.needfixedWidth = true
17432                $table.datagrid('fixedWidth')
17433                datagrid.needfixedWidth = false
17434            }
17435        })
17436
17437        $(window).trigger(BJUI.eventType.resizeGrid)
17438
17439        if ($.cookie) $.cookie('bjui_font', fontSize, { path: '/', expires: 30 });
17440    }
17441
17442    Theme.prototype.cookie = function() {
17443        var theme = this.options.theme
17444
17445        if ($.cookie) $.cookie('bjui_theme', theme, { path: '/', expires: 30 });
17446    }
17447
17448    // THEME PLUGIN DEFINITION
17449    // =======================
17450
17451    function Plugin(option) {
17452        var args     = arguments
17453        var property = option
17454
17455        return this.each(function () {
17456            var $this   = $(this)
17457            var options = $.extend({}, Theme.DEFAULTS, $this.data(), typeof option === 'object' && option)
17458            var data    = $this.data('bjui.theme')
17459
17460            if (!data) $this.data('bjui.theme', (data = new Theme(this, options)))
17461            if (typeof property === 'string' && $.isFunction(data[property])) {
17462                [].shift.apply(args)
17463                if (!args) data[property]()
17464                else data[property].apply(data, args)
17465            } else {
17466                data.init()
17467            }
17468        })
17469    }
17470
17471    var old = $.fn.theme
17472
17473    $.fn.theme             = Plugin
17474    $.fn.theme.Constructor = Theme
17475
17476    // THEME NO CONFLICT
17477    // =================
17478
17479    $.fn.theme.noConflict = function () {
17480        $.fn.theme = old
17481        return this
17482    }
17483
17484    // THEME DATA-API
17485    // ==============
17486
17487    $(document).on('click.bjui.theme.data-api', '[data-toggle="theme"]', function(e) {
17488        Plugin.call($(this))
17489
17490        e.preventDefault()
17491    })
17492
17493    $(document).on('click.bjui.fonts.data-api', '[data-toggle="fonts"]', function(e) {
17494        Plugin.call($(this), 'setFont', $(this).attr('class'))
17495
17496        e.preventDefault()
17497    })
17498
17499}(jQuery);
17500/*!
17501 * B-JUI  V1.31 (http://b-jui.com)
17502 * Git@OSC (http://git.oschina.net/xknaan/B-JUI)
17503 * Copyright 2014 K'naan.
17504 * Licensed under Apache (http://www.apache.org/licenses/LICENSE-2.0)
17505 */
17506
17507/* ========================================================================
17508 * B-JUI: bjui-initui.js  V1.31
17509 * @author K'naan
17510 * http://git.oschina.net/xknaan/B-JUI/blob/master/BJUI/js/bjui-initui.js
17511 * ========================================================================
17512 * Copyright 2014 K'naan.
17513 * Licensed under Apache (http://www.apache.org/licenses/LICENSE-2.0)
17514 * ======================================================================== */
17515
17516+function ($) {
17517    'use strict';
17518
17519    // INITUI CLASS DEFINITION
17520    // ======================
17521    var Initui = function(element, options) {
17522        var $this     = this
17523        this.$element = $(element)
17524        this.options  = options
17525    }
17526
17527    Initui.DEFAULTS = {}
17528
17529    Initui.prototype.init = function() {
17530        var that = this, $element = that.$element
17531
17532        $.when(that.initUI()).done(function(){
17533            $element.trigger(BJUI.eventType.afterInitUI)
17534        })
17535    }
17536
17537    Initui.prototype.initUI = function() {
17538        var $element = this.$element
17539
17540        $.when($element.trigger(BJUI.eventType.beforeInitUI)).done(function(){
17541            $element.trigger(BJUI.eventType.initUI)
17542        })
17543    }
17544
17545    // INITUI PLUGIN DEFINITION
17546    // =======================
17547
17548    function Plugin(option) {
17549        var args     = arguments,
17550            property = option
17551
17552        return this.each(function () {
17553            var $this   = $(this),
17554                options = $.extend({}, Initui.DEFAULTS, $this.data(), typeof option === 'object' && option),
17555                data    = $this.data('bjui.initui')
17556
17557            if (!data) $this.data('bjui.initui', (data = new Initui(this, options)))
17558
17559            if (typeof property === 'string' && $.isFunction(data[property])) {
17560                [].shift.apply(args)
17561                if (!args) data[property]()
17562                else data[property].apply(data, args)
17563            } else {
17564                data.init()
17565            }
17566        })
17567    }
17568
17569    var old = $.fn.initui
17570
17571    $.fn.initui             = Plugin
17572    $.fn.initui.Constructor = Initui
17573
17574    // INITUI NO CONFLICT
17575    // =================
17576
17577    $.fn.initui.noConflict = function () {
17578        $.fn.initui = old
17579        return this
17580    }
17581
17582    // INITUI DATA-API
17583    // ==============
17584
17585    $(document).on('click.bjui.initui.data-api', '[data-toggle="initui"]', function(e) {
17586        Plugin.call($this, $this.data())
17587
17588        e.preventDefault()
17589    })
17590
17591    /* beforeInitUI */
17592    $(document).on(BJUI.eventType.beforeInitUI, function(e) {
17593        var $box    = $(e.target),
17594            noinits = [],
17595            $noinit = $box.find('[data-noinit], pre')
17596
17597        //progress
17598        $box.find('> .bjui-maskProgress').find('.progress').stop().animate({width:'85%'}, 'fast')
17599
17600        // Hide not need to initialize the UI DOM
17601        $noinit.each(function(i) {
17602            var $this = $(this), pos = {}
17603
17604            pos.$target = $this
17605            pos.$next   = $this.next()
17606            pos.$prev   = $this.prev()
17607            pos.$parent = $this.parent()
17608            pos.visible = $this.is(':visible') ? true : false
17609
17610            noinits.push(pos)
17611            $this.remove()
17612        })
17613
17614        $box.data('bjui.noinit', noinits)
17615    })
17616
17617    /* initUI */
17618    $(document).on(BJUI.eventType.initUI, function(e) {
17619        var $box    = $(e.target)
17620
17621        //progress
17622        $box.find('> .bjui-maskProgress').find('.progress').stop().animate({width:'95%'}, 'fast')
17623    })
17624
17625    /* afterInitUI */
17626    $(document).on(BJUI.eventType.afterInitUI, function(e) {
17627        var $box    = $(e.target),
17628            noinits = $box.data('bjui.noinit'),
17629            $form   = $box.find('> .bjui-pageContent').find('form')
17630
17631        // Recovery not need to initialize the UI DOM
17632        if (noinits) {
17633            $.each(noinits, function(i, n) {
17634                if (n.$next.length) n.$next.before(n.$target)
17635                else if (n.$prev.length) n.$prev.after(n.$target)
17636                else if (n.$parent.length) n.$parent.append(n.$target)
17637
17638                if (n.visible) n.$target.show()
17639
17640                $box.removeData('bjui.noinit')
17641            })
17642        }
17643
17644        /* resizePageH */
17645        $box.resizePageH()
17646
17647        //submit
17648        if ($form.length) {
17649            $box.find('> .bjui-pageFooter').find(':submit').on('click.bjui.submit', function(e) {
17650                e.preventDefault()
17651
17652                $form.submit()
17653            })
17654        }
17655
17656        $box.find('> .bjui-pageFooter').find(':submit.btn-submit-header').on('click.bjui.submit', function(e) {
17657            e.preventDefault()
17658
17659            var $form = $box.find('> .bjui-pageHeader').find('form')
17660
17661            $form.length && $form.submit()
17662        })
17663
17664        //progress
17665        $box.find('> .bjui-maskProgress').find('.progress').stop().animate({width:'100%'}, 'fast', function() {
17666            $box.find('> .bjui-ajax-mask').fadeOut('normal', function() { $(this).remove() })
17667        })
17668    })
17669
17670    /* Lateral Navigation */
17671    $(document).one(BJUI.eventType.afterInitUI, function(e) {
17672        var $hnavbar = $('#bjui-hnav-navbar'), $active = $hnavbar.find('> li.active'), $a = $active.find('> a')
17673
17674        if ($active.length) {
17675            if ($active.find('> .items').length) {
17676                $a.trigger('click')
17677            } else {
17678                var href = $a.attr('href')
17679
17680                if (href && !(href.startsWith('#') || href.startsWith('javascript'))) {
17681                    $a.trigger('click')
17682                }
17683            }
17684        }
17685    })
17686
17687    /* ajaxStatus */
17688    var bjui_ajaxStatus = function($target) {
17689        var $this    = $target,
17690            $offset  = $this,
17691            position = $this.css('position'),
17692            top      = $this.scrollTop() || 0,
17693            height   = ($this[0].clientHeight) / 2
17694
17695        if (position == 'static') {
17696            $this.css('position', 'relative').data('bjui.ajax.static', true)
17697            $offset  = $this.offsetParent()
17698        }
17699
17700        var zIndex   = parseInt($offset.css('zIndex')) || 0,
17701            $ajaxBackground = $this.find('> .bjui-maskBackground'),
17702            $ajaxProgress   = $this.find('> .bjui-maskProgress')
17703
17704        if (!$ajaxBackground.length) {
17705            $ajaxBackground = $(FRAG.maskBackground)
17706            $ajaxProgress   = $(BJUI.doRegional(FRAG.maskProgress, BJUI.regional))
17707            $this.prepend($ajaxBackground).prepend($ajaxProgress)
17708        }
17709
17710        var bgZindex = parseInt($ajaxBackground.css('zIndex')) || 0,
17711            prZindex = parseInt($ajaxProgress.css('zIndex')) || 0
17712
17713        $ajaxBackground.css('zIndex', zIndex + 1).css('top', top)
17714        $ajaxProgress.css('zIndex', zIndex + 2)
17715
17716        if (top)
17717            $ajaxProgress.css('top', top + height)
17718
17719        if (height == 0) {
17720            setTimeout(function() {
17721                $ajaxProgress.css('top', $(this).scrollTop() + $this[0].clientHeight / 2)
17722            }, 50)
17723        }
17724
17725        $this.off('scroll.ajaxmask').on('scroll.ajaxmask', function() {
17726            var top = $(this).scrollTop()
17727
17728            $ajaxBackground.css('top', $this.scrollTop())
17729            $ajaxProgress.css('top', top + this.clientHeight / 2)
17730        })
17731
17732        return {$bg:$ajaxBackground, $pr:$ajaxProgress}
17733    }
17734
17735    $(document)
17736        .on('bjui.ajaxStart', function(e, timeout, callback) {
17737            var ajaxMask = bjui_ajaxStatus($(e.target))
17738
17739            ajaxMask.$bg.fadeIn()
17740            ajaxMask.$pr.fadeIn()
17741            ajaxMask.$pr.find('.progress').animate({width:'80%'}, timeout || 500)
17742
17743            if (callback) {
17744                setTimeout(function() {
17745                    callback.toFunc().call(this)
17746                }, 25)
17747            }
17748        })
17749        .on('bjui.ajaxStop', function(e) {
17750            var $target = $(e.target), ajaxMask = bjui_ajaxStatus($target)
17751
17752            ajaxMask.$pr.find('.progress').animate({width:'100%'}, 'fast', function() {
17753                ajaxMask.$bg.remove()
17754                ajaxMask.$pr.remove()
17755
17756                if ($target.data('bjui.ajax.static'))
17757                    $target.css('position', 'static')
17758            })
17759        })
17760        .on('bjui.ajaxError', function(e) {
17761            var $target = $(e.target), ajaxMask = bjui_ajaxStatus($target)
17762
17763            ajaxMask.$bg.remove()
17764            ajaxMask.$pr.remove()
17765
17766            if ($target.data('bjui.ajax.static'))
17767                $target.css('position', 'static')
17768        })
17769
17770    $(document).on(BJUI.eventType.ajaxStatus, function(e) {
17771        var $target = $(e.target), ajaxMask = bjui_ajaxStatus($target)
17772
17773        $target
17774            .one('ajaxStart', function() {
17775                ajaxMask.$bg.fadeIn()
17776                ajaxMask.$pr.fadeIn()
17777
17778                ajaxMask.$pr.find('.progress').animate({width:'10%'}, 'fast')
17779            })
17780            .one('ajaxStop', function() {
17781                //ajaxMask.$bg.fadeOut()
17782                //ajaxMask.$pr.fadeOut()
17783                //ajaxMask.$pr.find('.progress').animate({width:'80%'}, 'fast')
17784            })
17785            .one('ajaxError', function() {
17786                ajaxMask.$bg.remove()
17787                ajaxMask.$pr.remove()
17788
17789                if ($target.data('bjui.ajax.static'))
17790                    $target.css('position', 'static')
17791            })
17792    })
17793
17794    /* Clean plugins generated 'Dom elements' in the body */
17795    var bodyClear = function($target) {
17796        $target.find('select[data-toggle="selectpicker"]').selectpicker('destroyMenu')
17797        $target.find('[data-toggle="selectztree"]').trigger('destroy.bjui.selectztree')
17798        $target.find('.bjui-suggest-input').trigger('destroy.bjui.suggest')
17799    }
17800
17801    $(document).on(BJUI.eventType.beforeLoadDialog, function(e) {
17802
17803    }).on(BJUI.eventType.beforeAjaxLoad, function(e) {
17804        bodyClear($(e.target))
17805    }).on(BJUI.eventType.beforeCloseNavtab, function(e) {
17806        bodyClear($(e.target))
17807    }).on(BJUI.eventType.beforeCloseDialog, function(e) {
17808        bodyClear($(e.target))
17809    })
17810
17811    /* other */
17812    $(function() {
17813        $(document).on('keydown keyup', function(e) {
17814            if (e.which === BJUI.keyCode.CTRL) {
17815                BJUI.KeyPressed.ctrl = e.type == 'keydown' ? true : false
17816            }
17817            if (e.which === BJUI.keyCode.SHIFT) {
17818                BJUI.KeyPressed.shift = e.type == 'keydown' ? true : false
17819            }
17820        })
17821    })
17822
17823}(jQuery);
17824/*!
17825 * B-JUI  V1.31 (http://b-jui.com)
17826 * Git@OSC (http://git.oschina.net/xknaan/B-JUI)
17827 * Copyright 2014 K'naan.
17828 * Licensed under Apache (http://www.apache.org/licenses/LICENSE-2.0)
17829 */
17830
17831/* ========================================================================
17832 * B-JUI: bjui-plugins.js  V1.31
17833 * @author K'naan
17834 * http://git.oschina.net/xknaan/B-JUI/blob/master/BJUI/js/bjui-plugins.js
17835 * ========================================================================
17836 * Copyright 2014 K'naan.
17837 * Licensed under Apache (http://www.apache.org/licenses/LICENSE-2.0)
17838 * ======================================================================== */
17839
17840+function ($) {
17841    'use strict';
17842
17843    $(document).on(BJUI.eventType.initUI, function(e) {
17844        var $box    = $(e.target)
17845
17846        // UI init begin...
17847
17848        /* i-check */
17849        if ($.fn.iCheck) {
17850            var $icheck = $box.find('input[data-toggle="icheck"]')
17851
17852            $icheck.each(function(i) {
17853                var $element = $(this),
17854                    id       = $element.attr('id'),
17855                    name     = $element.attr('name'),
17856                    label    = $element.data('label')
17857
17858                if (label) $element.after('<label for="'+ id +'" class="ilabel">'+ label +'</label>')
17859
17860                $element
17861                    .on('ifCreated', function(e) {
17862                        /* Fixed validate msgbox position */
17863                        var $parent = $(this).closest('div'),
17864                            $ilabel = $parent.next('[for="'+ id +'"]')
17865
17866                        $parent.attr('data-icheck', name)
17867                        $ilabel.attr('data-icheck', name)
17868                    })
17869                    .iCheck({
17870                        checkboxClass : 'icheckbox_minimal-purple',
17871                        radioClass    : 'iradio_minimal-purple',
17872                        increaseArea  : '20%' // optional
17873                    })
17874                    .on('ifChanged', function() {
17875                        /* Trigger validation */
17876                        $.fn.validator && $(this).trigger('validate')
17877                    })
17878
17879                if ($element.prop('disabled')) $element.iCheck('disable')
17880            })
17881            /* i-check check all */
17882            $icheck.filter('.checkboxCtrl').on('ifChanged', function(e) {
17883                var checked = e.target.checked == true ? 'check' : 'uncheck'
17884                var group   = $(this).data('group')
17885
17886                $box.find(':checkbox[name="'+ group +'"]').iCheck(checked)
17887            })
17888        }
17889
17890        /* fixed ui style */
17891        $box.find('button').each(function() {
17892            var $element = $(this), icon = $element.data('icon')
17893
17894            $element.addClass('btn')
17895
17896            if (icon && !$element.find('> i').length) {
17897                icon = 'fa-'+ icon.replace('fa-', '')
17898
17899                if (!$element.data('bjui.icon')) {
17900                    $element.html('<i class="fa '+ icon +'"></i> '+ $element.html()).data('bjui.icon', true)
17901                }
17902            }
17903        })
17904
17905        $box.find('input:text, input:password').each(function() {
17906            var $element = $(this).addClass('form-control'), size = $element.attr('size') || 0, width = size * 10
17907
17908            width && $element.css('width', width)
17909        })
17910
17911        $box.find('textarea').each(function() {
17912            var $element = $(this).addClass('form-control'), cols = $element.attr('cols') || 0, width = cols * 10, toggle = $element.attr('data-toggle')
17913
17914            width && $element.css('width', width)
17915
17916            if (toggle && toggle == 'autoheight' && $.fn.autosize)
17917                $element.addClass('autosize').autosize()
17918        })
17919
17920        $box.find('a.btn').each(function() {
17921            var $element = $(this), icon = $element.data('icon')
17922
17923            if (icon && !$element.find('> i').length) {
17924                icon = 'fa-'+ icon.replace('fa-', '')
17925
17926                if (!$element.data('bjui.icon')) {
17927                    $element.html('<i class="fa '+ icon +'"></i> '+ $element.html()).data('bjui.icon', true)
17928                }
17929            }
17930        })
17931
17932        /* form validate */
17933        if ($.fn.validator) {
17934            $box.find('form[data-toggle="validate"]').each(function() {
17935                var $element = $(this)
17936
17937                $(this)
17938                    .validator({
17939                        valid: function(form) {
17940                            $(form).bjuiajax('_ajaxform', $(form), $(form).data())
17941                        },
17942                        validClass : 'ok',
17943                        msgClass   : 'n-bottom',
17944                        theme      : 'red_bottom_effect_grid'
17945                    })
17946                    .on('invalid.form', function(e, form, errors) {
17947                        if ($(form).data('alertmsg')) $(form).alertmsg('error', BJUI.regional.validatemsg.replaceMsg(errors.length))
17948                    })
17949            })
17950        }
17951
17952        /* moreSearch */
17953        $box.find('[data-toggle="moresearch"]').each(function() {
17954            var $element = $(this),
17955                $parent  = $element.closest('.bjui-pageHeader'),
17956                $more    = $parent && $parent.find('.bjui-moreSearch'),
17957                name     = $element.data('name')
17958
17959            if (!$element.attr('title')) $element.attr('title', '更多查询条件')
17960            $element.click(function(e) {
17961                if (!$more.length) {
17962                    BJUI.debug('Not created \'moresearch\' box[class="bjui-moreSearch"]!')
17963                    return
17964                }
17965                $more.css('top', $parent.outerHeight() - 1)
17966                if ($more.is(':visible')) {
17967                    $element.html('<i class="fa fa-angle-double-down"></i>')
17968                    if (name) $('body').data('moresearch.'+ name, false)
17969                } else {
17970                    $element.html('<i class="fa fa-angle-double-up"></i>')
17971                    if (name) $('body').data('moresearch.'+ name, true)
17972                }
17973                $more.fadeToggle('slow', 'linear')
17974
17975                e.preventDefault()
17976            })
17977
17978            if (name && $('body').data('moresearch.'+ name)) {
17979                $more.css('top', $parent.outerHeight() - 1).fadeIn()
17980                $element.html('<i class="fa fa-angle-double-up"></i>')
17981            }
17982        })
17983
17984        /* bootstrap - select */
17985        if ($.fn.selectpicker) {
17986            var $selectpicker       = $box.find('select[data-toggle="selectpicker"]')
17987            var bjui_select_linkage = function($obj, $next) {
17988                if (!$next || !$next.length) return
17989
17990                var refurl    = $obj.data('refurl')
17991                var _setEmpty = function($select) {
17992                    var $_nextselect = $($select.data('nextselect'))
17993
17994                    if ($_nextselect && $_nextselect.length) {
17995                        var emptytxt = $_nextselect.data('emptytxt') || '&nbsp;'
17996
17997                        $_nextselect.html('<option>'+ emptytxt +'</option>').selectpicker('refresh')
17998                        _setEmpty($_nextselect)
17999                    }
18000                }
18001
18002                if (($next && $next.length) && refurl) {
18003                    var val = $obj.data('val'), nextVal = $next.data('val'), keys = $obj.data('keys')
18004
18005                    if (keys && typeof keys === 'string')
18006                        keys = keys.toObj()
18007                    if (!keys)
18008                        keys = {}
18009
18010                    if (typeof val === 'undefined') val = $obj.val()
18011                    $.ajax({
18012                        type     : 'POST',
18013                        dataType : 'json',
18014                        url      : refurl.replace('{value}', encodeURIComponent(val)),
18015                        cache    : false,
18016                        data     : {},
18017                        success  : function(json) {
18018                            if (!json) return
18019
18020                            var html = '', selected = ''
18021
18022                            $.each(json, function(i) {
18023                                var value, label
18024
18025                                if (json[i] && json[i].length) {
18026                                    value = json[i][0]
18027                                    label = json[i][1]
18028                                } else {
18029                                    value = json[i][keys.value || 'value']
18030                                    label = json[i][keys.label || 'label']
18031                                }
18032                                if (typeof nextVal !== 'undefined') selected = value == nextVal ? ' selected' : ''
18033                                html += '<option value="'+ value +'"'+ selected +'>' + label + '</option>'
18034                            })
18035
18036                            $obj.removeAttr('data-val').removeData('val')
18037                            $next.removeAttr('data-val').removeData('val')
18038
18039                            if (!html) {
18040                                html = $next.data('emptytxt') || '&nbsp;'
18041                                html = '<option>'+ html +'</option>'
18042                            }
18043
18044                            $next.html(html).selectpicker('refresh')
18045                            _setEmpty($next)
18046                        },
18047                        error   : BJUI.ajaxError
18048                    })
18049                }
18050            }
18051
18052            $selectpicker.each(function() {
18053                var $element  = $(this)
18054                var options   = $element.data()
18055                var $next     = $(options.nextselect)
18056
18057                $element.addClass('show-tick')
18058                if (!options.style) $element.data('style', 'btn-default')
18059                if (!options.width) $element.data('width', 'auto')
18060                if (!options.container) $element.data('container', 'body')
18061                else if (options.container == true) $element.attr('data-container', 'false').data('container', false)
18062
18063                $element.selectpicker()
18064
18065                if ($next && $next.length && (typeof $next.data('val') != 'undefined'))
18066                    bjui_select_linkage($element, $next)
18067
18068            })
18069
18070            /* bootstrap - select - linkage && Trigger validation */
18071            $selectpicker.change(function() {
18072                var $element    = $(this)
18073                var $nextselect = $($element.data('nextselect'))
18074
18075                bjui_select_linkage($element, $nextselect)
18076
18077                /* Trigger validation */
18078                if ($element.attr('aria-required')) {
18079                    $.fn.validator && $element.trigger('validate')
18080                }
18081            })
18082        }
18083
18084        if ($.fn.zTree) {
18085            /* zTree - plugin */
18086            $box.find('[data-toggle="ztree"]').each(function() {
18087                var $this = $(this), op = $this.data(), options = op.options, _setting
18088
18089                if (options && typeof options === 'string') options = options.toObj()
18090                if (options) $.extend(op, typeof options === 'object' && options)
18091
18092                _setting = op.setting
18093
18094                if (!op.nodes) {
18095                    op.nodes = []
18096                    $this.find('> li').each(function() {
18097                        var $li   = $(this)
18098                        var node  = $li.data()
18099
18100                        if (node.pid) node.pId = node.pid
18101                        node.name = $li.html()
18102                        op.nodes.push(node)
18103                    })
18104                    $this.empty()
18105                } else {
18106                    if (typeof op.nodes === 'string') {
18107                        if (op.nodes.trim().startsWith('[') || op.nodes.trim().startsWith('{')) {
18108                            op.nodes = op.nodes.toObj()
18109                        } else {
18110                            op.nodes = op.nodes.toFunc()
18111                        }
18112                    }
18113                    if (typeof op.nodes === 'function') {
18114                        op.nodes = op.nodes.call(this)
18115                    }
18116
18117                    $this.removeAttr('data-nodes')
18118                }
18119
18120                if (!op.showRemoveBtn) op.showRemoveBtn = false
18121                if (!op.showRenameBtn) op.showRenameBtn = false
18122                if (op.addHoverDom && typeof op.addHoverDom !== 'function')       op.addHoverDom    = (op.addHoverDom === 'edit')    ? _addHoverDom    : op.addHoverDom.toFunc()
18123                if (op.removeHoverDom && typeof op.removeHoverDom !== 'function') op.removeHoverDom = (op.removeHoverDom === 'edit') ? _removeHoverDom : op.removeHoverDom.toFunc()
18124                if (!op.maxAddLevel)   op.maxAddLevel   = 2
18125
18126                var setting = {
18127                    view: {
18128                        addHoverDom    : op.addHoverDom || null,
18129                        removeHoverDom : op.removeHoverDom || null,
18130                        addDiyDom      : op.addDiyDom ? op.addDiyDom.toFunc() : null
18131                    },
18132                    edit: {
18133                        enable        : op.editEnable,
18134                        showRemoveBtn : op.showRemoveBtn,
18135                        showRenameBtn : op.showRenameBtn
18136                    },
18137                    check: {
18138                        enable    : op.checkEnable,
18139                        chkStyle  : op.chkStyle,
18140                        radioType : op.radioType
18141                    },
18142                    callback: {
18143                        onClick       : op.onClick      ? op.onClick.toFunc()      : null,
18144                        beforeDrag    : op.beforeDrag   ? op.beforeDrag.toFunc()   : _beforeDrag,
18145                        beforeDrop    : op.beforeDrop   ? op.beforeDrop.toFunc()   : _beforeDrop,
18146                        onDrop        : op.onDrop       ? op.onDrop.toFunc()       : null,
18147                        onCheck       : op.onCheck      ? op.onCheck.toFunc()      : null,
18148                        beforeRemove  : op.beforeRemove ? op.beforeRemove.toFunc() : null,
18149                        onRemove      : op.onRemove     ? op.onRemove.toFunc()     : null,
18150                        onNodeCreated : _onNodeCreated,
18151                        onCollapse    : _onCollapse,
18152                        onExpand      : _onExpand
18153                    },
18154                    data: {
18155                        simpleData: {
18156                            enable: op.simpleData || true
18157                        },
18158                        key: {
18159                            title: op.title || ''
18160                        }
18161                    }
18162                }
18163
18164                if (_setting && typeof _setting === 'string') _setting = _setting.toObj()
18165                if (_setting) $.extend(true, setting, typeof _setting === 'object' && _setting)
18166
18167                $.fn.zTree.init($this, setting, op.nodes)
18168
18169                var IDMark_A = '_a'
18170                var zTree    = $.fn.zTree.getZTreeObj($this.attr('id'))
18171
18172                if (op.expandAll) zTree.expandAll(true)
18173
18174                // onCreated
18175                function _onNodeCreated(event, treeId, treeNode) {
18176                    if (treeNode.faicon) {
18177                        var $a    = $('#'+ treeNode.tId +'_a')
18178
18179                        if (!$a.data('faicon')) {
18180                            $a.data('faicon', true)
18181                                .addClass('faicon')
18182                                .find('> span.button').append('<i class="fa fa-'+ treeNode.faicon +'"></i>')
18183                        }
18184                    }
18185                    if (op.onNodeCreated) {
18186                        op.onNodeCreated.toFunc().call(this, event, treeId, treeNode)
18187                    }
18188                }
18189                // onCollapse
18190                function _onCollapse(event, treeId, treeNode) {
18191                    if (treeNode.faiconClose) {
18192                        $('#'+ treeNode.tId +'_ico').find('> i').attr('class', 'fa fa-'+ treeNode.faiconClose)
18193                    }
18194
18195                    if (op.onCollapse) {
18196                        op.onCollapse.toFunc().call(this, event, treeId, treeNode)
18197                    }
18198                }
18199                // onExpand
18200                function _onExpand(event, treeId, treeNode) {
18201                    if (treeNode.faicon && treeNode.faiconClose) {
18202                        $('#'+ treeNode.tId +'_ico').find('> i').attr('class', 'fa fa-'+ treeNode.faicon)
18203                    }
18204                    if (op.onExpand) {
18205                        op.onExpand.toFunc().call(this, event, treeId, treeNode)
18206                    }
18207                }
18208                // add button, del button
18209                function _addHoverDom(treeId, treeNode) {
18210                    var level = treeNode.level
18211                    var $obj  = $('#'+ treeNode.tId + IDMark_A)
18212                    var $add  = $('#diyBtn_add_'+ treeNode.id)
18213                    var $del  = $('#diyBtn_del_'+ treeNode.id)
18214
18215                    if (!$add.length) {
18216                        if (level < op.maxAddLevel) {
18217                            $add = $('<span class="tree_add" id="diyBtn_add_'+ treeNode.id +'" title="添加"></span>')
18218                            $add.appendTo($obj);
18219                            $add.on('click', function(){
18220                                zTree.addNodes(treeNode, {name:'新增Item'})
18221                            })
18222                        }
18223                    }
18224
18225                    if (!$del.length) {
18226                        var $del = $('<span class="tree_del" id="diyBtn_del_'+ treeNode.id +'" title="删除"></span>')
18227
18228                        $del
18229                            .appendTo($obj)
18230                            .on('click', function(event) {
18231                                    var delFn = function() {
18232                                        $del.alertmsg('confirm', '确认要删除 '+ treeNode.name +' 吗?', {
18233                                            okCall: function() {
18234                                                zTree.removeNode(treeNode)
18235                                                if (op.onRemove) {
18236                                                    var fn = op.onRemove.toFunc()
18237
18238                                                    if (fn) fn.call(this, event, treeId, treeNode)
18239                                                }
18240                                            },
18241                                            cancelCall: function () {
18242                                                return
18243                                            }
18244                                        })
18245                                    }
18246
18247                                    if (op.beforeRemove) {
18248                                        var fn = op.beforeRemove.toFunc()
18249
18250                                        if (fn) {
18251                                            var isdel = fn.call(fn, treeId, treeNode)
18252
18253                                            if (isdel && isdel == true) delFn()
18254                                        }
18255                                    } else {
18256                                        delFn()
18257                                    }
18258                                }
18259                            )
18260                    }
18261                }
18262
18263                // remove add button && del button
18264                function _removeHoverDom(treeId, treeNode) {
18265                    var $add = $('#diyBtn_add_'+ treeNode.id)
18266                    var $del = $('#diyBtn_del_'+ treeNode.id)
18267
18268                    if ($add && $add.length) {
18269                        $add.off('click').remove()
18270                    }
18271
18272                    if ($del && $del.length) {
18273                        $del.off('click').remove()
18274                    }
18275                }
18276
18277                // Drag
18278                function _beforeDrag(treeId, treeNodes) {
18279                    for (var i = 0; i < treeNodes.length; i++) {
18280                        if (treeNodes[i].drag === false) {
18281                            return false
18282                        }
18283                    }
18284                    return true
18285                }
18286
18287                function _beforeDrop(treeId, treeNodes, targetNode, moveType) {
18288                    return targetNode ? targetNode.drop !== false : true
18289                }
18290            })
18291
18292            /* zTree - drop-down selector */
18293
18294            var $selectzTree = $box.find('[data-toggle="selectztree"]')
18295
18296            $selectzTree.each(function() {
18297                var $this   = $(this)
18298                var options = $this.data(),
18299                    $tree   = $(options.tree),
18300                    w       = parseFloat($this.css('width')),
18301                    h       = $this.outerHeight()
18302
18303                options.width   = options.width || $this.outerWidth()
18304                options.height  = options.height || 'auto'
18305
18306                if (!$tree || !$tree.length) return
18307
18308                var treeid = $tree.attr('id')
18309                var $box   = $('#'+ treeid +'_select_box')
18310                var setPosition = function($box) {
18311                    var top        = $this.offset().top,
18312                        left       = $this.offset().left,
18313                        $clone     = $tree.clone().appendTo($('body')),
18314                        treeHeight = $clone.outerHeight()
18315
18316                    $clone.remove()
18317
18318                    var offsetBot = $(window).height() - treeHeight - top - h,
18319                        maxHeight = $(window).height() - top - h
18320
18321                    if (options.height == 'auto' && offsetBot < 0) maxHeight = maxHeight + offsetBot
18322                    $box.css({top:(top + h), left:left, 'max-height':maxHeight})
18323                }
18324
18325                $this.click(function() {
18326                    if ($box && $box.length) {
18327                        setPosition($box)
18328                        $box.show()
18329                        return
18330                    }
18331
18332                    var zindex = 2
18333                    var dialog = $.CurrentDialog
18334
18335                    if (dialog && dialog.length) {
18336                        zindex = dialog.css('zIndex') + 1
18337                    }
18338                    $box  = $('<div id="'+ treeid +'_select_box" class="tree-box"></div>')
18339                        .css({position:'absolute', 'zIndex':zindex, 'min-width':options.width, height:options.height, overflow:'auto', background:'#FAFAFA', border:'1px #EEE solid'})
18340                        .hide()
18341                        .appendTo($('body'))
18342
18343                    $tree.appendTo($box).css('width','100%').data('fromObj', $this).removeClass('hide').show()
18344                    setPosition($box)
18345                    $box.show()
18346                })
18347
18348                $('body').on('mousedown', function(e) {
18349                    var $target = $(e.target)
18350
18351                    if (!($this[0] == e.target || ($box && $box.length > 0 && $target.closest('.tree-box').length > 0))) {
18352                        $box.hide()
18353                    }
18354                })
18355
18356                var $scroll = $this.closest('.bjui-pageContent')
18357
18358                if ($scroll && $scroll.length) {
18359                    $scroll.scroll(function() {
18360                        if ($box && $box.length) {
18361                            setPosition($box)
18362                        }
18363                    })
18364                }
18365
18366                //destroy selectzTree
18367                $this.on('destroy.bjui.selectztree', function() {
18368                    $box.remove()
18369                })
18370            })
18371        }
18372
18373        /* Kindeditor */
18374        /*if (KindEditor) {
18375            $box.find('textarea[data-toggle="kindeditor"]').each(function() {
18376                var $editor = $(this).removeClass('form-control'), options = $editor.data(), _op = options.options
18377
18378                if (_op && typeof _op === 'string') _op = _op.toObj()
18379                if (_op && typeof _op === 'object') {
18380                    $.extend(options, _op)
18381                    delete options.options
18382                }
18383
18384                if (options.items && typeof options.items === 'string')
18385                    options.items = options.items.replaceAll('\'', '').replaceAll(' ', '').split(',')
18386                if (options.afterUpload)         options.afterUpload = options.afterUpload.toFunc()
18387                if (options.afterSelectFile) options.afterSelectFile = options.afterSelectFile.toFunc()
18388                if (options.confirmSelect)     options.confirmSelect = options.confirmSelect.toFunc()
18389
18390                var htmlTags = {
18391                    font : ['color', 'size', 'face', '.background-color'],
18392                    span : ['.color', '.background-color', '.font-size', '.font-family'
18393                            '.color', '.background-color', '.font-size', '.font-family', '.background',
18394                            '.font-weight', '.font-style', '.text-decoration', '.vertical-align', '.line-height'
18395                    ],
18396                    div : ['.margin', '.padding', '.text-align'
18397                            'align', '.border', '.margin', '.padding', '.text-align', '.color',
18398                            '.background-color', '.font-size', '.font-family', '.font-weight', '.background',
18399                            '.font-style', '.text-decoration', '.vertical-align', '.margin-left'
18400                    ],
18401                    table: ['align', 'width'
18402                            'border', 'cellspacing', 'cellpadding', 'width', 'height', 'align', 'bordercolor',
18403                            '.padding', '.margin', '.border', 'bgcolor', '.text-align', '.color', '.background-color',
18404                            '.font-size', '.font-family', '.font-weight', '.font-style', '.text-decoration', '.background',
18405                            '.width', '.height', '.border-collapse'
18406                    ],
18407                    'td,th': ['align', 'valign', 'width', 'height', 'colspan', 'rowspan'
18408                            'align', 'valign', 'width', 'height', 'colspan', 'rowspan', 'bgcolor',
18409                            '.text-align', '.color', '.background-color', '.font-size', '.font-family', '.font-weight',
18410                            '.font-style', '.text-decoration', '.vertical-align', '.background', '.border'
18411                    ],
18412                    a : ['href', 'target', 'name'],
18413                    embed : ['src', 'width', 'height', 'type', 'loop', 'autostart', 'quality', '.width', '.height', 'align', 'allowscriptaccess'],
18414                    img : ['src', 'width', 'height', 'border', 'alt', 'title', 'align', '.width', '.height', '.border'],
18415                    'p,ol,ul,li,blockquote,h1,h2,h3,h4,h5,h6' : [
18416                        'class', 'align', '.text-align', '.color', '.background-color', '.font-size', '.font-family', '.background',
18417                        '.font-weight', '.font-style', '.text-decoration', '.vertical-align', '.text-indent', '.margin-left'
18418                    ],
18419                    pre : ['class'],
18420                    hr : ['class', '.page-break-after'],
18421                    'br,tbody,tr,strong,b,sub,sup,em,i,u,strike,s,del' : []
18422                }
18423
18424                KindEditor.create($editor, {
18425                    pasteType                : options.pasteType,
18426                    minHeight                : options.minHeight || 260,
18427                    autoHeightMode           : options.autoHeight || false,
18428                    items                    : options.items || KindEditor.options.items,
18429                    uploadJson               : options.uploadJson,
18430                    fileManagerJson          : options.fileManagerJson,
18431                    allowFileManager         : options.allowFileManager || true,
18432                    //fillDescAfterUploadImage : options.fillDescAfterUploadImage || true, //上传图片成功后转到属性页,为false则直接插入图片[设为true方便自定义函数(X_afterSelect)]
18433                    afterUpload              : options.afterUpload,
18434                    afterSelectFile          : options.afterSelectFile,
18435                    //X_afterSelect            : options.confirmSelect,
18436                    //htmlTags                 : htmlTags,
18437
18438                    cssPath                  : [
18439                                                    BJUI.PLUGINPATH + 'kindeditor_4.1.10/editor-content.css',
18440                                                    BJUI.PLUGINPATH + 'kindeditor_4.1.10/plugins/code/prettify.css'
18441                                               ],
18442
18443                    afterBlur                : function() { this.sync() }
18444                })
18445            })
18446        }*/
18447
18448        if ($.fn.colorpicker) {
18449            /* colorpicker */
18450            $box.find('[data-toggle="colorpicker"]').each(function() {
18451                var $this     = $(this)
18452                var isbgcolor = $this.data('bgcolor')
18453
18454                $this.colorpicker()
18455                if (isbgcolor) {
18456                    $this.on('changeColor', function(ev) {
18457                        $this.css('background-color', ev.color.toHex())
18458                    })
18459                }
18460            })
18461
18462            $box.find('[data-toggle="clearcolor"]').each(function() {
18463                var $this   = $(this)
18464                var $target = $this.data('target') ? $($this.data('target')) : null
18465
18466                if ($target && $target.length) {
18467                    $this.click(function() {
18468                        $target.val('')
18469                        if ($target.data('bgcolor')) $target.css('background-color', '')
18470                    })
18471                }
18472            })
18473        }
18474
18475        /* tooltip */
18476        $box.find('[data-toggle="tooltip"]').each(function() {
18477            $(this).tooltip()
18478        })
18479
18480        $box.find('[data-toggle="popover"]').each(function() {
18481            var $element = $(this), target = $element.data('target')
18482
18483            if (target && $(target).length) {
18484                $element.attr('data-content', $(target).html())
18485            }
18486
18487            $element.popover()
18488        })
18489
18490        /* WebUploader */
18491        if (WebUploader) {
18492            var initWebUploader = function($element, index) {
18493                var old = $element.data('webuploader'), options = $element.data('options')
18494
18495                if (old) {
18496                    old.destroy()
18497                    $element.data('webuploader.wrap').remove()
18498                }
18499
18500                if (options) {
18501                    if (typeof options === 'string') {
18502                        options = options.trim().toObj()
18503                    }
18504
18505                    if (typeof options === 'object') {
18506                        $element.hide()
18507
18508                        var $wrap = $('<div id="uploader" class="wu-example"><div class="queueList"><div id="dndArea" class="placeholder"><div id="filePicker"></div><p>或将文件拖到这里</p></div></div><div class="statusBar" style="display:none;"><div class="progress"><span class="text">0%</span><span class="percentage"></span></div><div class="info"></div><div class="btns"><div id="filePicker2"></div><div class="uploadBtn">开始上传</div></div></div>'),
18509                            // 图片容器
18510                            $queue = $('<ul class="filelist"></ul>').appendTo($wrap.find('.queueList')),
18511                            // 状态栏,包括进度和控制按钮
18512                            $statusBar = $wrap.find('.statusBar'),
18513                            // 文件总体选择信息。
18514                            $info = $statusBar.find('.info'),
18515                            // 上传按钮
18516                            $upload = $wrap.find('.uploadBtn'),
18517                            // 没选择文件之前的内容。
18518                            $placeHolder = $wrap.find('.placeholder'),
18519                            // 总体进度条
18520                            $progress = $statusBar.find('.progress').hide(),
18521                            // 添加的文件数量
18522                            fileCount = 0,
18523                            // 添加的文件总大小
18524                            fileSize = 0,
18525                            // 优化retina, 在retina下这个值是2
18526                            ratio = window.devicePixelRatio || 1,
18527                            // 缩略图大小
18528                            thumbnailWidth = 110 * ratio,
18529                            thumbnailHeight = 110 * ratio,
18530                            // 可能有pedding, ready, uploading, confirm, done.
18531                            state = 'pedding',
18532                            // 所有文件的进度信息,key为file id
18533                            percentages = {},
18534                            supportTransition = (function() {
18535                                var s = document.createElement('p').style,
18536                                    r = 'transition' in s ||
18537                                        'WebkitTransition' in s ||
18538                                        'MozTransition' in s ||
18539                                        'msTransition' in s ||
18540                                        'OTransition' in s
18541
18542                                s = null
18543
18544                                return r
18545                            })(),
18546                            // 图片访问基地址
18547                            basePath = options.basePath || '',
18548                            // WebUploader实例
18549                            uploader,
18550                            // 上传文件的单位(单位 + 类型)
18551                            upunit = options.upunit || '张图片'
18552
18553                        // 当有文件添加进来时执行,负责view的创建
18554                        var addFile = function(file, isuploaded, _index) {
18555                            if (!file && options.uploaded) {
18556                                $.each(options.uploaded.split(','), function(i, n) {
18557                                    var uploadedFile = {id:'WU_FILE_UP_'+ i, name:n.trim(), src:basePath + n.trim()}
18558
18559                                    addFile(uploadedFile, true, i)
18560
18561                                    fileCount++
18562                                })
18563
18564                                if (fileCount) {
18565                                    $placeHolder.addClass('element-invisible');
18566                                    $statusBar.show()
18567                                    setState('uploaded')
18568                                }
18569
18570                                return
18571                            }
18572
18573                            if (fileCount >= options.fileNumLimit) {
18574                                $statusBar.find('#filePicker2').hide()
18575                            }
18576
18577                            var uploadedAttr = isuploaded && upunit === '张图片' ? ' style="cursor:pointer;" data-toggle="dialog" data-options="{id:\'bjui-dialog-view-upload-image\', image:\''+ encodeURIComponent(file.src) +'\', width:800, height:500, mask:true, title:\'查看已上传图片\'}"' : '',
18578                                $li = $('<li class="'+ (isuploaded ? 'uploaded' : '') +'" id="'+ file.id +'_'+ index +'">' +
18579                                    '<p class="title">' + file.name + '</p>' +
18580                                    '<p class="imgWrap" '+ uploadedAttr +'></p>'+
18581                                    '<p class="progress"><span></span></p>' +
18582                                    '</li>'),
18583                                $btns = $('<div class="file-panel">' +
18584                                    '<span class="cancel">删除</span>' +
18585                                    '<span class="rotateRight">向右旋转</span>' +
18586                                    '<span class="rotateLeft">向左旋转</span></div>').appendTo($li),
18587                                $prgress = $li.find('p.progress span'),
18588                                $imgWrap = $li.find('p.imgWrap'),
18589                                $info = $('<p class="error"></p>'),
18590                                text = '',
18591                                showError = function(code) {
18592                                    switch(code) {
18593                                        case 'exceed_size':
18594                                            text = '文件大小超出'
18595
18596                                            break
18597                                        case 'interrupt':
18598                                            text = '上传暂停'
18599
18600                                            break
18601                                        default:
18602                                            text = '上传失败,请重试'
18603
18604                                            break
18605                                    }
18606
18607                                    $info.text(text).appendTo($li)
18608                                }
18609
18610                            if (!isuploaded) {
18611                                if (file.getStatus() === 'invali
18611d') {
18612                                    showError(file.statusText)
18613                                } else {
18614                                    // @todo lazyload
18615                                    $imgWrap.text('预览中')
18616                                    uploader.makeThumb(file, function(error, src) {
18617                                        if (error) {
18618                                            $imgWrap.text('不能预览')
18619                                            return
18620                                        }
18621
18622                                        var img = $('<img src="'+src+'">')
18623
18624                                        $imgWrap.empty().append(img)
18625                                    }, thumbnailWidth, thumbnailHeight)
18626
18627                                    percentages[file.id] = [file.size, 0]
18628                                    file.rotation = 0
18629                                }
18630
18631                                file.on('statuschange', function(cur, prev) {
18632                                    if (prev === 'progress') {
18633                                        $prgress.hide().width(0)
18634                                    } else if (prev === 'queued') {
18635
18636                                    }
18637
18638                                    // 成功
18639                                    if (cur === 'error' || cur === 'invalid') {
18640                                        showError(file.statusText)
18641                                        percentages[file.id][1] = 1
18642                                    } else if (cur === 'interrupt') {
18643                                        showError('interrupt')
18644                                    } else if (cur === 'queued') {
18645                                        percentages[file.id][1] = 0
18646                                    } else if (cur === 'progress') {
18647                                        $info.remove()
18648                                        $prgress.css('display', 'block')
18649                                    } else if (cur === 'complete') {
18650                                        $li.append('<span class="success"></span>')
18651                                    }
18652
18653                                    $li.removeClass('state-' + prev).addClass('state-' + cur)
18654                                })
18655                            } else {
18656                                $imgWrap.empty().append('<img src="'+ file.src +'">')
18657                                if (options.initUploaded) {
18658                                    var arr = options.initUploaded.split(',')
18659
18660                                    $li.append('<input type="hidden" class="upload" name="'+ (options.upname || $element.data('name')) +'" value="'+ arr[_index] +'">')
18661                                }
18662                            }
18663
18664                            $li.on('mouseenter', function() {
18665                                $btns.stop().animate({height: 30})
18666                            })
18667
18668                            $li.on('mouseleave', function() {
18669                                $btns.stop().animate({height: 0})
18670                            })
18671
18672                            $btns.on('click', 'span', function() {
18673                                var index = $(this).index(),
18674                                    deg
18675
18676                                switch (index) {
18677                                    case 0:
18678                                        if (isuploaded) {
18679                                            fileCount --
18680                                            removeFile(file)
18681
18682                                            if (!fileCount) {
18683                                                setState('pedding');
18684                                            }
18685                                            uploader.refresh()
18686                                            updateTotalProgress()
18687                                        } else {
18688                                            uploader.removeFile(file)
18689                                        }
18690
18691                                        return
18692                                    case 1:
18693                                        file.rotation += 90
18694
18695                                        break
18696                                    case 2:
18697                                        file.rotation -= 90
18698
18699                                        break
18700                                }
18701
18702                                if (supportTransition) {
18703                                    deg = 'rotate(' + file.rotation + 'deg)'
18704                                    $imgWrap.css({
18705                                        '-webkit-transform': deg,
18706                                        '-mos-transform': deg,
18707                                        '-o-transform': deg,
18708                                        'transform': deg
18709                                    })
18710                                } else {
18711                                    $imgWrap.css('filter', 'progid:DXImageTransform.Microsoft.BasicImage(rotation='+ (~~((file.rotation/90)%4 + 4)%4) +')')
18712                                }
18713                            })
18714
18715                            $li.appendTo($queue)
18716                        }
18717
18718                        // 负责view的销毁
18719                        var removeFile = function(file) {
18720                            var $li = $wrap.find('#'+ file.id +'_'+ index)
18721
18722                            delete percentages[file.id]
18723                            updateTotalProgress()
18724
18725                            $li.off().find('.file-panel').off().end().remove()
18726
18727                            if (fileCount < options.fileNumLimit) {
18728                                $statusBar.find('#filePicker2').show()
18729                            }
18730                        }
18731
18732                        var updateTotalProgress = function() {
18733                            var loaded = 0,
18734                                total  = 0,
18735                                spans  = $progress.children(),
18736                                percent
18737
18738                            $.each(percentages, function(k, v) {
18739                                total  += v[0]
18740                                loaded += v[0] * v[1]
18741                            })
18742
18743                            percent = total ? loaded / total : 0
18744
18745                            spans.eq(0).text(Math.round(percent * 100) + '%')
18746                            spans.eq(1).css('width', Math.round(percent * 100) + '%')
18747                            updateStatus()
18748                        }
18749
18750                        var updateStatus = function() {
18751                            var text = '', stats;
18752
18753                            if (state === 'ready') {
18754                                text = '选中'+ fileCount + upunit + ',共'+ WebUploader.formatSize(fileSize) +'。'
18755                            } else if (state === 'confirm') {
18756                                stats = uploader.getStats()
18757                                if (stats.uploadFailNum) {
18758                                    text = '已成功上传'+ stats.successNum + upunit +','+
18759                                        stats.uploadFailNum + upunit +'上传失败,<a class="retry" href="#">重新上传</a> 或 <a class="ignore" href="#">忽略</a>'
18760                                }
18761
18762                            } else if (state === 'uploaded') {
18763                                text = '已上传'+ fileCount + upunit
18764                            } else {
18765                                stats = uploader.getStats()
18766                                text = '共'+ fileCount + upunit +'(' + WebUploader.formatSize(fileSize) +'),已上传' + stats.successNum
18767
18768                                if (stats.uploadFailNum) {
18769                                    text += ',失败' + stats.uploadFailNum
18770                                }
18771                            }
18772
18773                            $info.html(text)
18774                            $element.data('fileCount', fileCount)
18775                        }
18776
18777                        var setState = function(val) {
18778                            var file, stats
18779
18780                            if (val === state) {
18781                                return
18782                            }
18783
18784                            $upload.removeClass('state-' + state)
18785                            $upload.addClass('state-' + val)
18786                            state = val
18787
18788                            switch (state) {
18789                                case 'pedding':
18790                                    $placeHolder.removeClass('element-invisible')
18791                                    $queue.parent().removeClass('filled')
18792                                    $queue.hide();
18793                                    $statusBar.addClass('element-invisible')
18794                                    uploader.refresh()
18795
18796                                    break
18797                                case 'ready':
18798                                    $placeHolder.addClass('element-invisible')
18799                                    $wrap.find('#filePicker2').removeClass('element-invisible')
18800                                    $queue.parent().addClass('filled')
18801                                    $queue.show()
18802                                    $statusBar.removeClass('element-invisible')
18803                                    uploader.refresh()
18804                                    $upload.removeClass('disabled')
18805
18806                                    break
18807                                case 'uploading':
18808                                    $wrap.find('#filePicker2').addClass('element-invisible')
18809                                    $progress.show()
18810                                    $upload.text('暂停上传')
18811
18812                                    break
18813                                case 'paused':
18814                                    $progress.show()
18815                                    $upload.text('继续上传')
18816
18817                                    break
18818                                case 'confirm':
18819                                    $progress.hide()
18820                                    $upload.text('开始上传').addClass('disabled')
18821
18822                                    stats = uploader.getStats()
18823                                    if (stats.successNum && !stats.uploadFailNum) {
18824                                        setState('finish')
18825                                        return
18826                                    }
18827
18828                                    break
18829                                case 'finish':
18830                                    stats = uploader.getStats()
18831                                    if (stats.successNum) {
18832
18833                                    } else {
18834                                        // 没有成功的图片,重设
18835                                        state = 'done'
18836
18837                                        BJUI.alertmsg('info', '上传失败!')
18838                                    }
18839
18840                                    break
18841                                case 'uploaded':
18842                                    $upload.text('开始上传').addClass('disabled')
18843
18844                                    break
18845                            }
18846
18847                            if (state !== 'uploaded')
18848                                updateStatus()
18849                        }
18850
18851                        $wrap.insertAfter($element)
18852
18853                        if (!WebUploader.Uploader.support()) {
18854                            alert('Web Uploader 不支持您的浏览器!如果你使用的是IE浏览器,请尝试升级 flash 播放器');
18855                            throw new Error('WebUploader does not support the browser you are using.');
18856                        }
18857
18858                        // 是否允许重新上传
18859                        if (typeof options.reupload === 'undefined')
18860                            options.reupload = true
18861
18862                        options = $.extend(true, {}, {
18863                            pick: {
18864                                id: $wrap.find('#filePicker'),
18865                                label: '点击选择图片'
18866                            },
18867                            dnd: $wrap.find('.queueList'),
18868                            paste: false,
18869                            accept: {
18870                                title: 'Images',
18871                                extensions: 'gif,jpg,jpeg,bmp,png',
18872                                mimeTypes: 'image/*'
18873                            },
18874                            swf: BJUI.PLUGINPATH + 'webuploader/Uploader.swf', // swf文件路径
18875                            disableGlobalDnd: false,
18876                            chunked: false,
18877                            server: null,
18878                            fileNumLimit: 300,
18879                            fileSizeLimit: 200 * 1024 * 1024,        // 200 M
18880                            fileSingleSizeLimit: 50 * 1024 * 1024    // 50 M
18881                        }, options)
18882
18883                        // 实例化
18884                        uploader = WebUploader.create(options)
18885
18886                        // 如果有已上传的图片(编辑时)
18887                        if (typeof $element.data('uploaded') !== 'undefined')
18888                            options.uploaded = $element.data('uploaded')
18889                        if (options.uploaded) {
18890                            // 将已上传图片加到队列
18891                            addFile()
18892
18893                            $queue.parent().addClass('filled')
18894                        }
18895
18896                        // 上传成功
18897                        uploader.on('uploadSuccess', function(file, response) {
18898                            if (response[BJUI.keys.statusCode] != BJUI.statusCode.ok) {
18899                                BJUI.alertmsg('error', response.message)
18900                            } else {
18901                                var $li = $wrap.find('#'+ file.id +'_'+ index)
18902
18903                                $li.find('input.upload').remove().end()
18904                                    .append('<input type="hidden" class="upload" name="'+ (options.upname || $element.data('name')) +'" value="'+ response.filename +'">')
18905                            }
18906                        })
18907                        // 上传失败
18908                        uploader.on('uploadError', function(file, response) {
18909                            BJUI.alertmsg('error', response.message)
18910                        })
18911
18912                        // 添加“添加文件”的按钮,
18913                        if (options.fileNumLimit > 1) {
18914                            uploader.addButton({
18915                                id: $wrap.find('#filePicker2'),
18916                                label: '继续添加'
18917                            })
18918
18919                            if (fileCount >= options.fileNumLimit)
18920                                $statusBar.find('#filePicker2').hide()
18921                        }
18922
18923                        uploader.onUploadProgress = function(file, percentage) {
18924                            var $li = $wrap.find('#'+ file.id +'_'+ index),
18925                                $percent = $li.find('.progress span')
18926
18927                            $percent.css('width', percentage * 100 + '%')
18928                            percentages[file.id][1] = percentage
18929                            updateTotalProgress()
18930                        }
18931
18932                        uploader.onFileQueued = function(file) {
18933                            fileCount++
18934                            fileSize += file.size
18935
18936                            if (fileCount === 1) {
18937                                $placeHolder.addClass('element-invisible');
18938                                $statusBar.show()
18939                            }
18940
18941                            addFile(file)
18942                            setState('ready')
18943                            updateTotalProgress()
18944                        }
18945
18946                        uploader.onFileDequeued = function(file) {
18947                            fileCount--
18948                            fileSize -= file.size
18949
18950                            if (!fileCount) {
18951                                setState('pedding');
18952                            }
18953
18954                            removeFile(file)
18955                            updateTotalProgress()
18956                        }
18957
18958                        uploader.on('all', function(type) {
18959                            var stats
18960
18961                            switch(type) {
18962                                case 'uploadFinished':
18963                                    setState('confirm')
18964
18965                                    break
18966                                case 'startUpload':
18967                                    setState('uploading')
18968
18969                                    break
18970                                case 'stopUpload':
18971                                    setState('paused')
18972
18973                                    break
18974                            }
18975                        })
18976
18977                        uploader.onError = function(code) {
18978                            if (code === 'Q_EXCEED_NUM_LIMIT') {
18979                                BJUI.alertmsg('info', '只允许上传'+ options.fileNumLimit + upunit +'!')
18980                            } else if (code === 'Q_TYPE_DENIED') {
18981                                BJUI.alertmsg('info', '不支持的文件类型!')
18982                            } else if (code === 'F_EXCEED_SIZE') {
18983                                BJUI.alertmsg('info', '文件太大了!')
18984                            } else if (code === 'F_DUPLICATE') {
18985                                BJUI.alertmsg('info', '已添加过该文件!')
18986                            } else {
18987                                BJUI.alertmsg('info', code)
18988                            }
18989                        }
18990
18991                        $upload.on('click', function() {
18992                            if ($(this).hasClass('disabled')) {
18993                                return false
18994                            }
18995
18996                            if (state === 'ready') {
18997                                uploader.upload()
18998                            } else if (state === 'paused') {
18999                                uploader.upload()
19000                            } else if (state === 'uploading') {
19001                                uploader.stop()
19002                            }
19003                        })
19004
19005                        $info.on('click', '.retry', function() {
19006                            uploader.retry()
19007                        })
19008
19009                        $info.on('click', '.ignore', function() {
19010                            alert('todo')
19011                        })
19012
19013                        $upload.addClass('state-' + state)
19014                        updateTotalProgress()
19015
19016                        $element.data('webuploader', uploader).data('webuploader.wrap', $wrap)
19017                    }
19018                }
19019            }
19020
19021            $box.find('input[data-toggle="webuploader"]').each(function(i) {
19022                initWebUploader($(this), i)
19023
19024                $(this).on('reload.webuploader', function() {
19025                    initWebUploader($(this), i)
19026                })
19027            })
19028        }
19029
19030        /* fixed dropdown-menu width */
19031        $box.find('[data-toggle="dropdown"]').parent().on('show.bs.dropdown', function(e) {
19032            var $this = $(this), width = $this.outerWidth(), $menu = $this.find('> .dropdown-menu'), menuWidth = $menu.outerWidth()
19033
19034            if (width > menuWidth) {
19035                $menu.css('min-width', width)
19036            }
19037        })
19038
19039        /* ========================================================================
19040         * @description highCharts
19041         * @author 小策一喋 <[email protected]>
19042         * @Blog http://www.topjui.com
19043         * ======================================================================== */
19044        var $highcharts = $box.find('[data-toggle="highcharts"]')
19045
19046        $highcharts.each(function(){
19047            var $element = $(this)
19048            var options  = $element.data()
19049
19050            $.get(options.url, function(chartData){
19051                $element.highcharts(chartData)
19052            }, 'json')
19053        })
19054
19055        /* ========================================================================
19056         * @description ECharts
19057         * @author 小策一喋 <[email protected]>
19058         * @Blog http://www.topjui.com
19059         * ======================================================================== */
19060        var $echarts = $box.find('[data-toggle="echarts"]')
19061
19062        $echarts.each(function(){
19063            var $element = $(this)
19064            var options  = $element.data()
19065            var theme    = options.theme ? options.theme : 'default'
19066            var typeArr  = options.type.split(',')
19067
19068            require.config({
19069                paths: {
19070                    echarts: BJUI.PLUGINPATH + 'echarts'
19071                }
19072            })
19073
19074            require(
19075                [
19076                    'echarts',
19077                    'echarts/theme/' + theme,
19078                    'echarts/chart/' + typeArr[0],
19079                    typeArr[1] ? 'echarts/chart/' + typeArr[1] : 'echarts'
19080                ],
19081                function (ec,theme) {
19082                    var myChart = ec.init($element[0],theme)
19083
19084                    $.get(options.url, function(chartData){
19085                        myChart.setOption(chartData)
19086                    }, 'json')
19087                }
19088            )
19089        })
19090    })
19091
19092}(jQuery);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.