The function ImageScrollerSetup() is run when the page loads. This function will look for appropriate image links and apply the appropriate event handlers. ImageScrollerSetup() can be run again if further image links are added to the DOM. Image links that are already controlled will not be affected.
41 |
42 |
Notes:
43 |
44 |
the system is unobtrusive and cross-browser
45 |
the user can still click a thumbnail for the full image
46 |
the system fails gracefully: if the large graphic can not be loaded, the thumbnail remains in place
47 |
image fade in and out can be enabled or disabled if necessary (change the variables ISfadeOn, ISfadeStep, and ISfadePause)
48 |
all large graphics are downloaded and cached in the background
49 |
because all large graphics are loaded, care should be taken to preserve bandwidth
50 |
in Opera, clicking an image then clicking back fails to run the window onload event and the ImageScroller will not be initialised
Any object or value can be converted to an integer using object.toInt().
68 |
69 |
70 |
String prototypes
71 |
The following String prototypes are provided:
72 |
73 |
74 |
Trim()
75 | removes whitespace for the beginning and end of a string, e.g. str = str.Trim();
76 |
77 |
Clean()
78 | removes unnecessary whitespace and unusual characters from a string, e.g. str = str.Clean();
79 |
80 |
Pad(length[, char])
81 | adds characters to the beginning of a string so its length equals 'length', e.g. addzeros = addzeros.Pad(10, "0");. If char is omitted, a space is used by default.
82 |
83 |
SerialToDate()
84 | converts a string in the format YYYYMMDD to a real date, e.g. d = datestr.SerialToDate();
85 |
86 |
DateToSerial()
87 | converts a date to a string in YYYYMMDD format, e.g. s = date.DateToSerial();
88 |
89 |
90 |
Array prototypes
91 |
The following Array prototypes are provided:
92 |
93 |
94 |
push(object)
95 | pushes an object on to the array 'stack', e.g. arrayx.push(value); Note that this is already provided in some JavaScript implementations, but not in IE5.0.
96 |
97 |
pop(object)
98 | pops an object off the array 'stack', e.g. value = arrayx.pop(); Note that this is already provided in some JavaScript implementations, but not in IE5.0.
99 |
100 |
Exists(key)
101 | returns true if a value exists for a key within an associative array, e.g. arrayx.value1 = 1; alert(arrayx.Exists("value1")); // shows true;
102 |
103 |
StoreAll(name[, minutes])
104 | stores all array values (except for functions) in a single cookie called 'name' that expires in 'minutes' (session-only if not defined), e.g. arrayx.SaveAll("arrayx", 60); // saves a cookie for 1 hour
105 |
106 |
LoadAll(name)
107 | loads all array values stored using StoreAll, e.g. arrayx.LoadAll("arrayx");
108 |
109 |
110 |
HTTParguments()
111 |
This function returns an associative array of HTTP GET arguments passed on the URL, e.g. var a = HTTParguments(); if (a.Exists("id")) alert("ID = "+a.id);
112 |
113 |
Cookie functions
114 |
The following cookie functions are provided:
115 |
116 |
117 |
CookieSet(name, value[, minutes])
118 | defines a cookie called 'name' with a value of 'value' that expires in 'minutes' minutes (session-only if not defined)
119 |
120 |
CookieGet(name)
121 | returns the value of the cookie called 'name'. The value will always be a string.
122 |
123 |
CookiesEnabled()
124 | returns true if cookies are enabled.
125 |
126 |
127 |
128 |
--------------------------------------------------------------------------------
/js/ajax/resources/import.css:
--------------------------------------------------------------------------------
1 | *
2 | {
3 | color: #f00;
4 | }
--------------------------------------------------------------------------------
/js/ajax/resources/import.js:
--------------------------------------------------------------------------------
1 | // this JavaScript is imported
2 | alert("JS successfully imported!\nNote that this has loaded after the page load,\nso further window.onload events will not fire.");
--------------------------------------------------------------------------------
/js/ajax/resources/test.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | This is the document title
5 | Craig Buckler
6 |
7 | This is some XML that has been transformed using XSLT.
8 | If you can read this, the transformation was successful.
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/js/ajax/resources/test.xsl:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | ]]>
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/js/ajax/scriptlibrary/events v1.js:
--------------------------------------------------------------------------------
1 | /*
2 | Event class, by Craig Buckler
3 | Creates a cross-browser event object.
4 | All added events are detached when the page unloads to prevent browser memory leaks.
5 | Note that window.unload events can not be automatically detached.
6 |
7 | Dependencies:
8 | misc.js (if IE5 is supported)
9 | */
10 | function Event(element, eventType, eventHandler) {
11 |
12 | // reference to this object
13 | var thisEvent = this;
14 |
15 | // event object
16 | this.Raised = null;
17 |
18 | // handler function (parses event and passes reference to this)
19 | var handler = function(e) { thisEvent.Raised = new EventInformation(e); eventHandler(thisEvent); }
20 |
21 | // attach event
22 | try {
23 | if (element.addEventListener) element.addEventListener(eventType, handler, false);
24 | else if (element.attachEvent) var evt = element.attachEvent("on"+eventType, handler);
25 | else element["on"+eventType] = handler;
26 | }
27 | catch (e) {}
28 |
29 | // add to event manager (if not a window unload)
30 | if (element !== window || eventType != "unload") EventManager.Add(this);
31 |
32 | // detach event method
33 | this.Detach = function() {
34 | try {
35 | if (element.removeEventListener) element.removeEventListener(eventType, handler, false);
36 | else if (element.detachEvent) var evt = element.detachEvent("on"+eventType, handler);
37 | else element["on"+eventType] = null;
38 | }
39 | catch(e) {}
40 | }
41 |
42 | }
43 |
44 |
45 | // Event information object (cross-browser)
46 | function EventInformation(event, stopPropagation, stopDefault) {
47 |
48 | // store event
49 | this.Event = (event ? event : window.event);
50 |
51 | // default values
52 | this.Type = "";
53 | this.Element = null;
54 | this.Key = "";
55 | this.ControlKey = "";
56 | this.Shift = false;
57 | this.Ctrl = false;
58 | this.Alt = false;
59 | this.MouseX = 0;
60 | this.MouseY = 0;
61 |
62 | if (this.Event) {
63 | // event type
64 | this.Type = String(event.type).toLowerCase();
65 |
66 | // source element
67 | this.Element = (event.target ? event.target : event.srcElement);
68 |
69 | // standard key press
70 | var keyCode = (this.Event.keyCode ? this.Event.keyCode : this.Event.charCode);
71 | if (this.Event.charCode != 0 && keyCode >= 32) this.Key = String.fromCharCode(keyCode);
72 |
73 | // control key press
74 | if (this.Key == "") {
75 | this.ControlKey = ControlKeys[keyCode];
76 | if (!this.ControlKey) this.ControlKey = "";
77 | }
78 |
79 | // action keys
80 | this.Ctrl = event.ctrlKey;
81 | this.Alt = event.altKey;
82 | this.Shift = event.shiftKey;
83 |
84 | // mouse co-ordinates
85 | var mre = /mouse|click/i;
86 | if (mre.test(this.Type)) {
87 | this.MouseX = (this.Event.pageX ? this.Event.pageX : this.Event.clientX + Math.max(document.documentElement.scrollLeft, document.body.scrollLeft));
88 | this.MouseY = (this.Event.pageY ? this.Event.pageY : this.Event.clientY + Math.max(document.documentElement.scrollTop, document.body.scrollTop));
89 | }
90 |
91 | // default actions
92 | if (stopPropagation) this.StopPropagation();
93 | if (stopDefault) this.StopDefaultAction();
94 | }
95 | }
96 |
97 |
98 | // stop event propagation
99 | EventInformation.prototype.StopPropagation = function() {
100 | if (this.Event) {
101 | try { this.Event.stopPropagation(); } catch(e) {}
102 | this.Event.cancelBubble = true;
103 | }
104 | }
105 |
106 |
107 | // stop event default action
108 | EventInformation.prototype.StopDefaultAction = function() {
109 | if (this.Event) {
110 | try { this.Event.preventDefault(); } catch(e) {}
111 | this.Event.returnValue = false;
112 | }
113 | }
114 |
115 |
116 | // control key definitions
117 | var ControlKeys = []; ControlKeys[8] = "backspace"; ControlKeys[9] = "tab"; ControlKeys[13] = "enter"; ControlKeys[27] = "esc"; ControlKeys[33] = "pageup"; ControlKeys[34] = "pagedown"; ControlKeys[35] = "end"; ControlKeys[36] = "home"; ControlKeys[37] = "left"; ControlKeys[38] = "up"; ControlKeys[39] = "right"; ControlKeys[40] = "down"; ControlKeys[45] = "insert"; ControlKeys[46] = "delete"; ControlKeys[112] = "f1"; ControlKeys[113] = "f2"; ControlKeys[114] = "f3"; ControlKeys[115] = "f4"; ControlKeys[116] = "f5"; ControlKeys[117] = "f6"; ControlKeys[118] = "f7"; ControlKeys[119] = "f8"; ControlKeys[120] = "f9"; ControlKeys[121] = "f10"; ControlKeys[122] = "f11"; ControlKeys[123] = "f12"; ControlKeys[144] = "numlock"; ControlKeys[145] = "scrolllock";
118 |
119 |
120 | // event manager object
121 | var EventManager = new function() {
122 |
123 | // initialise event stack
124 | var eStack = null;
125 | this.Initialise = function() {
126 | if (eStack == null) { eStack = new Array(); new Event(window, "unload", this.CleanUp); }
127 | }
128 |
129 | // add an event to the stack (except window unload events)
130 | this.Add = function(event) { this.Initialise(); eStack.push(event); }
131 |
132 | // detach all stacked events
133 | this.CleanUp = function(e) { while (eStack.length > 0) eStack.pop().Detach(); }
134 | }
--------------------------------------------------------------------------------
/js/ajax/scriptlibrary/imagescroller.js:
--------------------------------------------------------------------------------
1 | /*
2 | ImageScroller, by Craig Buckler
3 | Scrolls an image when a mouseover occurs over the thumbnail
4 |
5 | Dependencies:
6 | misc.js (if IE5 is supported)
7 | events.js
8 | dom.js
9 | graphic.js
10 | */
11 | new Event(window, "load", ImageScrollerSetup);
12 |
13 | var ISfadeOn = true; // switch fade on/off
14 | var ISfadeStep = 2; // fade steps (1 - 100)
15 | var ISfadePause = 10; // fade pause between steps
16 |
17 | // find links with class of imagescroller
18 | function ImageScrollerSetup() {
19 | var links = DOM.Class("imagescroller", "a");
20 | for (var i = 0; i < links.length; i++) if (links[i].getAttribute("imagescroller") != 'true') new ImageScroller(links[i]);
21 | }
22 |
23 | // define ImageScroller
24 | function ImageScroller(aNode) {
25 |
26 | var IS = this; // this object
27 |
28 | // set image background and mousemove event
29 | this.Initialise = function() {
30 | aNode.style.backgroundImage = "url("+fImage.src+")";
31 | aNode.style.backgroundRepeat = "no-repeat";
32 | aNode.style.cursor = "move";
33 | Graphic.Opacity(iNode, fop, true);
34 | new Event(aNode, "mouseover", function(evt) { IS.MoveEvent(evt); });
35 | new Event(aNode, "mousemove", function(evt) { IS.PositionImage(evt); });
36 | new Event(aNode, "mouseout", function(evt) { IS.MoveEvent(evt); });
37 | }
38 |
39 | // show or hide image
40 | this.MoveEvent = function(evt) {
41 | if (ftimer) clearInterval(ftimer);
42 | if (evt.Raised.Type == "mouseover") {
43 | aX = DOM.AbsoluteX(aNode); aY = DOM.AbsoluteY(aNode); // find element location (if screen resized)
44 | if (ISfadeOn) ftimer = setInterval(function() { IS.Fade(-ISfadeStep); }, ISfadePause); else iNode.style.visibility = "hidden";
45 | }
46 | else if (evt.Raised.Type == "mouseout") {
47 | if (ISfadeOn) ftimer = setInterval(function() { IS.Fade(ISfadeStep); }, ISfadePause); else iNode.style.visibility = "visible";
48 | }
49 | }
50 |
51 | // fade the image
52 | this.Fade = function(step) {
53 | fop += step;
54 | fop = (fop <= 0 ? 0 : (fop >= 100 ? 100 : fop));
55 | Graphic.Opacity(iNode, fop, true);
56 | if (fop == 0 || fop == 100) clearInterval(ftimer);
57 | }
58 |
59 | // position the image
60 | this.PositionImage = function(evt) {
61 | var piX = parseInt(((evt.Raised.MouseX - aX) / aW) * 100); piX = (piX < 5 ? 0 : (piX > 95 ? 100 : piX));
62 | var piY = parseInt(((evt.Raised.MouseY - aY) / aH) * 100); piY = (piY < 5 ? 0 : (piY > 95 ? 100 : piY));
63 | aNode.style.backgroundPosition = piX+"% "+piY+"%";
64 | }
65 |
66 | // setup
67 | var iNode = DOM.Tags("img", aNode);
68 | if (iNode.length > 0) iNode = iNode[0]; else iNode = null;
69 |
70 | var ext = /\.(gif|jpg|jpeg|png|bmp)$/i;
71 | if (iNode && aNode.getAttribute("imagescroller") != 'true' && ext.test(aNode.getAttribute("href").Trim())) {
72 |
73 | // mark as controlled
74 | aNode.setAttribute("imagescroller", "true");
75 |
76 | // element dimensions
77 | var aX = DOM.AbsoluteX(aNode); var aY = DOM.AbsoluteY(aNode);
78 | var aW = aNode.offsetWidth; var aH = aNode.offsetHeight;
79 |
80 | // fade opacity and timer
81 | var fop = 100;
82 | var ftimer;
83 |
84 | // load image and initialise
85 | var fImage = new Image;
86 | fImage.src = aNode.getAttribute("href");
87 | if (fImage.complete) this.Initialise();
88 | else new Event(fImage, "load", function(evt) { IS.Initialise(); });
89 | }
90 | }
--------------------------------------------------------------------------------
/js/ajax/scriptlibrary/misc.js:
--------------------------------------------------------------------------------
1 | // miscellaneous functions, by Craig Buckler
2 |
3 | // ________________________________________________________
4 | // convert a value to an integer
5 | Object.prototype.toInt = function() {
6 | var str = String(this);
7 | str = str.replace(/[^0-9-.]/g, "");
8 | var ret = parseInt(str, 10);
9 | if (isNaN(ret)) ret = 0;
10 | return ret;
11 | }
12 |
13 |
14 | // ________________________________________________________
15 | // string trimming
16 | String.prototype.Trim = function() { return this.replace(/^\s*|\s*$/g, ""); }
17 |
18 | // string cleaning
19 | String.prototype.Clean = function() { return this.replace(/[^\w|\s|@|&|.|,|!|%|(|)|+|-]/g, "").replace(/_/g, " ").replace(/\s+/g, " ").Trim(); }
20 |
21 | // string padding
22 | String.prototype.Pad = function(length, padChar) {
23 | var str = String(this);
24 | length = length.toInt();
25 | if (typeof padChar == 'undefined') padChar = " ";
26 | else {
27 | padChar = String(padChar);
28 | if (padChar.length < 1) padChar = " ";
29 | }
30 | while (str.length < length) str = padChar + str;
31 | return str;
32 | }
33 |
34 | // convert a serial YYYYMMDD string to a date
35 | String.prototype.SerialToDate = function() {
36 | var d = String(this);
37 | d = d.Trim();
38 | var date = (d.length >= 8 ? new Date(d.substr(0,4).toInt(), d.substr(4,2).toInt() - 1, d.substr(6,2).toInt()) : new Date());
39 | return date;
40 | }
41 |
42 | // convert a date to serial YYYYMMDD format
43 | Date.prototype.DateToSerial = function() {
44 | return String(this.getFullYear()).Pad(4,"0")+String(this.getMonth()+1).Pad(2,"0")+String(this.getDate()).Pad(2,"0");
45 | }
46 |
47 |
48 | // ________________________________________________________
49 | // array stack push (if unsupported)
50 | if (!Array.prototype.push) { Array.prototype.push = function(element) { this[this.length] = element; } }
51 |
52 | // array stack pop (if unsupported)
53 | if (!Array.prototype.pop) {
54 | Array.prototype.pop = function() {
55 | var ret;
56 | if (this.length > 0) {
57 | ret = this[this.length-1];
58 | this.length--;
59 | }
60 | return ret;
61 | }
62 | }
63 |
64 |
65 | // ________________________________________________________
66 | // does associative array item exist?
67 | Array.prototype.Exists = function(key) {
68 | var type = typeof(this[key]);
69 | return (type != 'undefined' && type != 'function');
70 | }
71 |
72 | // save array to cookie
73 | Array.prototype.StoreAll = function(name, minutes) {
74 | var values = "";
75 | for (var key in this) if (typeof(this[key]) != 'function') values += (values == "" ? "" : "[:]") + key + "[=]" + String(this[key]);
76 | CookieSet(name, values, minutes);
77 | }
78 |
79 | // load array from cookie
80 | Array.prototype.LoadAll = function(name) {
81 | var allValues = CookieGet(name);
82 | var values = allValues.split("[:]");
83 | var thisValue;
84 | for (var i = 0; i < values.length; i++) {
85 | thisValue = values[i].split("[=]");
86 | if (thisValue.length == 2) {
87 | if (thisValue[1] == "true" || thisValue[1] == "false") this[thisValue[0]] = (thisValue[1] == "true"); // boolean values
88 | else this[thisValue[0]] = thisValue[1]; // other values
89 | }
90 | }
91 | }
92 |
93 |
94 | // ________________________________________________________
95 | // parse querystring arguments
96 | function HTTParguments() {
97 | var args = new Array();
98 | var arglist = location.search.Trim();
99 | if (arglist.charAt(0) == '?') arglist = arglist.substr(1);
100 | var argsep = arglist.split('&');
101 | var thisValue;
102 | for (var i = 0; i < argsep.length; i++) {
103 | thisValue = argsep[i].split("=");
104 | if (thisValue.length == 2) args[unescape(thisValue[0])] = unescape(thisValue[1]);
105 | }
106 | return args;
107 | }
108 |
109 |
110 | // ________________________________________________________
111 | // set a cookie value (path set to root)
112 | function CookieSet(name, value, minutes) {
113 | value = String(value).replace(/\r/g, "").replace(/\n/g, "[#]");
114 | if (minutes) {
115 | var date = new Date();
116 | date.setTime(date.getTime()+(minutes*60000));
117 | var expires = "; expires="+date.toGMTString();
118 | }
119 | else expires = "";
120 | document.cookie = name+"="+String(value)+expires+"; path="+location.pathname.substr(0, location.pathname.indexOf("/",1)+1);
121 | }
122 |
123 | // read a cookie value
124 | function CookieGet(name) {
125 | var ret = "";
126 | name += "=";
127 | var allCookies = document.cookie.split(';');
128 | var thisCookie;
129 | for(var i = 0; i < allCookies.length && ret == ""; i++) {
130 | thisCookie = allCookies[i].Trim();
131 | if (thisCookie.indexOf(name) == 0) ret = thisCookie.substring(name.length).replace(/\[#\]/g, "\n");
132 | }
133 | return ret;
134 | }
135 |
136 | // are cookies enabled?
137 | function CookiesEnabled() {
138 | CookieSet("testcookie", "testvalue", 0.05);
139 | return (CookieGet("testcookie") == "testvalue");
140 | }
--------------------------------------------------------------------------------
/js/ajax/scriptlibrary/styles.js:
--------------------------------------------------------------------------------
1 | /*
2 | StyleHandler class (static), by Craig Buckler
3 | Provides CSS switching functionality in all browsers
4 |
5 | Dependencies:
6 | misc.js (if IE5 is supported)
7 | events.js
8 | dom.js
9 | */
10 | var StyleHandler = new function() {
11 |
12 | var DefaultTitle = "default style"; // default style title (if not defined)
13 | var AlternateTitle = "alternate style"; // alternate style title (if not defined)
14 |
15 | var Styles; // stylesheet array
16 | var Initialised = false; // true when StyleHandler has been initialised
17 |
18 | // initialise StyleHandler
19 | this.Initialise = function() {
20 |
21 | if (!Initialised) {
22 | Initialised = true; // StyleHandler initialised
23 |
24 | // find style declarations
25 | var slist = DOM.Tags("link");
26 | var title, rel, media;
27 |
28 | // examine styles
29 | for (var i = 0; i < slist.length; i++) {
30 | title = slist[i].getAttribute("title");
31 | rel = slist[i].getAttribute("rel");
32 | media = slist[i].getAttribute("media");
33 |
34 | // set default titles
35 | if (!title && (!media || media == "screen")) {
36 | if (rel && rel.indexOf("style") >= 0 && rel.indexOf("alt") < 0) title = DefaultTitle; else title = AlternateTitle;
37 | slist[i].setAttribute("title", title);
38 | }
39 |
40 | // set screen media
41 | if (!media) slist[i].setAttribute("media", "screen");
42 | }
43 | }
44 | }
45 |
46 |
47 | // returns current stylesheet
48 | this.Current = function() {
49 | this.Initialise();
50 | var slist = DOM.Tags("link");
51 | var current = "";
52 | for (var i = 0; i < slist.length && current == ""; i++) if (!slist[i].disabled) current = slist[i].getAttribute("title");
53 | return current;
54 | }
55 |
56 |
57 | // return an array of style titles
58 | this.Titles = function() {
59 | this.Initialise();
60 | var slist = DOM.Tags("link");
61 | var titles = new Array();
62 | var title, media, exists, i, j;
63 |
64 | for (i = 0; i < slist.length; i++) {
65 | title = slist[i].getAttribute("title");
66 | media = slist[i].getAttribute("media").Trim().toLowerCase();
67 |
68 | if (title != "" && media == "screen") {
69 | exists = false;
70 | for (j = 0; j < titles.length && !exists; j++) if (titles[j] == title) exists = true;
71 | if (!exists) titles.push(title);
72 | }
73 | }
74 | return titles;
75 | }
76 |
77 |
78 | // activate a style
79 | this.Activate = function(styletitle) {
80 | this.Initialise();
81 | var found = null;
82 | var currentstyle = null;
83 | var firststyle = null;
84 | var current = this.Current();
85 | var slist = DOM.Tags("link");
86 | var title, media, i;
87 |
88 | for (i = 0; i < slist.length; i++) {
89 |
90 | title = slist[i].getAttribute("title");
91 | media = slist[i].getAttribute("media").Trim().toLowerCase();
92 |
93 | if (title != "" && media == "screen") {
94 | if (found == null && title == styletitle) found = i;
95 | if (currentstyle == null && title == current) currentstyle = i;
96 | if (firststyle == null) firststyle = i;
97 | slist[i].disabled = true; // disable style
98 | }
99 | }
100 |
101 | // enable style (if not found, use current or first defined style)
102 | i = (found != null ? found : (currentstyle != null ? currentstyle : firststyle));
103 | if (i != null) { slist[i].disabled = false; slist[i].disabled = true; slist[i].disabled = false; }
104 | this.SavePreference();
105 | }
106 |
107 |
108 | // load user preference
109 | this.LoadPreference = function() {
110 | this.Initialise();
111 | this.Activate(CookieGet("stylepref"));
112 | }
113 |
114 |
115 | // save user preference
116 | this.SavePreference = function() {
117 | this.Initialise();
118 | CookieSet("stylepref", this.Current(), 10080); // store preference for 7 days
119 | }
120 | }
121 |
122 | // initialise StyleHandler
123 | new Event(window, "unload", function(evt) { StyleHandler.SavePreference(); });
124 | new Event(window, "load", function(evt) { StyleHandler.LoadPreference(); });
--------------------------------------------------------------------------------
/js/ajax/scriptlibrary/xml.js:
--------------------------------------------------------------------------------
1 | /*
2 | XML class (static), by Craig Buckler
3 | Provides various XML manipulation methods
4 |
5 | Dependencies:
6 | none
7 | */
8 | var XML = new function() {
9 |
10 | // common node types
11 | this.ElementNode = 1;
12 | this.AttributeNode = 2;
13 | this.TextNode = 3;
14 | this.CommentNode = 8;
15 |
16 |
17 | // create a new XML document
18 | this.New = function() {
19 | var xml = null;
20 | if (document.implementation && document.implementation.createDocument) {
21 | try { xml = document.implementation.createDocument("", "xml", null); }
22 | catch(e) {}
23 | }
24 | else {
25 | var ieDOM = [ "MSXML4.DOMDocument", "MSXML3.DOMDocument", "MSXML2.DOMDocument", "MSXML.DOMDocument", "Microsoft.XMLDOM"];
26 | for (var i = 0; i < ieDOM.length && !xml; i++) {
27 | try { xml = new ActiveXObject(ieDOM[i]); }
28 | catch(e) {}
29 | }
30 | }
31 | return xml;
32 | }
33 |
34 |
35 | // transform XML using XSL
36 | this.Transform = function() {
37 | var trans = null;
38 | if (window.XSLTProcessor) {
39 | try {
40 | var xslp = new XSLTProcessor();
41 | xslp.importStylesheet(xsl);
42 | trans = xslp.transformToDocument(xml, document);
43 | }
44 | catch(e) {}
45 | }
46 | else {
47 | try {
48 | trans = this.New();
49 | trans.loadXML( xml.transformNode(xsl) );
50 | }
51 | catch(e) {}
52 | }
53 |
54 | if (trans.documentElement.childNodes.length == 0) trans = null;
55 | return trans;
56 | }
57 |
58 |
59 | // copies the children of addNode (in an XML document) to the children of docNode (DOM, XML document, etc.)
60 | this.Copy = function(addNode, docNode, level) {
61 |
62 | if (typeof level == "undefined") level = 1;
63 |
64 | // create node
65 | if (addNode.nodeType == this.ElementNode && level != 1) {
66 |
67 | var i;
68 | var thisNode = document.createElement(addNode.nodeName);
69 |
70 | // append attributes
71 | for (i = 0; i < addNode.attributes.length; i++) {
72 | if (addNode.attributes[i].name == "class") thisNode.className = addNode.attributes[i].value; // class attribute fails in IE
73 | else thisNode.setAttribute(addNode.attributes[i].name, addNode.attributes[i].value);
74 | }
75 |
76 | // add node to document
77 | docNode = docNode.appendChild(thisNode);
78 | }
79 |
80 | // append text node (ensure it is not a comment)
81 | if (addNode.nodeType == this.TextNode && addNode.nodeValue && level != 1) {
82 | var nval = addNode.nodeValue.Trim();
83 | if (nval.indexOf("") != (nval.length - 3)) docNode.appendChild(document.createTextNode(nval));
84 | }
85 |
86 | // recurse child nodes
87 | for (i = 0; i < addNode.childNodes.length; i++) this.Copy(addNode.childNodes[i], docNode, level+1);
88 |
89 | // return document
90 | return docNode;
91 | }
92 |
93 |
94 | // removes all node children
95 | this.RemoveChildren = function(node) {
96 | while (node.lastChild) node.removeChild(node.lastChild);
97 | }
98 |
99 | }
--------------------------------------------------------------------------------
/js/ajax/styles.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | JavaScript testbed: client-side DOM handler
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
JavaScript testbed: client-side style handler
20 |
21 |
Cross-browser style switcher and handler. Choose your style...
22 |
23 |
24 |
25 |
Show a list of all styles...
26 |
27 |
28 |
72 |
73 |
StyleHandler class (static)
74 |
Provides CSS switching functionality in all browsers.
75 |
76 |
Public methods
77 |
78 |
StyleHandler.Current()
returns the title of the active style
79 |
StyleHandler.Titles()
returns an array of all style titles
80 |
StyleHandler.Activate(string title)
sets the active style (will revert to the current one if the title is not valid)
81 |
StyleHandler.LoadPreference()
sets the user's saved style (done automatically on page load)
82 |
StyleHandler.SavePreference()
stores the user's style (done on page unload and when Activate is called)
83 |
84 |
85 |
Notes
86 |
It was intended to provide load and unload events whenever a new style was activated. However, since some browsers natively support style switching, this could not easily be implemented. The only solution would be to periodically check the default stylesheet and run events accordingly.
87 |
88 |
Event handlers have therefore been removed. If a style implements functionality that is not required in an alternative style, e.g. a drop-down menu, you will either need to create a style watcher, or (preferably) implement appropriate show/hide selectors in the CSS.
Client-side cross-browser XML manipulation. Note that this is closely tied to the WebService and DOM objects.
31 |
32 |
33 |
34 |
35 |
38 |
39 |
87 |
88 |
XML class (static)
89 |
90 |
An object that provides XML document manipulation functions. Note that XSL transformations are not supported in Opera, so this object should be used with care.
91 |
92 |
Public properties
93 |
94 |
XML.ElementNode
the value of an element node (1)
95 |
XML.AttributeNode
the value of an attribute node (2)
96 |
XML.TextNode
the value of a text node (3)
97 |
XML.CommentNode
the value of an attribute node (8)
98 |
99 |
100 |
Public methods
101 |
102 |
XML.New()
create a new XML document
103 |
XML.Transform(XMLdocument xml, XMLdocument xsl)
returns result of XML/XSL transformation (not supported in Opera)
104 |
XML.Copy(node from, node to)
copy the children of node 'from' to children of node 'to'. Unlike DOM.Copy, this works with XML documents
105 |
XML.RemoveChildren(node)
remove all node children
106 |
107 |
108 |
Example
109 |
110 | function XMLtest() {
111 | // use WebService object to fetch XML
112 | var wsXML = new WebService("resources/test.xml", "GET");
113 | wsXML.Name = "xml";
114 | wsXML.OnComplete = XMLcheck;
115 | wsXML.Call();
116 |
117 | // use WebService object to fetch XSL
118 | var wsXSL = new WebService("resources/test.xsl", "GET");
119 | wsXSL.Name = "xsl";
120 | wsXSL.OnComplete = XMLcheck;
121 | wsXSL.Call();
122 | }
123 |
124 | function XMLcheck(WS) {
125 | if (WS.Name == "xml") xml = WS.ResponseXML; else xsl = WS.ResponseXML;
126 | if (xml && xsl) {
127 | var transdoc = XML.Transform(xml, xsl);
128 | if (transdoc) XML.Copy(transdoc.documentElement, DOM.Id("xmldoc")); // copy transformed XML to document
129 | else DOM.SetText(DOM.Id("xmldoc"), "Transformation failed.");
130 | }
131 | }
132 |
133 |
134 |
135 |
--------------------------------------------------------------------------------
/js/aurora/jquery.checkboxtoggle.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * jQuery toggle checkboxes plugin
3 | * http://optimalworks.net/
4 | * Copyright 2011, Craig Buckler
5 | */
6 |
7 | (function($) {
8 |
9 | $.fn.CheckboxToggle = function() {
10 |
11 | // click event
12 | $(this).click(function(e) {
13 | e.preventDefault();
14 | var t = $(e.target);
15 | var state = t.hasClass("toggleall");
16 | $("input[type='checkbox']", t.closest("fieldset")).prop("checked", state);
17 | });
18 |
19 | return this;
20 | };
21 |
22 | // initialise all buttons
23 | $(function() {
24 | $("a.toggleall").CheckboxToggle();
25 | $("a.togglenone").CheckboxToggle();
26 | });
27 |
28 | })(jQuery);
--------------------------------------------------------------------------------
/js/aurora/jquery.colourpicker.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * jQuery Colour Pickler plugin
3 | * http://optimalworks.net/
4 | * Copyright 2011, Craig Buckler
5 | */
6 |
7 | (function($) {
8 |
9 | $.fn.ColourPickler = function() {
10 |
11 | // configuration
12 | var $C = {
13 | ColourPickerClass: "colourpicker",
14 | ColourBoxClass: "colourlist",
15 | ColourPrefix: "colour",
16 | ColourActive: "active",
17 | OffsetX: -10,
18 | OffsetY: 10,
19 | WidthAdd: -10,
20 | CloseDelay: 300
21 | };
22 |
23 | var Open, ColourBox, cTimer;
24 |
25 | // display colour picker
26 | function ColourBoxShow(e) {
27 |
28 | Open = true;
29 | var t = e.target, $t = $(t);
30 |
31 | if (!ColourBox) {
32 |
33 | // create colour box
34 | var cols = $(t).data("bound").data("colours");
35 |
36 | var ul = document.createElement("ul");
37 | ul.setAttribute("tabindex", 0);
38 | ul.className = $C.ColourBoxClass;
39 | for (var c = 0; c <= cols; c++) {
40 | var li = document.createElement("li");
41 | li.className = $C.ColourPrefix + c;
42 | li.setAttribute("tabindex", 0);
43 | ul.appendChild(li);
44 | }
45 | ColourBox = $(ul).appendTo("body");
46 |
47 | // events
48 | ColourBox.click(ChooseColour).keyup(ChooseColour).focusout(ChooseColour);
49 | }
50 |
51 | // bind element
52 | ColourBox.data("input", t);
53 |
54 | // position box
55 | var o = $t.offset();
56 | o.left += t.offsetWidth + $C.OffsetX;
57 | o.top += $C.OffsetY;
58 | ColourBox.css("display", "block");
59 | ColourBox.offset(o);
60 | ColourBox[0].focus();
61 | cTimer = null;
62 |
63 | }
64 |
65 |
66 | // handle keypresses
67 | function ChooseColour(e) {
68 |
69 | if (e.type == "focusout" && !cTimer) {
70 | cTimer = setTimeout(function() { ChooseColour(e); }, $C.CloseDelay);
71 | return;
72 | }
73 |
74 | var t = e.target;
75 | if (t && t.nodeName.toLowerCase() == "li" && (e.type == "click" || e.keyCode == 13)) {
76 | ColourBox.data("input").className = $C.ColourPickerClass + " " + t.className;
77 | var c = t.className.substr(6);
78 | if (c == 0) c = "";
79 | $(ColourBox.data("input")).data("bound")[0].value = c;
80 | }
81 |
82 | Open = false;
83 | ColourBox.css("display", "none");
84 |
85 | }
86 |
87 |
88 | // autocomplete initialisation
89 | this.each(function() {
90 |
91 | // element
92 | var input = $(this);
93 |
94 | // bound input (real submitted value)
95 | var bound = this.id;
96 | bound = bound.substr(0, bound.length-7);
97 | bound = $('#'+bound);
98 | if (bound.length != 1 || !bound.data("colours")) return;
99 | input.attr("tabindex", 0);
100 | input.data("bound", bound);
101 |
102 | // events
103 | input.click(ColourBoxShow).focus(ColourBoxShow);
104 | $(input[0].form).submit(function (e) { if (Open) e.preventDefault(); });
105 |
106 | });
107 |
108 | return this;
109 | };
110 |
111 |
112 | // initialise all colour pickers
113 | $(function() {
114 | $('.colourpicker').ColourPickler();
115 | });
116 |
117 | })(jQuery);
--------------------------------------------------------------------------------
/js/aurora/jquery.draggable.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * jQuery draggable element plugin
3 | * http://optimalworks.net/
4 | * Copyright 2011, Craig Buckler
5 | */
6 |
7 | (function($) {
8 |
9 | $.fn.draggable = function(opts) {
10 |
11 | // default configuration
12 | var config = $.extend({}, {
13 | minX: -999999, // minimum X movement
14 | maxX: +999999, // maximum X movement
15 | minY: -999999, // minimim Y movement
16 | maxY: +999999, // maximum Y movement
17 | horz: true, // horizontal movement permitted
18 | vert: true, // vertical movement permitted
19 | onStart: null, // drag start event
20 | onDrag: null, // drag event
21 | onDrop: null // drop event
22 | }, opts);
23 |
24 | var target = null, start = null;
25 | this.mousedown(DragStart);
26 |
27 | // start dragging
28 | function DragStart(e) {
29 | e.preventDefault();
30 | if (!target) {
31 | target = e.target;
32 | $(target).css({ position: "relative", zIndex: "99999" });
33 | start = {
34 | left: e.pageX - target.style.left.replace(/px/, ''),
35 | top: e.pageY - target.style.top.replace(/px/, '')
36 | };
37 | if (config.onStart) config.onStart(target);
38 | $(window).on({ mousemove: Dragging, mouseup: DragEnd });
39 | }
40 | }
41 |
42 | // dragging
43 | function Dragging(e) {
44 | e.preventDefault();
45 | if (config.horz) target.style.left = Math.min(Math.max(config.minX, e.pageX - start.left), config.maxX) + "px";
46 | if (config.vert) target.style.top = Math.min(Math.max(config.minY, e.pageY - start.top), config.maxY) + "px";
47 | if (config.onDrag) config.onDrag(target);
48 | }
49 |
50 | // end dragging
51 | function DragEnd(e) {
52 | e.preventDefault();
53 | if (config.onDrop) config.onDrop(target);
54 | target = start = null;
55 | $(window).off({ mousemove: Dragging, mouseup: DragEnd });
56 | }
57 |
58 | return this;
59 | };
60 |
61 | })(jQuery);
--------------------------------------------------------------------------------
/js/aurora/jquery.password.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * jQuery password generation plugin
3 | * http://optimalworks.net/
4 | * Copyright 2011, Craig Buckler
5 | */
6 |
7 | (function($) {
8 |
9 | $.fn.PasswordGenerate = function(opts) {
10 |
11 | // default configuration
12 | var config = $.extend({}, {
13 | password1: "#password",
14 | password2: "#password2",
15 | pwlength: 8,
16 | pwdict: "bcdfghkmnpqrstwxyz23456789"
17 | }, opts);
18 |
19 | // find inputs
20 | var p1 = $(config.password1);
21 | p1 = (p1.length == 1 ? p1[0] : null);
22 | var p2 = $(config.password2);
23 | p2 = (p2.length == 1 ? p2[0] : null);
24 |
25 | // click event
26 | if (p1 && p2) $(this).click(function(e) {
27 | e.preventDefault();
28 | var p = '';
29 | while (p.length < config.pwlength) {
30 | p += config.pwdict.substr(Math.floor(Math.random() * config.pwdict.length-1), 1);
31 | }
32 | p1.value = p2.value = p;
33 | p1.focus();
34 | });
35 |
36 | return this;
37 | };
38 |
39 | // initialise all password buttons
40 | $(function() {
41 | $("#passgen").PasswordGenerate();
42 | });
43 |
44 | })(jQuery);
--------------------------------------------------------------------------------
/js/aurora/jquery.tabs.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * jQuery tab handling plugin
3 | * http://optimalworks.net/
4 | * Copyright 2011, Craig Buckler
5 | */
6 |
7 | (function($) {
8 |
9 | $.fn.Tabs = function(opts) {
10 |
11 | // default configuration
12 | var config = $.extend({}, {
13 | onchange: null,
14 | }, opts);
15 |
16 | // click event handler
17 | function ClickTab(e) {
18 | e.preventDefault();
19 | $(e.target).ActivateTab();
20 | }
21 |
22 | // tab initialisation
23 | this.each(function() {
24 |
25 | var ul = $(this); // list element
26 | if (config.onchange) ul.data("onchange", config.onchange);
27 | if (!!ul.data("height")) return;
28 | ul.data("height", 0);
29 | var pActive = location.hash; // currently active tab
30 |
31 | // parse individual tabs
32 | var $a = $("a", ul), active = null;
33 | $a.each(function() {
34 | var hash = this.hash;
35 | var content = $(hash);
36 | ul.data("height", Math.max(ul.data("height"), content.height()));
37 | content.css("display", "none");
38 | if (!active || hash == pActive) active = this;
39 | });
40 |
41 | // activate first or active tab
42 | $(active).ActivateTab();
43 |
44 | // event handler
45 | $a.click(ClickTab);
46 |
47 | });
48 |
49 | return this;
50 | };
51 |
52 |
53 | // activate tab
54 | $.fn.ActivateTab = function() {
55 |
56 | // default configuration
57 | var config = {
58 | activeClass: "active",
59 | };
60 |
61 | this.each(function() {
62 |
63 | var a = this;
64 | var $a = $(a);
65 | var ul = $a.closest("ul");
66 | var active = ul.data("active");
67 | if (a != active) {
68 |
69 | // hide previously active tab
70 | if (active) {
71 | $(active).removeClass(config.activeClass);
72 | var $c = $(active.hash);
73 | ul.data("height", Math.max(ul.data("height"), $c.height()));
74 | $c.css("display", "none");
75 | }
76 |
77 | // show active tab
78 | $a.addClass(config.activeClass);
79 | $(a.hash).css({ "display":"block", "minHeight":ul.data("height")+"px" });
80 | ul.data("active", a);
81 |
82 | // run onchange function
83 | var onchange = ul.data("onchange") || null;
84 | if (onchange) onchange(a.hash);
85 | }
86 |
87 | });
88 |
89 | return this;
90 | }
91 |
92 |
93 | // initialise all tables
94 | $(function() {
95 | $("ul.tabset").Tabs();
96 | });
97 |
98 | })(jQuery);
--------------------------------------------------------------------------------
/js/aurora/jquery.totaliser.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * jQuery automated field totaliser
3 | * Apply class of (plus|minus|mult|div)-[-priority] to any form field, e.g.
4 | * "plus-total" - add this field to the value of #total
5 | * "mult-total-5" - multiply current #total value by this field
6 | * (given a priority of 5: lower priority numbers are evaluated first)
7 | *
8 | * http://optimalworks.net/
9 | * Copyright 2011, Craig Buckler
10 | */
11 |
12 | (function($) {
13 |
14 | $.fn.Totaliser = function() {
15 |
16 |
17 | // perform calculation
18 | function Calculate(e) {
19 |
20 | $.each($(this).data("linked"), function() {
21 |
22 | var total = $(this);
23 | var eq = total.data("total");
24 |
25 | // sort calculation by priority
26 | if (!total.data("sorted")) {
27 | eq.sort(function (a,b) { return a.priority - b.priority; });
28 | total.data("total", eq);
29 | total.data("sorted", true);
30 | }
31 |
32 | // do calculation
33 | var calc = 0, i, op, v;
34 | for (i = 0; sum = eq[i]; i++) {
35 | v = SWS.Convert.toInt(sum.field.value) || 0;
36 | switch(sum.op) {
37 | case "minus": calc -= v; break;
38 | case "mult": calc *= v; break;
39 | case "div": if (v != 0) calc /= v; break;
40 | default: calc += v; break;
41 | }
42 | }
43 |
44 | // update field
45 | total.val(SWS.Format.Number(calc, total.data("dp") || 0));
46 | if (calc && total.val() == "") total.val(calc);
47 |
48 | });
49 |
50 | }
51 |
52 |
53 | // initialize
54 | this.each(function() {
55 |
56 | // is an input?
57 | if (this.nodeName.toLowerCase() != "input") return;
58 |
59 | // get total ID
60 | var t = this.className.match(/(plus|minus|mult|div)\-(\w*)\-*(\d*)/i);
61 | if (t && t.length > 2) {
62 | var total = $("#"+t[2]);
63 | if (total.length == 1) {
64 |
65 | // define linked total and change event
66 | var $this = $(this);
67 | var ts = $this.data("linked");
68 | if (!ts) ts = [];
69 | ts[ts.length] = total;
70 | $this.data("linked", ts).change(Calculate);
71 |
72 | // define sum
73 | var eq = {
74 | op: t[1],
75 | field: this,
76 | priority: t[3] || 0
77 | };
78 | ts = total.data("total");
79 | if (!ts) ts = [];
80 | ts[ts.length] = eq;
81 | total.data("total", ts);
82 | total.data("sorted", false);
83 |
84 | }
85 | }
86 |
87 | });
88 |
89 | return this;
90 | };
91 |
92 | // initialise all fields
93 | $(function() {
94 | $("input[class*=plus-]").add("input[class*=minus-]").add("input[class*=mult-]").add("input[class*=div-]").Totaliser();
95 | });
96 |
97 | })(jQuery);
--------------------------------------------------------------------------------
/js/aurora/sws.main.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * Main JavaScript libraries
3 | * http://optimalworks.net/
4 | * Copyright 2012, Craig Buckler
5 | */
6 |
7 | var SWS = SWS || {};
8 |
9 |
10 | // _______________________________________________________
11 | // string functions
12 | SWS.String = function() {
13 |
14 | var reTrim = /^\s*|\s*$/g;
15 |
16 | // trim
17 | function Trim(s) {
18 | return String(s).replace(reTrim, "");
19 | }
20 |
21 |
22 | // left pad
23 | function LPad(s, len, chr) {
24 | chr = chr || " ";
25 | while (s.length < len) s = [chr, s].join("");
26 | return s;
27 | }
28 |
29 |
30 | // right pad
31 | function RPad(s, len, chr) {
32 | chr = chr || " ";
33 | while (s.length < len) s = [s, chr].join("");
34 | return s;
35 | }
36 |
37 |
38 | // HTMLencode
39 | function HTMLencode(s) {
40 | return s.replace(/"/ig, '"').replace(/'/ig, "'").replace(/</ig, "<").replace(/>/ig, ">").replace(/&/ig, "&").replace(/→/g, '\u2192').replace(/×/g, '\u00D7');
41 | }
42 |
43 |
44 | return {
45 | Trim: Trim,
46 | LPad: LPad,
47 | RPad: RPad,
48 | HTMLencode: HTMLencode
49 | };
50 |
51 | }();
52 |
53 |
54 | // _______________________________________________________
55 | // conversion functions
56 | SWS.Convert = function() {
57 |
58 | var reNum = new RegExp("[^\\d"+$C.numberpoint+"]", "g");
59 | var reDate = /(\d+)\D+(\d+)\D+(\d+)/g;
60 | var tpDate = null;
61 |
62 | // to integer
63 | function toInt(v) {
64 | return toFloat(v);
65 | }
66 |
67 |
68 | // to float
69 | function toFloat(v, dp) {
70 | dp = Math.pow(10, dp || 0);
71 | v = parseFloat(String(v).replace(reNum, ""));
72 | return (isNaN(v) ? 0 : Math.round(v * dp) / dp);
73 | }
74 |
75 |
76 | // to date
77 | function toDate(v) {
78 | var d = null, v = v.split(reDate);
79 | if (v.length >= 4) {
80 |
81 | // parse date format (done once)
82 | if (tpDate == null) {
83 | var df = $C.dateinput.toLowerCase().replace(/[^djmnoy]/g, "");
84 | tpDate = {
85 | "d": df.search(/d|j/) || 0,
86 | "m": df.search(/m|n/) || 0,
87 | "y": df.search(/o|y/) || 0
88 | };
89 | for (p in tpDate) if (typeof tpDate[p] == "number") tpDate[p]++;
90 | }
91 |
92 | // convert to date
93 | var y = parseInt(v[tpDate.y], 10);
94 | if (y < 100) y += 2000;
95 | d = new Date(y, parseInt(v[tpDate.m], 10)-1, parseInt(v[tpDate.d], 10));
96 |
97 | }
98 | return d;
99 | }
100 |
101 |
102 | return {
103 | toInt: toInt,
104 | toFloat: toFloat,
105 | toDate: toDate
106 | };
107 |
108 | }();
109 |
110 |
111 | // _______________________________________________________
112 | // localisation
113 | SWS.Format = function() {
114 |
115 | // format number
116 | function Number(v, dp) {
117 |
118 | v = String(SWS.Convert.toFloat(v, dp));
119 | var p = v.indexOf(".");
120 | if (p < 0) p = v.length;
121 |
122 | var adp = SWS.String.RPad(v.substr(p+1), dp, "0");
123 | var bdp = v.substr(0, p), obdp;
124 | while (bdp!=obdp) {
125 | obdp=bdp;
126 | bdp = bdp.replace(/(\d+)(\d{3})/g, "$1" + $C.numbersep + "$2");
127 | }
128 |
129 | return bdp + (adp.length > 0 ? $C.numberpoint + adp : "");
130 |
131 | }
132 |
133 |
134 | // format integer
135 | function Int(v) {
136 | return Number(v, 0);
137 | }
138 |
139 |
140 | // format currency
141 | function Currency(v) {
142 | return $C.currencypre + Number(v, $C.currencydp) + $C.currencypost;
143 | }
144 |
145 |
146 | // format date (PHP date format)
147 | function Date(v) {
148 |
149 | var r = "";
150 | if (v && v.getDate) {
151 |
152 | var d = String(v.getDate());
153 | var m = String(v.getMonth()+1);
154 | var y = String(v.getFullYear());
155 |
156 | r = $C.dateinput.replace(/d/g, SWS.String.LPad(d, 2, "0")).replace(/j/g, d).replace(/m/g, SWS.String.LPad(m, 2, "0")).replace(/n/g, m).replace(/y/g, y.substr(2)).replace(/o|Y/g, y);
157 |
158 | }
159 | return r;
160 |
161 | }
162 |
163 |
164 | return {
165 | Number: Number,
166 | Int: Int,
167 | Currency: Currency,
168 | Date: Date
169 | }
170 |
171 | }();
--------------------------------------------------------------------------------
/js/form_changes.js:
--------------------------------------------------------------------------------
1 | // An evolution of http://www.sitepoint.com/javascript-form-change-checker/
2 | // ensure script is loaded at end of page
3 |
4 | // find all forms and hidden elements
5 | (function() {
6 |
7 | // parse all forms
8 | var f, i, h, form = document.getElementsByTagName("form");
9 | for (f = form.length - 1; f >= 0; f--) {
10 |
11 | // count form elements
12 | form[f].fcElementCount = form[f].elements.length;
13 |
14 | // store hidden element initial value
15 | for (i = form[f].elements.length - 1; i >= 0; i--) {
16 | h = form[f].elements[i];
17 | if (h.nodeName.toLowerCase() == "input" && h.type.toLowerCase() == "hidden") {
18 | h.fcDefaultValue = h.value;
19 | }
20 | }
21 | }
22 |
23 | }());
24 |
25 |
26 | // FormChanges(id-string|node) - pass a form node or ID
27 | // Returns an array of nodes of inputs changed since the page was loaded
28 | // (If elements are removed, the last item will be the form node itself)
29 | // e.g. if (FormChanges("myform").length > 0) { console.log("changed"); }
30 | function FormChanges(form) {
31 | if (typeof form == "string") form = document.getElementById(form);
32 | if (!form || !form.nodeName || form.nodeName.toLowerCase() != "form") return null;
33 |
34 | var changed = [], n, c, def, o, ol, opt;
35 |
36 | for (var e = 0, el = form.elements.length; e < el; e++) {
37 | n = form.elements[e];
38 | c = false;
39 |
40 | switch (n.nodeName.toLowerCase()) {
41 |
42 | // select boxes
43 | case "select":
44 | def = 0;
45 | for (o = 0, ol = n.options.length; o < ol; o++) {
46 | opt = n.options[o];
47 | c = c || (opt.selected != opt.defaultSelected);
48 | if (opt.defaultSelected) def = o;
49 | }
50 | if (c && !n.multiple) c = (def != n.selectedIndex);
51 | break;
52 |
53 | // input / textarea
54 | case "textarea":
55 | case "input":
56 |
57 | switch (n.type.toLowerCase()) {
58 | case "checkbox":
59 | case "radio":
60 | // checkbox / radio
61 | c = (n.checked !== n.defaultChecked);
62 | break;
63 | case "hidden":
64 | // hidden value
65 | c = (n.value !== n.fcDefaultValue);
66 | break;
67 | default:
68 | // standard values
69 | c = (n.value !== n.defaultValue);
70 | break;
71 | }
72 | break;
73 | }
74 | if (c) changed.push(n);
75 | }
76 |
77 | // have inputs been added or removed?
78 | if (el !== form.fcElementCount) changed.push(form);
79 |
80 | return changed;
81 | }
82 |
--------------------------------------------------------------------------------
/js/owl/image.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | owl core test
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
101 |
102 |
103 |
104 |
105 |
Image lightbox test
106 |
107 |
Need an inner DIV with overflow:hidden.
108 |
Must calculate difference between inner and outer dimensions. Then use those to calculate the image maximum width and height? NO - offsetWidth will be the same as the outer width because padding is added.