Tuesday, December 1, 2009

Cross browser XML

One of the more annoying issues I came with is the cross browser issue. And a very important one is managing an XML driven website.

For this reason I created a unified XML handler class. Here it is:

//-------------------------------------------------------------------------------------------------
// browser enumeration helper –holding browser type and version
//-------------------------------------------------------------------------------------------------
var userAgent = navigator.userAgent.toLowerCase();
var browserType = {
    Version : (userAgent.match( /.+(?:rv|it|ra|ie|me)[\/: ]([\d.]+)/ ) || [])[1],
    CHROME : /chrome/.test( userAgent ),
    SAFARI : /webkit/.test( userAgent ) && !/chrome/.test( userAgent ),
    OPERA : /opera/.test( userAgent ),
    IE : /msie/.test( userAgent ) && !/opera/.test( userAgent ),
    MOZILLA : /mozilla/.test( userAgent ) && !/(compatible|webkit)/.test( userAgent )
};

//-------------------------------------------------------------------------------------------------
// XmlHandler class
//-------------------------------------------------------------------------------------------------
var XmlHandler = function() {
    //---------------------------------------------------------------------------------------------
    // LoadXML
    // - xmlString: xml string or xml file path
    // - isPath: true/false (true if xmlString is a file path)
    // return: xml document
    //---------------------------------------------------------------------------------------------

    this.LoadXML = function(xmlString, isPath) {
        if (xmlString && IsString(xmlString)) {
            var xDoc, xmlHttp;
            if (isPath) {
                if (window.XMLHttpRequest)
                    xmlHttp = new XMLHttpRequest();
                else
                    xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");

                xmlHttp.open("GET", xmlString, false);
                xmlHttp.send();
                xDoc = xmlHttp.responseXML;
            } else {
                if (browserType.IE) {
                    xDoc = new ActiveXObject("MSXML2.DOMDocument")
                    xDoc.async = false;
                    xDoc.loadXML(xmlString);
                    xDoc.setProperty("SelectionLanguage", "XPath");
                } else {
                    var dp = new DOMParser();
                    xDoc = dp.parseFromString(xmlString, "text/xml");
                    xDoc.normalize();
                }
            }
            return xDoc;
        } else {
            return null;
        }
    }

    //---------------------------------------------------------------------------------------------
    // GetFirstItemValue
    // - doc: xml document
    // - nodeName: node name (tag name)
    // return: first node value
    //---------------------------------------------------------------------------------------------
    this.GetFirstItemValue = function(doc, nodeName) {
        var node = doc.getElementsByTagName(nodeName)[0].childNodes[0];
        if (node) {
            if (browserType.IE)
                return node.text;
            else
                return node.nodeValue;
        } else {
            return;
        }
    }

    //---------------------------------------------------------------------------------------------
    // GetNodeAttribute
    // - node: xml node
    // - attributeName: attribute name
    // return: attribute value
    //---------------------------------------------------------------------------------------------
    this.GetNodeAttribute = function(node, attributeName) {
        return node.getAttribute(attributeName);
    }

    //---------------------------------------------------------------------------------------------
    // SelectSingleNode
    // - xmlDoc: xml document
    // - elementPath: xPath
    // return: xml node
    //---------------------------------------------------------------------------------------------
    this.SelectSingleNode = function(xmlDoc, elementPath) {
        if(document.implementation && document.implementation.createDocument) {
            var nodes = xmlDoc.evaluate(elementPath, xmlDoc, null, XPathResult.ANY_TYPE, null);
            var results = nodes.iterateNext();
            return results;
        } else {
            return xmlDoc.selectSingleNode(elementPath);
        }
    }

    //---------------------------------------------------------------------------------------------
    // isString – private
    // - str: string
    // return: string
    //---------------------------------------------------------------------------------------------
    function IsString(str) {
        return str.toString();
    }

    //---------------------------------------------------------------------------------------------
    // ParseResponseText
    // - response: http response object
    // - nodeName: nodeName
    // return: first node value
    //---------------------------------------------------------------------------------------------
    this.ParseResponseText = function(response, nodeName) {
        var data = this.LoadXML(response.responseText);
        return this.GetFirstItemValue(data, nodeName || "string");
    }

};

This class is designed for a specific use, but, I believe that the methods written are useful for most purposes.

Enjoy,

Thursday, October 1, 2009

JavaScript events handler

Today, with the growth of web based applications (and I'm talking about applications and not image galleries websites), more and more of the server side is shifting back to the client. Thus, more and more BL is done in the client.
JavaScript, similar to to Java, C, C++, C# and others is a full scale OO language. YES, it's an OO language. Everything you have in the class based OO languages, you have here. Among a lot of things, there is a need for events handling. Here is a conglomeration of an events util class that handles everything. It's written in JS and it's a cross platform script (meaning, it'll work on IE, FF, Chrome etc).

This code was gathered from the book "Professional JavaScript for Web Developers" written by Nicholas C. Zakas

var EventUtil = {

// var btn = document.getElementById("btn1");
// var handler = function() {
//     alert('hello');
// }
// EventUtil.addHandler(btn, "click", handler};
addHandler : function(element, type, handler) {
    if (element.addEventListener) {
        element.addEventListener(type, handler, false);
    } else if (element.attachEvent) {
        element.attachEvent("on" + type, handler);
    } else {
        element["on" + type] = handler;
    }
},

getEvent : function(event) {
    return event ? event : window.event;
},

getTarget : function(event) {
    return event.target || event.srcElement;
},

preventDefault : function(event) {
    if (event.preventDefault) {
        event.preventDefault();
    } else {
        event.returnValue = false;
    }
},

// EventUtil.addHandler(btn, "click", handler};
removeHandler : function(element, type, handler) {
    if (element.removeEventListener) {
        element.removeEventListener(type, handler, false);
    } else if (element.detachEvent) {
        element.detachEvent("on" + type, handler);
    } else {
        element["on" + type] = null;
    }
},

stopPropagation : function(event) {
    if (event.stopPropagation) {
        event.stopPropagation();
    } else {
        event.cancelBubble = true;
    }
}
}


On the same issue, sometimes you need to create your own types (for example message type) and you need to listen/fire it. Here is an example for a class dealing with this. This sample was taken from the same book as the above.


/*

//
// sample for using the custom handler firing
//
function handleMessage(event) {
alert("Message received: " + event.message);
}
// create a new object
var target = new EventTarget();
 
// add an event handler
target.addHandler("message", handleMessage);
 
// fire the event
target.fire({ type : "message", message : "hello...." });
 
// remove the handler
target.removeHandler("message", handleMessage);
*/

function EventTarget() {
   this.handlers = {};
}

EventTarget.prototype = {
   constructor : EventTarget,
   
   addHandler : function(type, handler) {
       if (typeof this.handlers[type] == "undefined") {
           this.handlers[type] = [];
       }
       
       this.handlers[type].push(handler);
   },
   
   fire : function(event) {
       if (!event.target) {
           event.target = this;
       }
       if (this.handlers[event.type] instanceof Array) {
           var handlers = this.handlers[event.type];
           for (var i = 0, len = handlers.length; i < len; i++) {
               handlers[i](event);
           }
       }
   },
   
   removeHandler : function(type, handler) {
       if (this.handlers[event.type] instanceof Array) {
           var handlers = this.handlers[event.type];
           for (var i = 0, len = handlers.length; i < len; i++) {
               if (handlers[i] == handler) {
                   break;
               }
           }
           
           handlers.splice(i, 1);
       }
   }
}

Sunday, March 1, 2009

Usefull functions...

I seems that in every project there is a set of functions that I use.
For that reason, I've decided to place them here so I won't need to search for them any more.
The functions are:

// Finding a control recursively
public static Control FindControlRecursive(Control root, string id)
{
    if (root.ID == id)
    {
        return root;
    }
    foreach (Control ctrl in root.Controls)
    {
        Control c = FindControlRecursive(ctrl, id);
        if (c != null)
        {
            return c;
        }
    }
    return null;
}

// Generate random
public static Random GenerateRandom()
{
    Guid _temp = Guid.NewGuid();
    int _i = 0;
    byte[] bytes = _temp.ToByteArray();
    for (int i = 0; i < bytes.Length; i++)
        _i += (int)bytes[i];

    return new Random(_i);
}

// RenderControl into HTML
public static string RenderControl(Control ctrl)
{
    StringBuilder sb = new StringBuilder();
    StringWriter tw = new StringWriter(sb);
    HtmlTextWriter hw = new HtmlTextWriter(tw);

    ctrl.RenderControl(hw);
    return sb.ToString();
}

Monday, February 9, 2009

ASP.NET Page Lifecycle

From now and then I forget the life cycle of ASP.NET pages.
In the CodeProject website I found a wonderfull article: http://www.codeproject.com/KB/aspnet/ASPNET_Page_Lifecycle.aspx

If you really don't want to read, here is what you need to know and memorize (SILVER):
S - Start
I - Initialize
L - Load
V - Validate
E - Event Handling
R - Render



Some add "U" (SILVER-U) for "Unload"

And in a more detailed way, the methods are:

  1. Construct
  2. ProcessRequest
  3. FrameworkInitialize
  4. InitializeCulture
  5. If child controls are present:
    1. AddParsedSubObject
    2. CreateControlCollection
    3. AddedControl
    4. ResolveAdapter
  6. DeterminePostBackMode
  7. OnPreInit
  8. OnInit
  9. TrackViewState
  10. OnInitComplete
  11. OnPreLoad
  12. OnLoad
  13. OnLoadComplete
  14. EnsureChildControls
    1. CreateChildControls
  15. OnPreRender
  16. OnPreRenderComplete
  17. SaveViewState
  18. OnSaveStateComplete
  19. CreateHtmlTextWriter
  20. RenderControl
  21. Render
    1. RenderChildren
    2. VerifyRenderingInServerForm
  22. OnUnload
  23. Dispose

Hope it'll help you in any way.... I know it helps me.

Monday, February 2, 2009

SQL Server 2005 CTE and DateTime parsing

CTE - Common Table Expressions
On various occasions I come with a need to use recursive iterations in a stored procedure.
Since server programing is not what I usually do, I search, find and use CTE (Common Table Expressions)
A wonderfull reference I found in an article by Nigel Rivett on:
http://www.simple-talk.com/sql/sql-server-2005/sql-server-2005-common-table-expressions/

A sample for a recursive use with recursion position flag:


with MyCTE (r1, r2, i, x)
as (
select r1 = 1, r2 = 1, i = 0, x = convert(varchar(1000),'hello')
union all
select r1 = r1 + 1, r2 = r2, i = 1, convert(varchar(1000),x + 'a') from MyCTE
where len(x) < 10 and i in (0,1)
union all
select r1 = r1, r2 = r2 + 1, i = 2, convert(varchar(1000),x + 'b') from MyCTE
where len(x) < 10 and i in (0,2))
select r1, r2, x
from MyCTE
order by len(x), x
The output for this is:
1 1 hello
2 1 helloa
1 2 hellob
3 1 helloaa
1 3 hellobb
1 4 hellobbb
1 5 hellobbbb
1 6 hellobbbbb

DateTime parsing
Another issue that parsing DateTime datatype. In SQL 2000 I had to convert the DateTime into varchar/nvarchar (depending on the collation), split (another function) and parse the relevant thing I wanted (day, month, hour etc). In SQL 2005, Microsoft introduced us to a new and usefull function called DatePart. This function does the entire trick.
The way to use it, is just say what you want from the DateTime variable and voila...

DATEPART(datepart, date)
The dateparts can be as follows:
  • year (yy, yyyy)
  • quarter (qq, q)
  • month (mm, m)
  • dayofyear (dy, y)
  • day (dd, d)
  • week (wk, ww)
  • weekday (dw)
  • hour (hh)
  • minute (mi, n)
  • second (ss, s)
  • millisecond (ms)

Samples can be seen on:
http://msdn.microsoft.com/en-us/library/ms174420(SQL.90).aspx (SQL Server 2005)
http://msdn.microsoft.com/en-us/library/ms174420.aspx (SQL Server 2008)

Wednesday, January 28, 2009

My First Post Ever...

This is my first posting ever.... it's about time....
It's always a good thing to start by introducing ones self.
So, let's start.
My name is Roni, I'm a 31 years old Israeli, living in the city of Nes-Ziona.
I have a beautiful wife and a gorgeous son.
I love to travel, read, listen to good music, and play (almost any kind of) sports.
During my work (web programing) I come up with lost of various technological issues. In this blog I intend to save these thought, issues and solutions.
I hope that it could help some other people beside me :-)

Enjoy.