ttt

   1 //自己扩展的jquery函数
   2 //压缩时请把编码改成ANSI
   3 $.app = {
   4 
   5     /**初始化主页 layout,菜单,tab*/
   6     initIndex: function () {
   7         $.menus.initMenu();
   8         $.layouts.initLayout();
   9         $.tabs.initTab();
  10 
  11         $.app.initCommonBtn();
  12 
  13         var message = $.app.initMessage();
  14         var notification = $.app.initNotification();
  15         var fiveMinute = 5 * 60 * 1000;
  16         var pollingUrl = ctx + "/admin/polling";
  17         var longPolling = function(url, callback) {
  18             $.ajax({
  19                 url: url,
  20                 async: true,
  21                 cache: false,
  22                 global: false,
  23                 timeout: 30 * 1000,
  24                 dataType : "json",
  25                 success: function (data, status, request) {
  26                     callback(data);
  27                     data = null;
  28                     status = null;
  29                     request = null;
  30                     setTimeout(
  31                         function () {
  32                             longPolling(url, callback);
  33                         },
  34                         10
  35                     );
  36                 },
  37                 error: function (xmlHR, textStatus, errorThrown) {
  38                     xmlHR = null;
  39                     textStatus = null;
  40                     errorThrown = null;
  41 
  42                     setTimeout(
  43                         function () {
  44                             longPolling(url, callback);
  45                         },
  46                         30 * 1000
  47                     );
  48                 }
  49             });
  50         };
  51         longPolling(pollingUrl, function(data) {
  52             if(data) {
  53                 if(data.unreadMessageCount) {
  54                     message.update(data.unreadMessageCount);
  55                 }
  56                 if(data.notifications) {
  57                     notification.update(data.notifications);
  58                 }
  59             }
  60         });
  61 
  62     },
  63     initCommonBtn : function() {
  64         $(".btn-view-info,.btn-change-password").click(function() {
  65             var a = $(this);
  66             var url = "";
  67             if(a.is(".btn-view-info")) {
  68                 url = ctx +"/admin/sys/user/loginUser/viewInfo";
  69             } else if(a.is(".btn-change-password")) {
  70                 url = ctx + "/admin/sys/user/loginUser/changePassword";
  71             }
  72             setTimeout(function() {
  73                 $.tabs.activeTab($.tabs.nextCustomTabIndex(), "个人资料", url, true)
  74             }, 0);
  75         });
  76         $(".btn-view-message,.btn-message").click(function() {
  77             var url = ctx + "/admin/personal/message";
  78             setTimeout(function() {
  79                 $.tabs.activeTab($.tabs.nextCustomTabIndex(), "我的消息", url, true)
  80             }, 0);
  81         });
  82         $(".btn-view-notice").click(function() {
  83             var url = ctx + "/office/personal/notice/list?read=false";
  84             setTimeout(function() {
  85                 $.tabs.activeTab($.tabs.nextCustomTabIndex(), "我的通知", url, true)
  86             }, 0);
  87         });
  88         $(".btn-view-worklist,.btn-view-work").click(function() {
  89             var $that = $(this);
  90             var url = ctx + "/office/personal/worklist";
  91             setTimeout(function() {
  92                 if($that.is(".btn-view-work")) {
  93                     url = $that.data("url");
  94                 }
  95                 $.tabs.activeTab($.tabs.nextCustomTabIndex(), "我的待办工作", url, true)
  96             }, 0);
  97 
  98             return false;
  99         });
 100 
 101 
 102     },
 103     initMessage : function() {
 104         var messageBtn = $(".btn-message");
 105         var icon = messageBtn.find(".icon-message");
 106         var messageBtnInterval = null;
 107 
 108         var activeUnreadIcon = function(count) {
 109             clearInterval(messageBtnInterval);
 110             if(count > 0) {
 111                 var label = messageBtn.find(".icon-count");
 112                 if(!label.length) {
 113                     label = $("<i class='label label-important icon-count'></i>");
 114                     messageBtn.append(label);
 115                 }
 116                 label.text(count);
 117                 messageBtn.addClass("unread");
 118                 messageBtnInterval = setInterval(function() {icon.toggleClass("icon-envelope-alt").toggleClass("icon-envelope");}, 650);
 119             }
 120         };
 121 
 122         messageBtn.click(function() {
 123             clearInterval(messageBtnInterval);
 124             $($.find("#menu a:contains(我的消息)")).dblclick();
 125             messageBtn.removeClass("unread");
 126             messageBtn.find(".icon-count").remove();
 127             icon.removeClass("icon-envelope").addClass("icon-envelope-alt");
 128 
 129         });
 130 
 131         activeUnreadIcon(messageBtn.data("unread"));
 132 
 133         return {
 134             update : function(unReadMessageCount) {
 135                 activeUnreadIcon(unReadMessageCount);
 136             }
 137         };
 138     },
 139     initNotification : function() {
 140         var notificationBtn = $(".btn-notification");
 141         var notificationList = $(".notification-list");
 142         var menu = $(".notification-list .menu");
 143         var menuList = menu.find(".list");
 144         var detail = $(".notification-list .detail");
 145         var detailList = detail.find(".list");
 146         var loading = $(".notification-list .loading");
 147         var noComment = $(".notification-list .no-comment");
 148         var markReadUrl = ctx + "/admin/personal/notification/markRead?id=";
 149 
 150         var contentTemplate = '<li class="view-content {unread}"><span>{title}</span><span class="pull-right">{date}</span></li>';
 151         var detailContentTemplate = '<div id="notificaiton-{id}" class="notification-detail" style="display: none"><div class="title"><span>{title}</span><span class="pull-right">{date}</span></div><div class="content">{content}</div></div>';
 152         var moreContent = '<li class="view-all-notification"><span>&gt;&gt;查看所有通知</span></li>';
 153 
 154         var viewAllNotification = function() {
 155             $($.find("#menu a:contains(我的通知)")).dblclick();
 156             hideNotification();
 157             return false;
 158         };
 159         var hideNotification = function() {
 160             notificationList.find(".content > div").hide();
 161             notificationList.removeClass("in");
 162             $("body")
 163                 .off("click")
 164                 .find("iframe").contents().find("body").each(function() {
 165                     $(this).off("click");
 166                 });
 167         };
 168 
 169         var activeDetailBtn = function() {
 170             var notificationDetails = detail.find(".notification-detail");
 171             var current = notificationDetails.not(":hidden");
 172             var currentIndex = notificationDetails.index(current);
 173 
 174             var pre = detail.find(".pre");
 175             var next = detail.find(".next");
 176             pre.removeClass("none");
 177             next.removeClass("none");
 178 
 179 
 180             if(currentIndex == 0) {
 181                 pre.addClass("none");
 182             }
 183 
 184             var currentMenu = $(menu.find(".view-content").get(currentIndex));
 185             if(currentMenu.hasClass("unread")) {
 186                 currentMenu.removeClass("unread");
 187                 var id = current.attr("id").replace("notificaiton-", "");
 188                 $.ajax({
 189                     url: markReadUrl + id,
 190                     global: false,
 191                     error: function (xmlHR, textStatus, errorThrown) {
 192                         //ignore
 193                     }
 194                 });
 195             }
 196 
 197             if(currentIndex == notificationDetails.length - 1) {
 198                 next.addClass("none");
 199             }
 200 
 201         };
 202 
 203         var showNoComment = function() {
 204             notificationList.find(".content > div").hide();
 205             noComment.show();
 206         };
 207         var showMenu = function() {
 208             notificationList.find(".content > div").hide();
 209             menu.show();
 210         };
 211 
 212 
 213         var initDetail = function(dataList) {
 214             var content = "";
 215             $(dataList).each(function(index, data) {
 216                 content = content + detailContentTemplate.replace("{id}", data.id).replace("{title}", data.title).replace("{date}", data.date).replace("{content}", data.content);
 217             });
 218             detailList.html(content);
 219             detail.find(".notification-detail:first").show();
 220             detail.find(".back-notification-list").click(function() {
 221                 slide(detail, menu, "left");
 222             });
 223             detail.find(".pre").click(function() {
 224                 var current = detail.find(".notification-detail").not(":hidden");
 225                 var pre = current.prev(".notification-detail");
 226                 if (pre.length) {
 227                     slide(current, pre, "left");
 228                 }
 229             });
 230             detail.find(".next").click(function() {
 231                 var current = detail.find(".notification-detail").not(":hidden");
 232                 var next = current.next(".notification-detail");
 233                 if (next.length) {
 234                     slide(current, next, "right");
 235                 }
 236             });
 237             slide(menu, detail, "right");
 238 
 239             return false;
 240         };
 241 
 242 
 243 
 244         var initMenu = function(dataList, hasUnread) {
 245 
 246             var content = "";
 247             $(dataList).each(function (index, data) {
 248                 content = content + contentTemplate.replace("{unread}", data.read ? "" : "unread").replace("{title}", data.title).replace("{date}", data.date);
 249             });
 250             content = content + moreContent;
 251             menuList.html(content);
 252 
 253             menu.find(".view-content").click(function() {
 254                 initDetail(dataList);
 255             });
 256             menu.find(".view-all-notification").click(function() {
 257                 viewAllNotification();
 258             });
 259 
 260             if(hasUnread) {
 261                 showNotification();
 262             }
 263 
 264             return false;
 265         };
 266         var slide = function(from, to, direction) {
 267             from.css({
 268                 position: 'relative',
 269                 width:"100%"
 270             });
 271             from.stop(true).hide("slide", {direction : direction == "left" ? "rigth" : "left"}, function() {
 272                 from.css({
 273                     position : "",
 274                     width : "",
 275                     left : ""
 276                 });
 277             });
 278             to.css({
 279                 position: 'absolute',
 280                 top: to.is(".notification-detail") ? to.closest(".detail").find(".title").outerHeight() + "px" : "0px",
 281                 left: "0px",
 282                 width: "100%",
 283                 display : "none"
 284             });
 285             to.stop(true).show("slide", {direction : direction}, function() {
 286                 to.css({
 287                     position : "",
 288                     left : "",
 289                     top : "",
 290                     width : ""
 291                 });
 292                 if(to.is(".notification-detail") || to.is(".detail")) {
 293                     activeDetailBtn();
 294                 }
 295             });
 296         };
 297 
 298         var showNotification = function() {
 299             notificationList.addClass("in");
 300 
 301             var windowClickHideNotification = function (event) {
 302                 var target = $(event.target);
 303                 if (!target.closest(".btn-notification").length && !target.closest(".notification-list").length) {
 304                     hideNotification();
 305                 }
 306             };
 307 
 308             $("body")
 309                 .on("click", windowClickHideNotification)
 310                 .find("iframe").contents().find("body").each(function() {
 311                     $(this).on("click", windowClickHideNotification);
 312                 });
 313             if(menu.find(".view-content").length) {
 314                 showMenu();
 315             } else {
 316                 showNoComment();
 317             }
 318         };
 319 
 320         notificationBtn.click(function() {
 321             if(notificationList.hasClass("in")) {
 322                 hideNotification();
 323             } else {
 324                 showNotification();
 325             }
 326         });
 327         notificationList.find(".close-notification-list").click(function() {
 328             hideNotification();
 329         });
 330 
 331         hideNotification();
 332 
 333         return {
 334             update : function(dataList) {
 335 
 336                 if(!dataList.length) {
 337                     showNoComment();
 338                     return;
 339                 }
 340 
 341                 var hasUnread = false;
 342                 for(var i = 0, l = dataList.length; i < l; i++) {
 343                     var data = dataList[i];
 344                     if(!data.read) {
 345                         hasUnread = true;
 346                         data.title = data.title.replace("{ctx}", ctx);
 347                         data.content = data.content.replace("{ctx}", ctx);
 348                     }
 349                 }
 350 
 351                initMenu(dataList, hasUnread);
 352 
 353             }
 354         };
 355     },
 356     /**
 357      * 异步加载url内容到tab
 358      */
 359     loadingToCenterIframe: function (panel, url, loadingMessage, forceRefresh) {
 360         panel.data("url", url);
 361 
 362         var panelId = panel.prop("id");
 363         var iframeId = "iframe-" + panelId;
 364         var iframe = $("#" + iframeId);
 365 
 366         if (!iframe.length || forceRefresh) {
 367             if(!iframe.length) {
 368                 iframe = $("iframe[tabs=true]:last").clone(true);
 369                 iframe.prop("id", iframeId);
 370                 $("iframe[tabs=true]:last").after(iframe);
 371             }
 372 
 373             $.app.waiting(loadingMessage);
 374             iframe.prop("src", url).one("load", function () {
 375                 $.app.activeIframe(panelId, iframe);
 376                 $.app.waitingOver();
 377             });
 378 
 379         } else {
 380             $.app.activeIframe(panelId, iframe);
 381         }
 382 
 383     },
 384     activeIframe: function (panelId, iframe) {
 385         if (!iframe) {
 386             iframe = $("#iframe-" + panelId);
 387         }
 388         var layout = $.layouts.layout;
 389         if (layout.panes.center.prop("id") == iframe.prop("id")) {
 390             return;
 391         }
 392         layout.panes.center.hide();
 393         layout.panes.center = iframe;
 394         layout.panes.center.show();
 395         layout.resizeAll();
 396         $.tabs.initTabScrollHideOrShowMoveBtn(panelId);
 397     },
 398 
 399     waiting : function(message, isSmall) {
 400         if(!message) {
 401             message = "装载中...";
 402         }
 403 
 404         message = '<img src="' + ctx + '/static/images/loading.gif" '+ (isSmall ? "width='20px'" : "") +'/> ' + message;
 405         if(!isSmall) {
 406             message = "<h4>"+message+"</h4>";
 407         }
 408         $.blockUI({
 409             fadeIn: 700,
 410             fadeOut: 700,
 411             showOverlay: false,
 412             css: {
 413                 border: 'none',
 414                 padding: '15px',
 415                 backgroundColor: '#eee',
 416                 '-webkit-border-radius': '10px',
 417                 '-moz-border-radius': '10px',
 418                 opacity:1,
 419                 color: '#000',
 420                 width: isSmall ? "40%" : "30%"
 421 
 422             },
 423             message: message
 424         });
 425     }
 426     ,
 427     waitingOver: function () {
 428         $.unblockUI();
 429     }
 430     ,
 431     /**
 432      * 当前显示的模态窗口队列
 433      */
 434     _modalDialogQueue:null,
 435     /**
 436      * 模态窗口
 437      * @title 标题
 438      * @param url
 439      * @param settings
 440      */
 441     modalDialog : function(title, url, settings) {
 442 
 443         $.app.waiting();
 444         var defaultSettings = {
 445             title : title,
 446             closeText : "关闭",
 447             closeOnEscape:false,
 448             height:300,
 449             width:600,
 450             modal:true,
 451             noTitle : false,
 452             close: function() {
 453                 $(this).closest(".ui-dialog").remove();
 454             },
 455             _close : function(modal) {
 456                 $(modal).dialog("close");
 457                 if($.app._modalDialogQueue.length > 0) {
 458                     $.app._modalDialogQueue.pop();
 459                 }
 460             },
 461             buttons:{
 462                 '确定': function() {
 463                     if(settings.ok) {
 464                         if(settings.ok($(this))) {
 465                             settings._close(this);
 466                         }
 467                     } else {
 468                         settings._close(this);
 469                     }
 470                     if(settings.callback) {
 471                         settings.callback();
 472                     }
 473                 },
 474                 '关闭': function () {
 475                     settings._close(this);
 476                     if(settings.callback) {
 477                         settings.callback();
 478                     }
 479                 }
 480             }
 481         };
 482         if(!settings) {
 483             settings = {};
 484         }
 485         settings = $.extend(true, {}, defaultSettings, settings);
 486 
 487         if(!settings.ok) {
 488             delete settings.buttons['确定'];
 489         }
 490 
 491         $.ajax({
 492             url: url,
 493             headers: { table:true }
 494         }).done(function (data) {
 495                 $.app.waitingOver();
 496                 var div = $("<div></div>").append(data);
 497                 var dialog = div.dialog(settings)
 498                     .closest(".ui-dialog").data("url", url).removeClass("ui-widget-content")
 499                     .find(".ui-dialog-content ").removeClass("ui-widget-content").focus();
 500 
 501                 if(settings.noTitle) {
 502                     dialog.closest(".ui-dialog").find(".ui-dialog-titlebar").addClass("no-title");
 503                 }
 504                 dialog.closest(".ui-dialog").focus();
 505                 if(!$.app._modalDialogQueue) {
 506                     $.app._modalDialogQueue = new Array();
 507                 }
 508                 $.app._modalDialogQueue.push(dialog);
 509                 $.table.initTable(div.find(".table"));
 510 
 511 //            $.blockUI({
 512 //                url : url,
 513 //                theme:true,
 514 //                showOverlay : true,
 515 //                title : title,
 516 //                message : data,
 517 //                css : css,
 518 //                themedCSS: css
 519 //            });
 520 
 521 
 522             });
 523     }
 524     ,
 525     /**
 526      * 取消编辑
 527      */
 528     cancelModelDialog : function() {
 529         if($.app._modalDialogQueue && $.app._modalDialogQueue.length > 0) {
 530             $.app._modalDialogQueue.pop().dialog("close");
 531         }
 532     }
 533     ,
 534     alert : function(options) {
 535         if(!options) {
 536             options = {};
 537         }
 538         var defaults = {
 539             title : "警告",
 540             message : "非法的操作",
 541             okTitle : "关闭",
 542             ok : $.noop
 543         };
 544         options.alert = true;
 545         options = $.extend({}, defaults, options);
 546         this.confirm(options);
 547     }
 548     ,
 549     /**
 550      * 格式
 551      * @param options
 552      */
 553     confirm : function(options) {
 554         var defaults = {
 555             title : "确认执行操作",
 556             message : "确认执行操作吗?",
 557             cancelTitle : '取消',
 558             okTitle : '确定',
 559             cancel : $.noop,
 560             ok : $.noop,
 561             alert : false
 562         };
 563 
 564         if(!options) {
 565             options = {};
 566         }
 567         options = $.extend({}, defaults, options);
 568 
 569         var template =
 570             '<div class="modal hide fade confirm">' +
 571                 '<div class="modal-header">' +
 572                 '<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>' +
 573                 '<h3 class="title">{title}</h3>' +
 574                 '</div>' +
 575                 '<div class="modal-body">' +
 576                 '<div>{message}</div>' +
 577                 '</div>' +
 578                 '<div class="modal-footer">' +
 579                 '<a href="#" class="btn btn-ok btn-danger" data-dismiss="modal">{okTitle}</a>' +
 580                 '<a href="#" class="btn btn-cancel" data-dismiss="modal">{cancelTitle}</a>'+
 581                 '</div>' +
 582                 '</div>';
 583 
 584         var modalDom =
 585             $(template
 586                 .replace("{title}", options.title)
 587                 .replace("{message}", options.message)
 588                 .replace("{cancelTitle}", options.cancelTitle)
 589                 .replace("{okTitle}", options.okTitle));
 590 
 591 
 592         var hasBtnClick = false;
 593         if(options.alert) {
 594             modalDom.find(".modal-footer > .btn-cancel").remove();
 595         } else {
 596             modalDom.find(".modal-footer > .btn-cancel").click(function() {
 597                 hasBtnClick = true;
 598                 options.cancel();
 599             });
 600         }
 601         modalDom.find(".modal-footer > .btn-ok").click(function() {
 602             hasBtnClick = true;
 603             options.ok();
 604         });
 605 
 606         var modal = modalDom.modal();
 607 
 608         modal.on("hidden", function() {
 609             modal.remove();//移除掉 要不然 只是hidden
 610             if(hasBtnClick) {
 611                 return true;
 612             }
 613             if(options.alert) {
 614                 options.ok();
 615             } else {
 616                 options.cancel();
 617             }
 618         });
 619 
 620         return modal;
 621     }
 622     ,
 623     isImage : function(filename) {
 624         return /gif|jpe?g|png|bmp$/i.test(filename);
 625     }
 626     ,
 627     initDatetimePicker : function() {
 628         //初始化 datetime picker
 629         $('.date:not(.custom)').each(function() {
 630             var $date = $(this);
 631 
 632             if($date.attr("initialized") == "true") {
 633                 return;
 634             }
 635 
 636             var pickDate = $(this).find("[data-format]").data("format").toLowerCase().indexOf("yyyy-mm-dd") != -1;
 637             var pickTime = $(this).find("[data-format]").data("format").toLowerCase().indexOf("hh:mm:ss") != -1;
 638             $date.datetimepicker({
 639                 pickDate : pickDate,
 640                 pickTime : pickTime,
 641                 maskInput: true,
 642                 language:"zh-CN"
 643             }).on('changeDate', function(ev) {
 644                     if(pickTime == false) {
 645                         $(this).data("datetimepicker").hide();
 646                     }
 647                 });
 648             $date.find(":input").click(function() {$date.find(".icon-calendar,.icon-time,.icon-date").click();});
 649             $date.attr("initialized", true);
 650         });
 651     },
 652     initCalendar : function() {
 653 
 654         var date = new Date();
 655         var d = date.getDate();
 656         var m = date.getMonth();
 657         var y = date.getFullYear();
 658 
 659         var calendar = $('#calendar').fullCalendar({
 660             header: {
 661                 left: 'prev,next today',
 662                 center: 'title',
 663                 right: 'month,agendaWeek,agendaDay'
 664             },
 665             events: ctx + "/admin/personal/calendar/load",
 666             eventDrop: function(event, delta) {
 667                 moveCalendar(event);
 668             },
 669             eventClick: function(event, delta) {
 670                 viewCalendar(event);
 671             },
 672             loading: function(bool) {
 673                 if (bool) $('#loading').show();
 674                 else $('#loading').hide();
 675             },
 676             editable: true,
 677             selectable: true,
 678             selectHelper: true,
 679             select: function(start, end, allDay) {
 680                 openNewCalendarForm(start, end);
 681                 calendar.fullCalendar('unselect');
 682             }
 683         });
 684 
 685         $('span.fc-button-prev').before('<span class="fc-button fc-button-add fc-state-default fc-corner-left fc-corner-right">新增</span>');
 686 
 687         $(".fc-button-add").click(function() {
 688             openNewCalendarForm();
 689         });
 690 
 691         function openNewCalendarForm(start, end) {
 692             var url = ctx + "/admin/personal/calendar/new";
 693             if(start) {
 694                 start = $.fullCalendar.formatDate(start, "yyyy-MM-dd HH:mm:ss");
 695                 end = $.fullCalendar.formatDate(end, "yyyy-MM-dd HH:mm:ss");
 696                 url = url + "?start=" + start + "&end=" + end;
 697             }
 698             $.app.modalDialog("新增提醒事项", url, {
 699                 width:370,
 700                 height:430,
 701                 ok : function(modal) {
 702 
 703                     var form = modal.find("#editForm");
 704                     if(!form.validationEngine('validate')) {
 705                         return false;
 706                     }
 707                     var url = ctx + "/admin/personal/calendar/new";
 708                     $.post(url, form.serialize(), function() {
 709                         calendar.fullCalendar("refetchEvents");
 710                     });
 711 
 712                     return true;
 713                 }
 714             });
 715         }
 716 
 717         function moveCalendar(event) {
 718             var url = ctx + "/admin/personal/calendar/move";
 719             var id = event.id;
 720             var start = $.fullCalendar.formatDate(event.start, "yyyy-MM-dd HH:mm:ss");
 721             var end = $.fullCalendar.formatDate(event.end, "yyyy-MM-dd HH:mm:ss");
 722             url = url + "?id=" + id;
 723             url = url + "&start=" + start + "&end=" + end;
 724 
 725             $.post(url, function() {
 726                 calendar.fullCalendar("refetchEvents");
 727             });
 728         }
 729 
 730         function viewCalendar(event) {
 731             var url = ctx + "/admin/personal/calendar/view/" + event.id;
 732             $.app.modalDialog("查看提醒事项", url, {
 733                 width:370,
 734                 height:250,
 735                 noTitle : false,
 736                 okBtn : false,
 737                 closeBtn : false
 738             });
 739         }
 740         $("body").on("click", ".btn-delete-calendar", function() {
 741             var $this = $(this);
 742             $.app.confirm({
 743                 title : '确认删除提醒事项吗?',
 744                 message : '确认删除提醒事项吗?',
 745                 ok : function() {
 746                     var url = ctx + "/admin/personal/calendar/delete?id=" + $this.data("id");
 747                     $.post(url, function() {
 748                         calendar.fullCalendar("refetchEvents");
 749                         $.app.closeModalDialog();
 750                     });
 751                 }
 752             });
 753 
 754         });
 755     }
 756     ,
 757     removeContextPath : function(url) {
 758         if(url.indexOf(ctx) == 0) {
 759             return url.substr(ctx.length);
 760         }
 761         return url;
 762     }
 763     ,
 764     /**
 765      * 异步化form表单或a标签
 766      * @param $form
 767      * @param containerId
 768      */
 769     asyncLoad : function($tag, containerId) {
 770         if($tag.is("form")) {
 771             $tag.submit(function() {
 772                 if($tag.prop("method").toLowerCase() == 'post') {
 773                     $.post($tag.prop("action"), $tag.serialize(), function(data) {
 774                         $("#" + containerId).replaceWith(data);
 775                     });
 776                 } else {
 777                     $.get($tag.prop("action"), $tag.serialize(), function(data) {
 778                         $("#" + containerId).replaceWith(data);
 779                     });
 780                 }
 781                 return false;
 782             });
 783         } else if($tag.is("a")) {
 784             $tag.click(function() {
 785                 $.get($tag.prop("href"), function(data) {
 786                     $("#" + containerId).replaceWith(data);
 787                 });
 788                 return false;
 789             });
 790         } else {
 791             $.app.alert({message : "该标签不支持异步加载,支持的标签有form、a"});
 792         }
 793 
 794     },
 795     /**
 796      * 只读化表单
 797      * @param form
 798      */
 799     readonlyForm : function(form, removeButton) {
 800         var inputs = $(form).find(":input");
 801         inputs.not(":submit,:button").prop("readonly", true);
 802         if(removeButton) {
 803             inputs.remove(":button,:submit");
 804         }
 805     }
 806     ,
 807 
 808     /**
 809      * 将$("N").val() ----> [1,2,3]
 810      */
 811     joinVar : function(elem, separator) {
 812         if(!separator) {
 813             separator = ",";
 814         }
 815         var array = new Array();
 816         $(elem).each(function() {
 817             array.push($(this).val());
 818         });
 819 
 820         return array.join(separator);
 821     },
 822 
 823     /**
 824      * 异步加载table子内容(父子表格)
 825      * @param toggleEle
 826      * @param tableEle
 827      * @param asyncLoadURL
 828      */
 829     toggleLoadTable : function(tableEle, asyncLoadURL) {
 830         var openIcon = "icon-plus-sign";
 831         var closeIcon = "icon-minus-sign";
 832         $(tableEle).find("tr .toggle-child").click(function() {
 833             var $a = $(this);
 834             //只显示当前的 其余的都隐藏
 835             $a.closest("table")
 836                 .find(".toggle-child." + closeIcon).not($a).removeClass(closeIcon).addClass(openIcon)
 837                 .end().end()
 838                 .find(".child-data").not($a.closest("tr").next("tr")).hide();
 839 
 840             //如果是ie7
 841             if($(this).closest("html").hasClass("ie7")) {
 842                 var $aClone = $(this).clone(true);
 843                 if($aClone.hasClass(closeIcon)) {
 844                     $aClone.addClass(openIcon).removeClass(closeIcon);
 845                 } else {
 846                     $aClone.addClass(closeIcon).removeClass(openIcon);
 847                 }
 848                 $(this).after($aClone);
 849                 $(this).remove();
 850                 $a = $aClone;
 851             } else {
 852                 $a.toggleClass(openIcon);
 853                 $a.toggleClass(closeIcon);
 854             }
 855 
 856             var $currentTr = $a.closest("tr");
 857             var $dataTr = $currentTr.next("tr");
 858             if(!$dataTr.hasClass("child-data")) {
 859                 $.app.waiting();
 860                 $dataTr = $("<tr class='child-data' style='display: none;'></tr>");
 861                 var $dataTd = $("<td colspan='" + $currentTr.find("td").size() + "'></td>");
 862                 $dataTr.append($dataTd);
 863                 $currentTr.after($dataTr);
 864                 $dataTd.load(asyncLoadURL.replace("{parentId}", $a.data("id")),function() {
 865                     $.app.waitingOver();
 866                 });
 867             }
 868             $dataTr.toggle();
 869 
 870             return false;
 871         });
 872 
 873     },
 874 
 875     initAutocomplete : function(config) {
 876 
 877         var defaultConfig = {
 878             minLength : 1,
 879             enterSearch : false,
 880             focus: function( event, ui ) {
 881                 $(config.input).val( ui.item.label );
 882                 return false;
 883             },
 884             renderItem : function( ul, item ) {
 885                 return $( "<li>" )
 886                     .data( "ui-autocomplete-item", item )
 887                     .append( "<a>" + item.label + "</a>" )
 888                     .appendTo( ul );
 889             }
 890         };
 891 
 892         config = $.extend(true, defaultConfig, config);
 893 
 894         $(config.input)
 895             .on( "keydown", function( event ) {
 896                 //回车查询
 897                 if(config.enterSearch && event.keyCode === $.ui.keyCode.ENTER) {
 898                     config.select(event, {item:{value:$(this).val()}});
 899                 }
 900             })
 901             .autocomplete({
 902                 source : config.source,
 903                 minLength : config.minLength,
 904                 focus : config.focus,
 905                 select : config.select
 906             }).data( "ui-autocomplete" )._renderItem = config.renderItem;
 907     }
 908 
 909 };
 910 
 911 $.layouts = {
 912     layout: null,
 913     /**初始化布局*/
 914     initLayout: function () {
 915         function resizePanel(panelName, panelElement, panelState, panelOptions, layoutName) {
 916             var tabul = $(".tabs-fix-top");
 917             if (panelName == 'north') {
 918                 var top = 0;
 919                 if($("html").hasClass("ie")) {
 920                     top = panelElement.height() - 33;
 921 
 922                 } else {
 923                     top = panelElement.height() - 30;
 924                 }
 925                 if (panelState.isClosed) {
 926                     top = -58;
 927                 }
 928                 tabul.css("top", top);
 929             }
 930 
 931             if(panelName == "center") {
 932                 tabul.find(".ul-wrapper").andSelf().width(panelState.layoutWidth);
 933                 $.tabs.initTabScrollHideOrShowMoveBtn();
 934             }
 935 
 936 
 937         }
 938 
 939         this.layout = $('.index-panel').layout({
 940             west__size:  210
 941             ,   south__size: 30
 942             ,    west__spacing_closed:        20
 943             ,    west__togglerLength_closed:    100
 944             ,    west__togglerContent_closed:"菜<BR>单"
 945             ,    togglerTip_closed:    "打开"
 946             ,    togglerTip_open:    "关闭"
 947             ,    sliderTip:            "滑动打开"
 948             ,   resizerTip:         "调整大小"
 949             ,   onhide: resizePanel
 950             ,   onshow: resizePanel
 951             ,   onopen: resizePanel
 952             ,   onclose: resizePanel
 953             ,   onresize: resizePanel
 954             ,    center__maskContents:true // IMPORTANT - enable iframe masking
 955             ,   north : {
 956                 togglerLength_open : 0
 957                 ,  resizable : false
 958                 ,  size: 95
 959             },
 960             south: {
 961                 resizable:false
 962             }
 963         });
 964     }
 965 }
 966 
 967 $.menus = {
 968     /**初始化菜单*/
 969     initMenu: function () {
 970         var menus = $("#menu");
 971         menus.accordion({
 972             header:"h3",
 973             heightStyle:"content",
 974             icons : {
 975                 header: "icon-caret-right",
 976                 activeHeader: "icon-caret-down"
 977             },
 978             animate : {
 979                 easing : "easeOutQuart"
 980             }
 981         });
 982 
 983         menus.find(".ui-accordion-header-icon").removeClass("ui-icon").addClass("menu-header-icon");
 984 
 985         var leafIconClass = "menu-icon icon-angle-right";
 986         var branchOpenIconClass = "menu-icon icon-double-angle-right";
 987         var branchCloseIconClass = "menu-icon icon-double-angle-down";
 988         menus.find("li").each(function () {
 989             var li = $(this);
 990 
 991             li.children("a").wrap("<div class='li-wrapper'></div>");
 992             var liWrapper = li.children(".li-wrapper");
 993             var liUL = li.find("ul");
 994             var hasChild = liUL.length;
 995             if (hasChild) {
 996                 liUL.hide();
 997                 liWrapper.prepend('<span class="' + branchOpenIconClass + '"></span>')
 998                     .click(function () {
 999                         if (liWrapper.children("span").hasClass(branchCloseIconClass)) {
1000                             liWrapper.children("span")
1001                                 .removeClass(branchCloseIconClass)
1002                                 .addClass(branchOpenIconClass)
1003                                 .end()
1004                                 .closest("li").children("ul").hide("blind");
1005                         } else {
1006                             liWrapper.children("span")
1007                                 .removeClass(branchOpenIconClass)
1008                                 .addClass(branchCloseIconClass)
1009                                 .end()
1010                                 .closest("li").children("ul").show("blind");
1011                         }
1012                     });
1013             } else {
1014                 liWrapper.prepend('<span class="' + leafIconClass + '"></span>');
1015             }
1016         });
1017 
1018         menus.find("a").each(function () {
1019             var a = $(this);
1020             var title = a.text();
1021             var href = a.attr("href");
1022             a.attr("href", "#");
1023             if (href == "#" || href == '') {
1024                 return;
1025             }
1026 
1027             var active = function(a, forceRefresh) {
1028                 menus.find("a").closest("li > .li-wrapper").removeClass("active");
1029                 a.closest("li > .li-wrapper").addClass("active");
1030                 var oldPanelIndex = a.data("panelIndex");
1031                 var activeMenuCallback = function(panelIndex) {
1032                     if(!a.data("panelIndex")) {
1033                         a.data("panelIndex", panelIndex);
1034                         a.attr("id", "menu-" + panelIndex);
1035                     }
1036                 }
1037                 $.tabs.activeTab(oldPanelIndex, title, href, forceRefresh, activeMenuCallback);
1038 
1039                 return false;
1040             }
1041 
1042             a.closest("li")
1043                 .click(function () {
1044                     active(a, false);
1045                     return false;
1046                 }).dblclick(function() {
1047                     active(a, true);//双击强制刷新
1048                     return false;
1049                 });
1050         });
1051     }
1052 }
1053 
1054 $.tabs = {
1055     tabs: null,
1056     maxTabIndex : 1,
1057     /*自己创建tab时起始索引*/
1058     customTabStartIndex : 9999999999,
1059     /**初始化tab */
1060     initTab: function () {
1061         function activeMenu(tabPanelId) {
1062             var currentMenu = $("#menu-" + tabPanelId.replace("tabs-", ""));
1063             $("#menu .li-wrapper.active").removeClass("active");
1064 
1065             if(currentMenu.length) {
1066                 //把父菜单展示出来
1067                 currentMenu.parents("ul").each(function(){
1068                     //不能使用“ul:hidden” 因为它是把只有隐藏的都查出来
1069                     // 比如<ul style="display:none"><li><ul><li><a class='a'></a></li></ul></li></ul>
1070                     //$(".a").parents("ul:hidden") 会查出两个 即hidden的元素对其子也是有效的
1071                     if($(this).css("display") == 'none') {
1072                         $(this).prev("a").click();
1073                     }
1074                 });
1075                 currentMenu.closest(".li-wrapper").addClass("active");
1076             }
1077         }
1078         
1079         var tabs = $(".tabs-bar").tabs({
1080             beforeActivate : function(event, ui) {
1081                 setTimeout(function() {
1082                     var tabs = $.tabs.tabs;
1083                     tabs.find(".menu").hide();
1084                     tabs.find("#" + ui.newPanel.attr("aria-labelledby")).siblings(".menu").show();
1085                 }, 0);
1086             },
1087             activate: function (event, ui) {
1088                 setTimeout(function() {
1089                     var tabs = $.tabs.tabs;
1090                     var newPanelId = ui.newPanel.prop("id");
1091                     activeMenu(newPanelId);
1092                     $.app.activeIframe(newPanelId);
1093                 }, 0);
1094             }
1095         });
1096         $.tabs.tabs = tabs;
1097         tabs.delegate("span.icon-remove", "click", function () {
1098             var panelId = $(this).closest("li").remove().attr("aria-controls");
1099             setTimeout(function() {
1100                 $.tabs.removeTab(panelId);
1101             }, 0);
1102         });
1103         tabs.delegate("span.icon-refresh", "click", function () {
1104             var panelId = $(this).closest("li").attr("aria-controls");
1105             setTimeout(function() {
1106                 $.tabs.activeTab(panelId, null, null, true);
1107             }, 0);
1108         });
1109 
1110         tabs.bind("keyup", function (event) {
1111             if (event.altKey && event.keyCode === $.ui.keyCode.BACKSPACE) {
1112                 var panelId = tabs.find(".ui-tabs-active").remove().attr("aria-controls");
1113                 setTimeout(function() {
1114                     $.tabs.removeTab(panelId);
1115                 }, 0);
1116             }
1117         });
1118 
1119         $.tabs.initTabScroll();
1120         $.tabs.initTabContextMenu();
1121     },
1122     removeTab : function(panelId) {
1123         var tabs = $.tabs.tabs;
1124         var panel = $("#" + panelId);
1125         var iframe = $("#iframe-" + panelId);
1126 
1127         var currentMenu = $("#menu-" + panelId.replace("tabs-", ""));
1128         if(currentMenu.length) {
1129             currentMenu.attr("id", "");
1130             currentMenu.attr("panelIndex", "");
1131             $("#menu .li-wrapper.active").removeClass("active");
1132         }
1133 
1134         tabs.tabs("option", "active", tabs.find(".ui-tabs-panel").size());
1135         tabs.tabs("refresh");
1136 
1137         panel.remove();
1138         var iframeDom = iframe[0];
1139         iframeDom.src = "";
1140         iframeDom.contentWindow.document.write('');
1141         iframeDom.contentWindow.close();
1142         iframe.remove();
1143         var isIE = !-[1,];
1144         if (isIE) {
1145             CollectGarbage();
1146         }
1147 
1148     },
1149     /**
1150      * 创建新的tab
1151      * @param title
1152      * @param panelIndex
1153      */
1154     /**
1155      * 创建新的tab
1156      * @param title
1157      * @param panelIndex
1158      */
1159     createTab : function(title, panelIndex) {
1160         var tabs = $.tabs.tabs;
1161 
1162         if(tabs.find(".ui-tabs-panel").length > 20) {
1163             $.app.alert({
1164                 message : "您打开的面板太多,为提高系统运行速度,请先关闭一些!"
1165             });
1166             return;
1167         }
1168 
1169 
1170         var newPanelIndex = panelIndex || $.tabs.maxTabIndex++ || 1;
1171         var newPanelId = "tabs-" + newPanelIndex;
1172         var tabTemplate = "<li><a href='#{href}'>{label}</a> <span class='menu icon-remove' role='presentation'title='关闭'></span><br/><span class='menu icon-refresh' role='presentation' title='刷新'></span></li>";
1173         var li = $(tabTemplate.replace(/\{href\}/g, newPanelId).replace(/\{label\}/g, title));
1174 
1175         tabs.find("ul.ui-tabs-nav").append(li);
1176         tabs.append('<div id="' + newPanelId + '"></div>');
1177 
1178         tabs.tabs("refresh");
1179 
1180         var newPanel = $("#" + newPanelId);
1181         newPanel.data("index", newPanelIndex);
1182 
1183         return newPanel;
1184     },
1185     /**
1186      * 激活指定索引处的tab 如果没有就创建一个
1187      * @param panelIdOrIndex
1188      * @param title
1189      * @param url
1190      * @param forceRefresh
1191      * @return {*}
1192      */
1193     activeTab: function (panelIdOrIndex, title, url, forceRefresh, callback) {
1194         var tabs = $.tabs.tabs;
1195         if(panelIdOrIndex && ("" + panelIdOrIndex).indexOf("tabs-") == 0) {
1196             currentTabPanel = $("#" + panelIdOrIndex);
1197         } else {
1198             var currentTabPanel = $("#tabs-" + panelIdOrIndex);
1199         }
1200 
1201         if (!currentTabPanel.length) {
1202             currentTabPanel = $.tabs.createTab(title, panelIdOrIndex);
1203         }
1204 
1205         if(callback) {
1206             callback(currentTabPanel.data("index"));
1207         }
1208 
1209         if(!url) {
1210             url = currentTabPanel.data("url");
1211         }
1212 
1213         setTimeout(function() {
1214             $.app.loadingToCenterIframe(currentTabPanel, url, null, forceRefresh);
1215             tabs.tabs("option", "active", tabs.find(".ui-tabs-panel").index(currentTabPanel));
1216         }, 0);
1217         return currentTabPanel.data("index");
1218     },
1219 
1220     initTabScrollHideOrShowMoveBtn : function(panelId) {
1221         var $ulWrapper = $(".tabs-bar .ul-wrapper");
1222         var $lastLI = $ulWrapper.find("ul li:last");
1223         var $firstLI = $ulWrapper.find("ul li:first");
1224 
1225         var ulWapperOffsetLeft = $ulWrapper.offset().left;
1226         var ulWrapperLeftPos = ulWapperOffsetLeft + $ulWrapper.width();
1227 
1228         var hideOrShowBtn = function() {
1229             var lastLIOffsetLeft = $lastLI.offset().left;
1230             var lastLILeftPos = lastLIOffsetLeft + $lastLI.width();
1231             var firstLIOffsetLeft = $firstLI.offset().left;
1232 
1233             var $leftBtn = $(".tabs-bar .icon-chevron-left");
1234             var $rightBtn = $(".tabs-bar .icon-chevron-right");
1235 
1236             if (ulWapperOffsetLeft == firstLIOffsetLeft) {
1237                 $leftBtn.hide();
1238             } else {
1239                 $leftBtn.show();
1240             }
1241             if (ulWrapperLeftPos >= lastLILeftPos) {
1242                 $rightBtn.hide();
1243             } else {
1244                 $rightBtn.show();
1245             }
1246         };
1247 
1248         if(panelId) {
1249 
1250             var $li = $(".tabs-bar").find("li[aria-labelledby='" + $("#" + panelId).attr("aria-labelledby") + "']");
1251 
1252             var liOffsetLeft = $li.offset().left;
1253             var liLeftPos = liOffsetLeft + $li.width();
1254 
1255             var isLast = $li.attr("aria-controls") == $lastLI.attr("aria-controls");
1256 
1257             //如果当前tab没有隐藏 则不scroll
1258             if((ulWapperOffsetLeft <= liOffsetLeft) && (liLeftPos <= ulWrapperLeftPos) && !isLast) {
1259                 return;
1260             }
1261 
1262             var leftPos = 0;
1263             //right
1264             if(ulWrapperLeftPos < liLeftPos || isLast) {
1265                 leftPos = $ulWrapper.scrollLeft() + (liLeftPos - ulWrapperLeftPos) + (isLast ? 10 :55);
1266             } else {
1267                 //left
1268                 leftPos = "-=" + (ulWapperOffsetLeft - liOffsetLeft + 55);
1269             }
1270 
1271             $ulWrapper.animate({scrollLeft: leftPos}, 600, function () {
1272                 hideOrShowBtn();
1273             });
1274         } else {
1275             hideOrShowBtn();
1276         }
1277 
1278 
1279     },
1280     initTabScroll: function () {
1281         var move = function (step) {
1282             return function () {
1283                 var $ulWrapper = $(".tabs-bar .ul-wrapper");
1284                 var $lastLI = $ulWrapper.find("ul li:last");
1285 
1286                 var leftPos = $ulWrapper.scrollLeft() + step;
1287 
1288                 var ulWrapperLeftPos = $ulWrapper.offset().left + $ulWrapper.width();
1289                 var lastLILeftPos = $lastLI.offset().left + $lastLI.width();
1290                 var maxLeftPos = lastLILeftPos - ulWrapperLeftPos;
1291 
1292                 //right move
1293                 if (step > 0) {
1294                     if (maxLeftPos <= step + step / 2) {
1295                         leftPos = $ulWrapper.scrollLeft() + maxLeftPos;
1296                     }
1297                     if (maxLeftPos <= 0) {
1298                         return;
1299                     }
1300                 }
1301 
1302                 //left move
1303                 if (step < 0) {
1304                     if (leftPos < -step) {
1305                         leftPos = 0;
1306                     }
1307                 }
1308 
1309                 if (leftPos < 0) {
1310                     leftPos = 0;
1311                 }
1312                 $ulWrapper.animate({scrollLeft: leftPos}, 600, function () {
1313                     $.tabs.initTabScrollHideOrShowMoveBtn();
1314                 });
1315             };
1316         };
1317 
1318         $(".tabs-bar .icon-chevron-left").click(function () {
1319             setTimeout(function() {move(-200)()}, 0);
1320         });
1321         $(".tabs-bar .icon-chevron-right").click(function () {
1322             setTimeout(function() {move(200)()}, 0);
1323         });
1324 
1325     },
1326     /**
1327      * 初始化上下文菜单(右键菜单)
1328      */
1329     initTabContextMenu : function() {
1330         //初始化右键菜单
1331         var tabsMenu = $("#tabs-menu");
1332         //调用这个方法后将禁止系统的右键菜单
1333         $(document).bind('contextmenu', function (e) {
1334             var target = $(e.target);
1335             var clickTab = target.closest(".tabs-bar").length && target.is(".ui-tabs-anchor");
1336 
1337             if (clickTab && target.attr("href") == '#tabs-0') {
1338                 return true;
1339             }
1340             if (clickTab) {
1341                 showMenu(target.attr("id"), e.pageX - 5, e.pageY - 5);
1342                 tabsMenu.mouseleave(function () {
1343                     hideMenu();
1344                 });
1345                 return false;
1346             }
1347             return true;
1348         });
1349 
1350         function hideMenu() {
1351             tabsMenu.hide();
1352             tabsMenu.data("tabId", "");
1353         }
1354 
1355         function showMenu(tabId, x, y) {
1356             tabsMenu.data("tabId", tabId);
1357             tabsMenu.css("left", x).css("top", y);
1358             tabsMenu.show();
1359         }
1360 
1361         function closeTab(tabId) {
1362             $("#" + tabId).parent().find(".icon-remove").click();
1363         }
1364         tabsMenu.find(".close-current").click(function (e) {
1365             var currentTabId = tabsMenu.data("tabId");
1366             closeTab(currentTabId);
1367             hideMenu();
1368         });
1369 
1370         tabsMenu.find(".close-others").click(function (e) {
1371             var currentTabId = tabsMenu.data("tabId");
1372             var tabs = $.tabs.tabs.find(".ul-wrapper > ul > li > a");
1373             tabs.each(function() {
1374                 var tabId = this.id;
1375                 if(tabId != currentTabId) {
1376                     closeTab(tabId);
1377                 }
1378             });
1379             hideMenu();
1380         });
1381         tabsMenu.find(".close-all").click(function (e) {
1382             var currentTabId = tabsMenu.data("tabId");
1383             var tabs = $.tabs.tabs.find(".ul-wrapper > ul > li > a");
1384             tabs.each(function() {
1385                 var tabId = this.id;
1386                 closeTab(tabId);
1387             });
1388             hideMenu();
1389         });
1390 
1391         tabsMenu.find(".close-left-all").click(function (e) {
1392             var currentTabId = tabsMenu.data("tabId");
1393             var tabs = $.tabs.tabs.find(".ul-wrapper > ul > li > a");
1394             var currentTabIndex = tabs.index($("#" + currentTabId));
1395             tabs.each(function(index) {
1396                 if(index < currentTabIndex) {
1397                     var tabId = this.id;
1398                     closeTab(tabId);
1399                 }
1400             });
1401             hideMenu();
1402         });
1403         tabsMenu.find(".close-right-all").click(function (e) {
1404             var currentTabId = tabsMenu.data("tabId");
1405             var tabs = $.tabs.tabs.find(".ul-wrapper > ul > li > a");
1406             var currentTabIndex = tabs.index($("#" + currentTabId));
1407             tabs.each(function(index) {
1408                 if(index > currentTabIndex) {
1409                     var tabId = this.id;
1410                     closeTab(tabId);
1411                 }
1412             });
1413             hideMenu();
1414         });
1415     },
1416 
1417     /**
1418      * 获取下一个自定义panel的索引
1419      */
1420     nextCustomTabIndex : function() {
1421         var tabs = $.tabs.tabs;
1422         var maxIndex = $.tabs.customTabStartIndex;
1423         tabs.find(".ui-tabs-panel").each(function() {
1424             var index = parseInt($(this).attr("id").replace("tabs-"));
1425             if(maxIndex < index) {
1426                 maxIndex = index;
1427             }
1428         });
1429 
1430         return maxIndex + 1;
1431 
1432     }
1433 };
1434 
1435 $.parentchild = {
1436     /**
1437      * 初始化父子操作中的子表单
1438      * options
1439      *     {
1440                 form : 表单【默认$("childForm")】,
1441                 tableId : "表格Id"【默认"childTable"】,
1442                 excludeInputSelector : "[name='_show']"【排除的selector 默认无】,
1443                 trId : "修改的哪行数据的tr id, 如果没有表示是新增的",
1444                 validationEngine : null 验证引擎,
1445                 modalSettings:{//模态窗口设置
1446                     width:800,
1447                     height:500,
1448                     buttons:{}
1449                 },
1450                 updateUrl : "${ctx}/showcase/parentchild/parent/child/{id}/update" 修改时url模板 {id} 表示修改时的id,
1451                 deleteUrl : "${ctx}/showcase/parentchild/parent/child/{id}/delete  删除时url模板 {id} 表示删除时的id,
1452             }
1453      * @param options
1454      * @return {boolean}
1455      */
1456     initChildForm : function(options) {
1457         var defaults = {
1458             form : $("#childForm"),
1459             tableId : "childTable",
1460             excludeInputSelector : "",
1461             trId : "",
1462             validationEngine : null
1463         };
1464 
1465         if(!options) {
1466             options = {};
1467         }
1468         options = $.extend({}, defaults, options);
1469 
1470         //如果有trId则用trId中的数据更新当前表单
1471         if(options.trId) {
1472             var $tr = $("#" + options.trId);
1473             if($tr.length && $tr.find(":input").length) {
1474                 //因为是按顺序保存的 所以按照顺序获取  第一个是checkbox 跳过
1475                 var index = 1;
1476                 $(":input", options.form).not(options.excludeInputSelector).each(function() {
1477                     var $input = $(this);
1478                     var $trInput = $tr.find(":input").eq(index++);
1479                     if(!$trInput.length) {
1480                         return;
1481                     }
1482                     var $trInputClone = $trInput.clone(true).show();
1483                     //saveModalFormToTable 为了防止重名问题,添加了tr id前缀,修改时去掉
1484                     $trInputClone.prop("name", $trInputClone.prop("name").replace(options.trId, ""));
1485                     $trInputClone.prop("id", $trInputClone.prop("id").replace(options.trId, ""));
1486 
1487                     //克隆后 select的选择丢失了 TODO 提交给jquery bug?
1488                     if($trInput.is("select")) {
1489                         $trInput.find("option").each(function(i) {
1490                             $trInputClone.find("option").eq(i).prop("selected", $(this).prop("selected"));
1491                         });
1492                     }
1493                     if($trInput.is(":radio,:checkbox")) {
1494                         $trInputClone.prop("checked", $trInput.prop("checked"));
1495                     }
1496 
1497                     $trInputClone.replaceAll($input);
1498                 });
1499             }
1500         }
1501 
1502         //格式化子表单的 input label
1503         $(":input,label", options.form).each(function() {
1504             var prefix = "child_";
1505             if($(this).is(":input")) {
1506                 var id = $(this).prop("id");
1507                 if(id && id.indexOf(prefix) != 0) {
1508                     $(this).prop("id", prefix + id);
1509                 }
1510             } else {
1511                 var _for = $(this).prop("for");
1512                 if(_for && _for.indexOf(prefix) != 0) {
1513                     $(this).prop("for", prefix + _for);
1514                 }
1515             }
1516         });
1517 
1518         options.form.submit(function() {
1519             if(options.validationEngine && !options.validationEngine.validationEngine("validate")) {
1520                 return false;
1521             }
1522             return $.parentchild.saveModalFormToTable(options);
1523         });
1524     }
1525     ,
1526     //保存打开的模态窗口到打开者的表格中
1527     /**
1528      * options
1529      *     {
1530                 form : 表单【默认$("childForm")】,
1531                 tableId : "表格Id"【默认"childTable"】,
1532                 excludeInputSelector : "[name='_show']"【排除的selector 默认无】,
1533                 updateCallback : 【修改时的回调  默认 updateChild】,
1534                 deleteCallback : 【删除时的回调默认 deleteChild】,
1535                 trId : "修改的哪行数据的tr id, 如果没有表示是新增的"
1536             }
1537      * @param options
1538      * @return {boolean}
1539      */
1540     saveModalFormToTable :function(options) {
1541         var $childTable =  $("#" + options.tableId);
1542         var $childTbody = $childTable.children("tbody");
1543 
1544         if(!options.trId || options.alwaysNew) {
1545             var counter = $childTbody.data("counter");
1546             if(!counter) {
1547                 counter = 0;
1548             }
1549             options.trId = "new_" + counter++;
1550             $childTbody.data("counter", counter);
1551         }
1552         var $lastTr = $("#" + options.trId, $childTbody);
1553 
1554         var $tr = $("<tr></tr>");
1555         $tr.prop("id", options.trId);
1556         if(!$lastTr.length || options.alwaysNew) {
1557             $childTbody.append($tr);
1558         } else {
1559             $lastTr.replaceWith($tr);
1560         }
1561 
1562         var $td = $("<td></td>");
1563 
1564         //checkbox
1565         $tr.append($td.clone(true).addClass("check").append("<input type='checkbox'>"));
1566 
1567         var $inputs = $(":input", options.form).not(":button,:submit,:reset", options.form);
1568         if(options.excludeInputSelector) {
1569             $inputs = $inputs.not(options.excludeInputSelector);
1570         }
1571         $inputs = $inputs.filter(function() {
1572             return $inputs.filter("[name='" + $(this).prop("name") + "']").index($(this)) == 0;
1573         });
1574         $inputs.each(function() {
1575             var $input = $("[name='" + $(this).prop("name") + "']", options.form);
1576 
1577             var val = $input.val();
1578             //使用文本在父页显示,而不是值
1579             //如果是单选按钮/复选框 (在写的过程中,必须在输入框后跟着一个label)
1580             if($input.is(":radio,:checkbox")) {
1581                 val = "";
1582                 $input.filter(":checked").each(function() {
1583                     if(val != "") {
1584                         val = val + ",";
1585                     }
1586                     val = val + $("label[for='" + $(this).prop("id") + "']").text();
1587                 });
1588             }
1589             //下拉列表
1590             if($input.is("select")) {
1591                 val = "";
1592                 $input.find("option:selected").each(function() {
1593                     if(val != "") {
1594                         val = val + ",";
1595                     }
1596                     val = val + $(this).text();
1597                 });
1598             }
1599 
1600             //因为有多个孩子 防止重名造成数据丢失
1601             $input.each(function() {
1602                 if($(this).is("[id]")) {
1603                     $(this).prop("id", options.trId + $(this).prop("id"));
1604                 }
1605                 $(this).prop("name", options.trId + $(this).prop("name"));
1606             });
1607             $tr.append($td.clone(true).append(val).append($input.hide()));
1608 
1609         });
1610 
1611         $.table.initCheckbox($childTable);
1612 
1613         $.app.cancelModelDialog();
1614         return false;
1615     }
1616     ,
1617     /**
1618      * 更新子
1619      * @param $a 当前按钮
1620      * @param updateUrl  更新地址
1621      */
1622     updateChild : function($tr, updateUrl, modalSettings) {
1623         if(updateUrl.indexOf("?") > 0) {
1624             updateUrl = updateUrl + "&";
1625         } else {
1626             updateUrl = updateUrl + "?";
1627         }
1628         updateUrl = updateUrl + "trId={trId}";
1629 
1630         //表示已经在数据库中了
1631         if($tr.is("[id^='old']")) {
1632             updateUrl = updateUrl.replace("{id}", $tr.prop("id").replace("old_", ""));
1633         } else {
1634             //表示刚刚新增的还没有保存到数据库
1635             updateUrl = updateUrl.replace("{id}", 0);
1636         }
1637         updateUrl = updateUrl.replace("{trId}", $tr.prop("id"));
1638         $.app.modalDialog("修改", updateUrl, modalSettings);
1639     }
1640     ,
1641     /**
1642      * 以当前行复制一份
1643      * @param $a 当前按钮
1644      * @param updateUrl  更新地址
1645      */
1646     copyChild : function($tr, updateUrl, modalSettings) {
1647         if(updateUrl.indexOf("?") > 0) {
1648             updateUrl = updateUrl + "&";
1649         } else {
1650             updateUrl = updateUrl + "?";
1651         }
1652         updateUrl = updateUrl + "trId={trId}";
1653         updateUrl = updateUrl + "&copy=true";
1654 
1655         //表示已经在数据库中了
1656         if($tr.is("[id^='old']")) {
1657             updateUrl = updateUrl.replace("{id}", $tr.prop("id").replace("old_", ""));
1658         } else {
1659             //表示刚刚新增的还没有保存到数据库
1660             updateUrl = updateUrl.replace("{id}", 0);
1661         }
1662         updateUrl = updateUrl.replace("{trId}", $tr.prop("id"));
1663         $.app.modalDialog("复制", updateUrl, modalSettings);
1664     }
1665     ,
1666     /**
1667      * 删除子
1668      * @param $a 当前按钮
1669      * @param deleteUrl 删除地址
1670      */
1671     deleteChild : function($a, deleteUrl) {
1672         $.app.confirm({
1673             message : "确认删除吗?",
1674             ok : function() {
1675                 var $tr = $a.closest("tr");
1676                 //如果数据库中存在
1677                 if($tr.prop("id").indexOf("old_") == 0) {
1678                     deleteUrl = deleteUrl.replace("{id}", $tr.prop("id").replace("old_", ""));
1679                     $.post(deleteUrl, function() {
1680                         $tr.remove();
1681                     });
1682                 } else {
1683                     $tr.remove();
1684                 }
1685 
1686             }
1687         });
1688     }
1689     ,
1690     /**
1691      * 初始化父子表单中的父表单
1692      * {
1693      *     form: $form 父表单,
1694      *     tableId : tableId 子表格id,
1695      *     prefixParamName : "" 子表单 参数前缀,
1696      *     modalSettings:{} 打开的模态窗口设置
1697      *     createUrl : "${ctx}/showcase/parentchild/parent/child/create",
1698      *     updateUrl : "${ctx}/showcase/parentchild/parent/child/{id}/update" 修改时url模板 {id} 表示修改时的id,
1699      *     deleteUrl : "${ctx}/showcase/parentchild/parent/child/{id}/delete  删除时url模板 {id} 表示删除时的id,
1700      * }
1701      */
1702     initParentForm : function(options) {
1703 
1704 
1705         var $childTable = $("#" + options.tableId);
1706         $.table.initCheckbox($childTable);
1707         //绑定在切换页面时的事件 防止误前进/后退 造成数据丢失
1708         $(window).on('beforeunload',function(){
1709             if($childTable.find(":input").length) {
1710                 return "确定离开当前编辑页面吗?";
1711             }
1712         });
1713         $(".btn-create-child").click(function() {
1714             $.app.modalDialog("新增", options.createUrl, options.modalSettings);
1715         });
1716         $(".btn-update-child").click(function() {
1717             var $trs = $childTable.find("tbody tr").has(".check :checkbox:checked:first");
1718             if(!$trs.length) {
1719                 $.app.alert({message : "请先选择要修改的数据!"});
1720                 return;
1721             }
1722             $.parentchild.updateChild($trs, options.updateUrl, options.modalSettings);
1723         });
1724 
1725         $(".btn-copy-child").click(function() {
1726             var $trs = $childTable.find("tbody tr").has(".check :checkbox:checked:first");
1727             if(!$trs.length) {
1728                 $.app.alert({message : "请先选择要复制的数据!"});
1729                 return;
1730             }
1731             $.parentchild.copyChild($trs, options.updateUrl, options.modalSettings);
1732         });
1733 
1734 
1735         $(".btn-delete-child").click(function() {
1736             var $trs = $childTable.find("tbody tr").has(".check :checkbox:checked");
1737             if(!$trs.length) {
1738                 $.app.alert({message : "请先选择要删除的数据!"});
1739                 return;
1740             }
1741             $.app.confirm({
1742                 message: "确定删除选择的数据吗?",
1743                 ok : function() {
1744                     var ids = new Array();
1745                     $trs.each(function() {
1746                         var id = $(this).prop("id");
1747                         if(id.indexOf("old_") == 0) {
1748                             id = id.replace("old_", "");
1749                             ids.push({name : "ids", value : id});
1750                         }
1751                     });
1752 
1753                     $.post(options.batchDeleteUrl, ids, function() {
1754                         $trs.remove();
1755                         $.table.changeBtnState($childTable);
1756                     });
1757 
1758                 }
1759             });
1760         });
1761 
1762         options.form.submit(function() {
1763             //如果是提交 不需要执行beforeunload
1764             $(window).unbind("beforeunload");
1765             $childTable.find("tbody tr").each(function(index) {
1766                 var tr = $(this);
1767                 tr.find(".check > :checkbox").attr("checked", false);
1768                 tr.find(":input").each(function() {
1769                     if($(this).prop("name").indexOf(options.prefixParamName) != 0) {
1770                         $(this).prop("name", options.prefixParamName + "[" + index + "]." + $(this).prop("name").replace(tr.prop("id"), ""));
1771                     }
1772                 });
1773             });
1774         });
1775     }
1776 
1777 }
1778 
1779 
1780 
1781 
1782 $.table = {
1783 
1784     /**
1785      * 初始化表格:全选/反选 排序
1786      * @param table
1787      */
1788     initTable: function (table) {
1789         if(!table || !table.length || table.attr("initialized") == "true") {
1790             return;
1791         }
1792 
1793         table.attr("initialized", "true");
1794 
1795         $.table.initSort(table);
1796         $.table.initSearchForm(table);
1797         if(table.is(".move-table")) {
1798             $.movable.initMoveableTable(table);
1799         }
1800 
1801         //初始化table里的a标签
1802         $.table.initTableBtn(table);
1803         //初始化删除和修改按钮
1804         $.table.initDeleteSelected(table);
1805         $.table.initUpdateSelected(table);
1806         $.table.initCreate(table);
1807 
1808         //初始化checkbox
1809         $.table.initCheckbox(table);
1810         //初始化 按钮的状态
1811         $.table.changeBtnState(table);
1812 
1813 
1814     },
1815     initCheckbox: function(table) {
1816         var activeClass = "active";
1817         //初始化表格中checkbox 点击单元格选中
1818         table.find("td.check").each(function () {
1819             var checkbox = $(this).find(":checkbox,:radio");
1820             checkbox.off("click").on("click", function (event) {
1821                 var checked = checkbox.is(":checked");
1822                 if(!checked) {
1823                     checkbox.closest("tr").removeClass(activeClass);
1824                 } else {
1825                     checkbox.closest("tr").addClass(activeClass);
1826                 }
1827                 $.table.changeBtnState(table);
1828                 event.stopPropagation();
1829             });
1830             $(this).closest("tr").off("click").on("click", function (event) {
1831                 var checked = checkbox.is(":checked");
1832                 if(checked) {
1833                     checkbox.closest("tr").removeClass(activeClass);
1834                 } else {
1835                     checkbox.closest("tr").addClass(activeClass);
1836                 }
1837                 checkbox.prop("checked", !checked);
1838                 $.table.changeBtnState(table);
1839             });
1840         });
1841         //初始化全选反选
1842         table.find(".check-all").off("click").on("click", function () {
1843             var checkAll = $(this);
1844             if(checkAll.text() == '全选') {
1845                 checkAll.text("取消");
1846                 table.find("td.check :checkbox").prop("checked", true).closest("tr").addClass(activeClass);
1847             } else {
1848                 checkAll.text("全选");
1849                 table.find("td.check :checkbox").prop("checked", false).closest("tr").removeClass(activeClass);
1850             }
1851             $.table.changeBtnState(table);
1852         });
1853         table.find(".reverse-all").off("click").on("click", function () {
1854             table.find("td.check :checkbox").each(function () {
1855                 var checkbox = $(this);
1856                 var checked = checkbox.is(":checked");
1857                 if(checked) {
1858                     checkbox.closest("tr").removeClass(activeClass);
1859                 } else {
1860                     checkbox.closest("tr").addClass(activeClass);
1861                 }
1862                 checkbox.prop("checked", !checked);
1863                 $.table.changeBtnState(table);
1864             });
1865         });
1866     },
1867     changeBtnState : function(table) {
1868         var hasChecked = table.find("td.check :checkbox:checked").length;
1869         var btns = table.closest(".panel").find(".tool .btn").not(".no-disabled");
1870         if(hasChecked) {
1871             btns.removeClass("disabled");
1872             btns.each(function() {
1873                 var btn = $(this);
1874                 var href = btn.data("btn-state-href");
1875                 if(href) {
1876                     btn.attr("href", href);
1877                 }
1878             });
1879         } else {
1880             btns.addClass("disabled");
1881             btns.each(function() {
1882                 var btn = $(this);
1883                 var href = btn.attr("href");
1884                 if(href) {
1885                     btn.data("btn-state-href", href);
1886                     btn.removeAttr("href");
1887                 }
1888             });
1889         }
1890     },
1891     /**
1892      * 初始化对应的查询表单
1893      * @param table
1894      */
1895     initSearchForm : function(table) {
1896         var id = $(table).attr("id");
1897         var searchForm = table.closest("[data-table='" + id + "']").find(".search-form");
1898 
1899         if(!searchForm.length) {
1900             return;
1901         }
1902 
1903         searchForm.find(".btn").addClass("no-disabled");
1904 
1905         searchForm.find(".btn-clear-search").click(function() {
1906 
1907             if (table.data("async") == true) {
1908                 var resetBtn = searchForm.find("input[type='reset']");
1909                 if(!resetBtn.length) {
1910                     searchForm.append("<input type='reset' style='display:none'>");
1911                     resetBtn = searchForm.find("input[type='reset']");
1912                 }
1913                 resetBtn.click();
1914             }
1915             turnSearch(table, searchForm, true);
1916         });
1917 
1918         var turnSearch = function(table, searchForm, isSearchAll) {
1919             var url = $.table.tableURL(table);
1920             url = $.table.removeSearchParam(url, searchForm);
1921             url = $.table.removePageParam(url, searchForm);
1922             if(!isSearchAll) {
1923                 if(url.indexOf("?") == -1) {
1924                     url = url + "?";
1925                 } else {
1926                     url = url + "&";
1927                 }
1928                 url = url + searchForm.serialize();
1929             }
1930             $.table.reloadTable(table, url, null);
1931         }
1932 
1933         searchForm.off("submit").on("submit", function() {
1934             turnSearch(table, searchForm, false);
1935             return false;
1936         });
1937 
1938         if(searchForm.is("[data-change-search=true]")) {
1939             searchForm.find(":input:not(:button,:submit,:reset)").off("change").on("change", function(e) {
1940                 // avoid double search issue, when you click search button after change any input
1941                 searchForm.off("submit").on("submit", function() {
1942                     return false;
1943                 });
1944                 turnSearch(table, searchForm, false);
1945             });
1946         }
1947 
1948         searchForm.find(".btn-search-all").off("click").on("click", function() {
1949             turnSearch(table, searchForm, true);
1950             return false;
1951         });
1952 
1953 
1954     },
1955     /**
1956      * 初始化sort
1957      * @param table
1958      */
1959     initSort: function (table) {
1960         if (!table.length) {
1961             return;
1962         }
1963 
1964         //初始化排序
1965         var prefix = $.table.getPrefix(table);
1966 
1967         var sortURL = $.table.tableURL(table);
1968 
1969         var sortBtnTemplate = '<div class="sort"><a class="{sort-icon}" href="#" title="排序"></a></div>';
1970         table.find("[sort]").each(function () {
1971             var th = $(this);
1972             var sortPropertyName = prefix + "sort." + th.attr("sort");
1973             var sortBtnStr = null;
1974             var matchResult = sortURL.match(new RegExp(sortPropertyName + "=(asc|desc)", "gi"));
1975             var order = null;
1976             if (matchResult) {
1977                 order = RegExp.$1;
1978                 if (order == 'asc') {
1979                     sortBtnStr = sortBtnTemplate.replace("{sort-icon}", "sort-hover icon-arrow-up");
1980                 } else if (order == 'desc') {
1981                     sortBtnStr = sortBtnTemplate.replace("{sort-icon}", "sort-hover icon-arrow-down");
1982                 }
1983             }
1984             if (sortBtnStr == null) {
1985                 sortBtnStr = sortBtnTemplate.replace("{sort-icon}", "icon-arrow-down");
1986             }
1987             th.wrapInner("<div class='sort-title'></div>").append($(sortBtnStr));
1988 
1989             //当前排序
1990             th.prop("order", order);//设置当前的排序 方便可移动表格
1991 
1992             th.addClass("sort-th").click(function () {
1993                 sortURL = $.table.tableURL(table);
1994                 //清空上次排序
1995                 sortURL = $.table.removeSortParam(sortURL);
1996 
1997                 if (!order) { //asc
1998                     order = "asc";
1999                 } else if (order == "asc") { //desc
2000                     order = "desc";
2001                 } else if (order == "desc") { //none
2002                     order = "asc";
2003                 }
2004 
2005                 if (order) {
2006                     sortURL = sortURL + (sortURL.indexOf("?") == -1 ? "?" : "&");
2007                     sortURL = sortURL + sortPropertyName + "=" + order;
2008                 }
2009 
2010                 $.table.reloadTable(table, sortURL, null);
2011             });
2012 
2013         });
2014     },
2015     /**
2016      * 分页
2017      * @param pageSize
2018      * @param pn
2019      * @param child table的子
2020      */
2021     turnPage: function (pageSize, pn, child) {
2022         var table = $(child).closest(".table-pagination").prev("table");
2023         if(!table.length) {
2024             table = $(child).closest("table");
2025         }
2026 
2027         var pageURL = $.table.tableURL(table);
2028 
2029         //清空上次分页
2030         pageURL = $.table.removePageParam(pageURL);
2031 
2032 
2033         pageURL = pageURL + (pageURL.indexOf("?") == -1 ? "?" : "&");
2034 
2035         var prefix = $.table.getPrefix(table);
2036         pageURL = pageURL + prefix + "page.pn=" + pn;
2037 
2038         if (pageSize) {
2039             pageURL = pageURL + "&" + prefix + "page.size=" + pageSize;
2040         }
2041 
2042         $.table.reloadTable(table, pageURL, null);
2043     },
2044     /**
2045      * 执行跳转
2046      * @param table
2047      * @param url
2048      * @param backURL
2049      */
2050     reloadTable: function (table, url, backURL) {
2051 
2052         if(!url) {
2053             url = $.table.tableURL(table);
2054         }
2055 
2056         if (!backURL) {
2057             backURL = url;
2058         }
2059         //modalDialog时 把当前url保存下来方便翻页和排序
2060         table.closest(".ui-dialog").data("url", backURL);
2061 
2062         if (table.data("async") == true) {
2063             $.app.waiting();
2064 
2065             var tableId = table.attr("id");
2066             var containerId = table.data("async-container");
2067             var headers = {};
2068 
2069             if(!containerId) {//只替换表格时使用
2070                 headers.table = true;
2071             } else {
2072                 headers.container = true;
2073             }
2074 
2075             $.ajax({
2076                 url: url,
2077                 async:true,
2078                 headers: headers
2079             }).done(function (data) {
2080                     if (containerId) {//装载到容器
2081                         $("#" + containerId).replaceWith(data);
2082                     } else {
2083                         var pagination = table.next(".table-pagination");
2084                         if(pagination.length) {
2085                             pagination.remove();
2086                         }
2087                         table.replaceWith(data);
2088                     }
2089 
2090                     table = $("#" + tableId);
2091                     table.data("url", backURL);
2092                     $.table.initTable(table);
2093 
2094                     var callback = table.data("async-callback");
2095                     if(callback && window[callback]) {
2096                         window[callback](table);
2097                     }
2098 
2099                     $.app.waitingOver();
2100                 });
2101         } else {
2102             window.location.href = url;
2103         }
2104     }
2105     ,
2106     /**
2107      * 获取表格对于的url
2108      * @param table
2109      * @return {*}
2110      */
2111     tableURL : function(table) {
2112         var $dialog = table.closest(".ui-dialog");
2113 
2114         var url = table.data("url");
2115         if(!url && $dialog.length) {
2116             //modalDialog
2117             url = $dialog.data("url");
2118         }
2119         if (!url) {
2120             url = window.location.href;
2121         }
2122         //如果URL中包含锚点(#) 删除
2123         if(url.indexOf("#") > 0) {
2124             url = url.substring(0, url.indexOf("#"));
2125         }
2126 
2127         return url;
2128     },
2129     /**
2130      *
2131      * @param table
2132      */
2133     encodeTableURL : function(table) {
2134         return encodeURIComponent($.table.tableURL(table));
2135     }
2136     ,
2137     /**
2138      * 获取传递参数时的前缀
2139      * @param table
2140      */
2141     getPrefix : function(table) {
2142         var prefix = table.data("prefix");
2143         if (!prefix) {
2144             prefix = "";
2145         } else {
2146             prefix = prefix + "_";
2147         }
2148         return prefix;
2149     }
2150     ,
2151     removePageParam : function(pageURL) {
2152         pageURL = pageURL.replace(/\&\w*page.pn=\d+/gi, '');
2153         pageURL = pageURL.replace(/\?\w*page.pn=\d+\&/gi, '?');
2154         pageURL = pageURL.replace(/\?\w*page.pn=\d+/gi, '');
2155         pageURL = pageURL.replace(/\&\w*page.size=\d+/gi, '');
2156         pageURL = pageURL.replace(/\?\w*page.size=\d+\&/gi, '?');
2157         pageURL = pageURL.replace(/\?\w*page.size=\d+/gi, '');
2158         return pageURL;
2159     }
2160     ,
2161     removeSortParam : function(sortURL) {
2162         sortURL = sortURL.replace(/\&\w*sort.*=((asc)|(desc))/gi, '');
2163         sortURL = sortURL.replace(/\?\w*sort.*=((asc)|(desc))\&/gi, '?');
2164         sortURL = sortURL.replace(/\?\w*sort.*=((asc)|(desc))/gi, '');
2165         return sortURL;
2166     },
2167     removeSearchParam : function(url, form) {
2168         $.each(form.serializeArray(), function() {
2169             var name = this.name;
2170             url = url.replace(new RegExp(name + "=.*?\&","g"), '');
2171             url = url.replace(new RegExp("[\&\?]" + name + "=.*$","g"), '');
2172         });
2173         return url;
2174     }
2175     ,
2176     //格式化url前缀,默认清除url ? 后边的
2177     formatUrlPrefix : function(urlPrefix, $table) {
2178 
2179         if(!urlPrefix) {
2180             urlPrefix = $table.data("prefix-url");
2181         }
2182 
2183         if(!urlPrefix && $table && $table.length) {
2184             urlPrefix = decodeURIComponent($.table.tableURL($table));
2185         }
2186 
2187         if(!urlPrefix) {
2188             urlPrefix = currentURL;
2189         }
2190 
2191         if(urlPrefix.indexOf("?") >= 0) {
2192             return urlPrefix.substr(0, urlPrefix.indexOf("?"));
2193         }
2194         return urlPrefix;
2195     },
2196 
2197     initDeleteSelected : function($table, urlPrefix) {
2198         if(!$table || !$table.length) {
2199             return;
2200         }
2201 
2202         var $btn = $table.closest("[data-table='" + $table.attr("id") + "']").find(".btn-delete:not(.btn-custom)");
2203         urlPrefix = $.table.formatUrlPrefix(urlPrefix, $table);
2204         $btn.off("click").on("click", function() {
2205             var checkbox = $.table.getAllSelectedCheckbox($table);
2206             if(!checkbox.length)  return;
2207 
2208             $.app.confirm({
2209                 message: "确定删除选择的数据吗?",
2210                 ok : function() {
2211                     window.location.href =
2212                         urlPrefix + "/batch/delete?" + checkbox.serialize() + "&BackURL=" + $.table.encodeTableURL($table);
2213                 }
2214             });
2215         });
2216     }
2217     ,
2218     initUpdateSelected : function($table, urlPrefix) {
2219         if(!$table || !$table.length) {
2220             return;
2221         }
2222         var $btn = $table.closest("[data-table='" + $table.attr("id") + "']").find(".btn-update:not(.btn-custom)");
2223         urlPrefix = $.table.formatUrlPrefix(urlPrefix, $table);
2224         $btn.off("click").on("click", function() {
2225             var checkbox = $.table.getFirstSelectedCheckbox($table);
2226             if(!checkbox.length)  return;
2227             var id = checkbox.val();
2228             window.location.href = urlPrefix + "/" + id + "/update?BackURL=" + $.table.encodeTableURL($table);
2229         });
2230     },
2231     initCreate : function($table, urlPrefix) {
2232         if(!$table || !$table.length) {
2233             return;
2234         }
2235         var $btn = $table.closest("[data-table='" + $table.attr("id") + "']").find(".btn-create");
2236 
2237         $btn.addClass("no-disabled");
2238 
2239         $btn.off("click").on("click", function() {
2240             var url =  $.table.formatUrlPrefix(urlPrefix, $table) + "/create";
2241             if($btn.attr("href")) {
2242                 url = $btn.attr("href");
2243             }
2244             window.location.href = url + (url.indexOf("?") == -1 ? "?" : "&") + "BackURL=" + $.table.encodeTableURL($table);
2245             return false;
2246         });
2247     },
2248     initTableBtn : function($table, urlPrefix) {
2249         if(!$table || !$table.length) {
2250             return;
2251         }
2252         $table.closest("[data-table=" + $table.attr("id") + "]").find(".btn").not(".btn-custom,.btn-create,.btn-update,.btn-delete").each(function() {
2253             var $btn = $(this);
2254             var url = $btn.attr("href");
2255             if(!url || url.indexOf("#") == 0 || url.indexOf("javascript:") == 0) {//没有url就不处理了
2256                 return;
2257             }
2258             $btn.off("click").on("click", function() {
2259                 window.location.href = url + (url.indexOf("?") == -1 ? "?" : "&") + "BackURL=" + $.table.encodeTableURL($table);
2260                 return false;
2261             });
2262         });
2263 
2264         urlPrefix = $.table.formatUrlPrefix(urlPrefix, $table);
2265         //支持双击编辑
2266         if($table.hasClass("table-dblclick-edit")) {
2267             $table.children("tbody").children("tr").off("dblclick").on("dblclick", function() {
2268                 var id = $(this).find(":checkbox[name=ids]").val();
2269                 window.location.href = urlPrefix + "/" + id + "/update?BackURL=" + $.table.encodeTableURL($table);
2270             });
2271         }
2272 
2273     },
2274     getFirstSelectedCheckbox :function($table) {
2275         var checkbox = $("#table :checkbox:checked:first");
2276         if(!checkbox.length) {
2277 
2278             //表示不选中 不可以用,此时没必要弹窗
2279             if($(this).hasClass(".no-disable") == false) {
2280                 return checkbox;
2281             }
2282 
2283             $.app.alert({
2284                 message : "请先选择要操作的数据!"
2285             });
2286         }
2287         return checkbox;
2288     },
2289     getAllSelectedCheckbox :function($table) {
2290         var checkbox = $table.find(":checkbox:checked");
2291         if(!checkbox.length) {
2292 
2293             //表示不选中 不可以用,此时没必要弹窗
2294             if($(this).hasClass(".no-disable") == false) {
2295                 return checkbox;
2296             }
2297 
2298             $.app.alert({
2299                 message : "请先选择要操作的数据!"
2300             });
2301         }
2302         return checkbox;
2303     }
2304 }
2305 
2306 $.movable = {
2307     /**
2308      * urlPrefix:指定移动URL的前缀,
2309      * 如/sample,生成的URL格式为/sample/{fromId}/{toId}/{direction:方向(up|down)}
2310      * @param table
2311      * @param urlPrefix
2312      */
2313     initMoveableTable : function(table) {
2314         if(!table.length) {
2315             return;
2316         }
2317         var urlPrefix = table.data("move-url-prefix");
2318         if(!urlPrefix) {
2319             $.app.alert({message : "请添加移动地址URL,如&lt;table move-url-prefix='/sample'&gt;<br/>自动生成:/sample/{fromId}/{toId}/{direction:方向(up|down)}"});
2320         }
2321         var fixHelper = function (e, tr) {
2322             var $originals = tr.children();
2323             var $helper = tr.clone();
2324             $helper.children().each(function (index) {
2325                 // Set helper cell sizes to match the original sizes
2326                 $(this).width($originals.eq(index).width())
2327             });
2328             return $helper;
2329         };
2330 
2331         //事表格可拖拽排序
2332         table.find("tbody")
2333             .sortable({
2334                 helper: fixHelper,
2335                 opacity: 0.5,
2336                 cursor: "move",
2337                 placeholder: "sortable-placeholder",
2338                 update: function (even, ui) {
2339                     even.stopPropagation();
2340                     prepareMove(ui.item.find(".moveable").closest("td"));
2341                 }
2342             });
2343 
2344         //弹出移动框
2345         table.find("a.pop-movable[rel=popover]")
2346             .mouseenter(function (e) {
2347                 var a = $(this);
2348                 a.popover("show");
2349                 var idInput = a.closest("tr").find(".id");
2350                 idInput.focus();
2351                 a.next(".popover").find(".popover-up-btn,.popover-down-btn").click(function() {
2352                     var fromId = $(this).closest("tr").prop("id");
2353                     var toId = idInput.val();
2354 
2355                     if(!/\d+/.test(toId)) {
2356                         $.app.alert({message : "请输入数字!"});
2357                         return;
2358                     }
2359 
2360                     var fromTD = $(this).closest("td");
2361 
2362                     if($(this).hasClass("popover-up-btn")) {
2363                         move(fromTD, fromId, toId, "up");
2364                     } else {
2365                         move(fromTD, fromId, toId, "down");
2366                     }
2367                 });
2368                 a.parent().mouseleave(function() {
2369                     a.popover("hide");
2370                 });
2371             });
2372 
2373         table.find(".up-btn,.down-btn").click(function() {
2374             var fromTR = $(this).closest("tr");
2375             if($(this).hasClass("up-btn")) {
2376                 fromTR.prev("tr").before(fromTR);
2377             } else {
2378                 fromTR.next("tr").after(fromTR);
2379             }
2380             prepareMove($(this).closest("td"));
2381         });
2382 
2383         /**
2384          *
2385          * @param fromTD
2386          */
2387         function prepareMove(fromTD) {
2388             var fromTR = fromTD.closest("tr");
2389             var fromId = fromTR.prop("id");
2390             var nextTR = fromTR.next("tr");
2391             if(nextTR.length) {
2392                 move(fromTD, fromId, nextTR.prop("id"), "down");
2393             } else {
2394                 var preTR = fromTR.prev("tr");
2395                 move(fromTD, fromId, preTR.prop("id"), "up");
2396             }
2397 
2398         }
2399         function move(fromTD, fromId, toId, direction) {
2400             if(!(fromId && toId)) {
2401                 return;
2402             }
2403             var order = $.movable.tdOrder(fromTD);
2404             if (!order) {
2405                 $.app.alert({message: "请首先排序要移动的字段!"});
2406                 return;
2407             }
2408             //如果升序排列 需要反转direction
2409             if(order == "desc") {
2410                 if(direction == "up") {
2411                     direction = "down";
2412                 } else {
2413                     direction = "up";
2414                 }
2415             }
2416             $.app.waiting("正在移动");
2417             var url = urlPrefix + "/" + fromId + "/" + toId + "/" + direction;
2418             $.getJSON(url, function(data) {
2419                 $.app.waitingOver();
2420                 if(data.success) {
2421                     $.table.reloadTable(fromTD.closest("table"));
2422                 } else {
2423                     $.app.alert({message : data.message});
2424                 }
2425 
2426             });
2427         }
2428     }
2429     ,
2430     initMovableReweight : function($btn, url) {
2431         $btn.click(function () {
2432             $.app.confirm({
2433                 message: "确定优化权重吗?<br/><strong>注意:</strong>优化权重执行效率比较低,请在本系统使用人员较少时执行(如下班时间)",
2434                 ok: function () {
2435                     $.app.waiting("优化权重执行中。。");
2436                     $.getJSON(url, function(data) {
2437                         $.app.waitingOver();
2438                         if(!data.success) {
2439                             $.app.alert({message : data.message});
2440                         } else {
2441                             location.reload();
2442                         }
2443                     });
2444                 }
2445             });
2446         });
2447     },
2448 
2449     tdOrder : function(td) {
2450         var tdIndex = td.closest("tr").children("td").index(td);
2451         return td.closest("table").find("thead > tr > th").eq(tdIndex).prop("order");
2452     }
2453 };
2454 
2455 $.btn = {
2456     initChangeStatus : function(urlPrefix, tableId, config) {
2457         $(config.btns.join(",")).each(function(i) {
2458             $(this).off("click").on("click", function() {
2459                 var $table = $("#" + tableId);
2460                 var checkbox = $.table.getAllSelectedCheckbox($table);
2461                 if(checkbox.size() == 0) {
2462                     return;
2463                 }
2464                 var title = config.titles[i];
2465                 var message = config.messages[i];
2466                 var status = config.status[i];
2467                 var url = urlPrefix + "/" + status + "?" + checkbox.serialize();
2468                 $.app.confirm({
2469                     title : title,
2470                     message : message,
2471                     ok : function() {
2472                         window.location.href = url;
2473                     }
2474                 });
2475             });
2476         });
2477     },
2478     /**
2479      * 初始化改变显示隐藏的btn
2480      */
2481     initChangeShowStatus : function(urlPrefix, tableId) {
2482         $.btn.initChangeStatus(urlPrefix, tableId, {
2483             btns : [".status-show", ".status-hide"],
2484             titles : ['显示数据', '隐藏数据'],
2485             messages : ['确认显示数据吗?', '确认隐藏数据吗?'],
2486             status : ['true', 'false']
2487         });
2488     }
2489 };
2490 
2491 $.array = {
2492     remove : function(array, data) {
2493         if(array.length == 0) {
2494             return;
2495         }
2496         for(var i = array.length - 1; i >= 0; i--) {
2497             if(array[i] == data) {
2498                 array.splice(i, 1);
2499             }
2500         }
2501     },
2502     contains : function(array, data) {
2503         if(array.length == 0) {
2504             return false;
2505         }
2506         for(var i = array.length - 1; i >= 0; i--) {
2507             if(array[i] == data) {
2508                 return true;
2509             }
2510         }
2511         return false;
2512     },
2513     indexOf : function(array, data) {
2514         if(array.length == 0) {
2515             return -1;
2516         }
2517         for(var i = array.length - 1; i >= 0; i--) {
2518             if(array[i] == data) {
2519                 return i;
2520             }
2521         }
2522         return -1;
2523     },
2524     clear : function(array) {
2525         if(array.length == 0) {
2526             return;
2527         }
2528         array.splice(0, array.length);
2529     },
2530     trim : function(array) {
2531         for(var i = array.length - 1; i >= 0; i--) {
2532             if(array[i] == "" || array[i] == null) {
2533                 array.splice(i, 1);
2534             }
2535         }
2536         return array;
2537     }
2538 
2539 };
2540 
2541 /*
2542  * Project: Twitter Bootstrap Hover Dropdown
2543  * Author: Cameron Spear
2544  * Contributors: Mattia Larentis
2545  *
2546  * Dependencies?: Twitter Bootstrap's Dropdown plugin
2547  *
2548  * A simple plugin to enable twitter bootstrap dropdowns to active on hover and provide a nice user experience.
2549  *
2550  * No license, do what you want. I'd love credit or a shoutout, though.
2551  *
2552  * http://cameronspear.com/blog/twitter-bootstrap-dropdown-on-hover-plugin/
2553  */
2554 ;(function($, window, undefined) {
2555     // outside the scope of the jQuery plugin to
2556     // keep track of all dropdowns
2557     var $allDropdowns = $();
2558 
2559     // if instantlyCloseOthers is true, then it will instantly
2560     // shut other nav items when a new one is hovered over
2561     $.fn.dropdownHover = function(options) {
2562 
2563         // the element we really care about
2564         // is the dropdown-toggle's parent
2565         $allDropdowns = $allDropdowns.add(this.parent());
2566 
2567         return this.each(function() {
2568             var $this = $(this).parent(),
2569                 defaults = {
2570                     delay: 100,
2571                     instantlyCloseOthers: true
2572                 },
2573                 data = {
2574                     delay: $(this).data('delay'),
2575                     instantlyCloseOthers: $(this).data('close-others')
2576                 },
2577                 settings = $.extend(true, {}, defaults, options, data),
2578                 timeout;
2579 
2580             $this.hover(function() {
2581                 if(settings.instantlyCloseOthers === true)
2582                     $allDropdowns.removeClass('open');
2583 
2584                 window.clearTimeout(timeout);
2585                 $(this).addClass('open');
2586             }, function() {
2587                 timeout = window.setTimeout(function() {
2588                     $this.removeClass('open');
2589                 }, settings.delay);
2590             });
2591         });
2592     };
2593 
2594     // apply dropdownHover to all elements with the data-hover="dropdown" attribute
2595     $(document).ready(function() {
2596         $('[data-hover="dropdown"]').dropdownHover();
2597     });
2598 })(jQuery, this);
2599 
2600 
2601 $(function () {
2602     //global disable ajax cache
2603     $.ajaxSetup({ cache: true });
2604 
2605     $(".table").each(function() {
2606         $.table.initTable($(this));
2607     });
2608     $.app.initDatetimePicker();
2609 
2610     $.layout = top.$.layout;
2611 //    $.app = top.$.app;
2612     $.tabs = top.$.tabs;
2613     $.menus = top.$.menus;
2614 
2615     $("[data-toggle='tooltip']").each(function() {
2616 
2617         $(this).tooltip({delay:300});
2618     });
2619 
2620 //    if(!$("body").is(".index")) {
2621 //        $("html").niceScroll({styler:"fb",cursorcolor:"#777", zindex:1});
2622 //    }
2623 
2624     $(document).ajaxError(function(event, request, settings) {
2625 
2626         $.app.waitingOver();
2627 
2628         if(request.status == 0) {// 中断的不处理
2629             return;
2630         }
2631 
2632         top.$.app.alert({
2633             title : "网络故障/系统故障",
2634             //<refresh>中间的按钮在ajax方式中删除不显示
2635             message : request.responseText.replace(/(<refresh>.*<\/refresh>)/g, "")
2636         });
2637     });
2638 });

 

posted @ 2015-05-05 22:47  javahuang  阅读(5770)  评论(0编辑  收藏  举报