<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>LivingMachines.net &#187; Development</title>
	<atom:link href="http://livingmachines.net/category/development/feed/" rel="self" type="application/rss+xml" />
	<link>http://livingmachines.net</link>
	<description>Test-driven development of a JavaScript MVC library, from the ground up...</description>
	<lastBuildDate>Thu, 04 Jun 2009 04:33:27 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Adding Event Handling to JavaScript Classes</title>
		<link>http://livingmachines.net/2009/06/adding-event-handling-to-javascript-classes/</link>
		<comments>http://livingmachines.net/2009/06/adding-event-handling-to-javascript-classes/#comments</comments>
		<pubDate>Thu, 04 Jun 2009 04:33:27 +0000</pubDate>
		<dc:creator>Jason S. Kerchner</dc:creator>
				<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://livingmachines.net/?p=477</guid>
		<description><![CDATA[Download code
The next item I need to address is object events.  I have a mechanism for attaching event handlers to DOM objects, so when the user clicks a button, or changes the value of a text box, or does some other interaction with a DOM element, the View can handle that event.  But [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://livingmachines.net/code/2009-06-03/LivingMachines.zip">Download code</a></p>
<p>The next item I need to address is object events.  I have a mechanism for <a href="/2009/05/adding-dom-event-handlers-to-the-view">attaching event handlers to DOM objects</a>, so when the user clicks a button, or changes the value of a text box, or does some other interaction with a DOM element, the View can handle that event.  But then the View will need to fire its own event to notify a Controller object (yet to be created) that the user is attempting to accomplish some task.</p>
<p>For example, the user might click a Search button, or press the Enter key on a text box, both of which might fire the View&#8217;s &#8220;onSearch&#8221; event.  A Controller listening for this event could then initiate the search.  When the search is complete, the Controller could fire an event to indicate that the results are available.  Maybe an &#8220;onSearchResults&#8221; event or something.  Models will also need to fire events to notify other objects when data is loaded, changed, etc.</p>
<p>In fact, I figure there are very few objects that won&#8217;t need to fire events.  Therefore, I decided to include events and event handling as a basic core functionality of all classes.  This means revisiting the <code>Class</code> function and making some enhancements.  </p>
<p>Here is the original <code>Class</code> function. If you are unfamiliar with it, you might want to review the original <a href="/?tag=creating-javascript-classes-series">series about creating the Class object</a>.  It&#8217;s probably not necessary, but it might help you understand the changes.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;">LivingMachines.<span style="color: #003366; font-weight: bold;">Class</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>init<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
	<span style="color: #006600; font-style: italic;">// Create constructor function that will check if we are inheriting, </span>
	<span style="color: #006600; font-style: italic;">// then call real constructor</span>
	<span style="color: #003366; font-weight: bold;">var</span> cstr <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>arguments<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">===</span> inheriting<span style="color: #009900;">&#41;</span> <span style="color: #000066; font-weight: bold;">return</span><span style="color: #339933;">;</span>
		<span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">construct</span>.<span style="color: #660066;">apply</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #339933;">,</span> arguments<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #006600; font-style: italic;">// If we are inheriting, copy the prototype, otherwise assign a new prototype</span>
	<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>init.<span style="color: #660066;">inherits</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		cstr.<span style="color: #660066;">prototype</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> init.<span style="color: #660066;">inherits</span><span style="color: #009900;">&#40;</span>inheriting<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		cstr.<span style="color: #660066;">base</span> <span style="color: #339933;">=</span> init.<span style="color: #660066;">inherits</span>.<span style="color: #660066;">prototype</span><span style="color: #339933;">;</span>
		<span style="color: #000066; font-weight: bold;">delete</span> init.<span style="color: #660066;">inherits</span><span style="color: #339933;">;</span>	<span style="color: #006600; font-style: italic;">// Keeps it from being added to the prototype later</span>
	<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #006600; font-style: italic;">// Copy init properties to the prototype (adds/overrides base class methods)</span>
	<span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> p <span style="color: #000066; font-weight: bold;">in</span> init<span style="color: #009900;">&#41;</span>
		cstr.<span style="color: #660066;">prototype</span><span style="color: #009900;">&#91;</span>p<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> init<span style="color: #009900;">&#91;</span>p<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #006600; font-style: italic;">// Return the constructor function (this is the class)</span>
	<span style="color: #000066; font-weight: bold;">return</span> cstr<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>The basic premise here is that I only need to add the event methods to a base class.  Any descendant classes will then automatically inherit those methods.  As I see it, the methods will be <code>createEvent</code> (to add an event to the class), <code>listenTo</code> (to add an event handler to an event), <code>unlistenTo</code> (to remove an event handler from an event, and yes I know that &#8220;unlisten&#8221; not a real word, but it works), and <code>fire</code> (to execute all event handlers that are attached to an event).</p>
<p>Since I am going to allow multiple event handlers, I will need an array to hold the handlers (which are just functions that will be executed when the event is fired).  I decided to create an object, called <code>events</code>, that will hold an array for each event of the class.  This will be an instance object, and so will need to be added to the constructor (line 7, below).</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>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
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;">LivingMachines.<span style="color: #003366; font-weight: bold;">Class</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>init<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
	<span style="color: #006600; font-style: italic;">// Create constructor function that will check if we are inheriting, </span>
	<span style="color: #006600; font-style: italic;">// then call real constructor</span>
	<span style="color: #003366; font-weight: bold;">var</span> cstr <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>arguments<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">===</span> inheriting<span style="color: #009900;">&#41;</span> <span style="color: #000066; font-weight: bold;">return</span><span style="color: #339933;">;</span>
		<span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">events</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>    <span style="color: #006600; font-style: italic;">// To hold our arrays of event handlers</span>
		<span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">construct</span>.<span style="color: #660066;">apply</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #339933;">,</span> arguments<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #006600; font-style: italic;">// If we are inheriting, copy the prototype, otherwise assign a new prototype</span>
	<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>init.<span style="color: #660066;">inherits</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		cstr.<span style="color: #660066;">prototype</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> init.<span style="color: #660066;">inherits</span><span style="color: #009900;">&#40;</span>inheriting<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		cstr.<span style="color: #660066;">base</span> <span style="color: #339933;">=</span> init.<span style="color: #660066;">inherits</span>.<span style="color: #660066;">prototype</span><span style="color: #339933;">;</span>
		<span style="color: #000066; font-weight: bold;">delete</span> init.<span style="color: #660066;">inherits</span><span style="color: #339933;">;</span>	<span style="color: #006600; font-style: italic;">// Keeps it from being added to the prototype later</span>
	<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #006600; font-style: italic;">// Copy init properties to the prototype (adds/overrides base class methods)</span>
	<span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> p <span style="color: #000066; font-weight: bold;">in</span> init<span style="color: #009900;">&#41;</span>
		cstr.<span style="color: #660066;">prototype</span><span style="color: #009900;">&#91;</span>p<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> init<span style="color: #009900;">&#91;</span>p<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #006600; font-style: italic;">// Return the constructor function (this is the class)</span>
	<span style="color: #000066; font-weight: bold;">return</span> cstr<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Next, I need to add the event methods.  Since all classes will have event capabilities, I simply need to add event methods to the class&#8217;s prototype if this is a base class, that is, if this is a class that is not inherited from any other class.  This will ensure that all top-level classes have event capabilities, and those capabilities will pass on to all descendant classes through inheritance.  </p>
<p>If a class inherits from another class, then the <code>inherits</code> property of the <code>init</code> argument will be set, and I&#8217;m already checking for it (line 12).  So, I simply need to add an <code>else</code> to the <code>if</code>, and add the event methods there (lines 17-47, below).</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;">LivingMachines.<span style="color: #003366; font-weight: bold;">Class</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>init<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">// Create constructor function that will check if we are inheriting, </span>
    <span style="color: #006600; font-style: italic;">// then call real constructor</span>
    <span style="color: #003366; font-weight: bold;">var</span> cstr <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>arguments<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">===</span> inheriting<span style="color: #009900;">&#41;</span> <span style="color: #000066; font-weight: bold;">return</span><span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">events</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>    <span style="color: #006600; font-style: italic;">// To hold our arrays of event handlers</span>
        <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">construct</span>.<span style="color: #660066;">apply</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #339933;">,</span> arguments<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #006600; font-style: italic;">// If we are inheriting, copy the prototype, otherwise assign a new prototype</span>
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>init.<span style="color: #660066;">inherits</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        cstr.<span style="color: #660066;">prototype</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> init.<span style="color: #660066;">inherits</span><span style="color: #009900;">&#40;</span>inheriting<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        cstr.<span style="color: #660066;">base</span> <span style="color: #339933;">=</span> init.<span style="color: #660066;">inherits</span>.<span style="color: #660066;">prototype</span><span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">delete</span> init.<span style="color: #660066;">inherits</span><span style="color: #339933;">;</span>	<span style="color: #006600; font-style: italic;">// Keeps it from being added to the prototype later</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span>
&nbsp;
        <span style="color: #006600; font-style: italic;">// Since we are not inheriting, then we must add event methods,</span>
        <span style="color: #006600; font-style: italic;">// otherwise they will be included via inheritance.</span>
&nbsp;
        cstr.<span style="color: #660066;">prototype</span>.<span style="color: #660066;">createEvents</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009966; font-style: italic;">/* event */</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> len <span style="color: #339933;">=</span> arguments.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> len<span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span>
                <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">events</span><span style="color: #009900;">&#91;</span>arguments<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span> <span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
        cstr.<span style="color: #660066;">prototype</span>.<span style="color: #660066;">listenTo</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>obj<span style="color: #339933;">,</span> event<span style="color: #339933;">,</span> handler<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            obj.<span style="color: #660066;">events</span><span style="color: #009900;">&#91;</span>event<span style="color: #009900;">&#93;</span>.<span style="color: #660066;">push</span><span style="color: #009900;">&#40;</span> <span style="color: #009900;">&#123;</span> handler<span style="color: #339933;">:</span> handler<span style="color: #339933;">,</span> scope<span style="color: #339933;">:</span> <span style="color: #000066; font-weight: bold;">this</span> <span style="color: #009900;">&#125;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
        cstr.<span style="color: #660066;">prototype</span>.<span style="color: #660066;">unlistenTo</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>obj<span style="color: #339933;">,</span> event<span style="color: #339933;">,</span> handler<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #003366; font-weight: bold;">var</span> ev <span style="color: #339933;">=</span> obj.<span style="color: #660066;">events</span><span style="color: #009900;">&#91;</span>event<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
            <span style="color: #006600; font-style: italic;">// Loop down, just in case handler was added multiple times (and will be removed multiple times)</span>
            <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> i <span style="color: #339933;">=</span> ev.<span style="color: #660066;">length</span> <span style="color: #339933;">-</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&gt;=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i<span style="color: #339933;">--</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>ev<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span>.<span style="color: #660066;">handler</span> <span style="color: #339933;">===</span> handler<span style="color: #009900;">&#41;</span>
                    ev.<span style="color: #660066;">splice</span><span style="color: #009900;">&#40;</span>i<span style="color: #339933;">,</span> <span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>     <span style="color: #006600; font-style: italic;">// Deletes one element starting at index i</span>
            <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
        cstr.<span style="color: #660066;">prototype</span>.<span style="color: #660066;">fire</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>event<span style="color: #339933;">,</span> data<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #003366; font-weight: bold;">var</span> handlers <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">events</span><span style="color: #009900;">&#91;</span>event<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
            <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> len <span style="color: #339933;">=</span> handlers.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> len<span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                <span style="color: #003366; font-weight: bold;">var</span> h <span style="color: #339933;">=</span> handlers<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
                h.<span style="color: #660066;">handler</span>.<span style="color: #660066;">call</span><span style="color: #009900;">&#40;</span>h.<span style="color: #660066;">scope</span><span style="color: #339933;">,</span> <span style="color: #000066; font-weight: bold;">this</span><span style="color: #339933;">,</span> data<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">// Copy init properties to the prototype (adds/overrides base class methods)</span>
    <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> p <span style="color: #000066; font-weight: bold;">in</span> init<span style="color: #009900;">&#41;</span>
        cstr.<span style="color: #660066;">prototype</span><span style="color: #009900;">&#91;</span>p<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> init<span style="color: #009900;">&#91;</span>p<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">// Return the constructor function (this is the class)</span>
    <span style="color: #000066; font-weight: bold;">return</span> cstr<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>The first event method, <code>createEvents</code> (line 22) takes a variable number of arguments.  Each argument is the name of an event to be added to the class.  It simply loops through each argument (line 23) and adds the name of the event to the <code>events</code> object (line 24).  Each event is initialized to an empty array, and it&#8217;s these arrays that will hold all the handlers for a particular event.</p>
<p>The <code>createEvents</code> method should be called from the <code>construct</code> method of a class.  I had to do it this way since each event handlers array has to be associated with a class instance, and not the class itself.  So, for example, executing <code>createEvents('onSave', 'onCancel')</code> will add <code>onSave</code> and <code>onCancel</code> as properties to the <code>events</code> object (the one added in line 7).  These properties are initialized as empty arrays.  Since these are instance properties, each instance of the class can have a different set of handlers.</p>
<p>The <code>listenTo</code> method (line 27) is used to add an event handler to the appropriate event handler array.  It takes three arguments, <code>obj</code> (the object that has the event to listen to), <code>event</code> (the name of the event to listen to), and <code>handler</code> (the function that will handle the event).  It then adds the handler to the given event handlers array of the object that has the event (line 28).  Note that this is actually pushing the handler function and <code>this</code> as a scope object into the handlers array.  I will talk about why I am doing this when I describe the <code>fire</code> method.</p>
<p>The <code>unlistenTo</code> method (line 31) is used to remove a specific event handler from the list of handlers.  It takes three arguments, <code>obj</code> (the object that has the event we are no longer interested in), <code>event</code> (the name of the event that the handler is to be removed from), and <code>handler</code> (the previously added function that is to be removed).  This method first grabs the handlers list for the given event (line 32).  Next, it loops backward through the handlers list (line 34).  I typically loop backwards when removing items from a list.  The reason is that I don&#8217;t have to adjust the index after an item is removed.  If I&#8217;m on index 3, then whether or not I remove the item at index 3, the next index is always 2.  If I were to loop forward, and I removed the item at index 3, then the next item to check is still index 3 (since the item at index 4 has moved down to 3).  I also would need to adjust the stop index since the size of the array changed.  When you loop backward, the stop index is always 0.  Anyway, enough of that digression&#8230;  It loops backward through the handlers list and if the function passed in matches one in the list (line 35) then it is removed (line 36).  You can delete an array element with the <code>delete</code> keyword, but that will leave a gap in the array indexes, whereas using <code>splice</code> reindexes the array.  Hence my use of <code>splice</code> over <code>delete</code>.</p>
<p>The last event method is the <code>fire</code> method (line 40).  It takes two arguments, <code>event</code> (the event to be fired) and <code>data</code> (an object containing any data about the event).  This method loops through all of the event handlers for the given event (line 42) and executes each one (line 44).  This is where we need to be concerned with scope.  If I were to simply call the handler function, then the <code>this</code> variable inside that function would point to the current object.  That is, the <code>this</code> variable inside the handler function would point to the object that is <em>firing</em> the event.  But what I really want is for the <code>this</code> variable inside the handler function to point to the object that is <em>handling</em> the event.  That&#8217;s why I pass in the <code>this</code> variable as the scope object to the <code>listenTo</code> method when the handler is set up (line 28).  Then, in the <code>fire</code> method, I can call the handler using that scope object, ensuring that the <code>this</code> variable in the handler is set to the object handling the event (line 44).</p>
<p>Here is a simple example of how to use this event mechanism.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>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
28
29
30
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> VariableSwitch <span style="color: #339933;">=</span> LivingMachines.<span style="color: #003366; font-weight: bold;">Class</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
    construct<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">switchId</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'A'</span><span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">level</span> <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>
        createEvents<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'onLevelChanged'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
&nbsp;
    set<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>level<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">level</span> <span style="color: #339933;">=</span> level<span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">fire</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'onLevelChanged'</span><span style="color: #339933;">,</span> level<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">var</span> LightBulb <span style="color: #339933;">=</span> LivingMachines.<span style="color: #003366; font-weight: bold;">Class</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
    construct<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>sender<span style="color: #339933;">,</span> level<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">brightness</span> <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
&nbsp;
    setBrightness<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>sender<span style="color: #339933;">,</span> level<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">brightness</span> <span style="color: #339933;">=</span> level<span style="color: #339933;">;</span>
        <span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'Brightness was set by switch '</span> <span style="color: #339933;">+</span> sender.<span style="color: #660066;">switchId</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">var</span> variableSwitch <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> VariableSwitch<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> lightBulb <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> LightBulb<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
lightBulb.<span style="color: #660066;">listenTo</span><span style="color: #009900;">&#40;</span>variableSwitch<span style="color: #339933;">,</span> <span style="color: #3366CC;">'onLevelChanged'</span><span style="color: #339933;">,</span> lightBulb.<span style="color: #660066;">setBrightness</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
variableSwitch.<span style="color: #660066;">set</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">5</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>I&#8217;m creating two sample classes here.  The first is <code>VariableSwitch</code> (line 1-12).  It has an <code>switchId</code> property so we can tell which switch it is (line 3), a <code>level</code> property to indicate the current level of the switch (line 4) and an <code>onLevelChanged</code> event that will be fired when the switch level is changed (line 5).  This class also has one method, <code>set</code> (line 8), that will change the <code>level</code> of the switch (line 9) and fire the <code>onLevelChanged</code> event (line 10).</p>
<p>The second class is <code>LightBulb</code> (line 14-23).  It has a single property, <code>brightness</code> (line 16) to indicate the current brightness of the bulb.  It also has one method, <code>setBrightness</code> (line 19) that will set the brightness property to a given level (line 20) and alert the ID of the switch that caused the brightness to change (line 21).  This function is an event handler.  Notice the two arguments.  <code>sender</code> is the object that sent the event, which will be an instance of <code>VariableSwitch</code> in our case, and <code>level</code> is the data object of the event.</p>
<p>Next I create an instance of <code>VariableSwitch</code> and <code>LightBulb</code> (lines 25 and 26).  Then I attach the event handler (line 28).  The <code>lightBulb</code> object will listen to the <code>onLevelChanged</code> event of the <code>variableSwitch</code> object.  The <code>lightBulb.setBrightness</code> method will be executed when the event is fired.</p>
<p>Finally, I set the level of the <code>variableSwitch</code> (line 30) object.  This will cause the <code>onLevelChanged</code> event to be fired, and the <code>setBrightness</code> event handler method will be executed, alerting that &#8220;Brightness was set by switch A&#8221;.</p>
<p>And voilà, JavaScript classes now have event capabilities.</p>
]]></content:encoded>
			<wfw:commentRss>http://livingmachines.net/2009/06/adding-event-handling-to-javascript-classes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Adding DOM Event Handlers to the View</title>
		<link>http://livingmachines.net/2009/05/adding-dom-event-handlers-to-the-view/</link>
		<comments>http://livingmachines.net/2009/05/adding-dom-event-handlers-to-the-view/#comments</comments>
		<pubDate>Fri, 29 May 2009 18:10:15 +0000</pubDate>
		<dc:creator>Jason S. Kerchner</dc:creator>
				<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://livingmachines.net/?p=462</guid>
		<description><![CDATA[Download code
So, I have some functions that will add DOM elements to the page, allowing me to build a View.  Now, to allow the user to interact with the View, I need to add event handlers to the DOM elements.
There are basically three ways of doing this, one for W3C-compliant browsers, one for Internet [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://livingmachines.net/code/2009-05-29/LivingMachines.zip">Download code</a></p>
<p>So, I have some functions that will add DOM elements to the page, allowing me to build a View.  Now, to allow the user to interact with the View, I need to add event handlers to the DOM elements.</p>
<p>There are basically three ways of doing this, one for W3C-compliant browsers, one for Internet Explorer, and one using browser-independent JavaScript.  Personally, I prefer to use the lowest-common denominator when writing JavaScript.  If I can avoid <code>if</code> blocks that cycle through browser-specific code, I&#8217;ll be much happier.</p>
<p>Browsers that follow the W3C standards (such as Firefox) use the <code>addEventListener</code> function to attach handlers to DOM elements.  IE uses the <code>attachEvent</code> function instead.  There are some differences between these two, but both allow for multiple handlers to be attached to a single event through multiple calls to the browser-appropriate function. The IE version, however, has one serious drawback: the <code>this</code> variable in the handler function always refers to the <code>window</code> object, rather than the DOM element that the handler is attached to like the other attachment mechanisms do.  So while I could easily use browser detection to determine which function to use to attach handlers, I would still be stuck with the limitations of IE when that version was used.</p>
<p>The browser-agnostic version is to simply attach a handler function to the appropriate JavaScript event property directly.  For example,</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> btn <span style="color: #339933;">=</span> document.<span style="color: #660066;">getElementById</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'submitButton'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
btn.<span style="color: #660066;">onclick</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'I have been clicked!'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>The major drawback to this method is that you can only attach one function to the event.  This is a limitation easily gotten around, however, unlike IE&#8217;s inability to give us a useful <code>this</code> variable in the handler.  The benefit to this method is that it works on all browsers (even IE will give us a correct <code>this</code> variable inside the handler if we use this mechanism).</p>
<p>Now another drawback to event handling in general is the fact that the <code>this</code> variable will always point to the DOM element that the handler is attached to.  Yeah, I know I said it&#8217;s a drawback when it <em>doesn&#8217;t</em> point to the element, but while it is useful to know this information, it does make event handling a bit misleading when using object-oriented programming.  Consider the following:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> OkButton <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span>
    okClicked<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">,</span>
    handleClick<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">okClicked</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
document.<span style="color: #660066;">getElementById</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'ok-button'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">onclick</span> <span style="color: #339933;">=</span> OkButton.<span style="color: #660066;">handleClick</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Here I&#8217;m declaring a new object called <code>OkButton</code> (line 1).  It has a property called <code>okClicked</code> (line 2) which should be set to <code>true</code> when the OK button is clicked.  There is a <code>handleClick</code> function (line 3) which will be executed when the OK button is clicked, and will set the <code>okClicked</code> property to <code>true</code> (line 4).  Line 8 attaches the <code>handleClick</code> function to the OK button.  </p>
<p>Look carefully at line 4.  What does the <code>this</code> variable refer to?  Intuitively you would expect that it refers to the <code>OkButton</code> object, right?  After all, that is typically what we use <code>this</code> for.  But in this case, because the <code>handleClick</code> function is being executed from an event, the <code>this</code> variable will refer to the DOM element that the handler is attached to, <strong><em>not to the object that the handler function belongs to.</em></strong>  This, to me, is a bit misleading and confusing.  To make matters worse, if you call <code>OkButton.handleClick</code> directly, then the <code>this</code> variable <em>will</em> point to the <code>OkButton</code> object (since it was not executed from an event).  Ugh, I hate ambiguity.</p>
<p>I would like to change all that, so that I can write JavaScript that is more intuitive and less ambiguous.  I want the <code>this</code> variable to always refer to the object, not the DOM element, though I don&#8217;t want to lose the reference to the DOM element since it will be useful to have.  I also want to be able to attach multiple handlers to a single event.</p>
<p>I have two functions to make that happen.  One to attach an event to a DOM element, and another to dispatch an event to one or more event handlers.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>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
28
29
30
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;">LivingMachines.<span style="color: #660066;">View</span> <span style="color: #339933;">=</span> LivingMachines.<span style="color: #003366; font-weight: bold;">Class</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
&nbsp;
    <span style="color: #009966; font-style: italic;">/* ... Lots of code excluded here for brevity ... */</span>
&nbsp;
    addDomHandler<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>elem<span style="color: #339933;">,</span> event<span style="color: #339933;">,</span> fn<span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #003366; font-weight: bold;">var</span> ev <span style="color: #339933;">=</span> <span style="color: #3366CC;">'_'</span><span style="color: #339933;">+</span>event<span style="color: #339933;">;</span>       <span style="color: #006600; font-style: italic;">// Add underscore to event name (e.g. _onmousedown, _onkeypress, _onclick)</span>
        <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>elem<span style="color: #009900;">&#91;</span>ev<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span>
            elem<span style="color: #009900;">&#91;</span>ev<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span> <span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
        elem<span style="color: #009900;">&#91;</span>ev<span style="color: #009900;">&#93;</span>.<span style="color: #660066;">push</span><span style="color: #009900;">&#40;</span>scopedFn<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #339933;">,</span> fn<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        elem<span style="color: #009900;">&#91;</span>event<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">dispatchDomEvent</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
&nbsp;
    dispatchDomEvent<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>ev<span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #006600; font-style: italic;">// &quot;ev&quot; is the event object</span>
        <span style="color: #006600; font-style: italic;">// &quot;this&quot; is the element that this event handler is attached to</span>
        <span style="color: #006600; font-style: italic;">// &quot;elem&quot; is the element that initiated the event (will be a child of &quot;this&quot;, or might be &quot;this&quot;)</span>
&nbsp;
        ev <span style="color: #339933;">=</span> ev <span style="color: #339933;">||</span> window.<span style="color: #660066;">event</span><span style="color: #339933;">;</span>                      <span style="color: #006600; font-style: italic;">// IE uses global window.event</span>
        <span style="color: #003366; font-weight: bold;">var</span> elem <span style="color: #339933;">=</span> ev.<span style="color: #660066;">target</span> <span style="color: #339933;">||</span> ev.<span style="color: #660066;">srcElement</span><span style="color: #339933;">;</span>        <span style="color: #006600; font-style: italic;">// IE uses ev.srcElement</span>
        <span style="color: #003366; font-weight: bold;">var</span> handlers <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#91;</span><span style="color: #3366CC;">'_on'</span><span style="color: #339933;">+</span>ev.<span style="color: #660066;">type</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>           <span style="color: #006600; font-style: italic;">// e.g. ev.type = mousedown, keyup, click, etc.</span>
        <span style="color: #003366; font-weight: bold;">var</span> result <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> len <span style="color: #339933;">=</span> handlers.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> len<span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            result <span style="color: #339933;">=</span> handlers<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #339933;">,</span> elem<span style="color: #339933;">,</span> ev<span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;&amp;</span> result<span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #000066; font-weight: bold;">return</span> result<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Obviously, these functions are part of the View class (line 1).  </p>
<p>The first function is the <code>addDomHandler</code> method (line 5).  This is used to attach an event handler function to a DOM element event.  It takes three arguments.  <code>elem</code> is the DOM element that we want to attach the event to.  <code>event</code> is the name of the event (onclick, onmousedown, etc).  These event names must match to DOM element events, so they must be in all lowercase letters.  And <code>fn</code> is the handler function to be executed.  If you want to add more than one handler to an event, you will need to call <code>addDomHandler</code> once for each handler to be added.</p>
<p>When the <code>addDomHandler</code> function is executed, it first adds an underscore to the event name (line7).  So &#8220;onclick&#8221; becomes &#8220;_onclick&#8221;, for example.  It then checks to see if the underscored name is a property of the DOM element (line 8).  If it isn&#8217;t it creates the property as an empty array (line 9).  This is the property that the handlers will be added to.  This is what allows multiple handlers on a single event.  </p>
<p>Next, the event handler function is pushed onto the handlers array property that was just created (line 10).  The <code>scopedFn</code> function is part of the <a href="/2009/03/javascript-extensions">JavaScript Extensions</a> I created several months ago.  Basically, it ensures that a function is always executed in the scope of a given object.  In other words, it ensures that the <code>this</code> variable in a function always points to a certain object.  In this case, that object is the View (the <code>this</code> argument, which points to the View, is passed in to <code>scopedFn</code>).  This is how the <code>this</code> argument in the handler is always guaranteed to reference the View object, and never the DOM element. Don&#8217;t worry, we&#8217;ll still have access to that DOM element.  You&#8217;ll see how in a moment.  </p>
<p>The final step this function does is to attach an event handler named <code>dispatchDomEvent</code> to the event itself (line 11).  Note that we are using the event name that was passed in (not the underscored version).  This is the actual event of the DOM element, the one that gets fired when the event occurs.</p>
<p>So at this point, we have a DOM element that has a property (such as &#8220;_onclick&#8221;, &#8220;_onmousedown&#8221;, &#8220;_onkeypress&#8221;, etc.) that is an array of scope-corrected handler functions.  The DOM element&#8217;s event property (such as &#8220;onclick&#8221;, &#8220;onmousedown&#8221;, &#8220;onkeypress&#8221;, etc.) will execute the <code>dispatchDomEvent</code> method.</p>
<p>Now let&#8217;s take a look at what happens when an event is fired, causing the <code>dispatchDomEvent</code> to be executed.  Remember, it will be executed when an event is fired.  First, it get the correct event object.  In most browsers, an event object is passed directly into the function (line 14).  In Internet Explorer, the <code>window</code> object contains the event information.  I&#8217;m using the OR syntax to get the correct value for <code>ev</code> (line 20).  When an OR is executed, if the first expression has a value (is not <code>null</code>, <code>undefined</code>, an empty string or zero) then that value is returned from the OR operation and the second expression is never evaluated.  If, however, the first expression evaluates to a &#8220;nothing&#8221; value, then the second expression is evaluated and returned from the OR operation.  This ensures that the <code>ev</code> variable always points to the event object, regardless where it comes from.</p>
<p>Next, it grabs the target or source element (line 21).  This is the element that the user interacted with, <strong><em>not necessarily the element that the handler is attached to.</em></strong>  Why is that?  Because events bubble.  For example, we can attach an event handler to a DIV element.  If the user clicks on an element within that DIV element, the event will bubble up the DOM hierarchy until it finds an event handler.  In this case, the one attached to the DIV.  So the handler attached to the DIV will be executed, but the source of the event is the element that the user actually clicked on.  Most browsers keep this source element in the <code>target</code> property of the event object. Internet Explorer keeps it in the <code>srcElement</code> property.  We use the same OR technique as before to get the correct source element.  </p>
<p>Next, the function gets a pointer to the event handlers array that was added to the DOM element in the <code>addDomHandler</code> function (line 22).  </p>
<p>Events can return <code>true</code> or <code>false</code>.  If they return <code>false</code>, it will prevent the default action from happening for a given element.  For example, a form submit button, when clicked, will submit the form unless the JavaScript <code>onclick</code> event handler function returns <code>false</code>.  This will allow us to submit a form via AJAX, for example.  Because we have multiple event handlers attached to the event, we need to track the value they each return. If any one of them returns <code>false</code>, then the <code>dispatchDomEvent</code> function (which is the function actually attached to the event) should return <code>false</code> as well.  The <code>result</code> variable allows tracking of the event handler results (line 23).  </p>
<p>Finally, it loops through all the handler functions (line 24).  Remember that these are all scope-corrected functions, so when they execute, the <code>this</code> variable in each will point to the View object.  However, since the <code>dispatchDomEvent</code> method is executed from an event, the <code>this</code> variable in that function (the one we&#8217;re looking at right now) will point to the DOM element that the handler was attached to.  This is important as we look at actual execution of the handler functions (line 25).  <code>handlers</code> points to the array of event handlers, and <code>i</code> is the looping index used to access each in turn.  Since each array element points to a function, we can execute it using parenthesis, just like we do any function: <code>handlers[i]( /* arguments */ )</code>.  The <code>this</code> variable is passed in as the first argument to the handler function.  Remember, it points to the DOM element that the <code>dispatchDomEvent</code> function is attached to.  The next argument passed in is the element that initiated the event.  That is, the element that the user actually interacted with.  The last argument passed in is the <code>ev</code> (event) object.  Note that the function is ANDed with the current <code>result</code> value.  If any event handler function returns <code>false</code>, then <code>result</code> will be permanently set to <code>false</code> for the remainder of the loop.  </p>
<p>The last thing the function does is return the value of <code>result</code> (line 27).</p>
<p>Looking at how the event handler functions are executed, this means that event handler functions should have the following format:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;">MyView <span style="color: #339933;">=</span> LivingMachines.<span style="color: #003366; font-weight: bold;">Class</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
&nbsp;
    inherits<span style="color: #339933;">:</span> LivingMachines.<span style="color: #660066;">View</span><span style="color: #339933;">,</span>
&nbsp;
    handlerFn<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>sender<span style="color: #339933;">,</span> source<span style="color: #339933;">,</span> ev<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #006600; font-style: italic;">// &quot;sender&quot; is the DOM element that the handler was attached to (the element that sent the event)</span>
        <span style="color: #006600; font-style: italic;">// &quot;source&quot; is the DOM element that the user interacted with (the source of the event)</span>
        <span style="color: #006600; font-style: italic;">// &quot;ev&quot; is the event object</span>
        <span style="color: #006600; font-style: italic;">// &quot;this&quot; points to an instance of MyView</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>And there you have it.  An event handlers mechanism that allows multiple event handlers to be attached to a single event, corrects the <code>this</code> variable to always point to the View object, and gives us access to the DOM element that the handler is attached to and the DOM element that initiated the event.</p>
]]></content:encoded>
			<wfw:commentRss>http://livingmachines.net/2009/05/adding-dom-event-handlers-to-the-view/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Creating a Select Element that Plays Well with All Browsers</title>
		<link>http://livingmachines.net/2009/05/creating-a-select-element-that-plays-well-with-all-browsers/</link>
		<comments>http://livingmachines.net/2009/05/creating-a-select-element-that-plays-well-with-all-browsers/#comments</comments>
		<pubDate>Fri, 22 May 2009 01:00:14 +0000</pubDate>
		<dc:creator>Jason S. Kerchner</dc:creator>
				<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://livingmachines.net/?p=446</guid>
		<description><![CDATA[Download code
Creating DOM elements like text and password INPUTs, BUTTONs and TEXTAREAs is pretty simple.  Creating a SELECT element, however, proved to be a little more tricky thanks to a quirk in the Opera browser.
Let&#8217;s look at a SELECT tag.  It&#8217;s pretty simple, really. It has a SELECT tag with a number of [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://livingmachines.net/code/2009-05-21/LivingMachines.zip">Download code</a></p>
<p>Creating DOM elements like text and password INPUTs, BUTTONs and TEXTAREAs is pretty simple.  Creating a SELECT element, however, proved to be a little more tricky thanks to a quirk in the Opera browser.</p>
<p>Let&#8217;s look at a SELECT tag.  It&#8217;s pretty simple, really. It has a SELECT tag with a number of OPTION tags inside it.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
</pre></td><td class="code"><pre class="html" style="font-family:monospace;">&lt;select id=&quot;colors&quot; name=&quot;rgb_color&quot;&gt;
    &lt;option value=&quot;r&quot;&gt;Red&lt;/option&gt;
    &lt;option value=&quot;g&quot; selected=&quot;true&quot;&gt;Green&lt;/option&gt;
    &lt;option value=&quot;b&quot;&gt;Blue&lt;/option&gt;
&lt;/select&gt;</pre></td></tr></table></div>

<p>Each OPTION tag has a value attribute.  If this particular SELECT element was submitted from a FORM, it would send to the server the name &#8216;rgb_color&#8217; with the value &#8216;g&#8217;, since that&#8217;s the option that is currently selected.</p>
<p>From this example, it would seem that I could create a SELECT element, then add the OPTION elements to it with the selected attribute set for the appropriate option.  Using the View&#8217;s DOM rendering functions, that would look something like this (in View.js).</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;">select<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>id<span style="color: #339933;">,</span> selected<span style="color: #339933;">,</span> options<span style="color: #339933;">,</span> props<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>props<span style="color: #009900;">&#41;</span> props <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
    props.<span style="color: #660066;">id</span> <span style="color: #339933;">=</span> id<span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #003366; font-weight: bold;">var</span> optionElements <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span> <span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>options<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
        <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> value <span style="color: #000066; font-weight: bold;">in</span> options<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
            <span style="color: #003366; font-weight: bold;">var</span> optionProps <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span>
                selected<span style="color: #339933;">:</span> value <span style="color: #339933;">==</span> selected<span style="color: #339933;">,</span>
                value<span style="color: #339933;">:</span> value
            <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
            optionElements.<span style="color: #660066;">push</span><span style="color: #009900;">&#40;</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">createElement</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'option'</span><span style="color: #339933;">,</span> optionProps<span style="color: #339933;">,</span> <span style="color: #009900;">&#91;</span>options<span style="color: #009900;">&#91;</span>value<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">createElement</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'select'</span><span style="color: #339933;">,</span> props<span style="color: #339933;">,</span> optionElements<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>The first argument is the <code>id</code> of the SELECT element.  The <code>selected</code> argument is the value of the currently selected OPTION element.  This will allow us to set an option as already selected.  The <code>options</code> argument is an object that defines which OPTIONs are displayed in the SELECT drop down list.  The last argument is any additional properties to be set on the SELECT element.  So, to create the SELECT element in our example above, we would make the following call.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;">myView.<span style="color: #660066;">select</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'colors'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'g'</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span>
    r<span style="color: #339933;">:</span> <span style="color: #3366CC;">'Red'</span><span style="color: #339933;">,</span>
    g<span style="color: #339933;">:</span> <span style="color: #3366CC;">'Green'</span><span style="color: #339933;">,</span>
    b<span style="color: #339933;">:</span> <span style="color: #3366CC;">'Blue'</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span> <span style="color: #000066;">name</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">'rgb_color'</span> <span style="color: #009900;">&#125;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>When the <code>select</code> method is executed with the arguments in this call, it will loop through each of the <code>options</code> (lines 10 to 18 in the <code>select</code> function source code, above) and create an <code>optionProps</code> object for that option (lines 12 to 15).  The <code>optionProps</code> object contains the <code>value</code> (which is the property name in the <code>options</code> object, &#8216;r&#8217;, &#8216;g&#8217; or &#8216;b&#8217; in this example) and the <code>selected</code> property, which is set to true if the <code>selected</code> argument matches the <code>value</code> of the current option.  Next, it uses the <code>createElement</code> method to create the OPTION element (line 17), passing in the <code>option</code> text as a child (so that it appears between the OPTION&#8217;s open and close tags).  The third argument of <code>createElement</code> expects an array, which is why the argument is surrounded in square brackets.  Finally, the new option is added to the <code>optionElements</code> array using the array&#8217;s <code>push</code> function.</p>
<p>Now that the OPTION elements are created, the only thing left to do is create the SELECT element, and add the OPTION elements to it.  Using the <code>createElement</code> function, this is very simple (line 21).</p>
<p>And it works like a charm in all browsers except Opera.  For some reason, Opera does not like the <code>selected</code> property for the OPTION element.  I&#8217;ve tried different variations, but none seem to work.</p>
<p>The solution is to use the <code>selectedIndex</code> property of the SELECT element.  This is supported by all browsers.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>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
28
29
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;">select<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>id<span style="color: #339933;">,</span> selected<span style="color: #339933;">,</span> options<span style="color: #339933;">,</span> props<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>props<span style="color: #009900;">&#41;</span> props <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
    props.<span style="color: #660066;">id</span> <span style="color: #339933;">=</span> id<span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #003366; font-weight: bold;">var</span> optionElements <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span> <span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
    <span style="color: #003366; font-weight: bold;">var</span> selectedIndex <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>options<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
        <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> value <span style="color: #000066; font-weight: bold;">in</span> options<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
            <span style="color: #003366; font-weight: bold;">var</span> optionProps <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span>
                <span style="color: #006600; font-style: italic;">//selected: value == selected,  // Not supported by Opera</span>
                value<span style="color: #339933;">:</span> value
            <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
            <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>value <span style="color: #339933;">==</span> selected<span style="color: #009900;">&#41;</span>
                selectedIndex <span style="color: #339933;">=</span> optionElements.<span style="color: #660066;">length</span><span style="color: #339933;">;</span>
&nbsp;
            optionElements.<span style="color: #660066;">push</span><span style="color: #009900;">&#40;</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">createElement</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'option'</span><span style="color: #339933;">,</span> optionProps<span style="color: #339933;">,</span> <span style="color: #009900;">&#91;</span>options<span style="color: #009900;">&#91;</span>value<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #003366; font-weight: bold;">var</span> sel <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">createElement</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'select'</span><span style="color: #339933;">,</span> props<span style="color: #339933;">,</span> optionElements<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    sel.<span style="color: #660066;">selectedIndex</span> <span style="color: #339933;">=</span> selectedIndex<span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000066; font-weight: bold;">return</span> sel<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Line 7 adds a new variable to track the selected OPTION element, and is defaulted to zero (the first OPTION element).  In line 14, I&#8217;ve removed the <code>selected</code> property, as it will not be used.  Line 18 checks if the current option&#8217;s <code>value</code> matches the <code>selected</code> argument and, if it does, sets the <code>selectedIndex</code> appropriately (line 19).  Line 25 creates the SELECT element, and line 26 sets the <code>selectedIndex</code> of the SELECT element.  I have to set the <code>selectedIndex</code> after creating the element since the current version of <code>createElement</code> applies the <code>props</code> object <strong><em>before</em></strong> the child OPTION elements are added, and you can&#8217;t set <code>selectedIndex</code> when there are no OPTION elements.  If this were not the case, if the <code>props</code> object was applied to the element <strong><em>after</em></strong> all OPTION elements were added, then I could just add <code>selectedIndex</code> to the <code>props</code> object.  Hmm.  Maybe a change to <code>createElement</code> is in order.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>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
28
29
30
31
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;">createElement<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>tag<span style="color: #339933;">,</span> props<span style="color: #339933;">,</span> elements<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    <span style="color: #006600; font-style: italic;">// Create the element</span>
    <span style="color: #003366; font-weight: bold;">var</span> elem <span style="color: #339933;">=</span> document.<span style="color: #660066;">createElement</span><span style="color: #009900;">&#40;</span>tag<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">// MOVE THIS BLOCK DOWN TO LINE 24</span>
    <span style="color: #006600; font-style: italic;">//window.copy(props, elem, function(data) {</span>
    <span style="color: #006600; font-style: italic;">//    if (data.prop == 'cssFloat' &amp;&amp; !elem.cssFloat)</span>
    <span style="color: #006600; font-style: italic;">//        data.prop = 'styleFloat';</span>
    <span style="color: #006600; font-style: italic;">//});</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">// Add any inner element to the newly created DOM object        </span>
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>elements<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
        <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> len <span style="color: #339933;">=</span> elements.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> len<span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>isString<span style="color: #009900;">&#40;</span>elements<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
                elem.<span style="color: #660066;">appendChild</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">element</span><span style="color: #009900;">&#40;</span>elements<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>elements<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span>   <span style="color: #006600; font-style: italic;">// Make sure not null or undefined</span>
                elem.<span style="color: #660066;">appendChild</span><span style="color: #009900;">&#40;</span>elements<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">// Apply the properties to the element, correct property names where necessary (Globals.js)</span>
    window.<span style="color: #660066;">copy</span><span style="color: #009900;">&#40;</span>props<span style="color: #339933;">,</span> elem<span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>data<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>data.<span style="color: #660066;">prop</span> <span style="color: #339933;">==</span> <span style="color: #3366CC;">'cssFloat'</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #339933;">!</span>elem.<span style="color: #660066;">cssFloat</span><span style="color: #009900;">&#41;</span>
            data.<span style="color: #660066;">prop</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'styleFloat'</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">// Lastly, return our new DOM element</span>
    <span style="color: #000066; font-weight: bold;">return</span> elem<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>That&#8217;s better.  Now the <code>props</code> object will be applied after all child elements have been added.  All unit tests still pass with this change.  Will it break something else or cause problems in the future?  Maybe.  But for now, it simplifies the code for the <code>select</code> method, since I no longer need to track <code>selectedIndex</code> separately.  Instead, I can update it in the <code>props</code> object directly.  This also allows the <code>selectedIndex</code> property to be passed in to the <code>props</code> argument and have it be set correctly.  That gives another option for setting the currently selected option other than the <code>selected</code> argument.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;">select<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>id<span style="color: #339933;">,</span> selected<span style="color: #339933;">,</span> options<span style="color: #339933;">,</span> props<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>props<span style="color: #009900;">&#41;</span> props <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
    props.<span style="color: #660066;">id</span> <span style="color: #339933;">=</span> id<span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #003366; font-weight: bold;">var</span> optionElements <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span> <span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>options<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
        <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> value <span style="color: #000066; font-weight: bold;">in</span> options<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
            <span style="color: #003366; font-weight: bold;">var</span> optionProps <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span>
                value<span style="color: #339933;">:</span> value
            <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
            <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>value <span style="color: #339933;">==</span> selected<span style="color: #009900;">&#41;</span>
                props.<span style="color: #660066;">selectedIndex</span> <span style="color: #339933;">=</span> optionElements.<span style="color: #660066;">length</span><span style="color: #339933;">;</span>
&nbsp;
            optionElements.<span style="color: #660066;">push</span><span style="color: #009900;">&#40;</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">createElement</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'option'</span><span style="color: #339933;">,</span> optionProps<span style="color: #339933;">,</span> <span style="color: #009900;">&#91;</span>options<span style="color: #009900;">&#91;</span>value<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">createElement</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'select'</span><span style="color: #339933;">,</span> props<span style="color: #339933;">,</span> optionElements<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Note that the <code>selectedIndex</code> variable has been removed.  If the option <code>value</code> and the <code>selected</code> argument values match, then line 17 sets the <code>selectedIndex</code> property of the <code>props</code> object.  Thanks to JavaScript&#8217;s mutable objects, if this property doesn&#8217;t already exist, it will be created.  Line 23 is the call to the <code>createElement</code> method to create the SELECT element and set the properties.  </p>
<p>If you compare the original version (the one that didn&#8217;t work with Opera) to this version, one line of code was deleted and two were added, for a net result of one additional line of code.  Not too bad when trying to correct browser incompatibilities.</p>
<p>So, there&#8217;s the final version for now.  Of course, this does not support multiple option selects.  That&#8217;s for another time, I think.</p>
]]></content:encoded>
			<wfw:commentRss>http://livingmachines.net/2009/05/creating-a-select-element-that-plays-well-with-all-browsers/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Copying DOM Element Properties and Handling Browser Differences</title>
		<link>http://livingmachines.net/2009/05/copying-dom-element-properties-and-handling-browser-differences/</link>
		<comments>http://livingmachines.net/2009/05/copying-dom-element-properties-and-handling-browser-differences/#comments</comments>
		<pubDate>Thu, 21 May 2009 04:08:16 +0000</pubDate>
		<dc:creator>Jason S. Kerchner</dc:creator>
				<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://livingmachines.net/?p=435</guid>
		<description><![CDATA[Download code
I&#8217;ve made another slight, but significant, change to the way in which DOM elements are created by the View.  Going back to my original approach of building DOM elements from HTML strings, it made sense to refer directly to HTML and CSS attributes.  But now that I&#8217;m creating DOM elements directly through [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://livingmachines.net/code/2009-05-20/LivingMachines.zip">Download code</a></p>
<p>I&#8217;ve made another slight, but significant, change to the way in which DOM elements are created by the View.  Going back to my original approach of <a href="/2009/05/refining-the-creation-of-dom-elements">building DOM elements from HTML strings</a>, it made sense to refer directly to HTML and CSS attributes.  But now that I&#8217;m creating DOM elements directly through <code>document.createElement</code>, there is no need to use HTML attributes, and I can just use the DOM element properties.  </p>
<p>The first change, then, was to rename <code>attribs</code> (attributes) in all DOM element rendering functions to <code>props</code> (properties).</p>
<p>Next, I updated the view&#8217;s <code>createElement</code> function (in View.js, not <code>document.createElement</code>).  This is the original version.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>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
28
29
30
31
32
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;">createElement<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>tag<span style="color: #339933;">,</span> attribs<span style="color: #339933;">,</span> elements<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    <span style="color: #006600; font-style: italic;">// Create the element</span>
    <span style="color: #003366; font-weight: bold;">var</span> elem <span style="color: #339933;">=</span> document.<span style="color: #660066;">createElement</span><span style="color: #009900;">&#40;</span>tag<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">// Add the attributes to the element. HTML attribute names do not always match</span>
    <span style="color: #006600; font-style: italic;">// the name that the DOM uses, so we check for them here.  This may not be all</span>
    <span style="color: #006600; font-style: italic;">// of them yet!</span>
    <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> a <span style="color: #000066; font-weight: bold;">in</span> attribs<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        attr <span style="color: #339933;">=</span> a.<span style="color: #660066;">toLowerCase</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>attr <span style="color: #339933;">==</span> <span style="color: #3366CC;">'class'</span><span style="color: #009900;">&#41;</span>
            elem.<span style="color: #660066;">className</span> <span style="color: #339933;">=</span> attribs<span style="color: #009900;">&#91;</span>a<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>attr <span style="color: #339933;">==</span> <span style="color: #3366CC;">'for'</span><span style="color: #009900;">&#41;</span>
            elem.<span style="color: #660066;">htmlFor</span> <span style="color: #339933;">=</span> attribs<span style="color: #009900;">&#91;</span>a<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">else</span>
            elem.<span style="color: #660066;">setAttribute</span><span style="color: #009900;">&#40;</span>a<span style="color: #339933;">,</span> attribs<span style="color: #009900;">&#91;</span>a<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">// Add any inner element to the newly created DOM object        </span>
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>elements<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
        <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> len <span style="color: #339933;">=</span> elements.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> len<span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>isString<span style="color: #009900;">&#40;</span>elements<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
                elem.<span style="color: #660066;">appendChild</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">element</span><span style="color: #009900;">&#40;</span>elements<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>elements<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span>   <span style="color: #006600; font-style: italic;">// Make sure not null or undefined</span>
                elem.<span style="color: #660066;">appendChild</span><span style="color: #009900;">&#40;</span>elements<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">// Lastly, return our new DOM element</span>
    <span style="color: #000066; font-weight: bold;">return</span> elem<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>In the new version (below) note that the second argument has been changed from <code>attribs</code> to <code>props</code>.  It now expects DOM element property names, not HTML attribute names.  This means I need to use names like <code>className</code> instead of <code>class</code>, and <code>htmlFor</code> instead of <code>for</code>.  Since this function no longer has to do attribute name to property name conversions (since I&#8217;m now passing it property names and not attribute names), lines 6 through 10 (lines 6 through 17 in the original version) have been updated to use the <code>copy</code> function (in Globals.js, part of the <a href="/?tag=javascript-extensions">JavaScript Extensions</a>). I&#8217;ll explain that third argument to the <code>copy</code> function, the anonymous function with the <code>data</code> argument, in a moment.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>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
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;">createElement<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>tag<span style="color: #339933;">,</span> props<span style="color: #339933;">,</span> elements<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    <span style="color: #006600; font-style: italic;">// Create the element</span>
    <span style="color: #003366; font-weight: bold;">var</span> elem <span style="color: #339933;">=</span> document.<span style="color: #660066;">createElement</span><span style="color: #009900;">&#40;</span>tag<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">// Apply the properties to the element, correct property names where necessary (Globals.js)</span>
    window.<span style="color: #660066;">copy</span><span style="color: #009900;">&#40;</span>props<span style="color: #339933;">,</span> elem<span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>data<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>data.<span style="color: #660066;">prop</span> <span style="color: #339933;">==</span> <span style="color: #3366CC;">'cssFloat'</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #339933;">!</span>elem.<span style="color: #660066;">cssFloat</span><span style="color: #009900;">&#41;</span>
            data.<span style="color: #660066;">prop</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'styleFloat'</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">// Add any inner element to the newly created DOM object        </span>
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>elements<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
        <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> len <span style="color: #339933;">=</span> elements.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> len<span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>isString<span style="color: #009900;">&#40;</span>elements<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
                elem.<span style="color: #660066;">appendChild</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">element</span><span style="color: #009900;">&#40;</span>elements<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>elements<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span>   <span style="color: #006600; font-style: italic;">// Make sure not null or undefined</span>
                elem.<span style="color: #660066;">appendChild</span><span style="color: #009900;">&#40;</span>elements<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">// Lastly, return our new DOM element</span>
    <span style="color: #000066; font-weight: bold;">return</span> elem<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>There are some special cases to handle when copying properties, so I needed to alter the <code>copy</code> function, too.  These special cases are due to browser differences.  Like the fact that all browsers use the <code>style.cssFloat</code> property, but IE uses <code>style.styleFloat</code>.  If I&#8217;m going to use the <code>copy</code> function, a change is required to handle these special scenarios.  But since the <code>copy</code> function is an extension, I want to keep the change generic.  </p>
<p>The <code>copy</code> function originally took two arguments.  The first was the source object, and the second was the destination object.  Now, there is a third argument. This argument is a function that will be called for every property in the source object just before it is added to the destination object.  This allows the property name, value or data type to be changed before it is copied to the destination object.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>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
28
29
30
31
32
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;">window.<span style="color: #660066;">copy</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>src<span style="color: #339933;">,</span> dest<span style="color: #339933;">,</span> fn<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>dest<span style="color: #009900;">&#41;</span> 
        dest <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> prop <span style="color: #000066; font-weight: bold;">in</span> src<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #003366; font-weight: bold;">var</span> value <span style="color: #339933;">=</span> src<span style="color: #009900;">&#91;</span>prop<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
        <span style="color: #003366; font-weight: bold;">var</span> type <span style="color: #339933;">=</span> window.<span style="color: #000066; font-weight: bold;">typeOf</span><span style="color: #009900;">&#40;</span>value<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>fn<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #003366; font-weight: bold;">var</span> data <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span> prop<span style="color: #339933;">:</span> prop<span style="color: #339933;">,</span> value<span style="color: #339933;">:</span> value<span style="color: #339933;">,</span> type<span style="color: #339933;">:</span> type <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
            fn<span style="color: #009900;">&#40;</span>data<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            prop <span style="color: #339933;">=</span> data.<span style="color: #660066;">prop</span><span style="color: #339933;">;</span>
            value <span style="color: #339933;">=</span> data.<span style="color: #660066;">value</span><span style="color: #339933;">;</span>
            type <span style="color: #339933;">=</span> data.<span style="color: #660066;">type</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>type <span style="color: #339933;">==</span> <span style="color: #3366CC;">'object'</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>dest<span style="color: #009900;">&#91;</span>prop<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span>
                dest<span style="color: #009900;">&#91;</span>prop<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
            window.<span style="color: #660066;">copy</span><span style="color: #009900;">&#40;</span>value<span style="color: #339933;">,</span> dest<span style="color: #009900;">&#91;</span>prop<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>type <span style="color: #339933;">==</span> <span style="color: #3366CC;">'date'</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            dest<span style="color: #009900;">&#91;</span>prop<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Date<span style="color: #009900;">&#40;</span>value.<span style="color: #660066;">getTime</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>type <span style="color: #339933;">==</span> <span style="color: #3366CC;">'array'</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            dest<span style="color: #009900;">&#91;</span>prop<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> value.<span style="color: #660066;">slice</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span>
            dest<span style="color: #009900;">&#91;</span>prop<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> value<span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000066; font-weight: bold;">return</span> dest<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Lines 8 through 14 check if a callback function (<code>fn</code>) was passed in and, if so, creates an object that has three properties: the property name, value and data type.  This <code>data</code> object is then passed to the callback function.  Why use an object, rather than passing the values in as three separate arguments?  Because objects are passed by reference.  This means that the callback function <code>data</code> object points to the same <code>data</code> object as the <code>copy</code> function, so changing a value in the callback function also changes that value in the <code>copy</code> function (since both are pointing to the same <code>data</code> object).  If I was passing in three separate arguments, they would be local only to the callback function, so changing their values would not change them in the <code>copy</code> function.</p>
<p>If you look back at the modified code for the View&#8217;s <code>createElement</code> function above, you&#8217;ll see that the callback function checks to see if the property is <code>cssFloat</code> and, if it is, checks to see if that property exists in the DOM element.  If it doesn&#8217;t, it means we are running in IE and must use the <code>styleFloat</code> property name.  In that case, it changes the property name.</p>
<p>So adding the callback function to <code>copy</code> allows me to change property names to suit different browsers, but still keep the <code>copy</code> function generic.</p>
<p>The other advantage to using the <code>copy</code> function that that it handles nested objects.  So, specifying styles can be done with a <code>props</code> object like the following passed to the View&#8217;s <code>createElement</code> function.  Note that these are DOM element property names, not CSS attribute names.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #009900;">&#123;</span>
    id<span style="color: #339933;">:</span> <span style="color: #3366CC;">'someId'</span><span style="color: #339933;">,</span>
    style<span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
        display<span style="color: #339933;">:</span> <span style="color: #3366CC;">'block'</span><span style="color: #339933;">,</span>
        backgroundColor<span style="color: #339933;">:</span> <span style="color: #3366CC;">'#cccccc'</span><span style="color: #339933;">,</span>
        cssFloat<span style="color: #339933;">:</span> <span style="color: #3366CC;">'right'</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>So, not any major changes here, but they are significant from the perspective of using the View.  It also simplifies the View&#8217;s <code>createElement</code> function a little more, but still keeps it flexible.</p>
]]></content:encoded>
			<wfw:commentRss>http://livingmachines.net/2009/05/copying-dom-element-properties-and-handling-browser-differences/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Refining the Creation of DOM Elements</title>
		<link>http://livingmachines.net/2009/05/refining-the-creation-of-dom-elements/</link>
		<comments>http://livingmachines.net/2009/05/refining-the-creation-of-dom-elements/#comments</comments>
		<pubDate>Wed, 13 May 2009 21:22:11 +0000</pubDate>
		<dc:creator>Jason S. Kerchner</dc:creator>
				<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://livingmachines.net/?p=405</guid>
		<description><![CDATA[Download code
If you recall from my first stab at creating the MVC View, I had a method of the View class called tag that would take some arguments and create a DOM element from them.  This tag method would be called from higher-level methods designed to make creating a DOM element for the View [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://livingmachines.net/code/2009-05-13/LivingMachines.zip">Download code</a></p>
<p>If you recall from <a href="/2009/05/first-stab-at-putting-the-v-in-mvc">my first stab at creating the MVC View</a>, I had a method of the <code>View</code> class called <code>tag</code> that would take some arguments and create a DOM element from them.  This <code>tag</code> method would be called from higher-level methods designed to make creating a DOM element for the View easier.  For example, the <code>form</code> method below (also a member of the <code>View</code> class) is used to create a FORM element.  The <code>tag</code> method is called in line 9, and it does the actual work of creating the FORM element:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;">form<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>id<span style="color: #339933;">,</span> url<span style="color: #339933;">,</span> method<span style="color: #339933;">,</span> attribs <span style="color: #009966; font-style: italic;">/*, elements*/</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>attribs<span style="color: #009900;">&#41;</span> attribs <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
    attribs.<span style="color: #660066;">id</span> <span style="color: #339933;">=</span> id<span style="color: #339933;">;</span>
    attribs.<span style="color: #660066;">action</span> <span style="color: #339933;">=</span> url<span style="color: #339933;">;</span>
    attribs.<span style="color: #660066;">method</span> <span style="color: #339933;">=</span> method<span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">tag</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'&lt;form %a&gt;&lt;/form&gt;'</span><span style="color: #339933;">,</span> attribs<span style="color: #339933;">,</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">extractArgs</span><span style="color: #009900;">&#40;</span>arguments<span style="color: #339933;">,</span> <span style="color: #CC0000;">4</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Now, let me explain a few things.  First, I had envisioned calling <code>tag</code> with more options, like this:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #000066; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">tag</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'&lt;form id=&quot;%i&quot; action=&quot;%v&quot; %a&gt;%e&lt;/form&gt;'</span><span style="color: #339933;">,</span> id<span style="color: #339933;">,</span> url<span style="color: #339933;">,</span> attribs<span style="color: #339933;">,</span> elements<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>The <code>%i</code> would be replace with the id, <code>%v</code> would be the value (the <code>url</code> argument in this example), <code>%a</code> would be additional attributes, and <code>%e</code> would be the other elements contained by this element.  All elements would include these arguments, so an INPUT element would be created something like this:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #000066; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">tag</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'&lt;input id=&quot;%i&quot; value=&quot;%v&quot; %a /&gt;'</span><span style="color: #339933;">,</span> id<span style="color: #339933;">,</span> value<span style="color: #339933;">,</span> attribs<span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>What I realized, however, was that <code>%i</code> and <code>%v</code> were superfluous, and could be eliminated.  Since these were just attributes, they could simply be added as part of <code>%a</code>.  And this is exactly what I did in the first version of the <code>tag</code> function that I posted.</p>
<p>The <code>%e</code> I realized would require me to work strictly with HTML strings.  In other words, I could replace the <code>%e</code> with an HTML string, but not with an actual DOM element (I can&#8217;t insert an object into the format string).  The better plan, I figured, was to convert any HTML strings into DOM elements, then add the DOM elements to the containing element created by the <code>tag</code> method.  That gave me more flexibility with what I passed as elements to the <code>tag</code> method.  I could pass in an HTML string and convert it, or just pass in a DOM element.  It also eliminated the need for the <code>%e</code>.  Hence it was also dropped in the previous version of the <code>tag</code> method.</p>
<p>That left a much simpler structure, though it still had its roots in working with HTML strings.  The attributes were expected to be passed into the <code>tag</code> method as an object of name/value pairs.  That object would then be converted into an attributes string, and the <code>%a</code> in the <code>format</code> argument would be replaced with it.  So essentially, a call to the <code>tag</code> method, like in line 9 below&#8230;</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;">text<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>id<span style="color: #339933;">,</span> value<span style="color: #339933;">,</span> attribs<span style="color: #009900;">&#41;</span> 
<span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>attribs<span style="color: #009900;">&#41;</span> attribs <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
    attribs.<span style="color: #660066;">type</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'text'</span><span style="color: #339933;">;</span>
    attribs.<span style="color: #660066;">id</span> <span style="color: #339933;">=</span> id<span style="color: #339933;">;</span>
    attribs.<span style="color: #660066;">value</span> <span style="color: #339933;">=</span> value<span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">tag</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'&lt;input %a /&gt;'</span><span style="color: #339933;">,</span> attribs<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span></pre></td></tr></table></div>

<p>&#8230;would result in the following code being executed inside the <code>tag</code> method&#8230;</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// Convert the attribs object to an HTML string.</span>
<span style="color: #003366; font-weight: bold;">var</span> attribsHtml <span style="color: #339933;">=</span> <span style="color: #3366CC;">''</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> singleAttrib <span style="color: #339933;">=</span> <span style="color: #3366CC;">'.compact.checked.declare.readonly.disabled.selected.defer.ismap.nohref.noshade.nowrap.multiple.noresize.'</span><span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> a <span style="color: #000066; font-weight: bold;">in</span> attribs<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>singleAttrib.<span style="color: #660066;">indexOf</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'.'</span> <span style="color: #339933;">+</span> a <span style="color: #339933;">+</span> <span style="color: #3366CC;">'.'</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&gt;</span> <span style="color: #339933;">-</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>attribs<span style="color: #009900;">&#91;</span>a<span style="color: #009900;">&#93;</span> <span style="color: #339933;">==</span> <span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">||</span> <span style="color: #009900;">&#40;</span>attribs<span style="color: #009900;">&#91;</span>a<span style="color: #009900;">&#93;</span> <span style="color: #339933;">==</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">||</span> <span style="color: #009900;">&#40;</span>attribs<span style="color: #009900;">&#91;</span>a<span style="color: #009900;">&#93;</span> <span style="color: #339933;">==</span> <span style="color: #3366CC;">'true'</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">||</span> <span style="color: #009900;">&#40;</span>attribs<span style="color: #009900;">&#91;</span>a<span style="color: #009900;">&#93;</span> <span style="color: #339933;">==</span> a<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
            attribsHtml <span style="color: #339933;">+=</span> <span style="color: #3366CC;">' '</span> <span style="color: #339933;">+</span> a<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>attribs<span style="color: #009900;">&#91;</span>a<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> <span style="color: #006600; font-style: italic;">// Make sure its not null.</span>
            attribsHtml <span style="color: #339933;">+=</span> <span style="color: #3366CC;">' '</span> <span style="color: #339933;">+</span> a <span style="color: #339933;">+</span> <span style="color: #3366CC;">'=&quot;'</span> <span style="color: #339933;">+</span> attribs<span style="color: #009900;">&#91;</span>a<span style="color: #009900;">&#93;</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">'&quot;'</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// Insert the attributes into the tag format</span>
format <span style="color: #339933;">=</span> format.<span style="color: #660066;">replace</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'%a'</span><span style="color: #339933;">,</span> attribsHtml<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>&#8230;which would create an attributes string (lines 1-13) that would then be inserted into the <code>format</code> argument at the <code>%a</code> position (line 16).  In this particular example, this would result in an HTML string like the following:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;">format <span style="color: #339933;">=</span> <span style="color: #3366CC;">'&lt;input type=&quot;text&quot; id=&quot;username&quot; value=&quot;jdoe&quot; /&gt;'</span></pre></td></tr></table></div>

<p>I could then take this HTML string, this complete tag, and convert it into a DOM element with a call to the <code>element</code> method.  In fact, this is exactly what the <code>tag</code> method did next.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// Convert the HTML string to a DOM object</span>
<span style="color: #003366; font-weight: bold;">var</span> elem <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">element</span><span style="color: #009900;">&#40;</span>format<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>So that&#8217;s where it stood as per my last post, and up until recently, it worked nicely.</p>
<p>However, I began working on a method to create a TABLE element.  I got as far as attempting to create the TR and TD elements.  Turns out, these cannot be created anywhere except inside a TABLE element, which meant creating them using the <code>tag</code> method was impossible.  You see, the <code>element</code> method (which the <code>tag</code> method uses to actually create the DOM element) creates a DIV, sets the innerHTML of the DIV to the HTML string that was created, then extracts the DOM element that the browser created from the HTML.  But TR and TD elements can&#8217;t sit inside a DIV element, so the browser (at least Firefox) will not create them using the <code>element</code> method.</p>
<p>I really dislike making special cases and wanted to avoid that if at all possible.  In other words, I didn&#8217;t want to check if the tag passed in was a TR or a TD and then work some different magic to create them as DOM elements.  I wanted to use the same mechanism, regardless of the element being created.</p>
<p>I could create the TABLE element as a single string, with all the TR and TD elements inside it, but that would mean separate code to create the attribute strings, or pulling the attribute string generating code into a separate method.  It would also mean I could wind up concatenating a huge HTML string, depending on how big the table was.  Also, in order to keep the same mechanism where the programmer could pass in HTML strings or DOM elements, I would potentially have to convert a DOM element (one that might appear in a table cell, for example) into a string so that I could build it into the table.  The more I thought about it, the more convoluted the whole processes seemed.</p>
<p>It was at this point that I realized five things.  First, all the tags had the same format: <code>'&lt;tag %a&gt;&lt;/tag&gt;'</code>.  Only the tag name was different.  Second, any element can be created using the <code>document.createElement</code> function, even if that element can only sit inside specific other elements (like TR and TD can only sit inside a TABLE element).  Third, all you need is the tag name to use <code>document.createElement</code>.  Fourth, attributes can be added directly to a DOM element; they don&#8217;t need to be name/value pair strings.  Fifth, I really didn&#8217;t like the name &#8220;tag&#8221; for the method, since it does not describe what the method really does.</p>
<p>So, I set out to refactor the <code>tag</code> method.  First, I changed the name of the method to <code>createElement</code>, which more accurately describes what it does. Next, I<br />
 renamed the first argument from <code>format</code> to <code>tag</code>.  Now, it expects only a tag name, not a tag format.  And <code>%a</code> is no longer needed.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// Original</span>
tag<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>format<span style="color: #339933;">,</span> attribs<span style="color: #339933;">,</span> elements<span style="color: #009900;">&#41;</span>
<span style="color: #006600; font-style: italic;">// New</span>
createElement<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>tag<span style="color: #339933;">,</span> attribs<span style="color: #339933;">,</span> elements<span style="color: #009900;">&#41;</span></pre></td></tr></table></div>

<p>So, the part of the <code>form</code> method that calls the <code>tag</code> method changes, too.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;">form<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>id<span style="color: #339933;">,</span> url<span style="color: #339933;">,</span> method<span style="color: #339933;">,</span> attribs <span style="color: #009966; font-style: italic;">/*, elements*/</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>attribs<span style="color: #009900;">&#41;</span> attribs <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
    attribs.<span style="color: #660066;">id</span> <span style="color: #339933;">=</span> id<span style="color: #339933;">;</span>
    attribs.<span style="color: #660066;">action</span> <span style="color: #339933;">=</span> url<span style="color: #339933;">;</span>
    attribs.<span style="color: #660066;">method</span> <span style="color: #339933;">=</span> method<span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">// Original</span>
    <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">tag</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'&lt;form %a&gt;&lt;/form&gt;'</span><span style="color: #339933;">,</span> attribs<span style="color: #339933;">,</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">extractArgs</span><span style="color: #009900;">&#40;</span>arguments<span style="color: #339933;">,</span> <span style="color: #CC0000;">4</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #006600; font-style: italic;">// New</span>
    <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">createElement</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'form'</span><span style="color: #339933;">,</span> attribs<span style="color: #339933;">,</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">extractArgs</span><span style="color: #009900;">&#40;</span>arguments<span style="color: #339933;">,</span> <span style="color: #CC0000;">4</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>I still have concerns about the method name.  I can see where some people would confuse the View&#8217;s <code>createElement</code> method for the document&#8217;s <code>createElement</code> function.  They are not the same, but the name accurately describes what they do.  So for now, I will leave it with the new name.</p>
<p>Incidentally, if you are not familiar with the <code>extractArgs</code> method, you can learn about it in my <a href="/2009/05/first-stab-at-putting-the-v-in-mvc">first post on creating the MVC view</a>.</p>
<p>Finally, the <code>tag</code> method, now renamed to <code>createElement</code>, got some internal changes as well.  It now uses the <code>document.createElement</code> function to create elements, and it adds attributes directly to the newly created DOM element.  The following is the updated function in its entirety.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>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
28
29
30
31
32
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;">createElement<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>tag<span style="color: #339933;">,</span> attribs<span style="color: #339933;">,</span> elements<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    <span style="color: #006600; font-style: italic;">// Create the element</span>
    <span style="color: #003366; font-weight: bold;">var</span> elem <span style="color: #339933;">=</span> document.<span style="color: #660066;">createElement</span><span style="color: #009900;">&#40;</span>tag<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">// Add the attributes to the element. HTML attribute names do not always match</span>
    <span style="color: #006600; font-style: italic;">// the name that the DOM uses, so we check for them here.  This may not be all</span>
    <span style="color: #006600; font-style: italic;">// of them yet!</span>
    <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> a <span style="color: #000066; font-weight: bold;">in</span> attribs<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        attr <span style="color: #339933;">=</span> a.<span style="color: #660066;">toLowerCase</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>attr <span style="color: #339933;">==</span> <span style="color: #3366CC;">'class'</span><span style="color: #009900;">&#41;</span>
            elem.<span style="color: #660066;">className</span> <span style="color: #339933;">=</span> attribs<span style="color: #009900;">&#91;</span>a<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>attr <span style="color: #339933;">==</span> <span style="color: #3366CC;">'for'</span><span style="color: #009900;">&#41;</span>
            elem.<span style="color: #660066;">htmlFor</span> <span style="color: #339933;">=</span> attribs<span style="color: #009900;">&#91;</span>a<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">else</span>
            elem.<span style="color: #660066;">setAttribute</span><span style="color: #009900;">&#40;</span>a<span style="color: #339933;">,</span> attribs<span style="color: #009900;">&#91;</span>a<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">// Add any inner element to the newly created DOM object        </span>
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>elements<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
        <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> len <span style="color: #339933;">=</span> elements.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> len<span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>isString<span style="color: #009900;">&#40;</span>elements<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
                elem.<span style="color: #660066;">appendChild</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">element</span><span style="color: #009900;">&#40;</span>elements<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>elements<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span>   <span style="color: #006600; font-style: italic;">// Make sure not null or undefined</span>
                elem.<span style="color: #660066;">appendChild</span><span style="color: #009900;">&#40;</span>elements<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">// Lastly, return our new DOM element</span>
    <span style="color: #000066; font-weight: bold;">return</span> elem<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>First, it creates the DOM element (line 4).  Then it adds the attributes to the element (lines 6-17).  It is expected that these attributes are passed in with names that map to HTML attributes.  The DOM property names may be different.  For example, the HTML <code>class</code> attribute maps to the DOM element <code>className</code> property.  I haven&#8217;t gone through all of the attributes yet, so this is probably not a complete list.  As a bonus, now that I&#8217;m not creating a string of attributes, the code is much simpler.</p>
<p>The rest of the method is the same as the original, and uses the <code>element</code> method where necessary to convert HTML strings into DOM elements.  I think this will be fine since it is unlikely that we will be passing HTML strings in for inner elements that cannot be created inside a DIV element.  The <code>table</code> rendering method takes care of creating those elements that can only appear inside a TABLE element, and anything that we might pass in to be created inside a TD element should be able to be created inside a DIV, just the way the <code>element</code> method does it.</p>
<p>In my next post, I&#8217;ll take a closer look at that <code>table</code> method that started this whole refactoring process.  For those who are interested in taking a look at it now, it&#8217;s available if you <a href="http://livingmachines.net/code/2009-05-13/LivingMachines.zip">download the source code</a>.</p>
<p>One final note.  The test scripts for this are by no means complete and are, quite frankly, rather sloppy at the moment.  I&#8217;ll get them cleaned up soon.</p>
]]></content:encoded>
			<wfw:commentRss>http://livingmachines.net/2009/05/refining-the-creation-of-dom-elements/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Working out the Internet Explorer Bugs</title>
		<link>http://livingmachines.net/2009/05/working-out-the-internet-explorer-bugs/</link>
		<comments>http://livingmachines.net/2009/05/working-out-the-internet-explorer-bugs/#comments</comments>
		<pubDate>Sat, 09 May 2009 05:18:52 +0000</pubDate>
		<dc:creator>Jason S. Kerchner</dc:creator>
				<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://livingmachines.net/?p=400</guid>
		<description><![CDATA[I code on a Mac and test in Firefox during the majority of the development process.  I do have a PC, sitting in the corner of my office, which I use to test code periodically to make sure everything also works in IE.  (I also test Safari, Opera, Chrome and, if I&#8217;m feeling [...]]]></description>
			<content:encoded><![CDATA[<p>I code on a Mac and test in Firefox during the majority of the development process.  I do have a PC, sitting in the corner of my office, which I use to test code periodically to make sure everything also works in IE.  (I also test Safari, Opera, Chrome and, if I&#8217;m feeling generous, Netscape) The great thing about test-driven development is that, since testing is automatic, it&#8217;s really easy to test on multiple systems.  Just fire up the browser, point it to the test page, and the results are spit out for you.</p>
<p>But, alas, I don&#8217;t always do it.  Like when I posted the code for my <a href="/2009/05/first-stab-at-putting-the-v-in-mvc">first stab at creating the MVC View</a>.  Turns out, there was a problem running the code on Internet Explorer.</p>
<p>The problem was with generating the unique id for the View when one was not given in the constructor.  The <code>initContainer</code> function would generate a unique id for you using the <code>getTime</code> function, like so:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>elem<span style="color: #009900;">&#41;</span> 
    elem <span style="color: #339933;">=</span> <span style="color: #3366CC;">'view'</span> <span style="color: #339933;">+</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">new</span> Date<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">getTime</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>If <code>elem</code> was not passed in, or was passed in as <code>null</code>, then this would create a new date object and get the time.  <code>new Date()</code> should return a new date object with the current date and time, since we are not passing in any arguments.  The <code>getTime</code> function returns the number of milliseconds since January 1, 1970.  Theoretically, then, each call to <code>getTime</code> should return a new number, since we will not be creating Views within one millisecond of each other.  And this works just fine on all browsers except Internet Explorer.  Seems IE always returns the same value for <code>getTime</code>.  That is unless you get the value, then display it in an alert box.  In that case it does function properly.  But that&#8217;s not a very user-friendly solution.</p>
<p>So, I came up with a solution that uses a static class variable.  After creating the <code>LivingMachines.View</code> class, I added a static variable called <code>nextId</code> (line 5).</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;">LivingMachines.<span style="color: #660066;">View</span> <span style="color: #339933;">=</span> LivingMachines.<span style="color: #003366; font-weight: bold;">Class</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
    <span style="color: #009966; font-style: italic;">/* Lots of code excluded for brevity */</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
LivingMachines.<span style="color: #660066;">View</span>.<span style="color: #660066;">nextId</span> <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>I then use this static variable to create the unique id&#8217;s for my Views in <code>initContainer</code>.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>elem<span style="color: #009900;">&#41;</span> 
    elem <span style="color: #339933;">=</span> <span style="color: #3366CC;">'view'</span> <span style="color: #339933;">+</span> LivingMachines.<span style="color: #660066;">View</span>.<span style="color: #660066;">nextId</span><span style="color: #339933;">++;</span></pre></td></tr></table></div>

<p>This creates the View id by using the value of <code>nextId</code>, then incrementing that value by 1 so that it&#8217;s ready for the next View to be created (hence the name <code>nextId</code> and not <code>currentId</code>).</p>
<p>So, there you have it, static class variables and a fix for IE.  And now I know to avoid <code>getTime</code> in IE.  </p>
<p>I am currently working on expanding the View&#8217;s functionality, and now I have to go fix another IE problem that has cropped up with some of the new code that I am writing.  Actually, since it&#8217;s after 1 am here, I probably need to go to bed.</p>
]]></content:encoded>
			<wfw:commentRss>http://livingmachines.net/2009/05/working-out-the-internet-explorer-bugs/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>First Stab at Putting the V in MVC</title>
		<link>http://livingmachines.net/2009/05/first-stab-at-putting-the-v-in-mvc/</link>
		<comments>http://livingmachines.net/2009/05/first-stab-at-putting-the-v-in-mvc/#comments</comments>
		<pubDate>Wed, 06 May 2009 03:48:57 +0000</pubDate>
		<dc:creator>Jason S. Kerchner</dc:creator>
				<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://livingmachines.net/?p=384</guid>
		<description><![CDATA[Download code
OK, so here&#8217;s my first stab at creating an MVC View in JavaScript.  It doesn&#8217;t do much yet (especially since I have no Controller or Model to integrate with), but I think you&#8217;ll get the idea of where I&#8217;m going with this.  Whether its the right way to go or not remains [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://livingmachines.net/code/2009-05-06/LivingMachines.zip">Download code</a></p>
<p>OK, so here&#8217;s my first stab at creating an MVC View in JavaScript.  It doesn&#8217;t do much yet (especially since I have no Controller or Model to integrate with), but I think you&#8217;ll get the idea of where I&#8217;m going with this.  Whether its the <em>right</em> way to go or not remains to be seen.  Anyway, here it goes.</p>
<p>I&#8217;m creating a View class, using the <code>Class</code> function I <a href="/tag/creating-javascript-classes-series/">worked so diligently on</a> a couple months back.  Yeah, I&#8217;m finally putting that thing to some use.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;">LivingMachines.<span style="color: #660066;">View</span> <span style="color: #339933;">=</span> LivingMachines.<span style="color: #003366; font-weight: bold;">Class</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
&nbsp;
    construct<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>elem<span style="color: #339933;">,</span> tag<span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">container</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">initContainer</span><span style="color: #009900;">&#40;</span>elem<span style="color: #339933;">,</span> tag<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
&nbsp;
    <span style="color: #009966; font-style: italic;">/* More code goes here */</span>
&nbsp;
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>The <code>construct</code> method is, of course, the constructor for the class.  It simply creates a new property named <code>container</code> that points to the DOM element that will contain the view.  Typically, this will probably be a DIV element.  Incidentally, whenever I talk about an &#8220;element&#8221; I am always referring to a DOM element.  Unless I&#8217;m talking about arrays, in which case I will be referring to an array element.  If I&#8217;m talking about an array of DOM elements, I will always be sure to clarify.  Got it?  OK.</p>
<p>You&#8217;ll notice that the constructor takes two arguments, <code>elem</code> and <code>tag</code>.  Both are optional.  The first argument is the id of an existing or non-existing element, or the actual element itself, that is to be used as a container for the View.  If we are passing in the id of an element to be used as a container, but no container element with that id exists, then the <code>tag</code> argument tells the View what type of element to create (DIV, FORM, SPAN, etc.).  If no <code>tag</code> argument is passed in, then it assumes a DIV element.  If the element does not exist, it will be created with the given id.  If no id or tag is passed in, then a unique id is generated, a DIV is automatically created with that id, and the DIV is appended to the document body.  In short, we have many ways to get a container for our View.</p>
<p>But the constructor does none of this.  It just passes the arguments on to the <code>initContainer</code> method, and its this method does what I just described above.  The constructor just takes all the credit.  You create the View and viola, you have a container element for it.  At some point I may separate these.  Would you ever want to construct a View, then at some point in the future get the container for it?  Maybe.  Possibly.  As I think about it, most probably.  But I&#8217;m not making that change yet.  Anyway, here&#8217;s the <code>initContainer</code> method.  The code is pretty straight-forward, I think.  Just remember that <code>elem</code> is either an id or a DOM element.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;">initContainer<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>elem<span style="color: #339933;">,</span> tag<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>elem <span style="color: #339933;">!=</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">typeof</span> elem <span style="color: #339933;">==</span> <span style="color: #3366CC;">'object'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>  <span style="color: #006600; font-style: italic;">// null is considered an object. Go figure.</span>
        <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">container</span> <span style="color: #339933;">=</span> elem<span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">else</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>elem<span style="color: #009900;">&#41;</span> elem <span style="color: #339933;">=</span> <span style="color: #3366CC;">'view'</span> <span style="color: #339933;">+</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">new</span> Date<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">getTime</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">container</span> <span style="color: #339933;">=</span> document.<span style="color: #660066;">getElementById</span><span style="color: #009900;">&#40;</span>elem<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">container</span><span style="color: #009900;">&#41;</span> 
        <span style="color: #009900;">&#123;</span>
            <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>tag<span style="color: #009900;">&#41;</span> tag <span style="color: #339933;">=</span> <span style="color: #3366CC;">'div'</span><span style="color: #339933;">;</span>
            <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">container</span> <span style="color: #339933;">=</span> document.<span style="color: #660066;">createElement</span><span style="color: #009900;">&#40;</span>tag<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">container</span>.<span style="color: #660066;">setAttribute</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'id'</span><span style="color: #339933;">,</span> elem<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            document.<span style="color: #660066;">body</span>.<span style="color: #660066;">appendChild</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">container</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span></pre></td></tr></table></div>

<p>The code above first checks if <code>elem</code> is an object (line 3).  If it is, then we assume the programmer knows what he or she is doing and has given us a valid DOM element, and we point the <code>container</code> to it (line 4).  Otherwise, we assume <code>elem</code> is supposed to be an id.  If it was not passed in, or is <code>null</code>, then we generate a unique id using the <code>Date</code> object (line 7).  Next, we attempt to get the element (line 8).  If we generated the id, or if the id does not have an associated element, then this will return <code>null</code>, so our <code>container</code> won&#8217;t have been set (line 9).  So, we know we will need to create the container element ourselves.  We check to see if a <code>tag</code> was passed in and, if not, set it to be a DIV (line 11).  Again, we are assuming the programmer is intelligent and knows what a valid HTML tag is, so we&#8217;re not verifying the input.  Then we create the container element (line 12), set the id attribute (line 13), and append it to the document body (line 14).</p>
<p>Now that I&#8217;m thinking about it (yes, perhaps I should have been thinking about it earlier in this process, like when I was writing the code&#8230;) there is a good chance we won&#8217;t want to append the container element to the document body, but rather to some other element.  OK, that&#8217;s another one for later.</p>
<p>Another method of interest is <code>render</code>.  Looks like this.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;">render<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> 
<span style="color: #009900;">&#123;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span></pre></td></tr></table></div>

<p>It&#8217;s not of interest because of its pithy code.  No, it&#8217;s of interest because this is the method that we&#8217;ll call when we actually want to draw our View.  This method must be overridden in descendant classes.  And thanks to the <code>Class</code> function I <a href="/tag/creating-javascript-classes-series/">worked so diligently on</a> a couple months back, we can easily override it.  But that&#8217;s for another post.</p>
<p>So, the next question then should be, what are we going to render?  Well, I have a couple of methods to render a couple of things.  Like forms, input boxes, labels, divs and a few others.  Not a complete set yet, just a start.  And no fancy data grids and stuff like that yet.  Baby steps, baby steps.</p>
<p>Let&#8217;s look at the <code>form</code> method, since it&#8217;s more interesting than some of the others.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;">form<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>id<span style="color: #339933;">,</span> url<span style="color: #339933;">,</span> method<span style="color: #339933;">,</span> attribs <span style="color: #009966; font-style: italic;">/*, elements*/</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>attribs<span style="color: #009900;">&#41;</span> attribs <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
    attribs.<span style="color: #660066;">id</span> <span style="color: #339933;">=</span> id<span style="color: #339933;">;</span>
    attribs.<span style="color: #660066;">action</span> <span style="color: #339933;">=</span> url<span style="color: #339933;">;</span>
    attribs.<span style="color: #660066;">method</span> <span style="color: #339933;">=</span> method<span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">tag</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'&lt;form %a&gt;&lt;/form&gt;'</span><span style="color: #339933;">,</span> attribs<span style="color: #339933;">,</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">extractArgs</span><span style="color: #009900;">&#40;</span>arguments<span style="color: #339933;">,</span> <span style="color: #CC0000;">4</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span></pre></td></tr></table></div>

<p>Yeah, I know, but I didn&#8217;t say it <em>was</em> interesting.  I said it was <em>more</em> interesting than the <em>other</em> methods.  Here&#8217;s the pattern you need to know for each of these types of element rendering methods.  First, there are a series of arguments specific to the particular element we want to render.  This is to make it easy to write.  In this example they are <code>id</code>, <code>url</code> and <code>method</code>.  Those arguments are followed by an optional <code>attrib</code> argument.  This is a catch-all object of HTML attributes, given in name/value pairs.  This is how we can render an element with any attributes we want.  The remaining arguments are elements, and there may be any number of them.  These may be actual DOM elements, or strings of HTML.  These elements will be rendered inside the element we are creating.  That&#8217;s why I said the <code>form</code> element was more interesting than the others. It has several unique arguments in the beginning, and forms always contain other elements (at least the useful ones do).</p>
<p>You can see that the first thing we do is simply take the first set of arguments and assign them to attributes (lines 3-7).  The last line is where the money is.  The <code>tag</code> method takes three arguments.  The first is the HTML for the element that we are creating.  The <code>%a</code> in this HTML will be replaced with the attributes.  The attributes are given in the second argument as an object.  The last argument is an array of DOM elements or HTML strings that are to be included inside the element that we are creating (a FORM element in this case).</p>
<p>OK, a brief aside about the <code>extractArgs</code> method.  Every JavaScript function has a variable called <code>arguments</code>.  This is an array, where each element in the array corresponds to the arguments that have been passed in to the function.  So, the argument at position 0 is in <code>arguments[0]</code>, the argument in position 1 is in <code>arguments[1]</code>, etc.  The funny thing about <code>arguments</code> is that it really isn&#8217;t an array at all.  It just acts like one.  But if you try to access any <code>Array</code> methods, like <code>slice</code>, <code>arguments</code> is revealed for what it is: an impostor.  So, we want to get any DOM elements that have been passed in to the <code>form</code> method, so that we can pass them in, as an array, to the <code>tag</code> method.  But we can&#8217;t simply call <code>arguments.slice()</code> since <code>arguments</code> has no <code>slice</code> method.  Fortunately, we can use <code>call</code> to execute <code>slice</code> on <code>arguments</code>.  (I talked about <code>call</code>, and its counterpart <code>apply</code>, in <a href="/2009/02/creating-javascript-classes-part-2-property-inheritance-with-screencast/">this post</a>).  That&#8217;s what <code>extractArgs</code> does.  You pass it the <code>arguments</code> &#8220;array&#8221; and a <code>start</code> position, and it extracts all the arguments from the <code>start</code> position to the end of the <code>arguments</code> &#8220;array&#8221; and returns them as a real array.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;">extractArgs<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>args<span style="color: #339933;">,</span> start<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    <span style="color: #006600; font-style: italic;">// Convert the arguments to a real array, and extract only those elements we want.</span>
    <span style="color: #000066; font-weight: bold;">return</span> Array.<span style="color: #660066;">prototype</span>.<span style="color: #660066;">slice</span>.<span style="color: #660066;">call</span><span style="color: #009900;">&#40;</span>args<span style="color: #339933;">,</span> start<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span></pre></td></tr></table></div>

<p>Now, back to that <code>tag</code> method.  The <code>tag</code> method takes the HTML, the attributes, and the other elements, and returns a complete DOM element.  And because it returns a DOM element, we can use these rendering methods (<code>text</code>, <code>password</code>, <code>submit</code>, etc.) as arguments to other rendering methods that can contain elements (<code>form</code>, <code>div</code>, <code>span</code>, etc).  For example, here is what a View for a login might look like.  Watch out, I like to use my parenthesis like curly braces!</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">div</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'login'</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">,</span> 
    <span style="color: #3366CC;">'&lt;span&gt;Login here:&lt;/span&gt;'</span><span style="color: #339933;">,</span>
    <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">form</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'loginForm'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'url/to/post'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'post'</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span> <span style="color: #003366; font-weight: bold;">class</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">'login-form'</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
        <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">label</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'Username: '</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'username'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
        <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">text</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'username'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'Joe User'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
        <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">label</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'Password: '</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'password'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
        <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">password</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'password'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'Joes Password'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
        <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">submit</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'Login'</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>This is showing a couple of things.  First, we are rendering a DIV (line 1).  The id is &#8216;login&#8217;, and <code>null</code> is being passed in for <code>attribs</code>.  The remaining arguments are DOM elements and/or HTML strings.  That span string will be converted to a span element (line 2).  Next we have the <code>form</code> rendering function (lines 3-9).  This function returns a DOM element.  Its first argument is the form id, then the url to post to, then the method to use when submitting the form.  The next argument is the <code>attribs</code>, which is showing that we can add a class to the form attributes.  The remaining arguments are DOM elements that are to be rendered inside the form element.  Again, we are using our rendering functions to create those DOM elements.</p>
<p>So this is where it really <em>does</em> get interesting.  Mildly, at least.  This is where most of the work is done, in the <code>tag</code> method.  Note that in this function, <code>elements</code> is expected to be an array (unlike in the other functions where the elements were passed in as individual arguments).</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>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
28
29
30
31
32
33
34
35
36
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;">tag<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>format<span style="color: #339933;">,</span> attribs<span style="color: #339933;">,</span> elements<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    <span style="color: #006600; font-style: italic;">// Convert the attribs object to an HTML string.</span>
    <span style="color: #003366; font-weight: bold;">var</span> attribsHtml <span style="color: #339933;">=</span> <span style="color: #3366CC;">''</span><span style="color: #339933;">;</span>
    <span style="color: #003366; font-weight: bold;">var</span> singleAttrib <span style="color: #339933;">=</span> <span style="color: #3366CC;">'.compact.checked.declare.readonly.disabled.selected.defer.ismap.nohref.noshade.nowrap.multiple.noresize.'</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> a <span style="color: #000066; font-weight: bold;">in</span> attribs<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>singleAttrib.<span style="color: #660066;">indexOf</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'.'</span> <span style="color: #339933;">+</span> a <span style="color: #339933;">+</span> <span style="color: #3366CC;">'.'</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&gt;</span> <span style="color: #339933;">-</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>attribs<span style="color: #009900;">&#91;</span>a<span style="color: #009900;">&#93;</span> <span style="color: #339933;">==</span> <span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">||</span> <span style="color: #009900;">&#40;</span>attribs<span style="color: #009900;">&#91;</span>a<span style="color: #009900;">&#93;</span> <span style="color: #339933;">==</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">||</span> <span style="color: #009900;">&#40;</span>attribs<span style="color: #009900;">&#91;</span>a<span style="color: #009900;">&#93;</span> <span style="color: #339933;">==</span> <span style="color: #3366CC;">'true'</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">||</span> <span style="color: #009900;">&#40;</span>attribs<span style="color: #009900;">&#91;</span>a<span style="color: #009900;">&#93;</span> <span style="color: #339933;">==</span> a<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
                attribsHtml <span style="color: #339933;">+=</span> <span style="color: #3366CC;">' '</span> <span style="color: #339933;">+</span> a<span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>attribs<span style="color: #009900;">&#91;</span>a<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> <span style="color: #006600; font-style: italic;">// Make sure its not null.</span>
                attribsHtml <span style="color: #339933;">+=</span> <span style="color: #3366CC;">' '</span> <span style="color: #339933;">+</span> a <span style="color: #339933;">+</span> <span style="color: #3366CC;">'=&quot;'</span> <span style="color: #339933;">+</span> attribs<span style="color: #009900;">&#91;</span>a<span style="color: #009900;">&#93;</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">'&quot;'</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">// Insert the attributes into the tag format</span>
    format <span style="color: #339933;">=</span> format.<span style="color: #660066;">replace</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'%a'</span><span style="color: #339933;">,</span> attribsHtml<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">// Convert the HTML string to a DOM object</span>
    <span style="color: #003366; font-weight: bold;">var</span> elem <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">element</span><span style="color: #009900;">&#40;</span>format<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">// Add any inner element to the newly created DOM object        </span>
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>elements<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
        <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> len <span style="color: #339933;">=</span> elements.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> len<span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>isString<span style="color: #009900;">&#40;</span>elements<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
                elem.<span style="color: #660066;">appendChild</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">element</span><span style="color: #009900;">&#40;</span>elements<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #000066; font-weight: bold;">else</span>
                elem.<span style="color: #660066;">appendChild</span><span style="color: #009900;">&#40;</span>elements<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">// Lastly, return our new DOM element</span>
    <span style="color: #000066; font-weight: bold;">return</span> elem<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span></pre></td></tr></table></div>

<p>The first thing we do is convert the <code>attribs</code> object into an attributes string suitable for inclusion in an HTML string (lines 3-15).  I think you can figure out what the code is doing.  Then, we replace the <code>%a</code> in the HTML format string with the attributes string we just created (line 18).  Next, we convert the HTML string into a DOM object (line 21).  The <code>element</code> method does that magic, and it&#8217;s really pretty simple.  I know you&#8217;re as excited to look at it as I was writing it, but hold on for a minute, we&#8217;re not done with the tag method yet!  Once we have the DOM element, we loop through the <code>elements</code> array and append each element there to our new element (lines 23-32).  If the element is a string (checked using our <code>isString</code> extension function, just because we can, and we like to think we coded it for something) then it is converted to a DOM element using the <code>element</code> method (lines 27-28).  If it is not a string, then we assume it is a DOM element and append it directly (line 30).  Lastly, we return the new DOM element (line 35).</p>
<p>So, how do we convert those HTML strings to DOM elements?  We let the browser do it for us, of course.  What, you thought there was going to be some kind of hocus-pocus?  I&#8217;m not that smart.  Here it is, in all its glory.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;">element<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>html<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    <span style="color: #003366; font-weight: bold;">var</span> container <span style="color: #339933;">=</span> document.<span style="color: #660066;">createElement</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'div'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    container.<span style="color: #660066;">innerHTML</span> <span style="color: #339933;">=</span> html<span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">return</span> container.<span style="color: #660066;">childNodes</span><span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span></pre></td></tr></table></div>

<p>First, we create a DIV element (line 1), then set the <code>innerHTML</code> to our HTML string (line 2).  This will cause the browser to interpret the HTML and build us a DOM element.  Then, we just grab the element and send it back (line 3).  That&#8217;s it!</p>
<p>And I think that&#8217;s plenty for now.  Of course, there is a unit test for this, too, but you&#8217;ll have to <a href="http://livingmachines.net/code/2009-05-06/LivingMachines.zip">download the code</a> to take a look at it.</p>
<p>Feedback is always appreciated!</p>
]]></content:encoded>
			<wfw:commentRss>http://livingmachines.net/2009/05/first-stab-at-putting-the-v-in-mvc/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Even More JavaScript Extensions: Dates</title>
		<link>http://livingmachines.net/2009/04/even-more-javascript-extensions-dates/</link>
		<comments>http://livingmachines.net/2009/04/even-more-javascript-extensions-dates/#comments</comments>
		<pubDate>Mon, 20 Apr 2009 19:38:31 +0000</pubDate>
		<dc:creator>Jason S. Kerchner</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[JavaScript Extensions]]></category>

		<guid isPermaLink="false">http://livingmachines.net/?p=324</guid>
		<description><![CDATA[Download code
Continuing with JavaScript extensions, I&#8217;ve created a set of extensions to the Date data type.  These include some functions for date calculations, comparisons and formatting.  I&#8217;ve also added a new function to the String data type that will convert a string into a Date object.
Extensions to the Date object
Let&#8217;s start with the [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://livingmachines.net/code/2009-04-20/LivingMachines.zip">Download code</a></p>
<p>Continuing with JavaScript extensions, I&#8217;ve created a set of extensions to the Date data type.  These include some functions for date calculations, comparisons and formatting.  I&#8217;ve also added a new function to the String data type that will convert a string into a Date object.</p>
<h4>Extensions to the Date object</h4>
<p>Let&#8217;s start with the simpler one first, the Date object.  Most of the functions are pretty self-explanatory, but there are some notable things I should point out.</p>
<p>First, there are the static arrays that have been added to the Date data type.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;">Date.<span style="color: #660066;">dayNames</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #3366CC;">'Sunday'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'Monday'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'Tuesday'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'Wednesday'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'Thursday'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'Friday'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'Saturday'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
Date.<span style="color: #660066;">shortDayNames</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #3366CC;">'Sun'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'Mon'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'Tue'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'Wed'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'Thu'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'Fri'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'Sat'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
Date.<span style="color: #660066;">dayChars</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #3366CC;">'S'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'M'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'T'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'W'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'T'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'F'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'S'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
Date.<span style="color: #660066;">monthNames</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #3366CC;">'January'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'February'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'March'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'April'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'May'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'June'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'July'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'August'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'September'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'October'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'November'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'December'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
Date.<span style="color: #660066;">shortMonthNames</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #3366CC;">'Jan'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'Feb'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'Mar'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'Apr'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'May'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'Jun'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'Jul'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'Aug'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'Sep'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'Oct'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'Nov'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'Dec'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
Date.<span style="color: #660066;">monthChars</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #3366CC;">'J'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'F'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'M'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'A'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'M'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'J'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'J'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'A'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'S'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'O'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'N'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'D'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Lines 1 to 3 contain the names of the days of the week, and lines 5 to 7 contain the names of the months.  You can override these to provide localized names and abbreviations.</p>
<p>These are used to convert a weekday number or month number to a string version.  So, for example, I could use <code>Date.monthNames[3]</code> to get the value &#8220;April&#8221;.  But sometimes I need to be able to go the other way as well, like when converting a date string to a Date object.  The next block of code sets up for this type of conversion.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;">Date.<span style="color: #660066;">monthNumbers</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
Date.<span style="color: #660066;">shortMonthNumbers</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> <span style="color: #CC0000;">12</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  Date.<span style="color: #660066;">monthNumbers</span><span style="color: #009900;">&#91;</span>Date.<span style="color: #660066;">monthNames</span><span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> i<span style="color: #339933;">;</span>
  Date.<span style="color: #660066;">shortMonthNumbers</span><span style="color: #009900;">&#91;</span>Date.<span style="color: #660066;">shortMonthNames</span><span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> i<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>The above code creates two objects, one for long month names and one for short month names.  I saw no need to convert week day names to numbers, so those are not included here.  Once the empty objects are set up, it loops through the month names, adding each one as a property to the empty month numbers objects, and setting its value to the corresponding month number.  This allows me to look up a month number from the name by simply using <code>Date.monthNumbers['January']</code>.  Remember that month numbers in JavaScript are zero-based, so January is 0, not 1.  I&#8217;m doing this to make it easier and faster to convert month names to numbers.  I&#8217;m using the loop to build the objects so that I only have to set the month names one time (in the arrays I created earlier).  This loop uses those values, saving me from having to re-enter them.  This means I can localize the date strings in one place.</p>
<p>Another function of note that I added is the <code>copy</code> function.  When you assign one date variable to another, JavaScript creates a pointer to that date object.  This means that both variables will point to the same date object, which is not always desirable.  The <code>copy</code> function allows you to quickly create a copy of a date.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> d1 <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Date<span style="color: #009900;">&#40;</span><span style="color: #CC0000;">2009</span><span style="color: #339933;">,</span> 03<span style="color: #339933;">,</span> <span style="color: #CC0000;">20</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>  <span style="color: #006600; font-style: italic;">// April 20, 2009</span>
<span style="color: #003366; font-weight: bold;">var</span> d2 <span style="color: #339933;">=</span> d1<span style="color: #339933;">;</span>  <span style="color: #006600; font-style: italic;">// Creates pointer to d1</span>
<span style="color: #003366; font-weight: bold;">var</span> d3 <span style="color: #339933;">=</span> d1.<span style="color: #660066;">copy</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>  <span style="color: #006600; font-style: italic;">// Creates a copy of d1</span></pre></td></tr></table></div>

<p>The last function of interest is the <code>toFormat</code> function.  This allows you to easily convert a Date object to a string representation.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;">Date.<span style="color: #660066;">prototype</span>.<span style="color: #660066;">toFormat</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>format<span style="color: #009900;">&#41;</span> 
<span style="color: #009900;">&#123;</span>
    <span style="color: #003366; font-weight: bold;">var</span> pad <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>val<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> 
        <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #009900;">&#40;</span>val <span style="color: #339933;">&gt;</span> <span style="color: #CC0000;">9</span> <span style="color: #339933;">?</span> <span style="color: #3366CC;">''</span> <span style="color: #339933;">:</span> <span style="color: #3366CC;">'0'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">+</span>val<span style="color: #339933;">;</span> 
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
    <span style="color: #003366; font-weight: bold;">var</span> result <span style="color: #339933;">=</span> <span style="color: #3366CC;">''</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> len <span style="color: #339933;">=</span> format.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> len<span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #003366; font-weight: bold;">var</span> c <span style="color: #339933;">=</span> format.<span style="color: #660066;">charAt</span><span style="color: #009900;">&#40;</span>i<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">switch</span><span style="color: #009900;">&#40;</span>c<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #3366CC;">'Y'</span><span style="color: #339933;">:</span> 
                result <span style="color: #339933;">+=</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">getFullYear</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
            <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #3366CC;">'y'</span><span style="color: #339933;">:</span> 
                result <span style="color: #339933;">+=</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">getFullYear</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">+</span><span style="color: #3366CC;">''</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">substr</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
            <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #3366CC;">'M'</span><span style="color: #339933;">:</span> 
                result <span style="color: #339933;">+=</span> pad<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">getMonth</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">+</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
            <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #3366CC;">'m'</span><span style="color: #339933;">:</span> 
                result <span style="color: #339933;">+=</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">getMonth</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">+</span><span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>
                <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
            <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #3366CC;">'N'</span><span style="color: #339933;">:</span>
                result <span style="color: #339933;">+=</span> Date.<span style="color: #660066;">monthNames</span><span style="color: #009900;">&#91;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">getMonth</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
                <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
            <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #3366CC;">'n'</span><span style="color: #339933;">:</span> 
                result <span style="color: #339933;">+=</span> Date.<span style="color: #660066;">shortMonthNames</span><span style="color: #009900;">&#91;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">getMonth</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
                <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
            <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #3366CC;">'D'</span><span style="color: #339933;">:</span> 
                result <span style="color: #339933;">+=</span> pad<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">getDate</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
            <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #3366CC;">'d'</span><span style="color: #339933;">:</span> 
                result <span style="color: #339933;">+=</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">getDate</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
            <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #3366CC;">'W'</span><span style="color: #339933;">:</span> 
                result <span style="color: #339933;">+=</span> Date.<span style="color: #660066;">dayNames</span><span style="color: #009900;">&#91;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">getDay</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
                <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
            <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #3366CC;">'w'</span><span style="color: #339933;">:</span> 
                result <span style="color: #339933;">+=</span> Date.<span style="color: #660066;">shortDayNames</span><span style="color: #009900;">&#91;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">getDay</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
                <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
            <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #3366CC;">'H'</span><span style="color: #339933;">:</span> 
                <span style="color: #003366; font-weight: bold;">var</span> hour <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">getHours</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">%</span> <span style="color: #CC0000;">12</span><span style="color: #339933;">;</span>
                result <span style="color: #339933;">+=</span> pad<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>hour <span style="color: #339933;">?</span> hour <span style="color: #339933;">:</span> <span style="color: #CC0000;">12</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
            <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #3366CC;">'h'</span><span style="color: #339933;">:</span> 
                <span style="color: #003366; font-weight: bold;">var</span> hour <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">getHours</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">%</span> <span style="color: #CC0000;">12</span><span style="color: #339933;">;</span>
                result <span style="color: #339933;">+=</span> <span style="color: #009900;">&#40;</span>hour <span style="color: #339933;">?</span> hour <span style="color: #339933;">:</span> <span style="color: #CC0000;">12</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
            <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #3366CC;">'R'</span><span style="color: #339933;">:</span> 
                result <span style="color: #339933;">+=</span> pad<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">getHours</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
            <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #3366CC;">'r'</span><span style="color: #339933;">:</span> 
                result <span style="color: #339933;">+=</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">getHours</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
            <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #3366CC;">'I'</span><span style="color: #339933;">:</span> 
                result <span style="color: #339933;">+=</span> pad<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">getMinutes</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
            <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #3366CC;">'i'</span><span style="color: #339933;">:</span> 
                result <span style="color: #339933;">+=</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">getMinutes</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">toString</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
            <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #3366CC;">'S'</span><span style="color: #339933;">:</span> 
                result <span style="color: #339933;">+=</span> pad<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">getSeconds</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
            <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #3366CC;">'s'</span><span style="color: #339933;">:</span>
                result <span style="color: #339933;">+=</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">getSeconds</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">toString</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
            <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #3366CC;">'A'</span><span style="color: #339933;">:</span> 
                result <span style="color: #339933;">+=</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">getHours</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&lt;</span> <span style="color: #CC0000;">12</span> <span style="color: #339933;">?</span> <span style="color: #3366CC;">'AM'</span> <span style="color: #339933;">:</span> <span style="color: #3366CC;">'PM'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
            <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #3366CC;">'a'</span><span style="color: #339933;">:</span> 
                result <span style="color: #339933;">+=</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">getHours</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&lt;</span> <span style="color: #CC0000;">12</span> <span style="color: #339933;">?</span> <span style="color: #3366CC;">'am'</span> <span style="color: #339933;">:</span> <span style="color: #3366CC;">'pm'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
            <span style="color: #003366; font-weight: bold;">default</span><span style="color: #339933;">:</span>
                result <span style="color: #339933;">+=</span> <span style="color: #009900;">&#40;</span>c <span style="color: #339933;">==</span> <span style="color: #3366CC;">'^'</span> <span style="color: #339933;">?</span> format.<span style="color: #660066;">charAt</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">++</span>i<span style="color: #009900;">&#41;</span> <span style="color: #339933;">:</span> c<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #000066; font-weight: bold;">return</span> result<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>The function takes a single format string and replaces certain characters within that string with the actual date values.  Lines 3 to 5 are a small function used to left pad a single digit with a zero.  I&#8217;m using this version rather than the <code>String.leftPad</code> method (part of the string extensions) simply for performance reasons.  This little pad function assumes that the source value is a number and uses type coercion to convert the value, padded or not, to a string.  It will also only pad with a single digit.  These assumptions make it faster than the <code>String.leftPad</code> method.</p>
<p>Next, the code simply loops through each character of the format string, looking for those special characters that it needs to replace with the date values.  Those special characters are given in the following table:<br />
<center></p>
<table class="data">
<thead>
<tr>
<th class="data">Field</th>
<th class="data">Long form</th>
<th class="data">Short Form</th>
</tr>
</thead>
<tbody>
<tr>
<td class="data">Year</td>
<td class="data">Y (4 digit)</td>
<td class="data">y (2 digit)</td>
</tr>
<tr>
<td class="data">Month</td>
<td class="data">M (2 digit)</td>
<td class="data">m (1 or 2 digit)</td>
</tr>
<tr>
<td class="data">Month Name</td>
<td class="data">N (full name)</td>
<td class="data">n (abbreviation)</td>
</tr>
<tr>
<td class="data">Day of Month</td>
<td class="data">D (2 digit)</td>
<td class="data">d (1 or 2 digit)</td>
</tr>
<tr>
<td class="data">Day Name</td>
<td class="data">W (full name)</td>
<td class="data">w (abbreviation)</td>
</tr>
<tr>
<td class="data">Hour (1-12)</td>
<td class="data">H (2 digit)</td>
<td class="data">h (1 or 2 digit)</td>
</tr>
<tr>
<td class="data">Hour (0-23)</td>
<td class="data">R (2 digit)</td>
<td class="data">r (1 or 2 digit)</td>
</tr>
<tr>
<td class="data">Minute</td>
<td class="data">I (2 digit)</td>
<td class="data">i (1 or 2 digit)</td>
</tr>
<tr>
<td class="data">Second</td>
<td class="data">S (2 digit)</td>
<td class="data">s (1 or 2 digit)</td>
</tr>
<tr>
<td class="data">AM/PM</td>
<td class="data">A (upper case)</td>
<td class="data">y (lower case)</td>
</tr>
<tr>
<td class="data">literal</td>
<td class="data" colspan="2">^ (insert next character, do not replace)</td>
</tr>
</tbody>
</table>
<p></center><br />
So, for example, you can use the following formats:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> birthDate <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Date<span style="color: #009900;">&#40;</span><span style="color: #CC0000;">1980</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>  <span style="color: #006600; font-style: italic;">// Januatry 1, 1980</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// Alerts: January 1, 1980</span>
<span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span>birthDate.<span style="color: #660066;">toFormat</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'N, d, Y'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// Alerts: 01/01/80</span>
<span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span>birthDate.<span style="color: #660066;">toFormat</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'M/D/y'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// Alerts: Birthday is Jan 01 '80</span>
<span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span>birthDate.<span style="color: #660066;">toFormat</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;B^i^rt^h^d^a^y is n, D 'y&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #006600; font-style: italic;">// This is probably a better way to do the above:</span>
<span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span>String.<span style="color: #660066;">toFormat</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'Birthday is %s'</span><span style="color: #339933;">,</span> birthDate.<span style="color: #660066;">toFormat</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;n, D 'y&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Note that I decided to use the caret ^ for literals rather than the more typical backslash.  This is because JavaScript already uses the backslash as an escape character.  So, to insert a backslash into a JavaScript string you would always need to insert two backslashes, which I felt would be annoying, not very readable, and easy to forget.  For example, you would have to enter a string such as &#8216;\\D\\ate: M/D/Y&#8217;.  Each double backslash is interpreted by JavaScript as a single backslash.  If you entered it as &#8216;\D\ate: M/D/Y&#8217;, then JavaScript would try to escape the first &#8216;D&#8217; and the &#8216;a&#8217;.</p>
<p>The other included Date object extension functions are pretty self-explanatory, and the code should be fairly easy to interpret.</p>
<h4>More Extensions to the String Object</h4>
<p>I&#8217;ve also added a new function to the String object, <code>toDate</code>.  This method will read the value of the string and convert it into a Date object.  As you might imagine, this is a bit more complicated than converting a Date to a String.  The basic premise is to use regular expressions to extract the parts of the string that represent the various date part that we are looking for.  Once we have all the parts, we convert them as necessary into numeric values that we can use to create a Date object.</p>
<p>The first part of the function sets up a number of variables.  I&#8217;ll discuss the <code>Pos</code> variables (<code>yearPos</code>, <code>monthPos</code>, <code>dayPos</code>, etc.) in a moment.  Just note that they are all set to -1.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>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
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;">    <span style="color: #006600; font-style: italic;">// Default values set to midnight Jan 1 of the current year.</span>
    <span style="color: #003366; font-weight: bold;">var</span> year <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Date<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">getFullYear</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #003366; font-weight: bold;">var</span> month <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>
    <span style="color: #003366; font-weight: bold;">var</span> day <span style="color: #339933;">=</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>
    <span style="color: #003366; font-weight: bold;">var</span> hours <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>
    <span style="color: #003366; font-weight: bold;">var</span> minutes <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>
    <span style="color: #003366; font-weight: bold;">var</span> seconds <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">// Positions of each date element within the source string.  Use to know </span>
    <span style="color: #006600; font-style: italic;">// which backreference to check after a successful match.</span>
    <span style="color: #003366; font-weight: bold;">var</span> yearPos <span style="color: #339933;">=</span> <span style="color: #339933;">-</span><span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>
    <span style="color: #003366; font-weight: bold;">var</span> monthPos <span style="color: #339933;">=</span> <span style="color: #339933;">-</span><span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>
    <span style="color: #003366; font-weight: bold;">var</span> dayPos <span style="color: #339933;">=</span> <span style="color: #339933;">-</span><span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>
    <span style="color: #003366; font-weight: bold;">var</span> hoursPos <span style="color: #339933;">=</span> <span style="color: #339933;">-</span><span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>
    <span style="color: #003366; font-weight: bold;">var</span> minutesPos <span style="color: #339933;">=</span> <span style="color: #339933;">-</span><span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>
    <span style="color: #003366; font-weight: bold;">var</span> secondsPos <span style="color: #339933;">=</span> <span style="color: #339933;">-</span><span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>
    <span style="color: #003366; font-weight: bold;">var</span> amPmPos <span style="color: #339933;">=</span> <span style="color: #339933;">-</span><span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #003366; font-weight: bold;">var</span> monthStyle <span style="color: #339933;">=</span> <span style="color: #3366CC;">'m'</span><span style="color: #339933;">;</span>       <span style="color: #006600; font-style: italic;">// How we interpret the month, digits (M/m) or names (N/n)</span>
    <span style="color: #003366; font-weight: bold;">var</span> hoursStyle <span style="color: #339933;">=</span> <span style="color: #3366CC;">'h'</span><span style="color: #339933;">;</span>       <span style="color: #006600; font-style: italic;">// How we interpret the hours, 12-hour (h) or 24-hour (r)</span>
&nbsp;
    <span style="color: #003366; font-weight: bold;">var</span> position <span style="color: #339933;">=</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>           <span style="color: #006600; font-style: italic;">// Position of the current date element (year, month, day, etc.) in the source string</span>
    <span style="color: #003366; font-weight: bold;">var</span> pattern <span style="color: #339933;">=</span> <span style="color: #3366CC;">''</span><span style="color: #339933;">;</span>           <span style="color: #006600; font-style: italic;">// Date pattern to be matched.</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">// Remove extraneous whitespace from source string and format string.</span>
    <span style="color: #003366; font-weight: bold;">var</span> str <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">replace</span><span style="color: #009900;">&#40;</span><span style="color: #009966; font-style: italic;">/\s+/g</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">' '</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    format <span style="color: #339933;">=</span> format.<span style="color: #660066;">replace</span><span style="color: #009900;">&#40;</span><span style="color: #009966; font-style: italic;">/\s+/g</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">' '</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>The <code>Pos</code> variables in lines 11 to 17 will be set to the position within the source string where a particular value is found.  This will be used to retrieve the value from the matches array that is returned when the regular expression is executed.   The last thing this block of code does is remove any extraneous whitespace from the source and format strings.  I thought it would be safe to do that, and probably helpful when interpreting input from a user which may not be as clean as I would like.</p>
<p>The next block of code, shown below, loops through the format string and builds the regular expression string that will be used to extract the date values we need.  This is where we set the value of the <code>Pos</code> variables (<code>yearPos</code>, <code>monthPos</code>, <code>dayPos</code>, etc.).  Note that for &#8216;W&#8217; and &#8216;w&#8217; in the format string (weekday names) we will match them in the regular expression, just to ensure that the string is the correct format, but we don&#8217;t actually need them to create a Date object, so we will ignore their matched values.  The format string uses the same notation as the <code>Date.toFormat</code> function discussed above.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;">    <span style="color: #006600; font-style: italic;">// Loop throught the format string, and build the regex pattern</span>
    <span style="color: #006600; font-style: italic;">// for extracting the date elements.</span>
    <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> len <span style="color: #339933;">=</span> format.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> len<span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #003366; font-weight: bold;">var</span> c <span style="color: #339933;">=</span> format.<span style="color: #660066;">charAt</span><span style="color: #009900;">&#40;</span>i<span style="color: #009900;">&#41;</span>
        <span style="color: #000066; font-weight: bold;">switch</span> <span style="color: #009900;">&#40;</span>c<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #3366CC;">'Y'</span> <span style="color: #339933;">:</span>
                pattern <span style="color: #339933;">+=</span> <span style="color: #3366CC;">'(<span style="color: #000099; font-weight: bold;">\\</span>d{4})'</span><span style="color: #339933;">;</span>
                yearPos <span style="color: #339933;">=</span> position<span style="color: #339933;">++;</span>
                <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
            <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #3366CC;">'y'</span> <span style="color: #339933;">:</span>
                pattern <span style="color: #339933;">+=</span> <span style="color: #3366CC;">'(<span style="color: #000099; font-weight: bold;">\\</span>d{2})'</span><span style="color: #339933;">;</span>
                yearPos <span style="color: #339933;">=</span> position<span style="color: #339933;">++;</span>
                <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
            <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #3366CC;">'M'</span> <span style="color: #339933;">:</span>
            <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #3366CC;">'m'</span> <span style="color: #339933;">:</span>
                pattern <span style="color: #339933;">+=</span> <span style="color: #3366CC;">'(<span style="color: #000099; font-weight: bold;">\\</span>d{1,2})'</span><span style="color: #339933;">;</span>
                monthPos <span style="color: #339933;">=</span> position<span style="color: #339933;">++;</span>
                monthStyle <span style="color: #339933;">=</span> <span style="color: #3366CC;">'m'</span>
                <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
            <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #3366CC;">'N'</span> <span style="color: #339933;">:</span>
                pattern <span style="color: #339933;">+=</span> <span style="color: #3366CC;">'('</span> <span style="color: #339933;">+</span> Date.<span style="color: #660066;">monthNames</span>.<span style="color: #660066;">join</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'|'</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">')'</span><span style="color: #339933;">;</span>
                monthPos <span style="color: #339933;">=</span> position<span style="color: #339933;">++;</span>
                monthStyle <span style="color: #339933;">=</span> <span style="color: #3366CC;">'N'</span><span style="color: #339933;">;</span>
                <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
            <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #3366CC;">'n'</span> <span style="color: #339933;">:</span>
                pattern <span style="color: #339933;">+=</span> <span style="color: #3366CC;">'('</span> <span style="color: #339933;">+</span> Date.<span style="color: #660066;">shortMonthNames</span>.<span style="color: #660066;">join</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'|'</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">')'</span><span style="color: #339933;">;</span>
                monthPos <span style="color: #339933;">=</span> position<span style="color: #339933;">++;</span>
                monthStyle <span style="color: #339933;">=</span> <span style="color: #3366CC;">'n'</span><span style="color: #339933;">;</span>
                <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
            <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #3366CC;">'D'</span> <span style="color: #339933;">:</span>
            <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #3366CC;">'d'</span> <span style="color: #339933;">:</span>
                pattern <span style="color: #339933;">+=</span> <span style="color: #3366CC;">'(<span style="color: #000099; font-weight: bold;">\\</span>d{1,2})'</span><span style="color: #339933;">;</span>
                dayPos <span style="color: #339933;">=</span> position<span style="color: #339933;">++;</span>
                <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
            <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #3366CC;">'W'</span> <span style="color: #339933;">:</span> <span style="color: #006600; font-style: italic;">// We'll match W, but won't do anything with it.</span>
                pattern <span style="color: #339933;">+=</span> <span style="color: #3366CC;">'('</span> <span style="color: #339933;">+</span> Date.<span style="color: #660066;">dayNames</span>.<span style="color: #660066;">join</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'|'</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">')'</span><span style="color: #339933;">;</span>
                position<span style="color: #339933;">++;</span>
                <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
            <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #3366CC;">'w'</span> <span style="color: #339933;">:</span> <span style="color: #006600; font-style: italic;">// We'll match w, but won't do anything with it.</span>
                pattern <span style="color: #339933;">+=</span> <span style="color: #3366CC;">'('</span> <span style="color: #339933;">+</span> Date.<span style="color: #660066;">shortDayNames</span>.<span style="color: #660066;">join</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'|'</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">')'</span><span style="color: #339933;">;</span>
                position<span style="color: #339933;">++;</span>
                <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
            <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #3366CC;">'H'</span> <span style="color: #339933;">:</span>
            <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #3366CC;">'h'</span> <span style="color: #339933;">:</span>
                pattern <span style="color: #339933;">+=</span> <span style="color: #3366CC;">'(<span style="color: #000099; font-weight: bold;">\\</span>d{1,2})'</span><span style="color: #339933;">;</span>
                hoursPos <span style="color: #339933;">=</span> position<span style="color: #339933;">++;</span>
                hoursStyle <span style="color: #339933;">=</span> <span style="color: #3366CC;">'h'</span><span style="color: #339933;">;</span>
                <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
            <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #3366CC;">'R'</span> <span style="color: #339933;">:</span>
            <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #3366CC;">'r'</span> <span style="color: #339933;">:</span>
                pattern <span style="color: #339933;">+=</span> <span style="color: #3366CC;">'(<span style="color: #000099; font-weight: bold;">\\</span>d{1,2})'</span><span style="color: #339933;">;</span>
                hoursPos <span style="color: #339933;">=</span> position<span style="color: #339933;">++;</span>
                hoursStyle <span style="color: #339933;">=</span> <span style="color: #3366CC;">'r'</span><span style="color: #339933;">;</span>
                <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
            <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #3366CC;">'I'</span> <span style="color: #339933;">:</span>
            <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #3366CC;">'i'</span> <span style="color: #339933;">:</span>
                pattern <span style="color: #339933;">+=</span> <span style="color: #3366CC;">'(<span style="color: #000099; font-weight: bold;">\\</span>d{1,2})'</span><span style="color: #339933;">;</span>
                minutesPos <span style="color: #339933;">=</span> position<span style="color: #339933;">++;</span>
                <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
            <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #3366CC;">'S'</span> <span style="color: #339933;">:</span>
            <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #3366CC;">'s'</span> <span style="color: #339933;">:</span>
                pattern <span style="color: #339933;">+=</span> <span style="color: #3366CC;">'(<span style="color: #000099; font-weight: bold;">\\</span>d{1,2})'</span><span style="color: #339933;">;</span>
                secondsPos <span style="color: #339933;">=</span> position<span style="color: #339933;">++;</span>
                <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
            <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #3366CC;">'A'</span> <span style="color: #339933;">:</span>
            <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #3366CC;">'a'</span> <span style="color: #339933;">:</span>
                pattern <span style="color: #339933;">+=</span> <span style="color: #3366CC;">'(AM|am|PM|pm)'</span><span style="color: #339933;">;</span>
                amPmPos <span style="color: #339933;">=</span> position<span style="color: #339933;">++;</span>
                <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
            <span style="color: #003366; font-weight: bold;">default</span> <span style="color: #339933;">:</span>
                pattern <span style="color: #339933;">+=</span> <span style="color: #009900;">&#40;</span>c <span style="color: #339933;">==</span> <span style="color: #3366CC;">'^'</span> <span style="color: #339933;">?</span> format.<span style="color: #660066;">charAt</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">++</span>i<span style="color: #009900;">&#41;</span> <span style="color: #339933;">:</span> c<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>At the end of all this, the pattern variable will contain our regular expression.  We can then use that pattern to check the source string for matches.  That&#8217;s what the next section of code does, below.  If no match is found, we return <code>null</code>, meaning that the source string was not in the format we expected.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;">    <span style="color: #006600; font-style: italic;">// Pull out the date elements from the input string</span>
    <span style="color: #003366; font-weight: bold;">var</span> matches <span style="color: #339933;">=</span> str.<span style="color: #660066;">match</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">new</span> RegExp<span style="color: #009900;">&#40;</span>pattern<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>matches<span style="color: #009900;">&#41;</span>
        <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Next we have to interpret all of those parts.  If one of the <code>Pos</code> variables has a value greater than -1, then we know that there should be a match for that field.  The value will be stored in the matches array that was returned from the regular expression engine.  The position of the value within that array is the value of the <code>Pos</code> variable.  In other words, if <code>yearPos > -1</code>, then we can find the value of the year field at <code>matches[yearPos]</code>.  </p>
<p>Now, because we&#8217;ve used regular expressions, we know that if we were looking for a number, then we&#8217;ve got a number, and we won&#8217;t need to worry that we can&#8217;t convert it to an actual Number data type.  The <code>monthStyle</code> is used to record whether we are looking for a month number or name.  That&#8217;s the only value that could be returned as both a number or a name.  </p>
<p>Where possible, we will also check the ranges of the values, to make certain that the date entered is valid.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;">    <span style="color: #006600; font-style: italic;">// Now we have to interpret each of those parts...</span>
&nbsp;
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>yearPos <span style="color: #339933;">&gt;</span> <span style="color: #339933;">-</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        year <span style="color: #339933;">=</span> parseInt<span style="color: #009900;">&#40;</span>matches<span style="color: #009900;">&#91;</span>yearPos<span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">10</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        year <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>year <span style="color: #339933;">&lt;</span> <span style="color: #CC0000;">50</span> <span style="color: #339933;">?</span> year <span style="color: #339933;">+</span> <span style="color: #CC0000;">2000</span> <span style="color: #339933;">:</span> <span style="color: #009900;">&#40;</span>year <span style="color: #339933;">&lt;</span> <span style="color: #CC0000;">100</span> <span style="color: #339933;">?</span> year <span style="color: #339933;">+</span> <span style="color: #CC0000;">1900</span> <span style="color: #339933;">:</span> year<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>monthPos <span style="color: #339933;">&gt;</span> <span style="color: #339933;">-</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000066; font-weight: bold;">switch</span> <span style="color: #009900;">&#40;</span>monthStyle<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #3366CC;">'m'</span><span style="color: #339933;">:</span>
                month <span style="color: #339933;">=</span> parseInt<span style="color: #009900;">&#40;</span>matches<span style="color: #009900;">&#91;</span>monthPos<span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">10</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">-</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>    <span style="color: #006600; font-style: italic;">// JavaScript months are zero based, user input generally is not.</span>
                <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>month <span style="color: #339933;">&gt;</span> <span style="color: #CC0000;">11</span><span style="color: #009900;">&#41;</span>
                    <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">;</span>
                <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
            <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #3366CC;">'N'</span><span style="color: #339933;">:</span> 
                month <span style="color: #339933;">=</span> parseInt<span style="color: #009900;">&#40;</span>Date.<span style="color: #660066;">monthNumbers</span><span style="color: #009900;">&#91;</span>matches<span style="color: #009900;">&#91;</span>monthPos<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">10</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>isNaN<span style="color: #009900;">&#40;</span>month<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
                    <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">;</span>
                <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
            <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #3366CC;">'n'</span><span style="color: #339933;">:</span>
                month <span style="color: #339933;">=</span> parseInt<span style="color: #009900;">&#40;</span>Date.<span style="color: #660066;">shortMonthNumbers</span><span style="color: #009900;">&#91;</span>matches<span style="color: #009900;">&#91;</span>monthPos<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">10</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>isNaN<span style="color: #009900;">&#40;</span>month<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
                    <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">;</span>
                <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>dayPos <span style="color: #339933;">&gt;</span> <span style="color: #339933;">-</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        day <span style="color: #339933;">=</span> parseInt<span style="color: #009900;">&#40;</span>matches<span style="color: #009900;">&#91;</span>dayPos<span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">10</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>day <span style="color: #339933;">&lt;</span> <span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">||</span> <span style="color: #009900;">&#40;</span>day <span style="color: #339933;">&gt;</span> Date.<span style="color: #660066;">daysInMonth</span><span style="color: #009900;">&#40;</span>month<span style="color: #339933;">,</span> year<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
            <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>hoursPos <span style="color: #339933;">&gt;</span> <span style="color: #339933;">-</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        hours <span style="color: #339933;">=</span> parseInt<span style="color: #009900;">&#40;</span>matches<span style="color: #009900;">&#91;</span>hoursPos<span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">10</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>hoursStyle <span style="color: #339933;">==</span> <span style="color: #3366CC;">'h'</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #009900;">&#40;</span>hours <span style="color: #339933;">==</span> <span style="color: #CC0000;">0</span> <span style="color: #339933;">||</span> hours <span style="color: #339933;">&gt;</span> <span style="color: #CC0000;">12</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
            <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>hours <span style="color: #339933;">&gt;</span> <span style="color: #CC0000;">23</span><span style="color: #009900;">&#41;</span>
            <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>minutesPos <span style="color: #339933;">&gt;</span> <span style="color: #339933;">-</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        minutes <span style="color: #339933;">=</span> parseInt<span style="color: #009900;">&#40;</span>matches<span style="color: #009900;">&#91;</span>minutesPos<span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">10</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>minutes <span style="color: #339933;">&gt;</span> <span style="color: #CC0000;">59</span><span style="color: #009900;">&#41;</span>
            <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>secondsPos <span style="color: #339933;">&gt;</span> <span style="color: #339933;">-</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        seconds <span style="color: #339933;">=</span> parseInt<span style="color: #009900;">&#40;</span>matches<span style="color: #009900;">&#91;</span>secondsPos<span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">10</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>seconds <span style="color: #339933;">&gt;</span> <span style="color: #CC0000;">59</span><span style="color: #009900;">&#41;</span>
            <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">// Convert 12-hour time, if used, to 24-hour time.</span>
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>amPmPos <span style="color: #339933;">&gt;</span> <span style="color: #339933;">-</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #003366; font-weight: bold;">var</span> amPm <span style="color: #339933;">=</span> matches<span style="color: #009900;">&#91;</span>amPmPos<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>amPm <span style="color: #339933;">==</span> <span style="color: #3366CC;">'pm'</span> <span style="color: #339933;">||</span> amPm <span style="color: #339933;">==</span> <span style="color: #3366CC;">'PM'</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #009900;">&#40;</span>hours <span style="color: #339933;">&lt;</span> <span style="color: #CC0000;">12</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
            hours <span style="color: #339933;">+=</span> <span style="color: #CC0000;">12</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>An enhancement to this code would be to provide a specific error code and message for a date conversion failure.  For example, month is out of range, or February does not have a 29th day in 1999.  But that&#8217;s for another time.</p>
<p>The last thing to do is take all the values we&#8217;ve extracted from the string, and convert them to an actual Date object.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;">    <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">new</span> Date<span style="color: #009900;">&#40;</span>year<span style="color: #339933;">,</span> month<span style="color: #339933;">,</span> day<span style="color: #339933;">,</span> hours<span style="color: #339933;">,</span> minutes<span style="color: #339933;">,</span> seconds<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Of course, tests are included for all extension functions as well.</p>
<h4>Date Extensions</h4>
<p><strong>Date.daysInMonth(month, year)</strong><br />
Returns the number of days in the current month and year.  Note that the month is zero-based, so January = 0, February = 1, etc.</p>
<p><strong>Date.prototype.copy()</strong><br />
Creates a copy of the current date object.  Assigning one date variable to another simply points both variables to the same date object.  This function is useful when you need a unique copy of the date object. </p>
<p><strong>Date.prototype.getDayName()</strong><br />
Returns the full name of the day of the week.</p>
<p><strong>Date.prototype.getShortDayName()</strong><br />
Returns the short name of the day of the week, typically in 3 characters.</p>
<p><strong>Date.prototype.getDayChar()</strong><br />
Returns the single character representation of the day of the week.</p>
<p><strong>Date.prototype.getMonthName()</strong><br />
Returns the full name of the month.</p>
<p><strong>Date.prototype.getShortMonthName()</strong><br />
Returns the short name of the month, typically 3 characters.</p>
<p><strong>Date.prototype.getMonthChar()</strong><br />
Returns the single character representation of the month.</p>
<p><strong>Date.prototype.getMonthNumber()</strong><br />
Returns the normalized numeric representation of the month. (i.e. January = 1, February = 2, &#8230;, December = 12)</p>
<p><strong>Date.prototype.daysInMonth()</strong><br />
Returns the number of days in the current month and year, adjusting February for leap years.</p>
<p><strong>Date.prototype.addDays(offset)</strong><br />
Adds the given number of days to the date.  To subtract days, pass in a negative value for offset.</p>
<p><strong>Date.prototype.addMonths(offset)</strong><br />
Adds the given number of months to the date.  To subtract months, pass in a negative value for offset.</p>
<p><strong>Date.prototype.addYears(offset)</strong><br />
Adds the given number of years to the date.  To subtract  years, pass in a negative value for offset.</p>
<p><strong>Date.prototype.addHours(offset)</strong><br />
Adds the given number of hours to the time portion of a date.  To subtract time, pass in a negative value for offset.</p>
<p><strong>Date.prototype.addMinutes(offset)</strong><br />
Adds the given number of minutes to the time portion of a date.  To subtract time, pass in a negative value for offset.</p>
<p><strong>Date.prototype.addSeconds(offset)</strong><br />
Adds the given number of seconds to the time portion of a date.  To subtract time, pass in a negative value for offset.</p>
<p><strong>Date.prototype.clearTime()</strong><br />
Clear the time portion of a date object.</p>
<p><strong>Date.prototype.compareTo(date, ignoreTime)</strong><br />
Date comparison functions.  If ignoreTime is true, then the time portion will be ignored during the comparison.</p>
<p><strong>Date.prototype.isBefore(date, ignoreTime)</strong><br />
Returns true if this date is before another date.</p>
<p><strong>Date.prototype.isAfter(date, ignoreTime)</strong><br />
Returns true if this date is after another date.</p>
<p><strong>Date.prototype.equals(date, ignoreTime)</strong><br />
Returns true if this date is equal to another date.</p>
<p><strong>Date.prototype.toFormat(format)</strong><br />
Return a date in the given format.  Use ^ to force the use of a literal character.</p>
<h4>String Extensions (showing new only)</h4>
<p><strong>String.prototype.toDate(format)</strong><br />
Attempts to convert a string into a date based on a given format. Fields will match either the long or short form, except in the case of the year, where the string must match either a 2-digit or 4-digit format.  Ranges are checked.  Day names are expected if they are included in the format string, but are otherwise ignored.  Use ^ to force the use of a literal character. In other words, to have the character Y appear insead of the actual year, use ^Y.</p>
]]></content:encoded>
			<wfw:commentRss>http://livingmachines.net/2009/04/even-more-javascript-extensions-dates/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>More JavaScript Extensions, and a Library Framework</title>
		<link>http://livingmachines.net/2009/04/more-javascript-extensions-and-a-library-framework/</link>
		<comments>http://livingmachines.net/2009/04/more-javascript-extensions-and-a-library-framework/#comments</comments>
		<pubDate>Thu, 02 Apr 2009 18:35:17 +0000</pubDate>
		<dc:creator>Jason S. Kerchner</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[JavaScript Extensions]]></category>

		<guid isPermaLink="false">http://livingmachines.net/?p=299</guid>
		<description><![CDATA[Download code
As I mentioned in my previous post, I&#8217;m in the process of creating some JavaScript functions that extend the basic JavaScript data types.  Well, I&#8217;ve create a few extensions for the String and Number data types.  Also, since I&#8217;m building a JavaScript library, I went ahead and packaged the source code files [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://livingmachines.net/code/2009-04-02/LivingMachines.zip">Download code</a></p>
<p>As I mentioned in my previous post, I&#8217;m in the process of creating some JavaScript functions that extend the basic JavaScript data types.  Well, I&#8217;ve create a few extensions for the <code>String</code> and <code>Number</code> data types.  Also, since I&#8217;m building a JavaScript library, I went ahead and packaged the source code files into a library as well.</p>
<h4>JavaScript Extensions</h4>
<p>How do you extend the basic data types you ask?  There are two ways.  You can either create a static method, which is available from the from the data type itself, or a prototype method, which is available from all instances of that data type.</p>
<p>For example, the <code>repeat</code> function is a static method of the built-in JavaScript <code>String</code> class.  It was created like this:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;">String.<span style="color: #660066;">repeat</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>chr<span style="color: #339933;">,</span> count<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
  <span style="color: #003366; font-weight: bold;">var</span> s <span style="color: #339933;">=</span> <span style="color: #3366CC;">''</span><span style="color: #339933;">;</span>     
  <span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> count<span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> 
    s <span style="color: #339933;">+=</span> chr<span style="color: #339933;">;</span>     
  <span style="color: #000066; font-weight: bold;">return</span> s<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>You can then execute the <code>repeat</code> method like so:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> str <span style="color: #339933;">=</span> String.<span style="color: #660066;">repeat</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'x'</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">5</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span>str<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>  <span style="color: #006600; font-style: italic;">// Alerts: &quot;xxxxx&quot;</span></pre></td></tr></table></div>

<p>On the other hand, the <code>rightPad</code> function was created as a <code>prototype</code> method of the <code>String</code> class.  If you recall from the <a href="http://livingmachines.net/tag/creating-javascript-classes-series/">Creating JavaScript Classes</a> series, prototype methods are accessible from all object instances.  This means any instance of a <code>String</code> will have this method.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;">String.<span style="color: #660066;">prototype</span>.<span style="color: #660066;">rightPad</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>width<span style="color: #339933;">,</span> chr<span style="color: #339933;">,</span> trunc<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
  <span style="color: #003366; font-weight: bold;">var</span> s <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">toString</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #003366; font-weight: bold;">var</span> w <span style="color: #339933;">=</span> width <span style="color: #339933;">-</span> s.<span style="color: #660066;">length</span><span style="color: #339933;">;</span>
  <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>w <span style="color: #339933;">&gt;</span> <span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span>
    s <span style="color: #339933;">=</span> s <span style="color: #339933;">+</span> String.<span style="color: #660066;">repeat</span><span style="color: #009900;">&#40;</span>chr<span style="color: #339933;">,</span> w<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>trunc<span style="color: #009900;">&#41;</span>
    s <span style="color: #339933;">=</span> s.<span style="color: #660066;">substr</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> width<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000066; font-weight: bold;">return</span> s<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Now, there are two things to note in the above.  First, the declaration uses <code>String.prototype.rightPad</code> to add the <code>rightPad</code> function to the <code>prototype</code> of the <code>String</code> class.  Second, because the <code>rightPad</code> method is now available to a <code>String</code> object instance, the <code>this</code> variable is available in the function, and it will point to the current <code>String</code> instance.</p>
<p>Also of particular interest is line 3, which uses <code>this.toString()</code> to create a copy of the current string.  It is this copy that is modified and returned by the function.  This is common functionality in JavaScript, and I wanted to follow that same pattern here. For example, the <code>replace</code> method does not alter the string, but returns a new string with the replacements made.</p>
<p>The <code>String</code> extensions include basic string manipulation function like padding, trimming and formatting.  I&#8217;ve also include a function to convert a string to a number, while considering how a user might enter a number.  So these values could include thousands separators, currency symbols, or even fractions.  I often find that users appreciate the ability to enter fractions rather than decimals.  Its easier for a user to enter 1/8 rather than remembering or calculating the decimal value 0.125.  And I&#8217;m a big believer that the user should not be calculating anything.  That&#8217;s what the computer is for!</p>
<p>The <code>Number</code> extensions include a <code>toFormat</code> function that will take the number and convert it to a string.  Again, this can take a number like 0.125 and convert it back to the fraction 1/8, if desired.  I could have overridden the built-in <code>toString</code> function, but it has its own purpose that developers may still want to use, so I left it alone.</p>
<p>Here are some examples of using these extensions.  To format a number, you can use:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> num <span style="color: #339933;">=</span> <span style="color: #CC0000;">1234.56</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> str <span style="color: #339933;">=</span> num.<span style="color: #660066;">toFormat</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">3</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000066;">alert</span> <span style="color: #009900;">&#40;</span>str<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>  <span style="color: #006600; font-style: italic;">// Alerts: &quot;1,234.560&quot;</span></pre></td></tr></table></div>

<p>Or, if you want a fraction, set the first argument (the precision) to -1, like so:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> num <span style="color: #339933;">=</span> <span style="color: #CC0000;">1.333</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> str <span style="color: #339933;">=</span> num.<span style="color: #660066;">toFormat</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">-</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000066;">alert</span> <span style="color: #009900;">&#40;</span>str<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>  <span style="color: #006600; font-style: italic;">// Alerts: &quot;1-1/3&quot;</span></pre></td></tr></table></div>

<p>Using the string extensions, you can parse the fraction:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> str <span style="color: #339933;">=</span> <span style="color: #3366CC;">'1-1/3'</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> num <span style="color: #339933;">=</span> str.<span style="color: #660066;">toNumber</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000066;">alert</span> <span style="color: #009900;">&#40;</span>num<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>  <span style="color: #006600; font-style: italic;">// Alerts: &quot;1.3333&quot;</span></pre></td></tr></table></div>

<p>To pad a string, use something like this:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> str <span style="color: #339933;">=</span> <span style="color: #3366CC;">'123'</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> pstr <span style="color: #339933;">=</span> str.<span style="color: #660066;">leftPad</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'0'</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">5</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000066;">alert</span> <span style="color: #009900;">&#40;</span>pstr<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>  <span style="color: #006600; font-style: italic;">// Alerts: &quot;00123&quot;</span></pre></td></tr></table></div>

<p>Of course, you can chain all these functions, too:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> num <span style="color: #339933;">=</span> <span style="color: #CC0000;">123.4</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> str <span style="color: #339933;">=</span> num.<span style="color: #660066;">toFormat</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">2</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">leftPad</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'*'</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">8</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000066;">alert</span> <span style="color: #009900;">&#40;</span>pstr<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>  <span style="color: #006600; font-style: italic;">// Alerts: &quot;**123.40&quot;</span></pre></td></tr></table></div>

<p>This is just a sample of the extensions that are included.  All of them are pretty straight-forward, and the code is well-documented (in my opinion, let me know if you feel otherwise).  And, of course, all of the unit tests are in there as well.  Please keep in mind that these are first versions, so don&#8217;t expect perfection yet!  I can already see where I&#8217;d like to make some additions and changes to these functions.  I&#8217;m still in the early stages here, so I&#8217;ll try to keep things backward compatible.  But that may not be possible.  You&#8217;ve been warned!</p>
<h4>JavaScript Library Framework</h4>
<p>The other thing I did in this version is to package these extensions along with the <code>Class</code> function from the <a href="http://livingmachines.net/tag/creating-javascript-classes-series/">Creating JavaScript Classes</a> series, into a actual library.  I also added a namespace, and, come to think of it, I should probably also add a namespace function.  Will add that to my list of things to do.  Anyway, to use the <code>Class</code> function, you will now access it using <code>LivingMachines.Class()</code>.  Otherwise, it&#8217;s usage is the same as previously described in the <a href="http://livingmachines.net/tag/creating-javascript-classes-series/">Creating JavaScript Classes</a> series.  Going forward, all additional code will be added to this new library package.</p>
<p>Well, I hope you find these useful and educational.  This is only the start of the library, so make sure to <a href="http://feeds2.feedburner.com/livingmachines">subscribe to the RSS</a> feed so that you can keep up to date on new developments.  Next up, I&#8217;m going to work on some date formatting functions.  This means I&#8217;ll be adding some functions to the <code>Data</code> data type, and to the <code>String</code> data type as well.</p>
<h4>Included JavaScript Extension Functions</h4>
<p>Here is a quick overview of the new JavaScript extensions included in this release.  A quick look at the source code comments will give you more details on function usage.  Eventually, I will get around to converting the documentation comments to online docs.  I&#8217;ve got to investigate some of the tools that are out there for doing that, though.</p>
<h5>String Extensions</h5>
<p><code>String.repeat()</code><br />
Repeats a character or string a given number of times.</p>
<p><code>String.prototype.trim()</code><br />
Trims whitespace from the left and right sides of a string.</p>
<p><code>String.prototype.leftTrim()</code><br />
Trims whitespace only from the left side of a string.</p>
<p><code>String.prototype.rightTrim()</code><br />
Trims whitespace only from the right side of a string.</p>
<p><code>String.prototype.leftPad()</code><br />
Pads the left side of a string with a given character to a given width.</p>
<p><code>String.prototype.rightPad()</code><br />
Pads the right side of a string with a given character to a given width.</p>
<p><code>String.prototype.toFormat()</code><br />
Takes a source string with value placeholders and replaces the placeholders with actual values.</p>
<p><code>String.prototype.toNumber()</code><br />
Converts the string to a number.</p>
<h5>Number Extensions</h5>
<p><code>Number.prototype.toFormat()</code><br />
Converts a number to a formatted string.</p>
<p><code>Number.prototype.gcd()</code><br />
Calculates the greatest common divisor between this number and another number.</p>
]]></content:encoded>
			<wfw:commentRss>http://livingmachines.net/2009/04/more-javascript-extensions-and-a-library-framework/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JavaScript Extensions</title>
		<link>http://livingmachines.net/2009/03/javascript-extensions/</link>
		<comments>http://livingmachines.net/2009/03/javascript-extensions/#comments</comments>
		<pubDate>Mon, 23 Mar 2009 18:18:16 +0000</pubDate>
		<dc:creator>Jason S. Kerchner</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[JavaScript Extensions]]></category>

		<guid isPermaLink="false">http://livingmachines.net/?p=279</guid>
		<description><![CDATA[Download code
I&#8217;ve created a few JavaScript functions that I find tend to come in handy when programming.  I call them &#8220;extensions&#8221; because they extend the base window object with additional functions.  I debated on namespacing these, but find that either they are used often enough that having to type a namespace every time [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://livingmachines.net/code/2009-03-23/source-code.zip">Download code</a></p>
<p>I&#8217;ve created a few JavaScript functions that I find tend to come in handy when programming.  I call them &#8220;extensions&#8221; because they extend the base window object with additional functions.  I debated on namespacing these, but find that either they are used often enough that having to type a namespace every time becomes annoying, or the code is more readable without the namespace.  Also, these are functions that are useful in their own right, outside of any library, so namespacing them to a library didn&#8217;t seem right to me. (If you are not familiar with namespacing in JavaScript don&#8217;t worry about it.  I&#8217;ll discuss it in an upcoming post.)</p>
<p>Documentation is included in the source code, but below is a quick reference, so you can see what&#8217;s in there.  All of these functions are added to the global window object, so you can use them directly.  For example, to copy a JavaScript object, you can use:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;">source <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span>
  firstName<span style="color: #339933;">:</span> <span style="color: #3366CC;">'Jane'</span><span style="color: #339933;">,</span>
  lastName<span style="color: #339933;">:</span> <span style="color: #3366CC;">'Doe'</span><span style="color: #339933;">,</span>
  birthDate<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">new</span> Date<span style="color: #009900;">&#40;</span><span style="color: #CC0000;">2000</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">10</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">15</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// Use the copy function to create a duplicate of source</span>
<span style="color: #003366; font-weight: bold;">var</span> dest <span style="color: #339933;">=</span> copy<span style="color: #009900;">&#40;</span>source<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Or, to check if an object is an array, you can use one of the following methods:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> arr <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">3</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>isArray<span style="color: #009900;">&#40;</span>arr<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
  <span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'It is an array!'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">typeOf</span><span style="color: #009900;">&#40;</span>arr<span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> <span style="color: #3366CC;">'array'</span><span style="color: #009900;">&#41;</span>
  <span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'It is an array!'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>This is only a first pass at these functions.  In an upcoming post, I will be adding more extensions to this library.  This will include adding some useful functions to the basic data types like String, Number, Date and Array.  More to come, so stay tuned.<br />
<br/></p>
<hr/>
<pre><strong>typeOf(obj)</strong></pre>
<p>Same as the built-in typeof operator, but distinguishes<br />
arrays and dates from objects.</p>
<p><em>Params</em>:<br />
obj {object} The object to get the type of.<br />
<em>Returns</em>:<br />
{string} The name of the type of the object.</p>
<hr/>
<pre><strong>isUndefined(obj)</strong></pre>
<p>Checks if the object passed in is undefined.</p>
<p><em>Params</em>:<br />
obj {object} The object to be checked.<br />
<em>Returns</em>:<br />
True if obj is undefined, and false otherwise.</p>
<hr/>
<pre><strong>isNull(obj)</strong></pre>
<p>Checks if the object passed in is null.</p>
<p><em>Params</em>:<br />
obj {object} The object to be checked.<br />
<em>Returns</em>:<br />
True if obj is null, and false otherwise.</p>
<hr/>
<pre><strong>isString(obj)</strong></pre>
<p>Checks if the type of object passed in is a string.</p>
<p><em>Params</em>:<br />
obj {object} The object to be checked.<br />
<em>Returns</em>:<br />
True if obj is a string, and false otherwise.</p>
<hr/>
<pre><strong>isNumber(obj)</strong></pre>
<p>Checks if the type of object passed in is a number.</p>
<p><em>Params</em>:<br />
obj {object} The object to be checked.<br />
<em>Returns</em>:<br />
True if obj is a number, and false otherwise.</p>
<hr/>
<pre><strong>isBoolean(obj)</strong></pre>
<p>Checks if the type of object passed in is a boolean.</p>
<p><em>Params</em>:<br />
obj {object} The object to be checked.<br />
<em>Returns</em>:<br />
True if obj is a boolean, and false otherwise.</p>
<hr/>
<pre><strong>isDate(obj)</strong></pre>
<p>Checks if the type of object passed in is a date. This function will<br />
distinguish between an object and a date.</p>
<p><em>Params</em>:<br />
obj {object} The object to be checked.<br />
<em>Returns</em>:<br />
True if obj is a date, and false otherwise.</p>
<hr/>
<pre><strong>isArray(obj)</strong></pre>
<p>Checks if the type of object passed in is an array. This function will<br />
distinguish between an object and an array.</p>
<p><em>Params</em>:<br />
obj {object} The object to be checked.<br />
<em>Returns</em>:<br />
True if obj is an array, and false otherwise.</p>
<hr/>
<pre><strong>isObject(obj)</strong></pre>
<p>Checks if the type of object passed in is an object. This function will distinguish between an array and date vs. an object.</p>
<p><em>Params</em>:<br />
obj {object} The object to be checked.<br />
<em>Returns</em>:<br />
True if obj is an array, and false otherwise.</p>
<hr/>
<pre><strong>isFunction(obj)</strong></pre>
<p>Checks if the type of object passed in is a function.</p>
<p><em>Params</em>:<br />
obj {object} The object to be checked.<br />
<em>Returns</em>:<br />
True if obj is a function, and false otherwise.</p>
<hr/>
<pre><strong>copy(source, [dest])</strong></pre>
<p>Copies the properties of one object to another (including inner objects, arrays and non-prototype functions).  Existing properties in the destination object are preserved, but will be overridden if those properties also exist in the source.  Any functions in the prototype of the source will NOT be  copied.  If no destination object is passed in, a destination object will be created.</p>
<p><em>Params</em>:<br />
src {object} Source object that properties are to be copied from.<br />
dest {object} Destination object that properties are to be copied to.<br />
<em>Returns</em>:<br />
The destination object.</p>
<hr/>
<pre><strong>scopedFn(scope, func)</strong></pre>
<p>Used to create a function pointer that will always be called against a specific object.  Can be especially useful when assigning event handlers to DOM objects and you want the &#8220;this&#8221; variable to point to your own object rather than the DOM object.</p>
<p><em>Params</em>:<br />
{object} scope The object on which func is to be called.<br />
func {function} The function to be called.<br />
<em>Returns</em>:<br />
A scope-corrected function that ensures func is always called against the given scope object.</p>
<hr/>
<pre><strong>emptyFn()</strong></pre>
<p>Shorthand for an empty function.</p>
]]></content:encoded>
			<wfw:commentRss>http://livingmachines.net/2009/03/javascript-extensions/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
