Created
June 2, 2014 07:59
-
-
Save manusa/e94dbcb4342b4a4643f3 to your computer and use it in GitHub Desktop.
Modified version of script-jq.js fo wicketstuff InMethodGrid (https://github.com/wicketstuff/core/tree/master/jdk-1.7-parent/inmethod-grid-parent)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Copyright (c) 2007 Matej Knopp, InMethod s.r.o. | |
* All rights reserved. | |
*/ | |
if (typeof(InMethod) === "undefined") { | |
InMethod = { }; | |
} | |
(function() { | |
var empty = function() { }; | |
var genIdCounter = 0; | |
/** | |
* YAHOO event cleanups the listeners only on page unload. However, if the page lives long | |
* enough the elements removed from document that have listener attached cause IE GC not free the | |
* memory. So we manually register each element with listener and then periodically check | |
* whether the element is still in document. If it's not the element's listeners are removed. | |
*/ | |
var elementsWithListeners = new Array(); | |
var addListener = function(element, event, fn, obj, override) { | |
// attach event | |
$(element).on(event, obj, fn); | |
if (element !== document && element !== window) { | |
elementsWithListeners.push(element); | |
} | |
}; | |
// temporary array of elements being processed during purge | |
var beingPurged = null; | |
// count of purged elements (debug) | |
var purgedCount = 0; | |
var purgeDebug = false; | |
// periodically called to initiate the purging process | |
var purgeInactiveListeners = function() { | |
// if purge is in progress don't do anything | |
if (typeof beingPurged !== 'undefined' && beingPurged !== null) { | |
return; | |
} | |
// the the elements | |
beingPurged = elementsWithListeners; | |
elementsWithListeners = new Array(); | |
if (purgeDebug) | |
Wicket.Log.info("Purge begin"); | |
purgedCount = 0; | |
// start the process | |
purge(); | |
}; | |
var purge = function() | |
{ | |
if (typeof beingPurged !== 'undefined' && beingPurged !== null) { | |
var done = 0; | |
// it is necessary to limit amount of items being purged in one go otherwise | |
// IE will complain about script being slow | |
var max = 50; | |
var a = beingPurged; | |
for (var i = 0; i < a.length && done < max; ++i) | |
{ | |
var e = a[i]; | |
if (e !== null) | |
{ | |
++done; | |
if ($(e).length === 0) { | |
// remove all events. | |
$(e).off(); | |
++purgedCount; | |
} else { | |
// element is still in document, return it | |
elementsWithListeners.push(e); | |
} | |
a[i] = null; | |
} | |
} | |
if (i === a.length) | |
{ | |
// we are done with purging | |
beingPurged = null; | |
if (purgeDebug) | |
Wicket.Log.info("Purge End; purged: " + purgedCount + ", total: " + elementsWithListeners.length); | |
} | |
else | |
{ | |
// not yet done, continue after 50ms | |
window.setTimeout(purge, 50); | |
} | |
} | |
}; | |
/** | |
* Prelight functionality | |
*/ | |
// map of elements with prelight | |
var curPrelight = new Object(); | |
var mouseIn = function(ev, instance) { | |
var e = this; | |
// if the old and new prelight are not related in any way make sure that | |
// the prelight is disabled on the old ones | |
for (property in curPrelight) { | |
var id = curPrelight[property]; | |
if (id) { | |
var c = Wicket.$(id); | |
if (c != null && $(e).parents().index($(c))==0 && $(c).parents().index($(e))==0) { | |
Wicket.bind(mouseOut,c)(null, instance); | |
} | |
} | |
} | |
var id = getElementId(e); | |
curPrelight[id] = id; | |
e.imxtPrelight = true; | |
if(ev !== null) { | |
ev.data.updatePrelight(e); | |
} else if(instance !== null) { | |
instance.updatePrelight(e); | |
} | |
}; | |
var mouseOut = function(ev, instance) { | |
var e = this; | |
curPrelight[getElementId(e)] = null; | |
e.imxtPrelight = false; | |
ev.data.updatePrelight(e); | |
}; | |
var ignorePrelight = function(element) | |
{ | |
// We need to ignore prelight on table rows for all browsers but IE<=6. | |
// For all other browsers we use :hover, it's much faster in IE7 | |
return !(element.tagName.toLowerCase() === "tr" && Wicket.Browser.isIELessThan7()) && hasClass(element, "imxt-grid-row"); | |
} | |
var attachPrelight = function(elements, instance) { | |
for (var i = 0; i < elements.length; ++i) { | |
var element = elements[i]; | |
if (element.imxtPrelightAttached !== true && !ignorePrelight(element)) { | |
if (curPrelight != null && curPrelight[getElementId(element)] != null) { | |
Wicket.bind(mouseIn,element)(null, instance); | |
} | |
addListener(element, "mouseover", mouseIn, instance, false); | |
addListener(element, "mouseout", mouseOut, instance, false); | |
element.imxtPrelightAttached = true; | |
} | |
} | |
}; | |
window.setInterval(purgeInactiveListeners, 10000); | |
$(window).on("unload", function() { elementsWithListeners = null; }); | |
var getElementId = function(element) { | |
if (typeof(element.getAttribute("id")) === "string" && element.getAttribute("id").length > 0) { | |
return element.getAttribute("id"); | |
} else { | |
var id = "imxt-generated-id-" + (++genIdCounter); | |
element.setAttribute("id", id); | |
return id; | |
} | |
}; | |
InMethod.Drag = Wicket.Class.create(); | |
InMethod.Drag.prototype = { | |
initialize: function(element, onDragBegin, onDragEnd, onDrag, thisRef) { | |
this.elementId = getElementId(element); | |
this.onDragBegin = onDragBegin || empty; | |
this.onDrag = onDrag || empty; | |
this.onDragEnd = onDragEnd || empty; | |
this.thisRef = thisRef || new Object(); | |
this.noTree = null; | |
addListener(element, "mousedown", this.onMouseDown, this, true); | |
element.imDrag = this; | |
}, | |
onMouseDown: function(e) { | |
if (typeof(e.ignore) === "undefined") { | |
e.stopPropagation(); | |
e.data.lastMouseX = e.clientX; | |
e.data.lastMouseY = e.clientY; | |
addListener(document, "selectstart", e.data.onSelectStart); | |
addListener(document, "mousemove", e.data.onMouseMove, e.data, true); | |
addListener(document, "mouseup", e.data.onMouseUp, e.data, true); | |
Wicket.bind(e.data.onDragBegin,e.data.thisRef)(Wicket.$(e.data.elementId), e); | |
} | |
return false; | |
}, | |
onMouseMove: function(e) { | |
e.stopPropagation(); | |
// this happens sometimes in Safari | |
if (e.clientX < 0 || e.clientY < 0) { | |
return; | |
} | |
var deltaX = e.clientX - e.data.lastMouseX; | |
var deltaY = e.clientY - e.data.lastMouseY; | |
var res = Wicket.bind(e.data.onDrag,e.data.thisRef)(Wicket.$(e.data.elementId), deltaX, deltaY, e); | |
if (typeof res === 'undefined' || res === null){ | |
res = [0, 0]; | |
} | |
e.data.lastMouseX = e.clientX + res[0]; | |
e.data.lastMouseY = e.clientY + res[1]; | |
return false; | |
}, | |
onMouseUp: function(e) { | |
e.stopPropagation(); | |
// cleanup | |
$(document).off("selectstart", e.data.onSelectStart); | |
$(document).off("mousemove", e.data.onMouseMove); | |
$(document).off("mouseup", e.data.onMouseUp); | |
Wicket.bind(e.data.onDragEnd,e.data.thisRef)(Wicket.$(e.data.elementId), e); | |
return false; | |
}, | |
onSelectStart: function(e) { | |
return false; | |
}, | |
cleanUp: function() { | |
$(Wicket.$(this.elementId)).off("mousedown"); | |
this.element = null; | |
this.onDragBegin = null; | |
this.onDrag = null; | |
this.onDragEnd = null; | |
this.thisRef = null; | |
} | |
}; | |
var colSpanRegex = /imxt-colspan-([\d]+)/; | |
var nextSibling = function(element) { | |
return $(element).next(element.tagName)[0]; | |
}; | |
var prevSibling = function(element) { | |
return $(element).prev(element.tagName)[0]; | |
}; | |
var hasClass = function(e, c) { | |
return $(e).hasClass(c); | |
}; | |
var addClass = function(e, c) { | |
$(e).addClass(c); | |
}; | |
var removeClass = function(e, c) { | |
$(e).removeClass(c); | |
}; | |
var contains = function(array, value) { | |
for (var i = 0; i < array.length; ++i) { | |
if (array[i] == value) { | |
return true; | |
} | |
} | |
return false; | |
}; | |
var isEmpty = function(string) { | |
return !(typeof string === 'string' && string.length > 0); | |
} | |
var getChildren = function(parent, tagName) { | |
if ($.isArray(tagName)) { | |
return $(parent).children(tagName.toString()); | |
} else { | |
return $(parent).children(tagName); | |
} | |
}; | |
var arrayEq = function(a1, a2) { | |
if (!$.isArray(a1) || !$.isArray(a2)) { | |
return false; | |
} | |
if (a1 == a2) { | |
return true; | |
} | |
if (a1.length != a2.length) { | |
return false; | |
} | |
for (var i = 0; i < a1.length; ++i) { | |
if (a1[i] != a2[i]) { | |
return false; | |
} | |
} | |
return true; | |
}; | |
var getFirstChild = function(parent, tagName) { | |
for (var i = 0; i < parent.childNodes.length; ++i) { | |
var c = parent.childNodes[i]; | |
if (c && c.tagName == tagName) { | |
return c; | |
} | |
} | |
return null; | |
} | |
Wicket.Browser.isIE9 = Wicket.Browser.isIE9 || function() { | |
var index = window.navigator.userAgent.indexOf("MSIE"); | |
var version = parseFloat(window.navigator.userAgent.substring(index + 5)); | |
return Wicket.Browser.isIE() && version == 9; | |
}; | |
// Issue #44: | |
// This bug can also be triggered when hiding a modal dialog or similar and the behind the dialog is a grid which | |
// would be hovered at that moment. | |
function globalIE9HoverLayoutFix() { | |
$(".imxt-body-container2").css({ | |
"overflow" : "auto" | |
}); | |
} | |
if (Wicket.Browser.isIE9()) | |
Wicket.Event.subscribe('/ajax/call/complete', globalIE9HoverLayoutFix); | |
InMethod.XTable = Wicket.Class.create(); | |
InMethod.XTable.prototype = { | |
initialize: function(id, columnsData, columnsStateCallback) { | |
this.id = id; | |
//Store browser version in variables, calls to Wicket.Browser methods burn CPU. | |
this.isIE = Wicket.Browser.isIE(); | |
this.isIEQuirks = Wicket.Browser.isIEQuirks(); | |
this.isIELessThan7 = Wicket.Browser.isIELessThan7(); | |
this.isGecko = Wicket.Browser.isGecko(); | |
this.isOpera = Wicket.Browser.isOpera(); | |
this.isSafari = Wicket.Browser.isSafari(); | |
this.initColumns(columnsData); | |
this.attachEventHandlers(); | |
this.prevColumnWidths = null; | |
this.updateScrollTop = this.lastScrollTop; | |
this.updateScrollLeft = this.lastScrollLeft; | |
//this.updateColumnWidths(); | |
this.update(); | |
this.columnsStateCallback = columnsStateCallback; | |
// IE needs update called twice, otherwise the top right corner flashes or there is a horizontal | |
// scrollbar where it shouldn't be | |
if (this.isIE && !this.isIEQuirks) { | |
var bodyContainer1 = this.getElement("div", "imxt-body-container1"); | |
bodyContainer1.imxtOldOffsetWidth = null; | |
this.update(); | |
} | |
if (this.isIE) { | |
addClass(Wicket.$(id), "imxt-ie"); | |
} else if (this.isGecko) { | |
addClass(Wicket.$(id), "imxt-ff"); | |
} else if (this.isSafari){ | |
addClass(Wicket.$(id), "imxt-safari"); | |
} | |
this.updateSelectCheckBoxes(); | |
this.initCells(this.getBodyTable()); | |
}, | |
initColumns: function(columnsData) { | |
var r = this.getColumnsRow(); | |
var ths = getChildren(r, "TH"); | |
for (var i = 0; i < columnsData.length && i < ths.length; ++i) { | |
var c = columnsData[i]; | |
var th = ths[i]; | |
th.imxtMinSize = c.minSize; | |
th.imxtMaxSize = c.maxSize; | |
th.imxtId = c.id; | |
th.imxtResizable = c.resizable; | |
th.imxtReorderable = c.reorderable; | |
} | |
}, | |
/** | |
* Returns the element that contains the XTable | |
*/ | |
getTopContainer: function() { | |
return Wicket.$(this.id); | |
}, | |
/** | |
* Returns the table that contains header (part that doesn't scroll vertically, e.g. columns) | |
*/ | |
getHeadTable: function() { | |
return this.getElement("table", "imxt-head"); | |
}, | |
/** | |
* Returns the table that contains the body (part that scrolls vertically) | |
*/ | |
getBodyTable: function() { | |
return this.getElement("table", "imxt-body"); | |
}, | |
/** | |
* Returns the elements that have specified tagName and css class. | |
* Optionally root parameter can narrow the searching scope. | |
* @param tagName | |
* @param className | |
* @param root | |
*/ | |
getElements: function(tagName, className, root) { | |
if (typeof(root) === "undefined") | |
root = this.getTopContainer(); | |
if (typeof className === 'undefined' || className === null) { | |
return $(root).find(tagName); | |
} else { | |
var selector = tagName + '.' + className; | |
return $(root).find(selector); | |
} | |
}, | |
/** | |
* Mapping between cacheId and real Id. We need caching because retrieving the elements | |
* based on the CSS class name is relative expensive. So once we retrieve en element | |
* (single component, not a group of components), we set it's id to generated id that | |
* can be used to retrieve the element quickly. If element has already id set, we use | |
* idCache to map between elementId (real Id) and the generatedId (cacheId). | |
*/ | |
idCache: new Object(), | |
/** | |
* Constructs cache id unique for this XTable. | |
* @param suffix | |
*/ | |
getCacheId: function(suffix) { | |
return "imxt-" + this.id + "-" + suffix; | |
}, | |
/** | |
* Returns element with specified id. If the element can't be found based on the id, | |
* it calls getElementFunc to find the element and then either sets element id or | |
* put a mapping to real id to idCache. | |
* @param id | |
* @param {function} getElementFunc | |
*/ | |
getElementCached: function(id, getElementFunc) { | |
var actualId = this.idCache[id] || id; | |
var e = Wicket.$(actualId); | |
if (typeof e === 'undefined' || e === null) { | |
e = getElementFunc(); | |
actualId = e.getAttribute("id"); | |
if (!isEmpty(actualId)) { | |
this.idCache[id] = actualId; | |
} else { | |
e.setAttribute("id", id); | |
} | |
} | |
return e; | |
}, | |
/** | |
* Returns element in this XTable with specified tagName and className, | |
* optionally narrowing the search scope with the root parameter. | |
* @param tagName | |
* @param className | |
* @param root | |
*/ | |
getElement: function(tagName, className, root) { | |
var id = this.getCacheId(className); | |
return this.getElementCached(id, Wicket.bind(function() { | |
return this.getElements(tagName, className, root)[0]; | |
},this)); | |
}, | |
/** | |
* Returns array of the TR elements inside the head table. | |
*/ | |
getHeadRows: function() { | |
var id = this.getCacheId("head-first-row"); | |
var firstRow = this.getElementCached(id, Wicket.bind(function() { | |
var head = this.getHeadTable(); | |
return head.getElementsByTagName("tr")[0]; | |
},this)); | |
return getChildren(firstRow.parentNode, "TR"); | |
}, | |
/** | |
* Returns array of the TR elements inside the body table. | |
*/ | |
getBodyRows: function() { | |
var id = this.getCacheId("body-first-row"); | |
var firstRow = this.getElementCached(id, Wicket.bind(function() { | |
var body = this.getBodyTable(); | |
return body.getElementsByTagName("tr")[0]; | |
},this)); | |
return getChildren(firstRow.parentNode, "TR"); | |
}, | |
/** | |
* Returns the TR element that contains column headers. | |
*/ | |
getColumnsRow: function() { | |
return this.getElement("tr", "imxt-columns", this.getHeadTable()); | |
}, | |
updateSelectCheckBoxes: function() { | |
var head = this.getElements("input", "imxt-select", this.getHeadTable()); | |
if (head.length > 0) { | |
var body = this.getElements("input", "imxt-select", this.getBodyTable()); | |
var selected = body.length > 0; | |
for (var i = 0; i < body.length; ++i) { | |
if (body[i].checked != true) { | |
selected = false; | |
break; | |
} | |
} | |
for (var i = 0; i < head.length; ++i) { | |
head[i].checked = selected; | |
} | |
} | |
}, | |
/** | |
* Returns array of column width strings. | |
* E.g. ["100px", "300px", "250px"]; | |
*/ | |
getColumnWidths: function() { | |
var row = this.getColumnsRow(); | |
var ths = getChildren(row, "TH"); | |
var res = new Array(); | |
for (var i = 0; i < ths.length; ++i) { | |
res.push(ths[i].offsetWidth); | |
} | |
return res; | |
}, | |
/** | |
* Updates the widths of columns in table body according to the headers | |
*/ | |
updateColumnWidths: function() { | |
var widths = this.getColumnWidths(); | |
var scroll; | |
if (this.isOpera) { | |
// for some reason opera doesn't preserve the scroll offset | |
bodyContainer1 = this.getElement("div", "imxt-body-container1"); | |
scroll = bodyContainer1.scrollLeft; | |
} | |
if (arrayEq(this.prevColumnWidths, widths) == false) { | |
var header = this.getColumnsRow(); | |
var rows = this.getBodyRows(); | |
if (rows.length > 0) { | |
var first = rows[0]; | |
var ths = getChildren(header, "TH"); | |
var tds = getChildren(first, "TD"); | |
for (var i = 0; i < ths.length - 2; ++i) { | |
var h = ths[i]; | |
var r = tds[i]; | |
var width = widths[i] + "px"; | |
// opera fails to refresh the table properly, so we need to hide it and show | |
// after the width is set, that way it's refreshed properly | |
if (r.style.width != width) { | |
if (this.isOpera) | |
this.getBodyTable().style.display = "none"; | |
r.style.width = width; | |
} | |
if (this.isOpera) { | |
this.getBodyTable().style.display = ""; | |
} | |
} | |
} | |
this.prevColumnWidths = widths; | |
// When there is horizontal scrollbar present firefox flickers on ajax replacement. | |
// The reason is that when the table is rendered the data columns have zero size, thus the scrollbar is not visible. | |
// Only in updateColumnWidths the column sizes are set and the scrollbar is displayed. However, this is too late for | |
// firefox and in some cases in shifts the content after the table and immediately moves it back which results in nasty | |
// flicker. This fix creates a style rule for imxt-body-cotnainer2 that forces it to have width of body table, so the | |
// scrollbar is immediately visible (if necessary) after ajax replacement. | |
if (this.isGecko) { | |
var c2 = this.getElement("div", "imxt-body-container2"); | |
c2.style.width="auto"; // we want the stylesheet rule only applied on fresh replaced component | |
var x = document.styleSheets[0]; | |
if (this.cssRulePos != null) { | |
x.deleteRule(this.cssRulePos); | |
} | |
this.cssRulePos = x.cssRules.length; | |
x.insertRule('div#' + this.id + ' div.imxt-body-container2 {width: ' + this.getBodyTable().offsetWidth + 'px}', this.cssRulePos) | |
var c1 = this.getElement("div", "imxt-body-container1"); | |
// sometimes firefox displays "fake" horizontal scrollbar, this is a workaround | |
if (c1.scrollWidth <= c1.offsetWidth) { | |
c1.style.overflowX = "hidden"; | |
} else { | |
c1.style.overflowX = "scroll"; | |
} | |
} | |
} | |
if (this.isOpera) { | |
bodyContainer1 = this.getElement("div", "imxt-body-container1"); | |
bodyContainer1.scrollLeft = scroll; | |
} | |
}, | |
/** | |
* Updates the table state | |
* @param force | |
*/ | |
updateInternal: function(force) { | |
//This Function is run periodically, old calls to Wicket.Browser burnt CPU in | |
//newest chrome versions. | |
var topContainer = this.getTopContainer(); | |
if (topContainer == null) { | |
// the table was probably removed | |
return false; | |
} | |
var head = this.getHeadTable(); | |
var body = this.getBodyTable(); | |
var headContainer1 = this.getElement("div", "imxt-head-container1"); | |
var headContainer2 = this.getElement("div", "imxt-head-container2"); | |
var bodyContainer1 = this.getElement("div", "imxt-body-container1"); | |
if (this.isIE || this.isGecko) { | |
bodyContainer1.style.width = topContainer.offsetWidth + "px"; | |
} | |
var padding = (bodyContainer1.offsetWidth - bodyContainer1.clientWidth); | |
// count new header width | |
var newWidth = (body.offsetWidth + padding); | |
// sometimes newWidth is negative in IE, we have to ignore it | |
if (this.isIE&& newWidth > 0 && head.style.width != newWidth) { | |
head.style.width = newWidth + "px"; | |
} else if (this.isSafari) { | |
var form = this.getElement("*", "imxt-form"); | |
var fieldset = this.getElement("fieldset", "imxt-fieldset", form); | |
fieldset.style.width = form.offsetWidth + "px"; | |
} | |
if (padding > 0) { | |
// compensate for scrollbar | |
var e = this.getElement("th", "imxt-padding-right", head); | |
e.style.width = padding + "px"; | |
} | |
this.updateHandles(force); | |
this.updateColumnWidths(); | |
this.updatePreservedScrollOffsets(); | |
// scroll the header if body is scrolled | |
var scroll = bodyContainer1.scrollLeft; | |
if (headContainer2.scrollLeft != scroll) | |
headContainer2.scrollLeft = scroll; | |
this.fixIEStd(); | |
// update ok | |
return true; | |
}, | |
/** | |
* After (ajax) refresh this updates the scroll offsets to match previous offset, so that the scrolling | |
* position remains same after component update. | |
*/ | |
updatePreservedScrollOffsets: function() { | |
if ($.isNumeric(this.updateScrollTop) || | |
$.isNumeric(this.updateScrollLeft)) { | |
var bodyContainer1 = this.getElement("div", "imxt-body-container1"); | |
bodyContainer1.style.visibility="hidden"; | |
if ($.isNumeric(this.updateScrollLeft)) { | |
bodyContainer1.scrollLeft = this.lastScrollLeft; | |
this.updateScrollLeft = null; | |
} | |
if ($.isNumeric(this.updateScrollTop)) { | |
bodyContainer1.scrollTop = this.updateScrollTop; | |
this.updateScrollTop = null; | |
} | |
bodyContainer1.style.visibility="visible"; | |
bodyContainer1.imxtOldOffsetWidth = null; | |
} | |
}, | |
fixIEStd: function() { | |
if (this.isIE && !this.isIEQuirks) { | |
var bodyContainer1 = this.getElement("div", "imxt-body-container1"); | |
// IE in standard compliance mode fails to display the scrollbars properly | |
// so we need to manually change the overflow mode | |
if (this.dragging || bodyContainer1.imxtOldOffsetWidth != bodyContainer1.offsetWidth) { | |
var body = this.getBodyTable(); | |
// this forces IE to recalculate the width. setting to 1px "hides" the scrollbar | |
// so that bodyContainer1 gives us real scrollWidth | |
body.style.width = "1px"; | |
body.style.width = bodyContainer1.scrollWidth + "px"; | |
bodyContainer1.imxtOldOffsetWidth = bodyContainer1.offsetWidth; | |
} | |
} | |
}, | |
/** | |
* On IE 6 or IE7 quirks this sets the drag handles height same as parent (column) height | |
*/ | |
updateHandles: function(force) { | |
// this is slow on IE so we only do it on every tenth update | |
if (this.isIELessThan7 || this.isIEQuirks) { | |
var c = this.counter || 0; | |
if (force) | |
c = 0; | |
if (c == 0) { | |
var header = this.getColumnsRow(); | |
var handles = this.getElements("a", "imxt-handle", header); | |
for (var i = 0; i < handles.length; ++i) { | |
var h = handles[i]; | |
h.style.height = h.parentNode.offsetHeight + "px"; | |
} | |
} else if (c == 10) { | |
c = -1; | |
} | |
++c; | |
this.counter = c; | |
} | |
}, | |
/** | |
* Updates the XTable. This is called during resizing, after column drag and also periodically. | |
* @param force | |
*/ | |
update: function(force) { | |
if (this.dragging === true) { | |
return true; | |
} else { | |
return this.updateInternal(force); | |
} | |
}, | |
getColumnMinSize: function(column) { | |
var res = column.imxtMinSize; | |
return $.isNumeric(res) && res > 0 ? res : 20; | |
}, | |
getColumnMaxSize: function(column) { | |
var res = column.imxtMaxSize; | |
return $.isNumeric(res) && res > 0 ? res : -1; | |
}, | |
getResizeProxy: function() { | |
var e = Wicket.$("imxt-resize-proxy"); | |
if (typeof e === 'undefined' || e === null) { | |
e = document.createElement("div"); | |
e.setAttribute("id", "imxt-resize-proxy"); | |
document.body.appendChild(e); | |
} | |
return e; | |
}, | |
showResizeProxy: function(column) { | |
var headContainer = this.getElement("div", "imxt-head-container"); | |
var bodyContainer = this.getElement("div", "imxt-body-container1"); | |
var columnPos = $(column).offset(); | |
var headContainerPos = $(headContainer).offset(); | |
var bodyContainerPos = $(bodyContainer).offset(); | |
var proxy = this.getResizeProxy(); | |
proxy.style.display = ""; | |
proxy.style.height = (bodyContainer.offsetHeight + bodyContainerPos.top - headContainerPos.top) + "px"; | |
var top = headContainerPos.top; | |
if (this.isIE) { // weird IE bug | |
top = top - 2; | |
} | |
proxy.style.top = top + "px"; | |
proxy.style.left = (columnPos.left + column.imxtWidth - proxy.offsetWidth) + "px"; | |
}, | |
hideResizeProxy: function(column) { | |
var proxy = this.getResizeProxy(); | |
proxy.style.display="none"; | |
}, | |
/** | |
* Called when column resizing handle dragging started. | |
* @param handle | |
*/ | |
handleDragBegin: function(handle) { | |
Wicket.Focus.lastFocusId = null; | |
this.dragging = true; | |
var column = handle; | |
// find the column itself | |
do { | |
column = column.parentNode; | |
} while (column.tagName.toLowerCase() !== "th"); | |
// add the css dragging class | |
addClass(column, "imxt-dragging"); | |
addClass(this.getColumnsRow(), "imxt-dragging"); | |
column.min = this.getColumnMinSize(column); | |
column.max = this.getColumnMaxSize(column); | |
column.imxtWidth = parseInt(column.style.width, 10); | |
this.showResizeProxy(column); | |
}, | |
/** | |
* Called when column resizing handle dragging ended | |
* @param handle | |
*/ | |
handleDragEnd: function(handle) { | |
this.dragging = false; | |
this.hideResizeProxy(); | |
var column = handle; | |
do { | |
column = column.parentNode; | |
} while (column.tagName.toLowerCase() !== "th"); | |
// opera has weird redrawing problems, to get over it we hide the handle and show | |
// it after setting the width | |
if (this.isOpera) { | |
column.style.display = "none"; | |
} | |
column.style.width = column.imxtWidth + "px"; | |
if (this.isOpera) { | |
column.style.display = ""; | |
} | |
// remove the css classes | |
removeClass(column, "imxt-dragging"); | |
removeClass(this.getColumnsRow(), "imxt-dragging"); | |
// fix for IE quirks mode (to force recalculating of table layout) | |
this.getElement("div", "imxt-body-container1").imxtOldOffsetWidth = null; | |
// the prelight has not been updated during dragging, update it now | |
if (this.isIE) // flickers otherwise | |
window.setTimeout(Wicket.bind(this.updatePrelight,this), 100); | |
else | |
this.updatePrelight(); | |
this.updateInternal(); | |
this.submitColumnState(); | |
}, | |
/** | |
* Called during a column handle dragging | |
* @param handle | |
* @param dX | |
* @param dY | |
*/ | |
handleDrag: function(handle, dX, dY) { | |
var column = handle; | |
do { | |
column = column.parentNode; | |
} while (column.tagName.toLowerCase() !== "th"); | |
var current = column.imxtWidth; | |
var newWidth = current + dX; | |
var delta = 0; | |
if (column.min != -1 && newWidth < column.min) { | |
delta = column.min - newWidth; | |
newWidth = column.min; | |
} else if (column.max != -1 && newWidth > column.max) { | |
delta = column.max - newWidth; | |
newWidth = column.max; | |
} | |
column.imxtWidth = newWidth; | |
this.showResizeProxy(column); | |
return [delta, 0]; | |
}, | |
handleDoubleClick: function(event) { | |
var table = event.data; | |
var column = event.target; | |
do { | |
column = column.parentNode; | |
} while (column.tagName.toLowerCase() !== "th"); | |
var min = table.getColumnMinSize(column); | |
column.style.width = min + "px"; | |
table.updateInternal(); | |
table.submitColumnState(); | |
}, | |
/** | |
* Returns the array of TH elements from the column row | |
*/ | |
getColumns: function() { | |
var columnsRow = this.getColumnsRow(); | |
return getChildren(columnsRow, "TH"); | |
}, | |
/** | |
* Returns array of handle links inside the columns row | |
*/ | |
getHandles: function() { | |
var columns = this.getColumnsRow(); | |
var handles = this.getElements("a", "imxt-handle", columns); | |
return handles; | |
}, | |
/** | |
* Calback invoked when the body is scrolled. | |
* @param event | |
*/ | |
onScroll: function(event) { | |
var bodyContainer = event.data.getElement("div", "imxt-body-container1"); | |
// only update on horizontal scrolling | |
if (bodyContainer.scrollLeft != bodyContainer.imxtPrevScrollLeft) { | |
event.data.update(); | |
bodyContainer.imxtPrevScrollLeft = bodyContainer.scrollLeft; | |
} | |
event.data.lastScrollLeft = bodyContainer.scrollLeft; | |
event.data.lastScrollTop = bodyContainer.scrollTop; | |
}, | |
/** | |
* Attach the various event handler to elements in this XTable. | |
*/ | |
attachEventHandlers: function() { | |
// 1 scroll handler | |
var bodyContainer = this.getElement("div", "imxt-body-container1"); | |
if (bodyContainer.imxtAttached != true) { | |
addListener(bodyContainer, "scroll", this.onScroll, this, true); | |
bodyContainer.imxtAttached = true; | |
} | |
// 2 column resize handlers | |
var handles = this.getHandles(); | |
for (var i = 0; i < handles.length; ++i) { | |
var h = handles[i]; | |
if (h.imxtAttached != true) { | |
new InMethod.Drag(h, this.handleDragBegin, this.handleDragEnd, | |
this.handleDrag, this); | |
addListener(h, "dblclick", this.handleDoubleClick, this); | |
h.imxtAttached = true; | |
} | |
} | |
// 3 columns reorder handlers | |
var columns = getChildren(this.getColumnsRow(), "TH"); | |
for (var i = 0; i < columns.length; ++i) { | |
var c = columns[i]; | |
if (!hasClass(c, "imxt-padding") && c.imxtReorderable == true && c.imxtAttached != true) { | |
new InMethod.Drag(c, this.columnDragBegin, this.columnDragEnd, this.columnDrag, this); | |
c.imxtAttached = true; | |
} | |
} | |
// 4 prelights | |
this.attachPrelight(); | |
}, | |
/** | |
* Called when user starts to drag a column (reorder) | |
* @param column | |
* @param event | |
*/ | |
columnDragBegin: function(column, event) { | |
Wicket.Focus.lastFocusId = null; | |
addClass(column, "imxt-dragging"); | |
this.dragging = true; | |
this.initDragProxy(event, column); | |
this.columnDragBeginX = event.pageX; | |
this.columnDragBeginY = event.pageY; | |
this.columnDragBeginTime = new Date().getTime(); | |
}, | |
/** | |
* Called after user finished dragging a column (reorder) | |
* @param column | |
*/ | |
columnDragEnd: function(column) { | |
this.cachedColumns = null; | |
// targetColumn is array [column, position] where position is 0 or 1 | |
var target = this.targetColumn; | |
var submitState = false; | |
if ($.isArray(target)) { | |
// find the delta - how many columns right or left has the source | |
// column been moved | |
var delta = 0; | |
var c = column; | |
// try moving left | |
do { | |
c = prevSibling(c); | |
--delta; | |
} while (typeof c !== 'undefined' && c !== null && c != target[0]); | |
// if the column hasn't been found in left siblings, try moving right | |
if (typeof c === 'undefined' || c === null) { | |
c = column; | |
delta = 0; | |
do { | |
c = nextSibling(c); | |
++delta; | |
} while (typeof c !== 'undefined' && c !== null && c != target[0]); | |
--delta; | |
} | |
// if we found target column, do the actual reordering | |
if (typeof c !== 'undefined' && c !== null) { | |
delta += target[1]; | |
this.moveColumn(column, delta); | |
submitState = true; | |
} | |
} | |
this.dragging = false; | |
removeClass(column, "imxt-dragging"); | |
this.hideArrows(); | |
this.hideDragProxy(); | |
this.updatePrelight(); | |
if (submitState) { | |
this.submitColumnState(); | |
} | |
}, | |
/** | |
* Initializes the drag proxy. If the drag proxy doesn't exist yet, creates it. | |
* This method doesn't make the proxy visible. Proxy is made visible in updateDragProxy. | |
* @param ev | |
* @param column | |
*/ | |
initDragProxy: function(ev, column) { | |
var p = Wicket.$("imxt-drag-proxy"); | |
if (typeof p === 'undefined' || p === null) { | |
p = document.createElement("div"); | |
document.body.appendChild(p); | |
p.setAttribute("id", "imxt-drag-proxy"); | |
p.innerHTML = "<div id='imxt-drag-proxy1'></div>"; | |
} | |
var p1 = Wicket.$("imxt-drag-proxy1"); | |
var columnPos = $(column).offset(); | |
var mousePos = [ev.pageX, ev.pageY]; | |
// get the initial proxy position relative to mouse cursor | |
ev.data.dragProxyDX = -column.offsetWidth / 2; //columnPos[0] - mousePos[0]; | |
ev.data.dragProxyDY = -column.offsetHeight / 2; //columnPos[1] - mousePos[1]; | |
// initialize dimensions | |
p.style.width = column.offsetWidth + "px"; | |
p1.style.height = (column.offsetHeight - 3) + "px"; | |
p.style.display = "none"; | |
this.setPosition(p, [columnPos.left,columnPos.top]); | |
}, | |
/** | |
* Moves the drag proxy to mouse cursor position. | |
* @param ev | |
*/ | |
updateDragProxy: function(ev) { | |
var p = Wicket.$("imxt-drag-proxy"); | |
p.style.display = ""; | |
this.setPosition(p, [ev.pageX + ev.data.dragProxyDX, ev.pageY + ev.data.dragProxyDY]); | |
}, | |
/** | |
* Hides the drag proxy. | |
*/ | |
hideDragProxy: function() { | |
var p = Wicket.$("imxt-drag-proxy"); | |
p.style.display = "none"; | |
}, | |
/** | |
* Returns the arrow element with specified id (should be either 'imxt-arrow-down' or 'imxt-arrow-up'). | |
* If the arrow element doesn't exist, creates it. | |
* @param id | |
*/ | |
getArrow: function(id) { | |
var a = Wicket.$(id); | |
if (typeof a === 'undefined' || a === null) { | |
a = document.createElement("a"); | |
a.setAttribute("id", id); | |
document.body.appendChild(a); | |
} | |
return a; | |
}, | |
setPosition: function(a, xy) { | |
$(a).css({left: xy[0], top: xy[1]}); | |
}, | |
/** | |
* Shows arrows (both up and down) at the specified position) | |
* @param column | |
* @param pos | |
*/ | |
showArrows: function(column, pos) { | |
var a1 = this.getArrow("imxt-arrow-down"); | |
var a2 = this.getArrow("imxt-arrow-up"); | |
a1.style.display = ""; | |
a2.style.display = ""; | |
var xy = $(column).offset(); | |
var x = xy.left + (pos * column.offsetWidth); | |
var y = xy.top; | |
this.setPosition(a1, [x - 7, y - 14]); | |
this.setPosition(a2, [x - 7, y - 2 + column.offsetHeight]); | |
// mark the target column - used in columnDragEnd() | |
this.targetColumn = [column, pos]; | |
}, | |
/** | |
* Hides the arrows | |
*/ | |
hideArrows: function() { | |
var a1 = this.getArrow("imxt-arrow-down"); | |
var a2 = this.getArrow("imxt-arrow-up"); | |
a1.style.display = "none"; | |
a2.style.display = "none"; | |
this.targetColumn = null; | |
}, | |
columnAndPrevSiblingsNotReorderable: function(column) { | |
while (typeof column !== 'undefined' && column !== null) { | |
if (column.imxtReorderable == true) { | |
return false; | |
} | |
column = prevSibling(column); | |
} | |
return true; | |
}, | |
columnAndNextSiblingsNotReorderable: function(column) { | |
while (typeof column !== 'undefined' && column !== null) { | |
if (column.imxtReorderable == true) { | |
return false; | |
} | |
column = nextSibling(column); | |
} | |
return true; | |
}, | |
/** | |
* Invoked when user is dragging a column (reorder). | |
* @param column | |
* @param dX | |
* @param dY | |
* @param event | |
*/ | |
columnDrag: function(column, dX, dY, event) { | |
var columns = this.cachedColumns; | |
if (typeof(columns) === "undefined" || columns === null) { | |
columns = getChildren(this.getColumnsRow(), "TH"); | |
this.cachedColumns = columns; | |
} | |
var x = event.pageX; | |
var y = event.pageY; | |
if (Math.abs(this.columnDragBeginY - y) < 10 && | |
Math.abs(this.columnDragBeginX - x) < 15 && | |
new Date().getTime() - this.columnDragBeginTime < 1000) { | |
return; | |
} | |
// find the column on cursor position | |
var c = null; | |
for (var i = 0; i < columns.length; ++i) { | |
cx = columns[i]; | |
var pos = $(cx).offset(); | |
if (x >= pos.left && x < pos.left + cx.offsetWidth) { | |
c = cx; | |
break; | |
} | |
} | |
// if the column is a column other than the column being dragged | |
if (typeof c !== 'undefined' && c != column && c !== null) { | |
// find if the cursor is in left or right half of column | |
var c_x = $(cx).offset().left; | |
var x = event.pageX - c_x; | |
var w = c.offsetWidth; | |
var pos = x < w / 2 ? 0 : 1; | |
if ((pos == 0 && c == nextSibling(column)) || | |
(pos == 0 && this.columnAndPrevSiblingsNotReorderable(c)) || | |
(pos == 1 && !hasClass(nextSibling(c), "imxt-reorderable") && this.columnAndPrevSiblingsNotReorderable(c)) || | |
(pos == 1 && c == prevSibling(column)) || | |
(pos == 1 && this.columnAndNextSiblingsNotReorderable(c)) || | |
(pos == 0 && !hasClass(prevSibling(c), "imxt-reorderable") && this.columnAndNextSiblingsNotReorderable(c)) || | |
(pos == 1 && hasClass(c, "imxt-padding"))) { | |
// the source column can't be dragged here | |
this.hideArrows(); | |
} else { | |
// this is a valid destination | |
this.showArrows(c, pos); | |
} | |
} else { | |
this.hideArrows(); | |
} | |
// move drag proxy to follow the cursor | |
this.updateDragProxy(event); | |
}, | |
getOriginalColSpan: function(column) { | |
var res = column.className.match(colSpanRegex); | |
if (res) { | |
return parseInt(res[1], 10); | |
} else { | |
return 1; | |
} | |
}, | |
/** | |
* Reorders the column according to the delta (positive or negative number) | |
* @param column | |
* @param delta | |
*/ | |
moveColumn: function(column, delta) { | |
while (column.tagName.toLowerCase() !== "th") { | |
column = column.parentNode; | |
} | |
// bug in opera - we need to hide both tables during reordering, | |
// otherwise the tables will not be refreshed afterwards | |
var bodyContainer1; | |
var scroll; | |
if (this.isOpera) { | |
bodyContainer1 = this.getElement("div", "imxt-body-container1"); | |
scroll = bodyContainer1.scrollLeft; | |
this.getHeadTable().style.display="none"; | |
this.getBodyTable().style.display="none"; | |
} | |
// the column might not be prelight after reordering | |
removeClass(column, "imxt-prelight"); | |
var header = this.getColumnsRow(); | |
var ths = getChildren(header, "TH"); | |
// get the source column index | |
var index; | |
for (var i = 0; i < ths.length; ++i) { | |
if (ths[i] == column) { | |
index = i; | |
break; | |
} | |
} | |
var other = ths[i + delta]; | |
var fixSpans = Wicket.bind(function(cells) { | |
var hide = 0; | |
for (var i = 0; i < cells.length; ++i) { | |
var cell = cells[i]; | |
var left = cells.length - i - 1; | |
if (hide > 0) { | |
cell.setAttribute("colSpan", 1); | |
cell.style.display = "none"; | |
--hide; | |
} else { | |
var span = this.getOriginalColSpan(cell); | |
if (span > left) { | |
span = left; | |
} | |
hide = span - 1; | |
cell.style.display = ""; | |
cell.setAttribute("colSpan", span > 0 ? span : 1); | |
} | |
} | |
}, this); | |
// helper function that reorders columns in the given rows | |
var updateRows = Wicket.bind(function(rows, fixSpans) { | |
for (var j = 0; j < rows.length; ++j) { | |
var row = rows[j]; | |
var tds = getChildren(row, ["TD", "TH"]); | |
var current = tds[i]; | |
if (typeof(current) === "undefined") { | |
continue; | |
} | |
var index = i + delta; | |
if (delta > 0) { | |
++index; | |
} | |
other = tds[index]; | |
row.insertBefore(current, other); | |
if ($.isFunction(fixSpans)) { | |
fixSpans(getChildren(row, ["TD", "TH"])); | |
} | |
} | |
}, this); | |
// update rows in both tables | |
updateRows(this.getHeadRows()); | |
updateRows(this.getBodyRows(), fixSpans); | |
// show the tables in opera | |
if (this.isOpera) { | |
this.getHeadTable().style.display=""; | |
this.getBodyTable().style.display=""; | |
bodyContainer1.scrollLeft = scroll; | |
} | |
// we might have changed the layout | |
this.update(true); | |
}, | |
/** | |
* To get around IE not supporting :hover on all elements but links, we attach special | |
* onmouseover and onmouseout handlers on elements with "imxt-want-prelight" class set | |
* that add and remove the imxt-prelight css class on element when mouse hovers it. | |
*/ | |
attachPrelight: function() { | |
var elements = this.getElements("*", "imxt-want-prelight"); | |
attachPrelight(elements, this); | |
// Issue #44: | |
// Workaround for an IE9 rendering bug. IE9 miscalculates | |
// the tables sizes on hover in/out ... This leads to issue #44. | |
// | |
// We just force the browser to do a full recaluclate on hover. | |
if (Wicket.Browser.isIE9()) { | |
var _this = this; | |
function fixIE9Layout() { | |
$(_this.getBodyTable()).parent().css({ | |
'overflow' : 'auto' | |
}); | |
} | |
var elements = _this.getElements("tr", "imxt-want-prelight"); | |
for (var i = 0; i < elements.length; i++) | |
$(elements[i]).hover(fixIE9Layout); | |
$(_this.getBodyTable()).hover(fixIE9Layout); | |
$(_this.getElement("div", "imxt-bottom-toolbar-container")).hover(fixIE9Layout); | |
// If there is a custom link in a table cell it can trigger the same problem on hover ... | |
$(_this.getBodyTable()).find("a").hover(fixIE9Layout); | |
} | |
}, | |
/** | |
* When the mouseover/mouseout event handlers set a prelight flag, this method adds/removes | |
* the actual css class depending on the flag. This behavior is intentionally supressed | |
* during column resizing/reordering. | |
* If the specified element is undefined, the css class is updated on all elements with | |
* "imxt-want-prelight" css class. | |
* @param element | |
*/ | |
updatePrelight: function(element) { | |
if (this.dragging != true) { | |
var update = Wicket.bind(function(e) { | |
var scrollLeft; | |
if (this.isOpera) { | |
// for some reason opera doesn't preserve the scroll offset when changing/removing style | |
bodyContainer1 = this.getElement("div", "imxt-body-container1"); | |
scrollLeft = bodyContainer1.scrollLeft; | |
//e.style.visibility = "hidden"; | |
} | |
if (e.imxtPrelight == true) { | |
addClass(e, "imxt-prelight"); | |
} else { | |
removeClass(e, "imxt-prelight"); | |
} | |
if (this.isOpera) { | |
//e.style.visibility = ""; | |
bodyContainer1 = this.getElement("div", "imxt-body-container1"); | |
bodyContainer1.scrollLeft = scrollLeft; | |
} | |
}, this); | |
if (typeof(element) !== "undefined") { | |
update(element); | |
} else { | |
var elements = this.getElements("*", "imxt-want-prelight", this.getHeadTable()); | |
for (var i = 0; i < elements.length; ++i) { | |
update(elements[i]); | |
} | |
} | |
} | |
}, | |
/** | |
* Returns the state of columns (order and widths) represented as string. | |
*/ | |
getColumnState: function() { | |
var r = this.getColumnsRow(); | |
var ths = getChildren(r, "TH"); | |
var state = ""; | |
for (var i = 0; i < ths.length - 1; ++i) { | |
var th = ths[i]; | |
state += th.imxtId; | |
state += ","; | |
var width = th.style.width; | |
if (width.match(/[\d]+px/)) | |
state += parseInt(th.style.width, 10); | |
else | |
state += "-1"; | |
state += ";"; | |
}; | |
return state; | |
}, | |
submitColumnState: function() { | |
this.columnsStateCallback(this.getColumnState()); | |
}, | |
/** | |
* Needs to be called when a row was added or updated. | |
* @param rowElement | |
*/ | |
rowUpdated: function(rowElement) { | |
var elements = this.getElements("*", "imxt-want-prelight", rowElement); | |
if (hasClass(rowElement, "imxt-want-prelight")) { | |
elements.push(rowElement); | |
} | |
attachPrelight(elements, this); | |
this.updateSelectCheckBoxes(); | |
this.initCells(rowElement); | |
}, | |
getCellId: function(cell) { | |
if (typeof(cell.imxtId) !== "string") { | |
var index = 0; | |
var c = cell; | |
while ((c = prevSibling(c)) != null) { | |
++index; | |
} | |
var row = this.getColumnsRow(); | |
var headerCells = getChildren(row, "TH"); | |
var headerCell = headerCells[index]; | |
if (typeof(headerCell.imxtId) === "string") { | |
cell.imxtId = headerCell.imxtId; | |
} else { | |
cell.imxtId = ""; | |
} | |
} | |
return cell.imxtId; | |
}, | |
initCellsEventHandler: function(event) { | |
var cell = event.target; | |
var table = event.data; | |
//Needed because when jquery handles cell event, return cell contents instead | |
//of td cell. | |
if(cell.tagName.toLowerCase() !== 'td' | !$(cell).hasClass('imxt-cell')){ | |
cell =$(cell).parents("td.imxt-cell")[0]; | |
} | |
cell.parentNode.imxtClickedColumn = table.getCellId(cell); | |
}, | |
initCells: function(container) { | |
var elements = this.getElements("td", "imxt-cell", container); | |
for (var i = 0; i < elements.length; ++i) { | |
var cell = elements[i]; | |
if (cell.imxtInitialized != true) { | |
//var addListener = function(element, event, fn, obj, override) { | |
addListener(cell, "click", this.initCellsEventHandler, this, false); | |
cell.imxtInitialized = true; | |
} | |
} | |
} | |
}; | |
InMethod.XTable.canSelectRow = function(event) { | |
var e = Wicket.Event.fix(event); | |
var element = e.target ? e.target : e.srcElement; | |
while (typeof element !== 'undefined' && element !== null && element != document.documentElement) { | |
var tn = element.tagName.toLowerCase(); | |
if (tn === "a" || tn === "input" || tn === "select" || tn === "button") { | |
return false; | |
} | |
element = element.parentNode; | |
} | |
return true; | |
}; | |
InMethod.XTableManager = Wicket.Class.create(); | |
InMethod.XTableManager.prototype = { | |
current: new Object(), | |
initialize: function() { | |
var interval = 100; | |
if (Wicket.Browser.isIELessThan7()) { | |
interval = 500; | |
} | |
window.setInterval(Wicket.bind(this.update, this), interval); | |
}, | |
update: function() { | |
for (var property in this.current) { | |
var table = this.current[property]; | |
if (typeof table !== 'undefined' && table !== null) { | |
var res = table.update(); | |
if (res != true) { | |
this.current[property] = null; | |
} | |
} | |
}; | |
}, | |
updateTreeColumns: function() { | |
for (var property in this.current) { | |
var table = this.current[property]; | |
if (typeof table !== 'undefined' && table !== null) { | |
table.updateTreeColumns(); | |
} | |
}; | |
}, | |
register: function(id, columnsData, columnsStateCallback) { | |
var existing = this.current[id]; | |
if (typeof existing === 'undefined' || existing === null) { | |
existing = new InMethod.XTable(id, columnsData, columnsStateCallback); | |
this.current[id] = existing; | |
} else { | |
// update existing | |
existing.initialize(id, columnsData, columnsStateCallback); | |
} | |
}, | |
updateRow: function(id, row) { | |
var table = this.current[id]; | |
if (typeof table !== 'undefined' && table !== null) { | |
table.rowUpdated(row); | |
} | |
} | |
}; | |
InMethod.XTableManager.instance = new InMethod.XTableManager(); | |
InMethod.setCursorPos = function(elm, begin, end) { | |
if (typeof elm.selectionStart !== "undefined" && typeof elm.selectionEnd !== "undefined") { | |
elm.setSelectionRange (begin, end); | |
elm.focus (); | |
} else if (document.selection && document.selection.createRange) { | |
var range = elm.createTextRange (); | |
range.move ("character", begin); | |
range.moveEnd ("character", end - begin); | |
range.select (); | |
} | |
}; | |
function findParent(node, tagName) { | |
return $(node).parents(tagName); | |
} | |
onKeyEvent = function(element, event) { | |
var e = Wicket.Event.fix(event) | |
var key = event.keyCode; | |
if (key == 13 || key == 27) { | |
if (key == 13 && Wicket.Browser.isSafari()) { | |
// somewhat ugly fix but this is the only thing preventing safari from submitting the form on enter | |
var form = findParent(element, "FORM"); | |
if (form != null) { | |
form.imxtOldOnSubmit = form.onsubmit; | |
form.onsubmit=function() { return false; }; | |
window.setTimeout(function() { form.onsubmit = form.imxtOldOnSubmit; form.imxtOldOnSubmit = null;}, 100); | |
} | |
} | |
var row = element; | |
do { | |
row = findParent(row, "TR"); | |
} while (typeof row !== 'undefined' && row !== null | |
&& !hasClass(findParent(row, "TABLE"), "imxt-body")); | |
if (typeof row !== 'undefined' && row !== null) { | |
var elements; | |
if (key == 13) { | |
elements = $(row).find("a.imxt-edit-submit"); | |
} else { | |
elements = $(row).find("a.imxt-edit-submit"); | |
} | |
if (typeof elements !== 'undefined' && elements !== null && elements.length > 0) { | |
$(elements[0]).click(); | |
} | |
} | |
} | |
}; | |
InMethod.editKeyUp = function(element, event) { | |
if (!Wicket.Browser.isOpera() && !Wicket.Browser.isSafari()) { | |
onKeyEvent(element, event); | |
} | |
var e = Wicket.Event.fix(event) | |
var key = event.keyCode; | |
if (key == 13 || key == 27) { | |
return false; | |
} else { | |
return true; | |
} | |
}; | |
InMethod.editKeyPress = function(element, event) { | |
if (Wicket.Browser.isOpera() || Wicket.Browser.isSafari()) { | |
return onKeyEvent(element, event); | |
} | |
var e = Wicket.Event.fix(event) | |
var key = event.keyCode; | |
if (key == 13 || key == 27) { | |
return false; | |
} else { | |
return true; | |
} | |
}; | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment