12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193 |
- /*
- TODO: can be dragged, DOM-Drag
- */
- ;(function($) {
- // if already load dialog, return directly
- if ($.dialog) {
- return;
- }
- var $window = $(window), $document = $(document);
- var ieBug = $.browser.msie && parseFloat($.browser.version) < 7;
- // jQuery doesn't support a is string judgement, so I made it by myself.
- function isString(obj) {
- return typeof obj == "string" || Object.prototype.toString.call(obj) === "[object String]";
- }
- // dialog list to manage the dialogs.
- var dialogList = [];
- dialogList.add = function($dialog) {
- this.push($dialog);
- return $dialog;
- };
- dialogList.remove = function($dialog) {
- var flag;
- for (var i = 0; i < this.length; i++) {
- if (this[i] == $dialog) {
- flag = true;
- }
- if (flag) {
- this[i] = this[i + 1];
- }
- }
- if (flag) {
- this.length--;
- }
- return $dialog;
- };
- // manage the window resize event.
- var resizeTimer;
- $window.resize(function() {
- window.clearTimeout(resizeTimer);
- resizeTimer = window.setTimeout(function() {
- for (var i = 0; i < dialogList.length; i++) {
- dialogList[i].adjust(false);
- }
- }, 100);
- });
- // manage the window scroll event for ie6.
- if (ieBug) {
- var scrollTimer;
- $window.scroll(function () {
- for (var i = 0; i < dialogList.length; i++) {
- dialogList[i].ieFixedHide();
- }
- window.clearTimeout(scrollTimer);
- scrollTimer = window.setTimeout(function() {
- for (var i = 0; i < dialogList.length; i++) {
- dialogList[i].ieFixedPos();
- }
- }, 400);
- });
- }
- // handle escape key to close dialog one by one.
- $document.keydown(function(event) {
- if (dialogList.length && event.keyCode == 27) {
- dialogList[dialogList.length - 1].close("cancel", event);
- }
- });
- // the basic dialog plugin
- $.dialog = function(settings) {
- var initializing = true;
- var defaults = {
- id: "",
- className: "",
- tip: false,
- direction: "top",
- title: "",
- content: "",
- labClose: null,
- titleClose: "关闭",
- btns: [],
- defaultBtn: "",
- labAccept: "纭畾",
- labCancel: "鍙栨秷",
- top: null,
- left: null,
- refer: null,
- fixed: true,
- scrollIntoView: true,
- contentWidth: null,
- contentHeight: null,
- contentBtnHelp: false,
- modal: true,
- onLoad: null,
- onBeforeAccept: null,
- onAccept: null,
- onBeforeCancel: null,
- onCancel: null,
- onBeforeClose: null,
- onClose: null
- };
- // give settings to UI elements
- var opts = $.extend(defaults, settings);
- opts.top = parseInt(opts.top);
- opts.left = parseInt(opts.left);
- opts.contentWidth = parseInt(opts.contentWidth);
- opts.contentHeight = parseInt(opts.contentHeight);
- // build button html template.
- var mapBtns = {
- "accept": '<button class="dialog-button-accept">' + opts.labAccept + '</button>',
- "cancel": '<button class="dialog-button-cancel">' + opts.labCancel + '</button>'
- };
- var templateBtns = "";
- if (opts.btns.length) {
- templateBtns += '<div class="dialog-button-container">';
- for (var i = 0 ; i < opts.btns.length; i++) {
- templateBtns += mapBtns[opts.btns[i]];
- }
- templateBtns += '</div>';
- }
- // build mask html template.
- var templateMask =
- '<div' + (opts.id ? (' id="' + opts.id + '-mask"') : '') + ' class="jquery-dialog-mask ' +
- (!$("div.jquery-dialog-mask").length ? "jquery-dialog-mask-color" : "jquery-dialog-mask-transparent") +
- (opts.className ? (' ' + opts.className + '-mask"') : '"') + '></div>';
- // build dialog html template.
- var templateDialog =
- '<div style="top: -10000px; left: -10000px;"' + (opts.id ? (' id="' + opts.id + '"') : '') + ' class="jquery-dialog ' +
- (!opts.fixed || ieBug ? 'dialog-outer-absolute' : 'dialog-outer-fixed') +
- (opts.tip ? ' jquery-tip' : '') + (opts.className ? (' ' + opts.className + '"') : '"') + '>' +
- (opts.tip ? '<div class="dialog-tip-arrow dialog-tip-arrow-' + opts.direction.toLowerCase() + '"></div>' : '') +
- '<div class="dialog-top-container">' +
- '<div class="dialog-top-left-corner"></div>' +
- '<div class="dialog-top-border"></div>' +
- '<div class="dialog-top-right-corner"></div>' +
- '</div>' +
- '<div class="dialog-middle-container">' +
- '<div class="dialog-left-border"></div>' +
- '<div class="dialog-inner-container">' +
- '<div class="dialog-title-container">' +
- '<div class="dialog-title">' + opts.title + '</div>' +
- '<div tabindex="0" class="dialog-button-close" title="' + opts.titleClose + '">' +
- (opts.labClose || '') +
- '</div>' +
- '</div>' +
- '<div class="dialog-content-container"></div>' + templateBtns +
- '</div>' +
- '<div class="dialog-right-border"></div>' +
- '</div>' +
- '<div class="dialog-bottom-container">' +
- '<div class="dialog-bottom-left-corner"></div>' +
- '<div class="dialog-bottom-border"></div>' +
- '<div class="dialog-bottom-right-corner"></div>' +
- '</div>' +
- '</div>';
- // append mask and dialog into document.
- var $body = $(document.body), $dialogInserter = $("#jquery-dialog-inserter");
- if (!$dialogInserter.length) {
- $dialogInserter = $('<div id="jquery-dialog-inserter"></div>');
- $dialogInserter.prependTo($body);
- }
- var $dialog = dialogList.add($(templateDialog));
- $dialog.data("jquery-dialog", $dialog);
- if (opts.modal) {
- $dialog.data("jquery-dialog-mask", $(templateMask).insertBefore($dialogInserter));
- }
- // set dom content into dialog
- var isNode = opts.content && !isString(opts.content) && (opts.content.parentNode || opts.content.jquery);
- if (isNode) {
- var $node = $(opts.content);
- var data = {
- el: $node[0],
- html: $node.html(),
- parent: $node.parent()[0],
- display: $node.css("display"),
- position: $node.css("position")
- };
- if (data.parent) {
- $node.remove();
- }
- $dialog.data("dialog.history", data);
- }
- $("div.dialog-content-container", $dialog).append(isNode ? $(opts.content).eq(0) : opts.content.toString());
- $dialog.insertBefore($dialogInserter);
- if (isNode) {
- $(opts.content).show();
- }
- // this method can remove dialog without any callback.
- $dialog.destroy = function() {
- // remove mask from dom
- dialogList.remove(this);
- if (opts.modal) {
- this.data("jquery-dialog-mask").removeShadow().remove();
- }
- // restore content node.
- var data = this.data("dialog.history");
- if (data && data.el) {
- var $node = $(data.el).css({"display": data.display, "position": data.position});
- if (data.parent) {
- $node.html(data.html).appendTo(data.parent);
- }
- this.removeData("dialog.history");
- }
- // remove dialog from dom.
- this.remove();
- };
- // add dialog close method.
- $dialog.close = function(state, event) {
- event = $.extend(event, {"state": state});
- if ($.isFunction(opts.onBeforeClose) && opts.onBeforeClose.call($dialog, event) === false) {
- return false;
- }
- // call destroy method
- this.destroy();
- if ($.isFunction(opts.onClose)) {
- opts.onClose(event);
- }
- if (state == "accept") {
- if ($.isFunction(opts.onAccept)) {
- opts.onAccept(event);
- }
- }
- else if (state == "cancel") {
- if ($.isFunction(opts.onCancel)) {
- opts.onCancel(event);
- }
- }
- return true;
- };
- // add adjust dialog size method.
- $dialog.adjust = function() {
- // adjust mask size
- var $mask = this.data("jquery-dialog-mask");
- if ($mask) {
- if (ieBug) {
- $mask.css("position", "absolute")
- .height(Math.max($body.boxHeight(), $window.height()))
- .width(Math.max($body.boxWidth(), $window.width()))
- .iShadow({position: "absolute", referPoint: "topleft"});
- }
- else {
- $mask
- .iShadow({position: "fixed", referPoint: "topleft"});
- }
- }
- if ((typeof arguments[0] == "undefined") || initializing) {
- var $contentContainer = $("div.dialog-content-container", this);
- if (!initializing) {
- $contentContainer.css({height: "auto"});
- }
- var $leftBorder = $("div.dialog-left-border", this);
- var $rightBorder = $("div.dialog-right-border", this);
- var $topBorder = $("div.dialog-top-border", this);
- var $bottomBorder = $("div.dialog-bottom-border", this);
- var $topLeftCorner = $("div.dialog-top-left-corner", this);
- var $topRightCorner = $("div.dialog-top-right-corner", this);
- var $bottomLeftCorner = $("div.dialog-bottom-left-corner", this);
- var $bottomRightCorner = $("div.dialog-bottom-right-corner", this);
- var $topContainer = $("div.dialog-top-container", this);
- var $midderContainer = $("div.dialog-middle-container", this);
- var $bottomContainer = $("div.dialog-bottom-container", this);
- var $innerContainer = $("div.dialog-inner-container", this);
- var $titleContainer = $("div.dialog-title-container", this);
- var $title = $("div.dialog-title", this);
- var $buttonClose = $("div.dialog-button-close", this);
- var $buttonContainer = $("div.dialog-button-container", this);
- // give the content a width or height define.
- var contentWidth = Math.max(
- (opts.contentWidth > 0 ? opts.contentWidth : Math.min($contentContainer.boxWidth(), $window.width() - $.scrollbarWidth())),
- opts.btns.length * 150
- );
- $contentContainer.boxWidth(contentWidth);
- var contentHeight = opts.contentHeight > 0 ? opts.contentHeight : $contentContainer.boxHeight();
- $contentContainer.boxHeight(contentHeight);
- // translate buttons inside content to iButton default style.
- if (opts.contentBtnHelp && $.fn.iButton) {
- $("input[type='button'], button", $contentContainer).iButton();
- }
- // set the title-container and button-container are sync with content width
- var contentBoxWidth = $contentContainer.boxWidth();
- $titleContainer.boxWidth(contentBoxWidth);
- $buttonContainer.boxWidth(contentBoxWidth);
- // adjust title and button layout.
- $title.boxWidth($titleContainer.width() - $buttonClose.boxWidth());
- if (initializing && $.fn.iButton) {
- $("input[type='button'], button", $buttonContainer).iButton();
- }
- // set the top-border and bottom-border width.
- var innerContainerBoxWidth = contentBoxWidth + $innerContainer.box("lr");
- $innerContainer.boxWidth(innerContainerBoxWidth);
- $topBorder.boxWidth(innerContainerBoxWidth);
- $bottomBorder.boxWidth(innerContainerBoxWidth);
- // set the left-border and right-border height.
- var innerContainerBoxHeight = $innerContainer.box("tb") + $contentContainer.boxHeight() +
- $titleContainer.boxHeight() + $buttonContainer.boxHeight();
- $leftBorder.boxHeight(innerContainerBoxHeight);
- $rightBorder.boxHeight(innerContainerBoxHeight);
- // give the top-c, middle-c and bottom-c a fixed width and height.
- $topContainer.width($topLeftCorner.boxWidth() + $topBorder.boxWidth() + $topRightCorner.boxWidth());
- $bottomContainer.width($bottomLeftCorner.boxWidth() + $bottomBorder.boxWidth() + $bottomRightCorner.boxWidth());
- $midderContainer
- .height(innerContainerBoxHeight)
- .width($leftBorder.boxWidth() + $innerContainer.boxWidth() + $rightBorder.boxWidth());
- // give the dialog a fixed width
- this.width($topContainer.boxWidth());
- }
- // calculate the center top and center left position
- if (initializing || opts.fixed) {
- var centerTop = Math.round(($window.height() - this.boxHeight()) / 2),
- centerLeft = Math.round(($window.width() - this.boxWidth()) / 2);
- }
- // calculate the dialog top and left position.
- var top = null, left = null;
- // ie6 fixed position.
- if (ieBug && opts.fixed) {
- top = $window.scrollTop() + (isNaN(opts.top) ? centerTop : opts.top );
- left = $window.scrollLeft() + (isNaN(opts.left) ? centerLeft : opts.left);
- }
- // for unfixed refer position.
- else if (!opts.fixed && opts.refer) {
- var offset = $(opts.refer).offset();
- top = offset.top + (opts.top || 0);
- left = offset.left + (opts.left || 0);
- }
- // for initialized unfixed dialog and always for fixed dialog
- else if (initializing || opts.fixed) {
- if (!opts.fixed) {
- centerTop = $window.scrollTop() + centerTop;
- centerLeft = $window.scrollLeft() + centerLeft;
- }
- top = isNaN(opts.top) ? centerTop : opts.top;
- left = isNaN(opts.left) ? centerLeft : opts.left;
- }
- if (top !== null) {
- this.css({"top": top + "px", "left": left + "px"});
- }
- // scroll into view control.
- if (initializing && !opts.fixed && opts.scrollIntoView) {
- this.scrollIntoView();
- }
- // give default button focus
- if (initializing) {
- if (opts.defaultBtn == "accept") {
- $(".dialog-button-accept", $buttonContainer).eq(0).focus();
- }
- else if (opts.defaultBtn == "cancel") {
- $(".dialog-button-cancel", $buttonContainer).eq(0).focus();
- }
- }
- return this;
- };
- // scroll dialog into view method.
- $dialog.scrollIntoView = function() {
- var pos = this.position(), scrollTop = $window.scrollTop(), scrollLeft = $window.scrollLeft();
- if (((pos.top < scrollTop) || (pos.top > $window.height() + scrollTop)) ||
- ((pos.left < scrollLeft) || (pos.left > $window.width() + scrollLeft))) {
- this[0].scrollIntoView();
- }
- };
- // ie fixed top method.
- $dialog.ieFixedPos = function() {
- if (ieBug && opts.fixed) {
- var top = isNaN(opts.top) ? Math.round(($window.height() - this.boxHeight()) / 2) : opts.top;
- var left = isNaN(opts.left) ? Math.round(($window.width() - this.boxWidth()) / 2) : opts.left;
- this.css({"top": top + $window.scrollTop() + "px",
- "left": left + $window.scrollLeft() + "px"});
- }
- return this;
- };
- // ie fixed hide method
- $dialog.ieFixedHide = function() {
- if (ieBug && opts.fixed) {
- this.css({"top": "-10000px", "left": "-10000px"});
- }
- return this;
- }
- /*
- init position and size for dialog.
- */
- $dialog.adjust(false);
- /*
- add event handlers for dialog.
- */
- $dialog
- .mouseover(function(event) {
- var $target = $(event.target);
- var fromElement = event.fromElement || event.relatedTarget;
- if ($target.is("div.dialog-button-close")) {
- $target.addClass("dialog-button-close-hover");
- }
- })
- .mouseout(function(event) {
- var $target = $(event.target);
- var toElement = event.toElement || event.relatedTarget;
- if ($target.is("div.dialog-button-close")) {
- $target.removeClass("dialog-button-close-hover");
- }
- })
- .click(function(event) {
- var $target = $(event.target);
-
- if ($target.is("div.dialog-button-close"))
- {
- $dialog.close("cancel");
- }else
- {
- var $btnAccept = $target.closest(".dialog-button-accept");
-
- var $btnCancel = $target.closest(".dialog-button-cancel");
- if ($btnAccept.length && $btnAccept.attr("data-disabled") != "true") {
- if ($.isFunction(opts.onBeforeAccept) &&
- opts.onBeforeAccept.call($dialog, $.extend(event, {"state": "accept"})) === false) {
- return;
- }
- $dialog.trigger("accept");
- }
- else if ($btnCancel.length && $btnCancel.attr("data-disabled") != "true") {
- if ($.isFunction(opts.onBeforeCancel) &&
- opts.onBeforeCancel.call($dialog, $.extend(event, {"state": "cancel"})) === false) {
- return;
- }
- $dialog.trigger("cancel");
- }
- else if ($target.is("div.dialog-button-close")) {
- $dialog.close("cancel");
- }
- }
-
- })
- .bind("accept", function() {
- $dialog.close("accept");
- })
- .bind("cancel", function() {
- $dialog.close("cancel");
- });
- if ($.isFunction(opts.onLoad)) {
- opts.onLoad.call($dialog);
- }
- initializing = false;
- return $dialog;
- };
- /* the jquery inform dialog */
- $.inform = function(settings) {
- var defaults = {
- icon: "",
- title: "",
- content: "",
- delay: 2000,
- easyClose: true,
- onClose: null
- };
- // give settings to UI elements
- var opts = $.extend(defaults, settings);
- // for icon class define.
- var content = $.isPlainObject(settings) ? opts.content : settings;
- if (opts.icon) {
- content = '<div class="' + opts.icon + '"></div><div class="dialog-content">' + content + '</div>';
- }
- var $inform = $.dialog({
- className: "jquery-inform",
- title: opts.title,
- content: content,
- onClose: opts.onClose
- });
- // bind close handler.
- var timer;
- if (opts.delay > 0) {
- timer = window.setTimeout(close, opts.delay);
- }
- if (opts.easyClose) {
- $document.bind("mouseup", close);
- }
- // close by timeout or click event.
- function close() {
- try{ $inform.close(); }catch(e){};
- window.clearTimeout(timer);
- if (opts.easyClose) {
- $document.unbind("mouseup", close);
- }
- };
- return $inform;
- };
- /* the jquery confirm dialog */
- $.alert = function(settings) {
- var defaults = {
- icon: "",
- title: "",
- content: "",
- labClose: "纭畾",
- onClose: null
- };
- // give settings to UI elements
- var opts = $.extend(defaults, settings);
- // for icon class define.
- var content = $.isPlainObject(settings) ? opts.content : settings;
- if (opts.icon) {
- content = '<div class="' + opts.icon + '"></div><div class="dialog-content">' + content + '</div>';
- }
- return $.dialog({
- className: "jquery-alert",
- btns: ["accept"],
- defaultBtn: "accept",
- labAccept: opts.labClose,
- title: opts.title,
- content: content,
- onClose: opts.onClose
- });
- };
- /* the jquery confirm dialog */
- $.confirm = function(settings) {
- var defaults = {
- icon: "",
- title: "",
- content: "",
- labConfirm: "纭畾",
- labCancel: "鍙栨秷",
- defaultBtn: "accept",
- onConfirm: null,
- onCancel: null
- };
- // give settings to UI elements
- var opts = $.extend(defaults, settings);
- // for icon class define.
- var content = $.isPlainObject(settings) ? opts.content : settings;
- if (opts.icon) {
- content = '<div class="' + opts.icon + '"></div><div class="dialog-content">' + content + '</div>';
- }
- return $.dialog({
- className: "jquery-confirm",
- btns: ["accept", "cancel"],
- defaultBtn: opts.defaultBtn,
- labAccept: opts.labConfirm,
- labCancel: opts.labCancel,
- title: opts.title,
- content: content,
- onAccept: opts.onConfirm,
- onCancel: opts.onCancel
- });
- };
- /*
- * jQuery tip plugins
- */
- // wrap the browser default getClientRects method to cross browser function.
- function getClientRects(target) {
- // create new wrapped rect objects.
- var rects = target.getClientRects();
- var newRects = [{"top": rects[0].top, "right": rects[0].right,
- "bottom": rects[0].bottom, "left": rects[0].left}];
- for (var i = 1, j = 0; i < rects.length; i++) {
- if (rects[i]) {
- // unit rects for IE6/IE7
- if ((newRects[j].right == rects[i].left &&
- newRects[j].bottom - newRects[j].top > Math.abs(newRects[j].top - rects[i].top)) ||
- (newRects[j].left == newRects[j].right)) {
- newRects[j].top = Math.min(newRects[j].top, rects[i].top);
- newRects[j].right = Math.max(newRects[j].right, rects[i].right);
- newRects[j].bottom = Math.max(newRects[j].bottom, rects[i].bottom);
- newRects[j].left = Math.min(newRects[j].left, rects[i].left);
- }
- else {
- newRects.push({"top": rects[i].top, "right": rects[i].right,
- "bottom": rects[i].bottom, "left": rects[i].left});
- j++;
- }
- }
- }
- // convert float position value to integer value for Firefox
- for (var i = 0; i < newRects.length; i++) {
- newRects[i].top = Math.round(newRects[i].top);
- newRects[i].right = Math.round(newRects[i].right);
- newRects[i].bottom = Math.round(newRects[i].bottom);
- newRects[i].left = Math.round(newRects[i].left);
- }
- return newRects;
- }
- /*
- * Extend a custom hover rect event plugin.
- * Because jQuery hover event doesn't work well for jQuery tip.
- */
- $.fn.hoverrect = function(mouseenter, mouseleave) {
- var pos = {x: 0, y: 0}, lastRect = {top: null, right: null, bottom: null, left: null};
- return this
- .mousemove(function(event) {
- if (pos.x == event.clientX && pos.y == event.clientY) {
- return;
- }
- pos.x = event.clientX;
- pos.y = event.clientY;
- // check rect by current mouse position.
- var rects = getClientRects(this), rect;
- for (var i = 0; i < rects.length; i++) {
- if (rects[i].left <= pos.x && rects[i].right >= pos.x &&
- rects[i].top <= pos.y && rects[i].bottom >= pos.y) {
- rect = rects[i];
- break;
- }
- }
- // rect which unders current mouse position has changed.
- if (rect && (lastRect.top !== rect.top || lastRect.right !== rect.right ||
- lastRect.bottom !== rect.bottom || lastRect.left !== rect.left)) {
- // mouse leave the last rect.
- if (lastRect.top !== null) {
- event.clientRect = lastRect;
- event.type = "mouseleaverect";
- if ($.isFunction(mouseleave)) {
- mouseleave.call(this, event);
- }
- }
- // mouse enter a new rect.
- lastRect = rect;
- event.clientRect = rect;
- event.type = "mouseenterrect";
- if ($.isFunction(mouseenter)) {
- mouseenter.call(this, event);
- }
- }
- })
- .mouseleave(function(event) {
- // mouse leave the last rect.
- event.clientRect = lastRect;
- event.type = "mouseleaverect";
- lastRect = {top: null, right: null, bottom: null, left: null};
- if ($.isFunction(mouseleave)) {
- mouseleave.call(this, event);
- }
- });
- };
- // build the tip arrow class string
- function buildArrowClass(direction) {
- return "dialog-tip-arrow dialog-tip-arrow-" + direction;
- }
- // calculate the tip location
- function calcTipPos(align, referRect, tipRect, offset) {
- var top = 0, left = 0;
- if (align == "top") {
- top = Math.round(referRect.top - tipRect.height - offset.y);
- left = Math.round(referRect.left + (referRect.width - tipRect.width) / 2 + offset.x);
- }
- else if (align == "bottom") {
- top = Math.round(referRect.top + referRect.height + offset.y);
- left = Math.round(referRect.left + (referRect.width - tipRect.width) / 2 + offset.x);
- }
- else if (align == "left") {
- top = Math.round(referRect.top + (referRect.height - tipRect.height) / 2 + offset.y);
- left = Math.round(referRect.left - tipRect.width - offset.x);
- }
- else if (align == "right") {
- top = Math.round(referRect.top + (referRect.height - tipRect.height) / 2 + offset.y);
- left = Math.round(referRect.left + referRect.width + offset.x);
- }
- return {top: top, left: left};
- }
- // alignTipToRect shared with $.tip() and $.fn.tip().
- function alignTipToRect($tip, rect, opts) {
- // get below help data info.
- var docElem = document.documentElement, body = document.body, $body = $(body);
- var winHeight = $window.height();
- var winWidth = $window.width();
- var scrollTop = window.pageYOffset || docElem.scrollTop;
- var scrollLeft = window.pageXOffset || docElem.scrollLeft;
- var clientTop = docElem.clientTop || body.clientTop || 0;
- var clientLeft = docElem.clientLeft || body.clientLeft || 0;
- // fill the referRect object.
- var referRect = {
- top: Math.round(rect.top + scrollTop - clientTop),
- left: Math.round(rect.left + scrollLeft - clientLeft),
- width: Math.round(rect.right - rect.left),
- height: Math.round(rect.bottom - rect.top)
- };
- // fill the tipRect object.
- var tipRect = {
- width: Math.round($tip.width()),
- height: Math.round($tip.height())
- };
- // fill the offset object.
- var offset = {x: opts.offsetX, y: opts.offsetY};
- // calculate the tip position by rectRect, tipRect and offset.
- var position = calcTipPos(opts.align, referRect, tipRect, offset);
- // get the scope top, left, bottom, right
- var scopeTop = (opts.scope === "viewport" ? scrollTop : 0) + 1;
- var scopeLeft = (opts.scope === "viewport" ? scrollLeft : 0) + 1;
- var scopeBottom = (opts.scope === "viewport" ? winHeight + scrollTop : Math.max($body.boxHeight(), winHeight)) - 1;
- var scopeRight = (opts.scope === "viewport" ? winWidth + scrollLeft : Math.max($body.boxWidth(), winWidth)) - 1;
- // reset arrow class by align option.
- var $arrow = $tip.find(".dialog-tip-arrow"), arrow = $arrow[0];
- arrow.className = buildArrowClass(alignMap[opts.align]);
- // the tip outside scope top, align to bottom
- if (opts.align == "top" && position.top < scopeTop) {
- position = calcTipPos("bottom", referRect, tipRect, offset);
- arrow.className = buildArrowClass("top");
- }
- // the tip outside scope bottom, align to top
- else if (opts.align == "bottom" && (position.top + tipRect.height) > scopeBottom) {
- position = calcTipPos("top", referRect, tipRect, offset);
- arrow.className = buildArrowClass("bottom");
- }
- // the tip outside scope left, align to right
- else if (opts.align == "left" && position.left < scopeLeft) {
- position = calcTipPos("right", referRect, tipRect, offset);
- arrow.className = buildArrowClass("left");
- }
- // the tip outside scope right, align to left
- else if (opts.align == "right" && (position.left + tipRect.width) > scopeRight) {
- position = calcTipPos("left", referRect, tipRect, offset);
- arrow.className = buildArrowClass("right");
- }
- // limit the tip and tip-arrow position.
- var minTop = scrollTop + 1,
- minLeft = scrollLeft + 1,
- maxTop = winHeight + scrollTop - tipRect.height - 1,
- maxLeft = winWidth + scrollLeft - tipRect.width - 1,
- tipTop = position.top,
- tipLeft = position.left;
- // set the tip arrow position.
- if (opts.align == "top" || opts.align == "bottom") {
- tipLeft = Math.max(Math.min(tipLeft, maxLeft), minLeft);
- $arrow.css({"left": Math.round((tipRect.width - $arrow.width()) / 2) - (tipLeft - position.left) + "px"});
- }
- else if (opts.align == "left" || opts.align == "right") {
- tipTop = Math.max(Math.min(tipTop, maxTop), minTop);
- $arrow.css({"top": Math.round((tipRect.height - $arrow.height()) / 2) - (tipTop - position.top) + "px"});
- }
- // set the tip dialog position.
- $tip.css({"top": tipTop + "px", "left": tipLeft + "px"});
- }
- // setTipContent shared with $.tip() and $.fn.tip().
- function setTipContent($tip, content) {
- var top = $tip.css("top");
- var left = $tip.css("left");
- $tip.css({"top": "-10000px", "left": "-10000px"}).show();
- $tip.find(".dialog-content-container").html(content).css("width", "auto");
- $tip.find(".dialog-inner-container").css("width", "auto");
- $tip.find(".dialog-middle-container").css("width", "auto");
- $tip.css("width", "auto");
- $tip.adjust();
- $tip.css({"top": top, "left": left});
- }
- // $.tip(): jQuery tip plugin.
- var alignMap = {"top": "bottom", "right": "left", "bottom": "top", "left": "right"};
- $.tip = function(settings) {
- var defaults = {
- id: "",
- className: "",
- title: "",
- content: "",
- labClose: null,
- titleClose: "鍏抽棴",
- btns: [],
- defaultBtn: "",
- labAccept: "纭畾",
- labCancel: "鍙栨秷",
- contentWidth: null,
- contentHeight: null,
- contentBtnHelp: false,
- modal: false,
- onLoad: null,
- onBeforeAccept: null,
- onAccept: null,
- onBeforeCancel: null,
- onCancel: null,
- onBeforeClose: null,
- onClose: null
- };
- var opts = $.extend(defaults, settings);
- // create the tip widget.
- var $tip = $.dialog({
- tip: true,
- fixed: false,
- scrollIntoView: false,
- top: -10000,
- left: -10000,
- id: opts.id,
- className: opts.className,
- title: opts.title,
- content: opts.content,
- labClose: opts.labClose,
- titleClose: opts.titleClose,
- btns: opts.btns,
- defaultBtn: opts.defaultBtn,
- labAccept: opts.labAccept,
- labCancel: opts.labCancel,
- contentWidth: opts.contentWidth,
- contentHeight: opts.contentHeight,
- contentBtnHelp: opts.contentBtnHelp,
- modal: opts.modal,
- onLoad: opts.onLoad,
- onBeforeAccept: opts.onBeforeAccept,
- onAccept: opts.onAccept,
- onBeforeCancel: opts.onBeforeCancel,
- onCancel: opts.onCancel,
- onBeforeClose: opts.onBeforeClose,
- onClose: opts.onClose
- })
- .hide();
- /*
- * tip.align(): adjust tip position.
- */
- $tip.align = function(settings) {
- if (!this.is(":visible")) {
- return this;
- }
- // fill the options object.
- var opts;
- if (typeof settings === "undefined") {
- opts = this.data("tip-settings");
- }
- else {
- var defaults = {
- scope: "viewport",
- align: "bottom",
- refer: null,
- referRect: null,
- offsetX: 0,
- offsetY: 0
- };
- // align setting.
- opts = $.extend(defaults, settings);
- // tip align map object.
- opts.align = opts.align.toLowerCase();
- if (!alignMap[opts.align]) {
- opts.align = defaults.align;
- }
- // save current setting to tip's data.
- this.data("tip-settings", opts);
- }
- // align the tip.
- alignTipToRect(this, opts.referRect ? opts.referRect : getClientRects($(opts.refer)[0])[0], opts);
- return this;
- };
- /*
- * tip.content(): get or set content of tip widget.
- */
- $tip.content = function(content) {
- if (typeof content == "undefined") {
- return this.find(".dialog-content-container").html();
- }
- else {
- var isVisible = this.is(":visible");
- setTipContent(this, content);
- // align tip position or restore hide states.
- if (!isVisible) {
- this.hide();
- }
- return this;
- }
- };
- return $tip;
- };
- /*
- * $(selector).tip: jQuery tip plugin.
- */
- $.fn.tip = function(settings) {
- var defaults = {
- hover: true,
- enterable: false,
- enterableDelay: 100,
- show: null,
- hide: null,
- scope: "viewport",
- align: "bottom",
- offsetX: 0,
- offsetY: 0,
- id: "",
- className: "",
- content: "",
- contentWidth: null,
- contentHeight: null
- };
- // give settings to UI elements
- var opts = $.extend(defaults, settings);
- // tip align map object.
- opts.align = opts.align.toLowerCase();
- if (!alignMap[opts.align]) {
- opts.align = defaults.align;
- }
- // handler code.
- return this.each(function() {
- // initialize the tip widget.
- var $refer = $(this),
- $tip = $refer.data("tip");
- if ($tip) {
- return;
- }
- // create the tip widget and save it to its data "tip".
- $tip = $.dialog({
- tip: true,
- modal: false,
- fixed: false,
- top: -10000,
- left: -10000,
- id: opts.id,
- className: opts.className,
- content: opts.content,
- contentWidth: opts.contentWidth,
- contentHeight: opts.contentHeight
- })
- .hide();
- $refer.data("tip", $tip);
- // auto hover show up.
- if (opts.hover) {
- // tip hide and show event handler.
- function hideTip(event) {
- if ($.isFunction(opts.hide)) {
- opts.hide.call($tip, event);
- }
- else {
- $tip.hide();
- }
- }
- function showTip(event) {
- $tip.data("tip-refer-rect", event.clientRect);
- if ($.isFunction(opts.show)) {
- opts.show.call($tip, event);
- }
- else {
- $tip.show();
- }
- $tip.data("tip-refer-rect", null);
- }
- // timer for tip enterable feature.
- var timer = null;
- function cancelledHideTip() {
- if (timer) {
- window.clearTimeout(timer);
- timer = null;
- return true;
- }
- else {
- return false;
- }
- }
- function delayedHideTip(event) {
- timer = window.setTimeout(function() {
- timer = null;
- hideTip(event);
- }, opts.enterableDelay);
- }
- // hover to show the tip.
- if (opts.enterable) {
- $tip.hover(cancelledHideTip, delayedHideTip);
- }
- var lastRect;
- $refer.hoverrect(
- function(event) {
- var rect = event.clientRect;
- // Igonre hidden only for the same rect.
- if (!cancelledHideTip() && lastRect &&
- lastRect.top == rect.top && lastRect.right == rect.right &&
- lastRect.bottom == rect.bottom && lastRect.left == rect.left) {
- showTip(event);
- }
- else {
- cancelledHideTip();
- showTip(event);
- }
- },
- function(event) {
- lastRect = event.clientRect;
- if (opts.enterable) {
- delayedHideTip(event);
- }
- else {
- hideTip(event);
- }
- }
- );
- }
- /*
- * fn.tip.algin(): adjust tip position.
- */
- $tip.align = function () {
- if (!this.is(":visible")) {
- return this;
- }
- var rect = this.data("tip-refer-rect");
- if (!rect) {
- rect = getClientRects($refer[0])[0];
- }
- // align the tip.
- alignTipToRect(this, rect, opts);
- return this;
- };
- /*
- * fn.tip.show(): inject code to the default jQuery show method.
- */
- var funShow = $tip.show;
- $tip.show = function(speed) {
- funShow.call(this);
- this.align();
- // for speed animation effect.
- if (speed || speed === 0) {
- this.hide();
- funShow.apply(this, arguments);
- }
- return this;
- };
- /*
- * fn.tip.fadeIn(): inject code to the default jQuery fadeIn method.
- */
- var funFadeIn = $tip.fadeIn;
- $tip.fadeIn = function() {
- funShow.call(this);
- this.align().hide();
- funFadeIn.apply(this, arguments);
- return this;
- };
- /*
- * fn.tip.content(): get or set content of tip widget.
- */
- $tip.content = function(content) {
- if (typeof content == "undefined") {
- return this.find(".dialog-content-container").html();
- }
- else {
- var isVisible = this.is(":visible");
- setTipContent(this, content);
- // align tip position or restore hide states.
- if (isVisible) {
- this.align();
- }
- else {
- this.hide();
- }
- return this;
- }
- };
- });
- };
- })(jQuery);
|