Archive

Posts Tagged ‘JavaScript’

JavaScript Event Wrapper

March 6, 2010 Comments off

Event Wrapper

js_event.js


/*
* Cross browser Event wrapper
*
* @author:    Costin Trifan
* @date:      06.03.2010
* @license:   MIT License  http://en.wikipedia.org/wiki/MIT_License
* @version:   1.0
*/
var Event = {
	/**
	* Attach an event listener
	* @return this
	*/
	add : function(el, ev, func, capture)
	{
		if (capture == null) { capture = false; }
		if (window.addEventListener) {
			el.addEventListener(ev, func, capture);
		}
		else if (window.attachEvent) {
			el.attachEvent("on"+ev, func);
		}
		else { el['on'+ev] = func; }

		return this;
	}
	/**
	* Detach an existent event listener
	* @return this
	*/
	,remove : function(el, ev, func)
	{
		if (window.removeEventListener) {
			el.removeEventListener(ev, func, false);
		}
		else if (window.detachEvent) {
			el.detachEvent("on"+ev, func);
		}
		else { el['on'+ev] = func; }

		return this;
	}
	/**
	* Prevent the default action & stop the event from propagating
	* @return bool false
	*/
	,cancel : function(e)
	{
	  if(!e) { e = window.event; }
	  if(e.stopPropagation) { e.stopPropagation(); }
	  if(e.preventDefault) { e.preventDefault(); }

	  e.cancelBubble = true;
	  e.cancel = true;
	  e.returnValue = false;
	  return false;
  	}
};

Example


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Cross browser Event wrapper</title>
	<script src="js_event.js" type="text/javascript"></script>
	<script type="text/javascript">
    
	function toggle(el){
		if (el.style.display != 'none')
			el.style.display = 'none';
		else
			el.style.display = 'block';
	}
	
	
    Event.add(window, 'load', function(){
		var a = document.getElementById('a');
		var p = document.getElementById('p');
		Event
			.add(a, 'click', function(e){
				Event.cancel(e);
				toggle(p);
			})
			.add(p, 'click', function(e){
				alert('paragraph clicked');
			});
	});
    
    </script>
</head>

<body>

<p>
	<a id="a" href="#">Toggle</a>
    <span id="p" style="display: block">
    	Lorem ipsum dolor sit amet, consectetur adipisicing elit,
        sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
        Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris
        nisi ut aliquip ex ea commodo consequat.
    </span>
</p>

</body>
</html>

Clib – a basic javascript library

December 17, 2009 Comments off

Notice: This class is subject to change.


/**
* Clib - a basic javascript library
*
* @author     Costin Trifan 
* @copyright  2009 Costin Trifan
* @licence    MIT License http://en.wikipedia.org/wiki/MIT_License
* @version    1.0
* 
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
* 
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
* 
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
============================================================*/


/**
 * PROTOTYPES
 *
 * @see $().ajax()
 */
if ( ! Array.prototype.inArray )
{
    Array.prototype.inArray = function ( theArray ) {
	    var i;
	    for (i=0; i < this.length; i++) {
		    if (this[i] === theArray) {
			    return true;
		    }
	    }
	    return false;
    };
}





/**
 * Clib library - Simple Ajax/Dom/Events/Cookie library
 *
 */
(function()
{

/******************************
*       AJAX RELATED
******************************/

    var xhr = null; /*[ will hold the instance of the XmlHttp object ]*/

    var _createRequest = function()
    {
        try { return new XMLHttpRequest ; } catch(e) {}
        try { return new ActiveXObject('MSXML2.XMLHTTP.3.0') ; } catch(e) {}
        try { return new ActiveXObject('MSXML2.XMLHTTP') ; } catch(e) {}
        try { return new ActiveXObject('Microsoft.XMLHTTP') ; } catch(e) { throw new Error("Details: AJAX is not supported!"); }
    };

    /**
     * Create an image loader
     * @return object   the created DOM Element
     */
    var _createImageLoader = function( imgSrc, parentCtl, loadingText )
    {
        var el = document.createElement("img");
        with (el)
        {
            setAttribute("src", imgSrc);
            setAttribute("title", loadingText);
            setAttribute("alt", loadingText);
            style.width = 'auto';
            style.height = 'auto';
            style.display = 'block';
        }
        parentCtl.appendChild(el);
        return el;
    };

/*>> End AJAX related stuff *******************************************************************************/




    /**
     * Populate the this.elements array
     * @access private
     */
    function _$( els )
    {
        this.elements = [];

        for (var i= 0; i < els.length; ++i)
        {
            var e = els[i];
            if (typeof(e) === "string") {
                e = document.getElementById(e);
            }
            this.elements.push(e);
        }

    }

    _$.prototype =
    {

/*==============================
 * UTILITY
==============================*/


        /**
         * Check to see whether the provided object is an array
         * @return bool
         */
        isArray : function ( obj )
        {
           return (obj.constructor.toString().indexOf("Array") >= 0 );
        },


        /**
         * Execute a given function for each of the elements from the this.elements array
         * @return this
         */
        each : function( fn )
        {
            if (this.elements.length == 0) { return this; }

            for (var i= 0; i < this.elements.length; ++i)
            {
                fn.call(this, this.elements[i]);
            }
            return this;
        },



/*==============================
 * COOKIE
==============================*/

        /*[ Source: http://www.dustindiaz.com/top-ten-javascript/ ]*/
        getCookie : function( name )
        {
	        var start = document.cookie.indexOf( name + "=" );
	        var len = start + name.length + 1;
	        if ( ( !start ) && ( name != document.cookie.substring( 0, name.length ) ) ) {
		        return null;
	        }
	        if ( start == -1 ) return null;
	        var end = document.cookie.indexOf( ';', len );
	        if ( end == -1 ) { end = document.cookie.length; }
	        return unescape( document.cookie.substring( len, end ) );
        },

        setCookie : function( name, value, expires, path, domain, secure )
        {
	        var today = new Date();
	        today.setTime( today.getTime() );
	        if ( expires ) { expires = expires * 1000 * 60 * 60 * 24; }
	        var expires_date = new Date( today.getTime() + (expires) );

	        document.cookie = name+'='+escape( value )
		                        + ( expires ? ';expires='+expires_date.toGMTString() : '' )
		                        + ( path ? ';path=' + path : '' )
		                        + ( domain ? ';domain=' + domain : '' )
		                        + ( secure ? ';secure' : '' );
        },

        deleteCookie : function( name, path, domain )
        {
	        if ( this.getCookie( name ) )
	        {
	            document.cookie = name + '=' +
			        ( (path) ? ';path=' + path : '') +
			        ( (domain) ? ';domain=' + domain : '' ) +
			        ';expires=Thu, 01-Jan-1970 00:00:01 GMT';
            }
        },




/*==============================
 * EVENTS
==============================*/
        
        /**
         * Attach an event listener to each of the elements from the this.elements array
         * @return this
         */
        on : function( type, fn )
        {
            var _add = function( el )
            {
                if (window.addEventListener) {
                    el.addEventListener(type, fn, false);
                }
                else if (window.attachEvent) {
                    el.attachEvent("on"+type, fn);
                }
            };
            this.each(function(el) { _add(el); });
            return this;
        },


        /**
         * Remove an event listener from each of the elements of the this.elements array
         * @return this
         */
        removeEvent : function( type, fn )
        {
            var _remove = function( el )
            {
                if (window.removeEventListener) {
                    el.removeEventListener(type, fn, false);
                }
                else if (window.detachEvent) {
                    el.detachEvent("on"+type, fn);
                }
            };
            this.each(function(el) { _remove(el); });
            return this;
        },


        /**
         * Prevent the default action from occurring
         * @return this
         */
        preventDefault : function( ev )
        {
            ev = ev || window.event;
            if (ev.preventDefault) {
                ev.preventDefault();
            }
            else {
                ev.returnValue = false;
            }
            return this;
        },


        /**
         * Stop the propagation of the event
         * @return this
         */
        stopPropagation : function( ev )
        {
            ev = ev || window.event;
            if (ev.stopPropagation) {
                ev.stopPropagation();
            }
            else {
                ev.cancelBubble = true;
            }
            return this;
        },


        /**
         * Prevent the default action from occurring
         * @return this
         */
        stopEvent : function( ev )
        {
            this.preventDefault( ev );
            this.stopPropagation( ev );
            return this;
        },





/*==============================
 * DOM
==============================*/


        /**
         * Check to see whether or not a given element has a class applied
         * @return bool
         */
        hasClass : function( cssClass )
        {
            var pattern = new RegExp("(^| )" +cssClass+ "( |$)");

            this.each(function(el) {
                if (pattern.test(el.className)) { return true; }
            });
            return false;
        },

        /**
         * Remove a class from the selected objects
         * @return this
         */
        removeClass : function( cssClass )
        {
            var pattern = new RegExp("(^| )" +cssClass+ "( |$)");
            this.each(function(el) {
                el.className = el.className.replace(pattern, "$1");
                el.className = el.className.replace(/ $/, "");
            });
            return this;
        },

        /**
         * Add a given class to selected elements
         * @return this
         */
        addClass : function( cssClass )
        {
            var self = this;
            this.each(function(el) {
                if ( ! self.hasClass(cssClass))
                {
                    if (el.className == "") { el.className = cssClass; }
                    else { el.className += " " + cssClass; }
                }
            });
            return this;
        },


        /**
         * Replace all elements from the this.elements array with the ones that match the regex pattern
         * @return this
         */
        getByClass : function( searchClass, parent, searchInTag )
        {
            // reset main array
            this.elements = [];

            if ( parent == null ) {
                parent = document;
            }
            if ( searchInTag == null ) {
                searchInTag = '*';
            }

            var els = parent.getElementsByTagName(searchInTag);
            var elsLen = els.length;
            var pattern = new RegExp('(^|\\\\s)'+searchClass+'(\\\\s|$)');

            for (i = 0, j = 0; i < elsLen; i++)
            {
                if ( pattern.test(els[i].className) )
                {
                    this.elements.push( els[i] );
                    j++;
                }
            }
            return this;
        },


        /**
         * Replace all elements from the this.elements array with the ones that match the regex pattern
         * @return this
         */
        getByTags : function( /*[ as Array ]*/searchTags, /*[ as Object ]*/parent )
        {
            if ( ! this.isArray(searchTags)) {
                throw new Error("The getByTags function expects the first argument to be an Array!");
            }

            if (searchTags.length == 0) { return this; }

            // temp array - holds the elements that match the regex
            var tempArr = [];

            // reset main array
            this.elements = [];

            if ( parent == null ) { parent = document; }


            for (var i= 0; i < searchTags.length; ++i)
            {
                var tag = searchTags[i];

                var els = parent.getElementsByTagName(tag);
            }



            var elsLen = els.length;
            var pattern = new RegExp('(^|\\\\s)'+searchClass+'(\\\\s|$)');

            for (i = 0, j = 0; i < elsLen; i++)
            {
                if ( pattern.test(els[i].className) )
                {
                    this.elements.push( els[i] );
                    j++;
                }
            }
            return this;
        },


        /**
         * Set the inner text to all of the elements from this.elements array
         * @return this
         */
        text : function( txt )
        {
            /*[ SET ]*/
            if (txt)
            {
                this.each(function(e) {
                    e.innerHTML = txt;
                });
                return this;
            }
            /*[ GET ]*/
            else { return this.elements[0].innerHTML; }
        },


        /**
         * Set/Get the value to all of the elements from this.elements array
         * @return this | mixed
         */
        value : function( txt )
        {
            /*[ SET ]*/
            if (txt)
            {
                this.each(function(e) {
                    e.value = txt;
                });
                return this;
            }
            /*[ GET ]*/
            else { return this.elements[0].value; }
        },

        /**
         * Set the css style property to all of the elements from this.elements array
		 *
		 * @param object properties	A key value pair object literal with the properties and values to apply to the selected object
         * @return this
         */
        css : function( /*[ as object ]*/properties )
        {
            this.each(function(el) {
				for (var p in properties)
                	el.style[ p ] = properties[ p ];
            });
            return this;
        },


        /**
         * Set the css style property to an element
         * @return this
         */
        setStyle : function( element, property, value )
        {
            element.style[ property ] = value;
            return this;
        },


        /**
         * Retrieve the computed style attribute of the element
         * @return string
         */
        getStyle : function( element, property )
        {
            var comp_style = null;

            if (window.getComputedStyle) {
                comp_style = window.getComputedStyle(element,null).getPropertyValue(property);
            }
            else {
                if (typeof(element) != "undefined") {
                    comp_style = element.currentStyle;
                    return comp_style[property];
                }
            }
            return comp_style;
        },






/*==============================
 * AJAX
==============================*/


        /**
         * Abort the active request
         * @return this
         */
        _abort : function( xhr )
        {
            xhr.abort();
			xhr = null;
            return this;
        },


        ajax : function( method, uri, /*[ as object ]*/options, onSuccess, onFailure )
        {
            method = method.toUpperCase();

			var self = this;

            /*[ Check and validate method ]*/
            var allow_methods = ["GET", "HEAD", "POST"];

            if ( ! allow_methods.inArray(method)) {
                throw new Error("The provided method: "+ method.toString() +" is not supported!");
            }


            xhr = _createRequest();

            if (xhr == null) { return this; }


            if ( ! options ) { options = {}; }
            /*[ Set options ]
            
                options = {
                    async       : false | true (default)
                    timeout     : null | 3000 (default)
                    postData    : string | null (default) // when making POST requests
                    label       : string | null (default) // when making HEAD requests
                    cache       : true | false (default)  // when making GET requests, whether or not to cache server's response
                    showLoader  : true | false (default)
                    imgSrc      : string | null (default) // the path to the image to be displayed
                    parentCtl   : DOMElement | null (default)  // the element that will append the image loader
                    loadingText : 'Loading...' (default) // the alternate text for the image loader
                }
            */
            if ( options.async == null )    { options.async = true; }
            if ( ! options.timeout )        { options.timeout  = 3000; }
            if ( ! options.postData )       { options.postData = null; }
            if ( ! options.label )          { options.label = null; }
            if ( ! options.cache )          { options.cache = false; }
            if ( ! options.showLoader )     { options.showLoader  = false; }
            if ( ! options.imgSrc )         { options.imgSrc  = null; }
            if ( ! options.parentCtl )      { options.parentCtl = null; }
            if ( ! options.loadingText )    { options.loadingText = "Loading..."; }


            /*[ Create the ajax loader ]*/
            var img_loader = null;
            if (options.showLoader)
            {
                /*[ Clear content first ]*/
                options.parentCtl.innerHTML = '';

                img_loader = _createImageLoader(options.imgSrc, options.parentCtl, options.loadingText);
            }


            /*[ Set timeout ]*/
            var _timer = setTimeout(function() { self._abort(xhr); }, options.timeout);


            /*[ Handle the state of the request ]*/
            xhr.onreadystatechange = function()
            {
                if (xhr.readyState == 4)
                {
                    /*[ Clear timeout ]*/
                    clearTimeout(_timer);

                    if (xhr.status == 200 || xhr.status == 304)
                    {
                        /*[ Clear the loading image ]*/
                        if (img_loader != null) { options.parentCtl.removeChild(img_loader); }

                        /*[ Retrieve response ]*/
                        if (method == "HEAD")
                        {
                            /*[ If a header label was provided ]*/
                             if (options.label) {
                                onSuccess( xhr.getResponseHeader(options.label) );
                             }
                             else {
                                onSuccess( xhr.getAllResponseHeaders() );
                             }
                        }
                        /*[ Common GET request ]*/
                        else { onSuccess( xhr.responseText, xhr.responseXML ); }
                    }
                    else {
                        /*[ Clear the loading image ]*/
                        if (img_loader != null)
                        {
                            try { options.parentCtl.removeChild(img_loader); }
                            catch(e){}
                        }

                        if (onFailure) { onFailure(xhr.statusText); self._abort(xhr); }
                        else {
                            /*[ Default error message ]*/
                            throw new Error("An error has occurred while executing the request.\r\nStatus: "+xhr.statusText);
                        }
                    }
                }
            };

            if ( ! options.cache)
            {
                var rand_no = Math.ceil(1000*Math.random());

                if (uri.indexOf('?') >= 0) {
                    uri += "&xyxz_rand="+rand_no;
                }
                else { uri += "?xyxz_rand="+rand_no; }
            }

            xhr.open(method, uri, options.async);

            if (method == "POST")
            {
                xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");

                if (options.postData) {
                    if (options.postData.indexOf("?") < 0) {
                        options.postData = "?" + options.postData;
                    }
                }
            }
            xhr.send(options.postData);

            return this;
        }


    };
    /*[ end _$.prototype ]*/


    /**
     * Map the $ object to the library's main function
     * return object
     */
    window.Clib = window.$ = function() {
        return new _$(arguments);
    };


})();

Usage:


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Clib - a basic javascript library</title>

	<script type="text/javascript" src="bin/c-lib.js"></script>
    <script type="text/javascript">
    
		// Clib == $
	
		Clib(window).on('load', function(event)
		{
			/*[ AJAX - GET ]*/
			Clib("call_server_button").on('click', function(ev)
			{
				// $().stopEvent(ev); /*[ if the default action should be prevented ]*/

				Clib().ajax("GET", "app_code/server.php?myname="+$('name_textbox').value(),
					/*[ OPTIONS ]*/
					{
						"cache"         : false,
						"showLoader"    : true,
						"imgSrc"        : 'bin/ajax-loader.gif',
						"parentCtl"     : document.getElementById('container')
					},
					/*[ ON SUCCESS ]*/
					function(txt, xml) {
						Clib("container").css({"background":"#f00", 'color':'#ff0'}).text(txt);
					}
				);
			});
			/*[ end ajax - get ]*/
		});
    </script>
</head>
<body>
	<h2>Ajax library</h2>


	<div>
    	<input type="text" id="name_textbox" />
    	<input type="button" id="call_server_button" value="Call server" />
    </div>
    <div id="container" style="margin: 25px; width: 400px;"></div>
</body>
</html>
Categories: JavaScript Tags: ,