1 // =========================================================================
\r
2 /// IWF - Interactive Website Framework. Javascript library for creating
\r
3 /// responsive thin client interfaces.
\r
5 /// Copyright (C) 2005 Brock Weaver brockweaver@users.sourceforge.net
\r
7 /// This library is free software; you can redistribute it and/or modify
\r
8 /// it under the terms of the GNU Lesser General Public License as published
\r
9 /// by the Free Software Foundation; either version 2.1 of the License, or
\r
10 /// (at your option) any later version.
\r
12 /// This library is distributed in the hope that it will be useful, but
\r
13 /// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
\r
14 /// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
\r
15 /// License for more details.
\r
17 /// You should have received a copy of the GNU Lesser General Public License
\r
18 /// along with this library; if not, write to the Free Software Foundation,
\r
19 /// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
\r
22 /// brockweaver@users.sourceforge.net
\r
23 /// 1605 NW Maple Pl
\r
24 /// Ankeny, IA 50021
\r
26 //! http://iwf.sourceforge.net/
\r
27 // =========================================================================
\r
28 //! NOTE: To minimize file size, strip all fluffy comments (except the LGPL, of course!)
\r
29 //! using the following regex (global flag and multiline on):
\r
30 //! ^\t*//([^/!].*|$)
\r
32 // This reduces file size by about 30%, give or take.
\r
34 //! To rip out only logging statements (commented or uncommented):
\r
36 // =========================================================================
\r
38 // --------------------------------------------------------------------------
\r
46 //! Brock Weaver - brockweaver@users.sourceforge.net
\r
47 //! v 0.2 - 2005-11-14
\r
48 //! iwfcore bug patch
\r
49 //! --------------------------------------------------------------------------
\r
50 //! - fixed iwfAttribute to return most current value instead of initial value
\r
52 //! v 0.1 - 2005-06-05
\r
53 //! Initial release.
\r
54 //! --------------------------------------------------------------------------
\r
56 // -----------------------------------
\r
57 // Begin: Configurable variables
\r
58 // -----------------------------------
\r
60 // set to true to enable logging. Logging simply means certain values are appended to a string. nothing is written out or communicated over the wire anywhere.
\r
61 var _iwfLoggingEnabled = true;
\r
64 // -----------------------------------
\r
65 // End: Configurable variables
\r
66 // -----------------------------------
\r
69 // -----------------------------------
\r
70 // Begin: Element Utility Functions
\r
71 // -----------------------------------
\r
73 function iwfGetById(id){
\r
75 if (iwfIsString(id) || iwfIsNumber(id)) el = document.getElementById(id);
\r
76 else if (typeof(id) == 'object') el = id;
\r
80 function iwfGetForm(id){
\r
81 var frm = iwfGetById(id);
\r
83 // or by forms collection...
\r
84 frm = document.forms ? document.forms[frm] : null;
\r
86 // or by tag elements...
\r
87 var allforms = iwfGetByTagName('form');
\r
88 for(var i=0;i<allforms.length;i++){
\r
89 if (iwfAttribute(allforms[i], 'name') == id){
\r
99 function iwfGetByNameWithinForm(form, nm){
\r
100 var frm = iwfGetForm(form);
\r
102 iwfLog("IWF Core Error: Could not locate form by id, document.forms, or document[] named '" + form + "'", true);
\r
105 // find element within this form with given id.
\r
107 if (iwfIsString(nm) || iwfIsNumber(nm)) {
\r
108 for(var i=0;i<frm.elements.length;i++){
\r
109 if (frm.elements[i].name == nm || frm.elements[i].id == nm){
\r
110 el = frm.elements[i];
\r
117 //iwfLog('iwfGetByNameWithinForm returning:\n\n' + iwfElementToString(el), true);
\r
122 function iwfGetOrCreateByNameWithinForm(form, nm, tagNameOrHtml, typeAtt){
\r
123 var elFrm = iwfGetForm(form);
\r
126 iwfLog("IWF Core Error: <form> with name or id of '" + form + "' could not be located.", true);
\r
130 var el = iwfGetByNameWithinForm(form, nm);
\r
132 // element does not exist. create it.
\r
133 el = document.createElement(tagNameOrHtml);
\r
134 iwfAttribute(el, 'name', nm);
\r
137 iwfAttribute(el, 'type', typeAtt);
\r
140 elFrm.appendChild(el);
\r
146 function iwfRemoveChild(parentId, id){
\r
147 var elParent = iwfGetById(parentId);
\r
149 var elChild = iwfGetById(id);
\r
151 elParent.removeChild(elChild);
\r
157 function iwfGetOrCreateById(id, tagNameOrHtml, parentNodeId){
\r
158 var el = iwfGetById(id);
\r
160 // element does not exist. create it.
\r
161 el = document.createElement(tagNameOrHtml);
\r
162 iwfAttribute(el, 'id', id);
\r
163 iwfAttribute(el, 'name', id);
\r
166 var elParent = iwfGetById(parentNodeId);
\r
168 iwfAddChild(elParent, el);
\r
169 } else if (parentNodeId.toLowerCase() == 'body'){
\r
170 iwfAddChild(document.body, el);
\r
179 function iwfAddChild(parentNodeId, childNodeId, atFront){
\r
181 var elChild = iwfGetById(childNodeId);
\r
182 if (!elChild) return null;
\r
184 // get the element who is to be the parent
\r
185 var elParent = iwfGetById(parentNodeId);
\r
187 // parent not found, try by tagName
\r
189 var nodes = iwfGetByTagName(parentNodeId);
\r
190 if (nodes && nodes.length > 0){
\r
191 // always use the first element with that tag name as the parent (think 'body')
\r
194 // couldn't find by id or tag name. bomb out.
\r
201 if (!atFront || !elParent.hasChildNodes()){
\r
202 // append as last child of elParent
\r
203 elParent.appendChild(elChild);
\r
205 // append as first child of elParent
\r
206 elParent.insertBefore(elChild, elParent.childNodes[0]);
\r
212 function iwfRemoveNode(id){
\r
213 var el = iwfGetById(id);
\r
214 if (!el) return false;
\r
215 document.removeNode(el);
\r
219 function iwfElementToString(id){
\r
220 var el = iwfGetById(id);
\r
221 if (!el) return 'element ' + id + ' does not exist.';
\r
223 var s = '<' + el.tagName + ' ';
\r
224 if (el.attributes){
\r
225 for(var i=0;i<el.attributes.length;i++){
\r
226 var att = el.attributes[i];
\r
227 s += ' ' + att.nodeName + '="' + att.nodeValue + '" ';
\r
230 if (el.innerHTML == ''){
\r
233 s += '>' + el.innerHTML + '</' + el.tagName + '>';
\r
239 function iwfGetByTagName(tagName, root) {
\r
240 var nodes = new Array();
\r
241 tagName = tagName || '*';
\r
242 root = root || document;
\r
244 if (tagName == '*'){
\r
247 nodes = root.all.tags(tagName);
\r
249 } else if (root.getElementsByTagName) {
\r
250 nodes = root.getElementsByTagName(tagName);
\r
255 function iwfGetByAttribute(tagName, attName, regex, callback) {
\r
256 var a, list, found = new Array();
\r
257 var reg = new RegExp(regex, 'i');
\r
258 list = iwfGetByTagName(tagName);
\r
259 for(var i=0;i<list.length;++i) {
\r
260 a = list[i].getAttribute(attName);
\r
261 if (!a) {a = list[i][attName];}
\r
262 if (typeof(a)=='string' && a.search(regex) != -1) {
\r
263 found[found.length] = list[i];
\r
264 if (callback) callback(list[i]);
\r
270 function iwfAttribute(id, attName, newval){
\r
271 var el = iwfGetById(id);
\r
275 if (iwfExists(newval)){
\r
276 if (newval == null){
\r
277 // remove it, don't set it to null.
\r
278 iwfRemoveAttribute(el, attName);
\r
280 el.setAttribute(attName, newval);
\r
283 // 2005-11-14 Brock Weaver
\r
284 // added check for attribute on el before trying getAttribute method
\r
285 // (Thanks J.P. Jarolim!)
\r
288 } else if (el.getAttribute) {
\r
289 val = el.getAttribute(attName);
\r
294 function iwfRemoveAttribute(id, attName){
\r
295 var el = iwfGetById(id);
\r
297 el.removeAttribute(attName);
\r
302 function iwfGetParent(id, useOffsetParent){
\r
303 var el = iwfGetById(id);
\r
304 if (!el) return null;
\r
306 if (useOffsetParent && iwfExists(el.offsetParent)) { cur = el.offsetParent;
\r
307 } else if (iwfExists(el.parentNode)) { cur = el.parentNode;
\r
308 } else if (iwfExists(el.parentElement)) { cur = el.parentElement; }
\r
312 // -----------------------------------
\r
313 // End: Element Utility Functions
\r
314 // -----------------------------------
\r
317 // -----------------------------------
\r
318 // Begin: Encoding Utility Functions
\r
319 // -----------------------------------
\r
321 function iwfXmlEncode(s){
\r
325 var ret = s.replace(/&/gi, '&').replace(/>/gi,'>').replace(/</gi, '<').replace(/'/gi, ''').replace(/"/gi, '"');
\r
326 //alert('after xmlencoding: \n\n\n' + ret);
\r
330 function iwfXmlDecode(s){
\r
334 var ret = s.replace(/>/gi, '>').replace(/</gi,'<').replace(/'/gi, '\'').replace(/"/gi, '"').replace(/&/gi, '&');
\r
335 //alert('after xmldecoding: \n\n\n' + ret);
\r
339 function iwfHtmlEncode(s){
\r
343 var ret = s.replace(/&/gi, '&').replace(/>/gi,'>').replace(/</gi, '<').replace(/'/gi, ''').replace(/"/gi, '"');
\r
344 //alert('after xmlencoding: \n\n\n' + ret);
\r
348 function iwfHtmlDecode(s){
\r
352 var ret = s.replace(/>/gi, '>').replace(/</gi,'<').replace(/'/gi, '\'').replace(/"/gi, '"').replace(/&/gi, '&');
\r
353 //alert('after xmldecoding: \n\n\n' + ret);
\r
356 // -----------------------------------
\r
357 // End: Encoding Utility Functions
\r
358 // -----------------------------------
\r
361 // -----------------------------------
\r
362 // Begin: Conversion / Formatting Utility Functions
\r
363 // -----------------------------------
\r
365 function iwfExists(){
\r
366 for(var i=0;i<arguments.length;i++){
\r
367 if(typeof(arguments[i])=='undefined') return false;
\r
372 function iwfIsString(s){
\r
373 return typeof(s) == 'string';
\r
376 function iwfIsNumber(n){
\r
377 return typeof(n) == 'number';
\r
380 function iwfIsBoolean(b){
\r
381 return typeof(b) == 'boolean';
\r
384 function iwfIsDate(val){
\r
385 var dt = iwfDateFormat(val);
\r
389 // determine if the month/day makes sense.
\r
390 var mo = iwfToInt(dt.substring(0,2));
\r
391 var dy = iwfToInt(dt.substring(3,2));
\r
392 var yr = iwfToInt(dt.substring(6,4));
\r
403 if (yr % 4 == 0 && (yr % 100 != 0 || yr % 400 == 0)){
\r
408 // 1, 3, 5, 7, 8, 10, 12
\r
412 return dy > 0 && dy <= maxdy;
\r
416 function iwfDateFormat(val){
\r
418 if (val.indexOf(delim) == -1){
\r
422 var today = new Date();
\r
423 var mo = '00' + (today.getMonth() + 1);
\r
424 var dy = '00' + (today.getDate());
\r
425 var yr = today.getFullYear();
\r
426 var arr = val.split(delim);
\r
427 switch(arr.length){
\r
429 //! possibles: 9/2, 9/2004, 09/06,
\r
430 //! assume first is always month
\r
431 mo = '00' + arr[0];
\r
432 if (arr[1].length == 4){
\r
433 //! assume second is year.
\r
436 //! assume second is date.
\r
437 dy = '00' + arr[1];
\r
441 //! possibles: 9/2/1, 9/02/04, 09/02/2004, 9/2/2004
\r
442 mo = '00' + arr[0];
\r
443 dy = '00' + arr[1];
\r
444 switch(arr[2].length){
\r
446 yr = '200' + arr[2];
\r
450 yr = '20' + arr[2];
\r
452 yr = '19' + arr[2];
\r
456 //! 3 digits... assume 2000 I guess
\r
471 mo = mo.substring(mo.length - 2);
\r
472 dy = dy.substring(dy.length - 2);
\r
473 return mo + '/' + dy + '/' + yr;
\r
477 function iwfToInt(val, stripFormatting){
\r
478 var s = iwfIntFormat(val, stripFormatting);
\r
479 return parseInt(s, 10);
\r
482 function iwfToFloat(val, dp, stripFormatting){
\r
483 var s = iwfFloatFormat(val, dp, stripFormatting);
\r
484 return parseFloat(s);
\r
487 function iwfIntFormat(val, stripFormatting){
\r
488 return iwfFloatFormat(val, -1, stripFormatting);
\r
491 function iwfFloatFormat(val, dp, stripFormatting){
\r
492 if (stripFormatting && iwfIsString(val)){
\r
493 val = val.replace(/[^0-9\.]/gi,'');
\r
500 var pos = s.indexOf('.');
\r
505 s += '0000000000000000000';
\r
506 s = s.substr(0,pos+dp+1);
\r
510 // -----------------------------------
\r
511 // End: Conversion / Formatting Utility Functions
\r
512 // -----------------------------------
\r
514 // -----------------------------------
\r
515 // Begin: Form Submittal Utility Functions
\r
516 // -----------------------------------
\r
517 function iwfDoAction(act, frm, id, targetElement){
\r
518 // validate the form first
\r
519 if (window.iwfOnFormValidate){
\r
520 if (!iwfOnFormValidate(act)){
\r
526 // try by id first...
\r
527 frm = iwfGetForm(frmId);
\r
530 iwfLog('IWF Core Error: Could not locate form with id or name of ' + frmId, true);
\r
534 // get or create the iwfId
\r
535 var elId = iwfGetOrCreateById('iwfId', 'input');
\r
538 iwfLog('IWF Core Error: Could not create iwfId element!', true);
\r
541 iwfAttribute(elId, 'value', id);
\r
542 iwfRemoveAttribute(elId, 'disabled');
\r
544 if (!iwfGetParent(elId)){
\r
545 // our element has not been added to the document yet.
\r
546 iwfAttribute(elId, 'type', 'hidden');
\r
547 if (!iwfAddChild(frm, elId)){
\r
548 iwfLog('IWF Core Error: Created iwfId element, but could not append to form ' + frm.outerHTML, true);
\r
555 // get or create the iwfMode
\r
556 var elMode = iwfGetOrCreateById('iwfMode', 'input');
\r
558 iwfLog('IWF Core Error: Could not create iwfMode element!', true);
\r
561 iwfAttribute(elMode, 'value', act);
\r
562 iwfRemoveAttribute(elMode, 'disabled');
\r
563 if (!iwfGetParent(elMode)){
\r
564 // our element has not been added to the document yet.
\r
565 iwfAttribute(elMode, 'type', 'hidden');
\r
566 if (!iwfAddChild(frm, elMode)){
\r
567 iwfLog('IWF Core Error: Created iwfMode element, but could not append to form ' + frm.outerHTML, true);
\r
573 // make our request
\r
574 var elRealTarget = iwfGetById(targetElement);
\r
576 // use ajax because they specified a particular element to shove the results into.
\r
578 // get or create the iwfTarget
\r
579 var elTarget = iwfGetOrCreateById('iwfTarget', 'input');
\r
581 iwfLog('IWF Core Error: Could not create iwfTarget element under form ' + frm.outerHTML, true);
\r
584 iwfAttribute(elTarget, 'value', iwfAttribute(elRealTarget, 'id'));
\r
585 iwfRemoveAttribute(elTarget, 'disabled');
\r
586 if (!iwfGetParent(elTarget)){
\r
587 // our element has not been added to the document yet.
\r
588 iwfAttribute(elTarget, 'type', 'hidden');
\r
589 if (!iwfAddChild(frm, elTarget)){
\r
590 iwfLog('IWF Core Error: Created iwfTarget element, but could not append to form ' + frm.outerHTML, true);
\r
596 if (!window.iwfRequest){
\r
597 iwfLog("IWF Core Error: when using the iwfDo* functions and passing a targetElement, you must also reference the iwfajax.js file from your main html file.", true);
\r
599 //alert('calling iwfRequest(' + frm + ')');
\r
603 // do a normal html submit, since they didn't specify a particular target
\r
604 iwfLog('doing frm.submit()', true);
\r
609 function iwfDoEdit(formId, id, targetElement){
\r
610 iwfDoAction('edit', formId, id, targetElement);
\r
612 function iwfDoSave(formId, id, targetElement){
\r
613 iwfDoAction('save', formId, id, targetElement);
\r
615 function iwfDoDelete(formId, id, targetElement){
\r
616 iwfDoAction('delete', formId, id, targetElement);
\r
618 function iwfDoAdd(formId, id, targetElement){
\r
619 iwfDoAction('add', formId, id, targetElement);
\r
621 function iwfDoSelect(formId, id, targetElement){
\r
622 iwfDoAction('select', formId, id, targetElement);
\r
624 function iwfDoCancel(formId, id, targetElement){
\r
625 iwfDoAction('cancel', formId, id, targetElement);
\r
628 function iwfMailTo(uid, host){
\r
629 // this is just so an email doesn't have to be output to the browser in raw text for
\r
630 // email harvesters to grab...
\r
631 location.href = 'mailto:' + uid + '@' + host;
\r
634 function iwfClickLink(id){
\r
635 var el = iwfGetById(id);
\r
641 location.href = el.href;
\r
645 function iwfShowMessage(msg){
\r
646 var el = iwfGetById('msg');
\r
648 // window.status = msg;
\r
649 alert(msg + '\n\nTo supress this alert, add a tag with an id of "msg" to this page.');
\r
651 el.innerHTML = msg.replace(/\n/, '<br />');
\r
656 // -----------------------------------
\r
657 // End: Form Submittal Utility Functions
\r
658 // -----------------------------------
\r
660 // -----------------------------------
\r
661 // Begin: Logging Utility Functions
\r
662 // -----------------------------------
\r
664 var _iwfLoggedItems = "";
\r
665 function iwfLog(txt, showAlert){
\r
666 if (_iwfLoggingEnabled){
\r
667 _iwfLoggedItems += txt + '\n';
\r
669 //! send to big bit bucket in the sky (/dev/null)
\r
676 function iwfHideLog(){
\r
677 iwfGetById("iwfLog").style.display="none";
\r
680 function iwfClearLog(){
\r
681 _iwfLoggedItems = '';
\r
685 function iwfRefreshLog(){
\r
690 function iwfShowLog(){
\r
691 if (!_iwfLoggingEnabled){
\r
692 alert("Logging for IWF has been disabled.\nSet the _iwfLoggingEnabled variable located in the iwfcore.js (or iwfconfig.js) file to true to enable logging.");
\r
694 var el = iwfGetOrCreateById('iwfLog', 'div', 'body');
\r
696 alert(_iwfLoggedItems);
\r
698 el.style.position = 'absolute';
\r
699 el.style.zIndex = '999999';
\r
700 el.style.left = '10px';
\r
701 el.style.top = '200px';
\r
702 el.style.color = 'blue';
\r
703 el.style.width = '500px';
\r
704 el.style.height = '300px';
\r
705 el.style.overflow = 'scroll';
\r
706 el.style.padding = '5px 5px 5px 5px;'
\r
707 el.style.backgroundColor = '#efefef';
\r
708 el.style.border = '1px dashed blue';
\r
709 el.style.display = 'block';
\r
710 el.style.visibility = 'visible';
\r
712 // el.innerHTML = "IWF Log <span style='width:100px'> </span><a href='javascript:iwfRefreshLog();'>refresh</a> <a href='javascript:iwfHideLog();'>close</a> <a href='javascript:iwfClearLog();'>clear</a>:<hr />" + iwfXmlEncode(_iwfLoggedItems).replace(/\n/gi, '<br />').replace(/\t/gi,' ');
\r
713 el.innerHTML = "IWF Log <span style='width:100px'> </span><a href='javascript:iwfRefreshLog();'>refresh</a> <a href='javascript:iwfHideLog();'>close</a> <a href='javascript:iwfClearLog();'>clear</a>:<hr /><pre>" + _iwfLoggedItems.replace(/</gi, '<').replace(/>/gi, '>') + "</pre>";
\r
720 // -----------------------------------
\r
721 // End: Logging Utility Functions
\r
722 // -----------------------------------
\r