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>>>查看所有通知</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">×</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 + "©=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,如<table move-url-prefix='/sample'><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 });