/** * This file contains a collection of JavaScript functions * required by various Knickers components. * * This is not meant to be an extensive library; * at some point we will be including a third-party JavaScript library for * underlying functionality -- the functions here are Knickers-specific functions. * *@author Knickers Dev Team *$Id: common.js,v 1.22 2009/03/05 19:13:01 abassett Exp $ * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is knickersproject.org code. * * The Initial Developer of the Original Code is * SurfMerchants LLC. * Portions created by the Initial Developer are Copyright (C) 2007 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Knickers Dev Team * * Alternatively, the contents of this file may be used under the terms of * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of the LGPL, and not to allow others to * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of either the MPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ /** * Find a document element based on the DOM id. * This will be replaced!! * * Inspired by Michael Foster's (Cross-Browser.com) xGetElementById * *@access public *@param string DOM id of element to find *@param object Optional document object (uses the current document by default) *@return object */ function k_getElementById(elemid, doc) { if(!doc) doc = document; if(typeof(elemid) != 'string') return elemid; var ret; if(doc.getElementById) ret = doc.getElementById(elemid); else if(doc.all) ret = doc.all[elemid]; else ret = null; return ret; } /** * this is a specialized function for dynamically adding new things * takes an id of a block containing inputs, figures out what they should * be named and sticks them in front of the block * *@access public *@param string DOM id of block of inputs *@return object */ function k_addAdders(addBlockId) { var addBlock = k_getElementById(addBlockId); if(!addBlock) return alert('Could not add, sorry, please complain to jim'); var holder = document.createElement(addBlock.tagName); if(addBlock.psuedoID == null) k_findSpawned(addBlock); else addBlock.psuedoID ++; var sRegExInput = new RegExp(addBlockId, "g"); if(addBlock.tagName.toUpperCase() == 'TR') { var kids = addBlock.childNodes.length; for(var i=0;i maxID) maxID = cleanID } } } elem.psuedoID = (maxID/1)+1; } /** * this is a specialized function for dynamically adding new things * finds blocks of inputs and clears them out so they dont get submitted * *@access public *@return object */ function k_clearAdder() { formLen = document.forms.length; for(var i=0;i 0) { node = __k_find_trans_input(elem.childNodes[j]); if(node) return node; } } return false; } /** * add a sort * * @return void * @access public * @param string namespace of this sorter * @param string field to sort by * @param string direction to sort in */ function __k_addSort(namespace,field,direction) { var fieldElem = k_getElementById(namespace+'SORT_FIELD'); var dirElem = k_getElementById(namespace+'SORT_DIRECTION'); if(!fieldElem || !dirElem) return alert('could not sort, master sort inputs not found.'); fieldElem.value = field; dirElem.value = direction; k_cleanSubmit(fieldElem.form); } // ***** start simple AJAX mechanism ***** // states we provide to the callback funtion var K_AJAX_NOT_SUPPORTED = -1; var K_AJAX_LOADING = 1; var K_AJAX_COMPLETE_FAILURE = -2; var K_AJAX_COMPLETE_SUCCESS = 10; // states from the internal request var XMLHTTP_RESPONSE_COMPLETE = 4; var XMLHTTP_STATUS_SUCCESS = 200; // this will store our cached requests var k_AJAXRequests = new Object(); /** * This is an attempt at a making AJAX requests relatively easy to deal with. * Basically, you set up a callback function as an event handler for a few different * states. This callback will be called during the course of a request initiated by * calling k_remoteRequest(). * * This mechanism also provides some caching; that is, if you've already made a request * with a given url and post params, it will not make the request again -- it will * simply call your callback function with a copy of the previous result. * * The callback function will always be called with an k_AJAXRequest object and a * K_AJAX_ constant representing the state. * * Example usage: * * function myCallback(request, status) * { * switch(status) * { * case K_AJAX_NOT_SUPPORTED: * alert('Sorry, your browser does not appear to support remote requests.'); * break; * case K_AJAX_LOADING: * alert('Loading!'); * break; * case K_AJAX_COMPLETE_FAILURE: * alert('Sorry, we could not complete your request at this time.'); * break; * case K_AJAX_COMPLETE_SUCCESS: * alert('Complete!' + request.getResponseText()); * break; * } * } * * k_remoteRequest('http://domain.com/somepage.php', 'myCallback'); * *@access public *@param string remoteURL - full absolute URL for the request *@param string callbackFunction - gets called with the k_AJAXRequest object and a K_AJAX_ constant representing the state. *@param string postParams - if these are provided, we will do a POST instead of a GET *@param string otherParams - anything else you want for future reference, but not part of the actual request; accesible as AJAXRequest.otherParams. *@param boolean async - should this request be make asynchronously? true by default. *@param boolean nocache - normally requests are cached...if you don't want it to cache, send true here. *@return k_AJAXRequest */ function k_remoteRequest(remoteURL, callbackFunction, postParams, otherParams, async, nocache) { var key = remoteURL + '|' + postParams; // cached? if(!nocache && k_AJAXRequests[key]) { // create a new object with our parameters, // and just set the response accordingly var cached = new k_AJAXRequest(remoteURL, callbackFunction, postParams, otherParams, async); cached.request = k_AJAXRequests[key].request; cached.status = k_AJAXRequests[key].status; eval(cached.callbackFunction)(cached, cached.status); } else { k_AJAXRequests[key] = new k_AJAXRequest(remoteURL, callbackFunction, postParams, otherParams, async); k_AJAXRequests[key].makeRequest(); } } /** * The following function is a simplified version * of the bind function from the "prototype.js" library. *@see http://prototype.conio.net/, http://www.sergiopereira.com/articles/prototype.js.html * * Returns an instance of the function pre-bound to the * function(=method) owner object. */ Function.prototype.bind = function(objToOperateOn) { // stupid lexical scoping makes defining these here necessary. var localthis = this; return function() { return localthis.apply(objToOperateOn); } } /** * This is the AJAXRequest class. Typically you don't want to use this directly; * call k_remoteRequest() instead. * *@access public *@param string remoteURL - full absolute URL for the request *@param string callbackFunction - gets called with the k_AJAXRequest object and a K_AJAX_ constant representing the state. *@param string postParams - if these are provided, we will do a POST instead of a GET *@param string otherParams - anything else you want for future reference, but not part of the actual request; accesible as AJAXRequest.otherParams. *@param boolean async - should this request be make asynchronously? true by default. *@return k_AJAXRequest */ function k_AJAXRequest(remoteURL, callbackFunction, postParams, otherParams, async) { this.remoteURL = remoteURL; this.callbackFunction = callbackFunction; this.postParams = postParams; this.otherParams = otherParams; this.request = null; this.async = (async == null) ? true : async; } /** * This simply calls the callback function when the request is complete, * passing the AJAXRequest object. * */ k_AJAXRequest.prototype.onStateChange = function() { // if the request shows "complete" if(this.request.readyState == XMLHTTP_RESPONSE_COMPLETE) { if(this.request.status == XMLHTTP_STATUS_SUCCESS) { // all is well! this.status = K_AJAX_COMPLETE_SUCCESS; eval(this.callbackFunction)(this, K_AJAX_COMPLETE_SUCCESS); } else { // uh oh! this.status = K_AJAX_COMPLETE_FAILURE; eval(this.callbackFunction)(this, K_AJAX_COMPLETE_FAILURE); } } } /** * This sets up and makes the request */ k_AJAXRequest.prototype.makeRequest = function() { // create a request/transport object // this version for Firefox, Safari, etc... if (window.XMLHttpRequest) this.request = new XMLHttpRequest(); // this for IE... else if (window.ActiveXObject) this.request = new ActiveXObject("Microsoft.XMLHTTP"); else { this.status = K_AJAX_NOT_SUPPORTED; eval(this.callbackFunction)(this, K_AJAX_NOT_SUPPORTED); return false; } // set the state change callback function this.request.onreadystatechange = this.onStateChange.bind(this); // tell the callback we're about to load... this.status = K_AJAX_LOADING; eval(this.callbackFunction)(this, K_AJAX_LOADING); try { // are we POST'ing or GET'ing? if(this.postParams && this.postParams.length > 0) { this.request.open('POST', this.remoteURL, this.async); this.request.setRequestHeader('Content-Type','application/x-www-form-urlencoded'); this.request.send(this.postParams); } else { // simple GET this.request.open('GET', this.remoteURL, this.async); this.request.send(null); } } catch(exception) { // uh oh! this.exception = exception; this.status = K_AJAX_COMPLETE_FAILURE; eval(this.callbackFunction)(this, K_AJAX_COMPLETE_FAILURE); } } /** * Convenience method to return the response text from the request * or the exception text if there was a problem. */ k_AJAXRequest.prototype.getResponseText = function() { if(this.exception) return this.exception; return this.request.responseText; } // ***** end simple AJAX mechanism ***** /** * Stop event proprogation * *@access public *@param Event *@return void */ function bubblePop(event) { event = (event) ? event : window.event; event.cancelBubble = true; if (event.stopPropagation) event.stopPropagation(); } /** * Returns the correct protocol and host * for callbacks based on the current environment * *@access public *@return string */ function getURLStarter() { if(document.URL.slice(0,5) == 'http:') return ''; else return ''; } /** * id exists on page? * *@access public *@param id *@return boolean */ function testExists(id) { if($('#'+id).length == 1) return true; else return false; } var Flash = { id: 'flash_message', success: 'success', error: 'error', EASING: 'linear', FLASH_FADE_IN: 500, FLASH_KEEP_ON: 2500, FLASH_FADE_OFF: 1500, /** * Reset the visibitly of a flash message * *@access public *@param string id of the message *@return void */ reset: function() { if(!testExists(this.id)) return; $('#'+this.id).css({visibility: 'hidden'}); $('#'+this.id).html(' '); }, /** * Flash success * *@access public *@param string the flash message *@return void */ success: function(msg) { this.message(this.success, msg); }, success_now: function(msg) { this.now(this.success, msg); }, /** * Flash error * *@access public *@param string the flash message *@return void */ error: function(msg) { this.message(this.error, msg); }, error_now: function(msg) { this.now(this.error, msg) }, /** * Flash message now * *@access public *@param string class of the flash message *@param string the flash message *@return void */ now: function(cls, msg) { if(!testExists(this.id)) return; $('#'+this.id).addClass(cls); msg = (msg == null) ? "" : msg; $('#'+this.id).html(msg); // annimate flash message $('#'+this.id) .css({ opacity: 0, visibility: 'visible' }) .animate({opacity: 1}, this.FLASH_FADE_IN, this.EASING, function() { $(this).animate({opacity: 1}, this.FLASH_KEEP_ON, this.EASING, function() { /* keep on $(this).animate({opacity: 0}, this.FLASH_FADE_OFF, "linear", function() { $(this) .css({ // when all done, reset visibilty to hidden visibility: 'hidden' }).removeClass(cls); }) */ }) }); }, /** * Flash message * *@access public *@param string class of the flash message *@param string the flash message *@return void */ load: function(cls, msg) { if(!testExists(this.id)) return; $(document).ready(function() { this.now(cls, msg); }); } }