<?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>Javascriptguy&#039;s blog</title>
	<atom:link href="http://jsguy.com/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://jsguy.com</link>
	<description>So much javascript, so little time</description>
	<lastBuildDate>Mon, 24 May 2010 01:45:12 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Long poll jsonp</title>
		<link>http://jsguy.com/?p=103</link>
		<comments>http://jsguy.com/?p=103#comments</comments>
		<pubDate>Tue, 04 May 2010 08:06:45 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Ajax]]></category>
		<category><![CDATA[JSONP]]></category>

		<guid isPermaLink="false">http://jsguy.com/?p=103</guid>
		<description><![CDATA[UPDATE: Implemented changes to the code as suggested by Akeru, thanks!
UPDATE2: Updated to the newer version of jQuery-jsonp, thanks Julian, the Ugly spinner loading is now gone!
Go straight to the code
or
Download it in a zip file
So, whatever happened to comet? Wasn&#8217;t it supposed to save the masses from wasteful ajax polling? I certainly appreciate Alex [...]]]></description>
			<content:encoded><![CDATA[<p><strong>UPDATE</strong>: Implemented changes to the code as suggested by Akeru, thanks!<br />
<strong>UPDATE2</strong>: Updated to the newer version of jQuery-jsonp, thanks Julian, the Ugly spinner loading is now gone!</p>
<p><a href="http://jsguy.com/?p=103#theCode">Go straight to the code</a><br />
or<br />
<a href="http://jsguy.com/labs/longpolljsonp.zip">Download it in a zip file</a></p>
<p>So, whatever happened to <a title="Comet on wikipedia" href="http://en.wikipedia.org/wiki/Comet_(programming)" target="_blank">comet</a>? Wasn&#8217;t it supposed to <a title="Cometd on Ajaxian" href="http://ajaxian.com/archives/cometd-brining-coment-to-the-masses" target="_blank">save the masses</a> from wasteful <a title="Periodic refresh" href="http://ajaxpatterns.org/Periodic_Refresh" target="_blank">ajax polling</a>? I certainly appreciate <a title="Alex Russel on comet, Ajaxian post" href="http://ajaxian.com/archives/comet-a-new-approach-to-ajax-applications" target="_blank">Alex Russel&#8217;s work</a> on the matter, but it really seems as though this very useful technology is falling to the wayside. I think this is mainly due to the difficulty and <a title="Apache and comet" href="http://www.google.com.au/search?q=how+to+get+comet-d+working+with+apache" target="_blank">requirements of a successful implementation on the most popular web server</a>, the main problem is Apache&#8217;s use of threading, <a title="Cometd on Apache" href="http://cometd.org/node/81" target="_blank">this post explains the problem</a> eloquently. Of course <a title="Apache camel" href="http://camel.apache.org/cometd.html" target="_blank">Apache have a whole project</a> that deals with this issue to a degree, but I don&#8217;t think that it is easy to implement, once you dig a little into the documentation, you quickly see that this is not really a thing that just works out of the box&#8230; You <a title="Apache camel getting started longer" href="http://camel.apache.org/book-getting-started.html" target="_blank">need to read a book</a> on the subject first. That is a bit of a deal-breaker for me; after all, the technique is not that difficult to understand, so why should you need to read a whole book to implement it?<span id="more-103"></span></p>
<h1>So is comet dead?</h1>
<p>No, not at all! As a matter of fact, <a title="Comet-d bayeux" href="http://svn.cometd.com/trunk/bayeux/bayeux.html" target="_blank">cometd implements the bayeux protocol</a>, and the technology is very much alive; I&#8217;m sure that it is very useful, for those who have the time, resources and patience to implement it, but where does this leave the rest of us? You know, the guys who want a quick way to get up and running with some instantly useful code that they can understand and tinker with? Well, comet-d does implement something <a title="Comet-d callback polling" href="http://cometd.org/documentation/cometd-javascript/transports" target="_blank">they call &#8220;callback-polling&#8221;</a>, and other people seem to call <a title="Script tag long polling" href="http://en.wikipedia.org/wiki/Comet_(programming)#Script_tag_long_polling" target="_blank">&#8220;script tag long polling&#8221;</a>, though I prefer the term &#8220;long poll jsonp&#8221;.</p>
<h1>Right, so now what?</h1>
<p>Let us look at what exactly &#8220;long poll jsonp&#8221; is. I&#8217;m assuming you already know <a title="JSONP" href="http://en.wikipedia.org/wiki/JSONP" target="_blank">what jsonp is</a>, so that just leaves &#8220;long polling&#8221;. To describe long polling, let us look at the backend and front-end parts in general terms.</p>
<h2>Back end</h2>
<p>On the back-end we simply have a program that doesn&#8217;t finish till it has some data for us. That&#8217;s all there is to it.</p>
<h2>Front end</h2>
<p>On the front end we make a jsonp request, which when finished, starts up again. We are of course passing a token that indicates what data we received, for example a timestamp.</p>
<p>That describes long polling in a nutshell; of course there are some pitfalls and issues to watch out for with this technique, such as error handling, (server timeout), and connection timing.</p>
<h1><a name="theCode">Show me the <span style="text-decoration: line-through;">money</span> code!</a></h1>
<p>It is time to look at some code! Most comet example implement a simple chat client, so I&#8217;ll do the same here. First lets looks at the backend, as it is very simple.</p>
<div class="dean_ch" style="white-space: wrap;"><span class="coMULTI">/*<br />
&nbsp; &nbsp; &nbsp; &nbsp; jQuery Long Poll plugin 0.0.1 (02-05-2010)</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; Note: requires jQuery-JSONP: http://code.google.com/p/jquery-jsonp/</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; Copyright (c) 2010 JavaScript Guy</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; This script is licensed as free software under the terms of the<br />
&nbsp; &nbsp; &nbsp; &nbsp; LGPL License: http://www.opensource.org/licenses/lgpl-license.php</p>
<p>*/</span><br />
<span class="br0">&#40;</span><span class="kw2">function</span><span class="br0">&#40;</span>$<span class="br0">&#41;</span><span class="br0">&#123;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; $.longPoll = <span class="kw2">function</span><span class="br0">&#40;</span> args <span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; args = args || <span class="br0">&#123;</span><span class="br0">&#125;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> self = $.extend<span class="br0">&#40;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; url: <span class="st0">&#8221;</span>,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">//&nbsp; &nbsp; &nbsp; URL To connect to</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; tsParameter: <span class="st0">&#8216;ts&#8217;</span>,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">//&nbsp; &nbsp; &nbsp; Parameter used for the timestamp</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; reconnect: <span class="kw2">true</span>,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">//&nbsp; &nbsp; &nbsp; If we&#8217;re automatically reconnecting</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; errorTimeout: <span class="nu0">60</span>,&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">//&nbsp; &nbsp; &nbsp; Timeout for errors, eg: server timeout, execution time limit, etc.</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; errorTimeoutDelay: <span class="nu0">5</span>,&nbsp; &nbsp;<span class="co1">//&nbsp; &nbsp; &nbsp; Seconds to delay, if the connection failed in an error</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; hasConnection: <span class="kw2">false</span>,&nbsp; &nbsp;<span class="co1">//&nbsp; &nbsp; &nbsp; If we have a connection</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; timestamp: <span class="nu0">0</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; error: <span class="kw2">false</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; request: <span class="kw2">null</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; reconnectFunc: <span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span><span class="br0">&#40;</span> self.reconnect <span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; self.disconnect<span class="br0">&#40;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">//&nbsp; &nbsp; &nbsp; Reconnect &#8211; with longer error timeout delay (in case we have an intermittent connection)</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span><span class="br0">&#40;</span> self.error <span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; setTimeout<span class="br0">&#40;</span> <span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span> self.connect<span class="br0">&#40;</span><span class="br0">&#41;</span>; <span class="br0">&#125;</span>, self.errorTimeoutDelay * <span class="nu0">1000</span> <span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span> <span class="kw1">else</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; setTimeout<span class="br0">&#40;</span> <span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span> self.connect<span class="br0">&#40;</span><span class="br0">&#41;</span>; <span class="br0">&#125;</span>, <span class="nu0">100</span> <span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; connect: <span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; self.reconnect = <span class="kw2">true</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">//&nbsp; &nbsp; &nbsp; self.request = $.ajax( {</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; self.request = $.jsonp<span class="br0">&#40;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; url: self.url + <span class="st0">&#8216;?&#8217;</span> + self.tsParameter + <span class="st0">&#8216;=&#8217;</span> + self.timestamp + <span class="st0">&#8216;&amp;amp;callback=?&#8217;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; timeout: self.errorTimeout * <span class="nu0">1000</span>,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">//&nbsp; &nbsp; &nbsp; Timeout and reconnect</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; error: <span class="kw2">function</span><span class="br0">&#40;</span>XHR, textStatus, errorThrown<span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; self.reconnectFunc<span class="br0">&#40;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; self.error = <span class="kw2">true</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dataType: <span class="st0">&quot;jsonp&quot;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; success: <span class="kw2">function</span><span class="br0">&#40;</span> data <span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; self.timestamp = <span class="br0">&#40;</span>data<span class="br0">&#91;</span>self.tsParameter<span class="br0">&#93;</span><span class="br0">&#41;</span>? data<span class="br0">&#91;</span>self.tsParameter<span class="br0">&#93;</span>: self.timestamp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; self.success<span class="br0">&#40;</span> data <span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; self.error = <span class="kw2">false</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; complete: <span class="kw2">function</span><span class="br0">&#40;</span> data <span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; self.reconnectFunc<span class="br0">&#40;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span> <span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; self.hasConnection = <span class="kw2">true</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>,</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Aborts request</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; disconnect: <span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; self.reconnect = <span class="kw2">false</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span><span class="br0">&#40;</span> self.request <span class="br0">&#41;</span>self.request.abort<span class="br0">&#40;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; self.hasConnection = <span class="kw2">false</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>,</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// User defined</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; success: <span class="kw2">function</span><span class="br0">&#40;</span> data <span class="br0">&#41;</span> <span class="br0">&#123;</span><span class="br0">&#125;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>, args <span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> self;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>;</p>
<p><span class="br0">&#125;</span><span class="br0">&#41;</span><span class="br0">&#40;</span>jQuery<span class="br0">&#41;</span>;</div>
<p>So in the above plugin code, we create a longpoll object, and then setup a bunch of parameters and functions. The <strong>reconnectFunc</strong> is used to handle reconnection on error or completion of calls; the <strong>connect</strong> function uses the <a href="http://code.google.com/p/jquery-jsonp/">jQuery-JSONP</a> library to connect to our url. The reason we&#8217;re using the jQuery-JSONP library is that natively, (as of version 1.4.2), jQuery&#8217;s support for jsonp is flawed. First of all it calls the success method twice (see: http://dev.jquery.com/ticket/6451), and secondly, it doesn&#8217;t support abort() correctly, which is a required function for our code to work. I&#8217;m sure that this will be fixed in the next version of jQuery.<br />
So, as you can see in the code, we&#8217;re handling connection timeouts and general connection errors gracefully; of course I recognise that the comet-d library with the implementation of the bayeux protocol does this too, but on a much grander scale; my library isn&#8217;t intended to replace comet-d, it is simply here to provide an alternative implementation of long poll jsonp, as that is the most useful part of comet, to most people.<br />
Let us look at the rest of the chat app, here is my HTML code:</p>
<div class="dean_ch" style="white-space: wrap;">
&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.1//EN&quot; &quot;http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd&quot;&gt;<br />
&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot;&gt;<br />
&lt;head&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &lt;title&gt;JSONP Long Poll chat demo&lt;/title&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=utf-8&quot; /&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &lt;script type=&quot;text/javascript&quot; src=&quot;jquery-1.4.2.js&quot;&gt;&lt;/script&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &lt;script type=&quot;text/javascript&quot; src=&quot;jquery-jsonp-2.0.2.js&quot;&gt;&lt;/script&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &lt;script type=&quot;text/javascript&quot; src=&quot;jquery-longpoll-0.0.1.js&quot;&gt;&lt;/script&gt;<br />
&lt;/head&gt;<br />
&lt;body&gt;</p>
<p>&lt;div id=&quot;content&quot;&gt;&lt;/div&gt;</p>
<p>&lt;p&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &lt;input type=&quot;button&quot; name=&quot;connect&quot; id=&quot;connect&quot; value=&quot;Connect&quot;/&gt;<br />
&lt;/p&gt;<br />
&lt;p&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &lt;input type=&quot;text&quot; name=&quot;message&quot; id=&quot;message&quot; value=&quot;&quot; /&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &lt;input type=&quot;button&quot; name=&quot;sendMsg&quot; id=&quot;sendMsg&quot; value=&quot;Send&quot;/&gt;<br />
&lt;/p&gt;</p>
<p>&lt;script type=&quot;text/javascript&quot;&gt;<br />
//&nbsp; &nbsp; &nbsp; Chat app<br />
var chatApp = function( url ) {<br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; var self = {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; connection: $.longPoll( {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; url: url,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; success: function( data ) {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Ignore server timeouts, the script will handle it.<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if( data['data'].indexOf( &quot;Maximum execution time of&quot; ) == -1 ) {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; jQuery(&#8216;#content&#8217;).append( &#8216;&lt;div&gt;&#8217; + data['data'] + &#8216;&lt;/div&gt;&#8217; );<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } ),<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //&nbsp; &nbsp; &nbsp; Sends a chat message<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sendChat: function(request) {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; jQuery.ajax( {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; url: url, <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; type: &quot;GET&quot;,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dataType: &quot;jsonp&quot;,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; data: { &#8216;msg&#8217; : request }<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } );<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; },<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //&nbsp; &nbsp; &nbsp; Toggle connection button<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; toggleConnect: function( button ) {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if( self.connection.hasConnection ) {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; self.connection.disconnect();<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; jQuery( button ).val(&quot;Connect&quot;);<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } else {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; self.connection.connect();<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; jQuery( button ).val(&quot;Disconnect&quot;);<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br />
&nbsp; &nbsp; &nbsp; &nbsp; };<br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; return self;<br />
};<br />
&lt;/script&gt;</p>
<p>&lt;script&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; //&nbsp; &nbsp; &nbsp; Chat app initialisation<br />
&nbsp; &nbsp; &nbsp; &nbsp; var c = chatApp( &#8216;http://paxjs.com/labs/longpolljsonp/chat.php&#8217; );</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; var sendMessage = function() {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; chatAppContext.sendChat( jQuery(&#8216;#message&#8217;).val() );<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; jQuery(&#8216;#message&#8217;).val(&#8221;);<br />
&nbsp; &nbsp; &nbsp; &nbsp; };</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; jQuery( &#8216;#connect&#8217; ).click( function() {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; chatAppContext.toggleConnect( jQuery( this ).get(0) );<br />
&nbsp; &nbsp; &nbsp; &nbsp; } );<br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; jQuery( &#8216;#sendMsg&#8217; ).click( sendMessage );<br />
&nbsp; &nbsp; &nbsp; &nbsp; jQuery( &#8216;#message&#8217;).keyup(function(e) {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(e.keyCode == 13)sendMessage();<br />
&nbsp; &nbsp; &nbsp; &nbsp; });</p>
<p>&lt;/script&gt;</p>
<p>&lt;/body&gt;<br />
&lt;/html&gt;<br />
&nbsp;</div>
<p>So as you can see, we simply create an input field for the message, and a button to send the message; we then hook up some simple code to each part of the functionality.</p>
<h1><del datetime="2010-05-22T04:10:34+00:00">Ugly spinner loading in some browsers</del></h1>
<p><del datetime="2010-05-22T04:10:34+00:00">Of course this is just a technique, it isn&#8217;t perfect &#8211; in some browsers, the loading indicator continually shows that a page is loading; a future enhancement will probably fix that&#8230; probably.</del><br />
Updated to the newer version of jQuery-jsonp, (thanks Julian!), the Ugly spinner loading is now gone!</p>
<p>There is a demo here, this is all served off the paxjs domain, to emphasise the cross-site nature of the technique:</p>
<p><script src="http://paxjs.com/labs/longpolljsonp/jquery-1.4.2.js" type="text/javascript"></script> <script src="http://paxjs.com/labs/longpolljsonp/jquery-jsonp-2.0.2.js" type="text/javascript"></script><br />
<script src="http://paxjs.com/labs/longpolljsonp/jquery-longpoll-0.0.1.js" type="text/javascript"></script></p>
<fieldset>
<legend>Chat demo</legend>
<div id="chatContent"></div>
<input id="chatConnect" name="connect" type="button" value="Connect" />
<input id="chatMessage" name="message" type="text" />
<input id="sendMsg" name="sendMsg" type="button" value="Send" /> </fieldset>
<p><script type="text/javascript">
//	Chat app
var chatApp = function( url ) {
	var self = {
		connection: $.longPoll( {
			url: url,
			success: function( data ) {
				// Ignore server timeouts, the script will handle it.
				if( data['data'].indexOf( "Maximum execution time of" ) == -1 ) {
					jQuery('#chatContent').append('<' + 'div' + '>' + data['data'] + '<' + '/div' + '>');
				}
			}
		} ),
		//	Sends a chat message
		sendChat: function(request) {
			jQuery.ajax( {
				url: url,
				type: "GET",
				dataType: "jsonp",
				data: { 'msg' : request }
			} );
		},
		//	Toggle connection button
		toggleConnect: function( button ) {
			if( self.connection.hasConnection ) {
				self.connection.disconnect();
				jQuery( button ).val("Connect");
			} else {
				self.connection.connect();
				jQuery( button ).val("Disconnect");
			}
		}
	};
	return self;
};
</script><br />
<script type="text/javascript">
	//	Chat app initialisation
	var chatAppContext = chatApp( 'http://paxjs.com/labs/longpolljsonp/chat.php' );
	var sendMessage = function() {
		chatAppContext.sendChat( jQuery('#chatMessage').val() );
		jQuery('#chatMessage').val('');
	};
	jQuery( '#chatConnect' ).click( function() {
		chatAppContext.toggleConnect( jQuery( this ).get(0) );
	} );
	jQuery( '#sendMsg' ).click( sendMessage );
	jQuery( '#chatMessage').keyup(function(e) {
		if(e.keyCode == 13)sendMessage();
	});
</script></p>
]]></content:encoded>
			<wfw:commentRss>http://jsguy.com/?feed=rss2&amp;p=103</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>CSS Formatter</title>
		<link>http://jsguy.com/?p=91</link>
		<comments>http://jsguy.com/?p=91#comments</comments>
		<pubDate>Mon, 01 Feb 2010 21:25:27 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://jsguy.com/?p=91</guid>
		<description><![CDATA[So I created a CSS parser and formatter on the weekend; I think it&#8217;s kinda neat as it formats CSS &#8220;just the way I like it&#8221;.
Why would I do this, when there are so many CSS formatters available? Well, the aim of most formatters is to &#8220;optimise&#8221; the CSS
(ie: make it as small as possible), [...]]]></description>
			<content:encoded><![CDATA[<p>So I created a CSS parser and formatter on the weekend; I think it&#8217;s kinda neat as it formats CSS &#8220;just the way I like it&#8221;.<br />
Why would I do this, when there are so <a href="http://www.lonniebest.com/FormatCSS/" target="_blank">many</a> <a href="http://www.codebeautifier.com/" target="_blank">CSS</a> <a href="http://www.cleancss.com/" target="_blank">formatters</a> <a href="http://styleneat.com/index.php" target="_blank">available</a>? Well, the aim of most formatters is to &#8220;optimise&#8221; the CSS<br />
(ie: make it as small as possible), whereas the aim of my formatter is to make it as readable as possible.<span id="more-91"></span><br />
How many times have you inherited a project, only to find the CSS is a giant mess?<br />
Many of the available parsers don&#8217;t have the option to display each entry on a single line, and most don&#8217;t keep the comments!<br />
And none of them allows you to format the CSS so that each entry is on a seperate line, and the entries are<br />
preceeded by X tabs, as long as the entry itself is less than X tabs long (though you may be able to configure CSSTidy to do this?). Let me demonstrate, take this CSS:</p>
<div class="dean_ch" style="white-space: wrap;"><span class="coMULTI">/*&nbsp; &nbsp; &nbsp; Spinner classes&nbsp;*/</span><br />
<span class="re1">.narrowDark</span> <span class="br0">&#123;</span><br />
<span class="kw1">width</span>: <span class="re3">16px</span>;<br />
<span class="kw1">height</span>: <span class="re3">16px</span>;<br />
<span class="kw1">background</span>: <span class="kw2">url</span><span class="br0">&#40;</span><span class="re4"> ../img/load_narrow_dark<span class="re1">.gif</span> </span><span class="br0">&#41;</span> <span class="kw2">no-repeat</span> <span class="kw1">top</span> <span class="kw1">left</span>;<br />
<span class="br0">&#125;</span></p>
<p><span class="coMULTI">/*&nbsp; &nbsp; &nbsp; Validation classes&nbsp; &nbsp; &nbsp; */</span><br />
<span class="re1">.formField</span> <span class="br0">&#123;</span><br />
<span class="kw1">width</span>: <span class="re3">1300px</span>;<span class="coMULTI">/* The surrounding container for each form field */</span><br />
<span class="kw1">clear</span>: <span class="kw1">left</span>;<br />
<span class="br0">&#125;</span></p>
<p><span class="re1">.narrowDarkOLD</span> <span class="br0">&#123;</span> <span class="kw1">height</span>: <span class="re3">16px</span>; <span class="kw1">background</span>: <span class="kw2">url</span><span class="br0">&#40;</span><span class="re4"> ../img/load_narrow_dark<span class="re1">.gif</span> </span><span class="br0">&#41;</span> <span class="kw2">no-repeat</span> <span class="kw1">top</span> <span class="kw1">left</span>; &nbsp; &nbsp; &nbsp; <span class="kw1">width</span>: <span class="re3">16px</span>; <span class="br0">&#125;</span></p>
<p><span class="re1">.formField</span> <span class="br0">&#123;</span><br />
<span class="kw1">height</span>: <span class="re3">32px</span>; <span class="br0">&#125;</span></p>
<p><span class="coMULTI">/*&nbsp; &nbsp; &nbsp; Menu&nbsp; &nbsp; */</span><br />
<span class="re1">.paxMenuDropDown</span><span class="br0">&#123;</span> <span class="kw1">background-color</span>: <span class="re0">#eee</span>; <span class="kw1">border-bottom</span>: <span class="re3">1px</span> <span class="kw2">solid</span> <span class="re0">#aaa</span> <span class="br0">&#125;</span></p>
<p><span class="re1">.paxMenuDropDown</span> li<span class="re1">.active</span> a<span class="re2">:hover</span> <span class="br0">&#123;</span><br />
text-decoration<span class="re2">:none</span>;<br />
<span class="kw1">background-color</span>: <span class="re0">#00f</span>;<br />
<span class="kw1">color</span>: <span class="kw2">white</span>; <span class="kw1">border</span>: <span class="kw2">none</span>;<br />
<span class="br0">&#125;</span></div>
<p>What I want to do is turn it into this:</p>
<div class="dean_ch" style="white-space: wrap;"><span class="coMULTI">/*&nbsp; &nbsp; &nbsp; Spinner classes&nbsp;*/</span><br />
<span class="re1">.narrowDark</span>,<br />
<span class="re1">.narrowDarkOLD</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span> <span class="kw1">background</span>: <span class="kw2">url</span><span class="br0">&#40;</span><span class="re4"> ../img/load_narrow_dark<span class="re1">.gif</span> </span><span class="br0">&#41;</span> <span class="kw2">no-repeat</span> <span class="kw1">top</span> <span class="kw1">left</span>; <span class="kw1">height</span>: <span class="re3">16px</span>; <span class="kw1">width</span>: <span class="re3">16px</span>; <span class="br0">&#125;</span><br />
<span class="coMULTI">/*&nbsp; &nbsp; &nbsp; Validation classes&nbsp; &nbsp; &nbsp; */</span><br />
<span class="coMULTI">/* The surrounding container for each form field */</span><br />
<span class="re1">.formField</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span> <span class="kw1">clear</span>: <span class="kw1">left</span>; <span class="kw1">height</span>: <span class="re3">32px</span>; <span class="kw1">width</span>: <span class="re3">1300px</span>; <span class="br0">&#125;</span><br />
<span class="coMULTI">/*&nbsp; &nbsp; &nbsp; Menu&nbsp; &nbsp; */</span><br />
<span class="re1">.paxMenuDropDown</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span> <span class="kw1">background-color</span>: <span class="re0">#eee</span>; <span class="kw1">border-bottom</span>: <span class="re3">1px</span> <span class="kw2">solid</span> <span class="re0">#aaa</span>; <span class="br0">&#125;</span><br />
<span class="re1">.paxMenuDropDown</span> li<span class="re1">.active</span> a<span class="re2">:hover</span><span class="br0">&#123;</span> <span class="kw1">background-color</span>: <span class="re0">#00f</span>; <span class="kw1">border</span>: <span class="kw2">none</span>; <span class="kw1">color</span>: <span class="kw2">white</span>; <span class="kw1">text-decoration</span>: <span class="kw2">none</span>; <span class="br0">&#125;</span></div>
<p>Here we have:</p>
<ol>
<li>One entry per line</li>
<li>All the comments are intact, and moved outside the class definition (you probably don&#8217;t want to do this with IE6 hacks)</li>
<li>Each property is sorted alphabetically</li>
<li>Duplicate entries are merged (narrowDark and narrowDarkOLD)</li>
<li>Repeated classes are consolidated (formField)</li>
<li>Nicely indented at 6 tabs</li>
</ol>
<p><a title="Javascript guys CSS Formatter" href="http://paxjs.com/labs/cssformatter/"><strong>Check out the CSS formatter here.</strong></a></p>
]]></content:encoded>
			<wfw:commentRss>http://jsguy.com/?feed=rss2&amp;p=91</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>WSG meeting was fun!</title>
		<link>http://jsguy.com/?p=97</link>
		<comments>http://jsguy.com/?p=97#comments</comments>
		<pubDate>Sat, 14 Nov 2009 07:16:50 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://jsguy.com/?p=97</guid>
		<description><![CDATA[Had a ton of fun presenting, and met some interesting people. Even some that want to help out with PAX which would be great!
Thanks very much to Russ for organising the night!!!
]]></description>
			<content:encoded><![CDATA[<p>Had a ton of fun presenting, and met some interesting people. Even some that want to help out with <a title="Paxjs" href="http://paxjs.com" target="_blank">PAX</a> which would be great!</p>
<p>Thanks very much to <a title="Max design" href="http://www.maxdesign.com.au/" target="_blank">Russ</a> for organising the night!!!</p>
]]></content:encoded>
			<wfw:commentRss>http://jsguy.com/?feed=rss2&amp;p=97</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The future of Mozilla</title>
		<link>http://jsguy.com/?p=79</link>
		<comments>http://jsguy.com/?p=79#comments</comments>
		<pubDate>Tue, 03 Nov 2009 14:32:09 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[opinion]]></category>

		<guid isPermaLink="false">http://jsguy.com/?p=79</guid>
		<description><![CDATA[I attended the free Mozilla booze-up Labs event the other month; it was quite interesting; Ben Galbraith spoke about what Mozilla is up to, and what they are planning in the near future&#8230; It was interesting because I got the feeling that whilst they have a few interesting projects in the pipeline, they don&#8217;t really [...]]]></description>
			<content:encoded><![CDATA[<p>I attended the free <a href="http://mozillawebweek.eventbrite.com/">Mozilla <del datetime="2009-10-12T21:54:23+00:00">booze-up</del> Labs event</a> the other month; it was quite interesting; <a href="http://benzilla.galbraiths.org/">Ben Galbraith</a> spoke about what Mozilla is up to, and what they are planning in the near future&#8230; It was interesting because I got the feeling that whilst they have a few <a href="http://labs.mozilla.com/bespin/">interesting</a> <a href="http://labs.mozilla.com/ubiquity/">projects</a> in the pipeline, they don&#8217;t really have anywhere specific to take their browser engine; it has gotten to a point where it performs on par with all the other browsers, and all the other browsers perform on par with it.<br />
So where <strong>should</strong> Mozilla go from here? I think it is blindingly obvious what they <em>could</em> do, though I don&#8217;t think they&#8217;re gonna like my suggestion&#8230; Before I mention what it is, lets take a closer look at Mozilla.<span id="more-79"></span><br />
<!--nextPage --></p>
<h3>What is Mozilla&#8217;s greatest asset?</h3>
<p>Ben touched on it briefly in his presentation, but mostly he spoke about the other side-projects and other new and exciting bits and pieces&#8230;<br />
It&#8217;s the browser, right!? &#8230; Isn&#8217;t it???<br />
Well, no it isn&#8217;t the browser, there are plenty of alternatives which perform just as well, and do exactly the same thing; Mozilla&#8217;s greatest asset is their <a href="https://addons.mozilla.org/">add-ons</a>. This is their only unique selling point; there are literally thousands of high quality plugins that are very easy to install, and make the browser do things Mozilla could never have imagined, and best of all, they didn&#8217;t have to do any of the development for it! I see Mozilla&#8217;s add-ons a lot like Apple would see their app store for the iPhone, a free asset that others keep maintaining for them, with a common goal of market domination. No other browser has an add-on library like this&#8230; At least till now!</p>
<h3>Enter Google Chrome extensions</h3>
<p>Yes, google just launched their <a href="https://chrome.google.com/extensions/">Chrome extensions</a>, and Mozilla should be suffering in their jocks &#8211; as soon as Google have all the most handy extensions, there is not much of a reason to stay with firefox, it will be especially difficult, as Chrome will no doubt be pre-installed on many devices and OS.</p>
<h3>So what should mozilla do then?</h3>
<p>To put it plainly: drop their browser engine, and concentrate on their add-ons. In the ideal world we would have one browser engine, so that developing websites and javascript would be so much easier. Chrome and Safari already use the web-kit engine, so I&#8217;m suggesting that Mozilla write XUL to work on top of  the web-kit engine, and concentrate on making their plugins work on it. I think Galbraith felt that he had done all he could at Mozilla, and the realisation that the future is not in the browser itself, but in the add-ons might be why he is no longer with Mozilla, and instead working on an App store for Palm&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://jsguy.com/?feed=rss2&amp;p=79</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>WSG Nov 11th</title>
		<link>http://jsguy.com/?p=82</link>
		<comments>http://jsguy.com/?p=82#comments</comments>
		<pubDate>Mon, 19 Oct 2009 04:45:55 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://jsguy.com/?p=82</guid>
		<description><![CDATA[I&#8217;m speaking at the WSG about my PAXJS framework next month! You can register at the WSG website! I always enjoy the WSG meetings, there is a great mix of people from different areas and backgrounds, and much discussion anout web development in general. Note that the cost is $10 to attend.
]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m speaking at the WSG about my <a href="http://paxjs.com">PAXJS</a> framework next month! You can <a href="http://webstandardsgroup.org/event/179">register at the WSG website</a>! I <strong>always</strong> enjoy the WSG meetings, there is a great mix of people from different areas and backgrounds, and much discussion anout web development in general. Note that the cost is $10 to attend.</p>
]]></content:encoded>
			<wfw:commentRss>http://jsguy.com/?feed=rss2&amp;p=82</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Manage your data with the jQuery Collections plugin</title>
		<link>http://jsguy.com/?p=55</link>
		<comments>http://jsguy.com/?p=55#comments</comments>
		<pubDate>Sun, 20 Sep 2009 23:10:58 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://jsguy.com/?p=55</guid>
		<description><![CDATA[The premise is quite simple, it works a little like a datagrid in that there is a concept of data-rows, but it doesn't matter what HTML you use for each row; this gives us flexibility to customise exactly how the layout looks, and at the same time has enough smarts to help you manage the collection of items very easily. <!--more-->]]></description>
			<content:encoded><![CDATA[<div style="display: none"><!-- 			textarea				{ height:21px; margin:0; padding:0; }</p>
<p>/*      Clearfix hack   */ 			.clearfix:after			{ content: "."; display: block; clear: both; visibility: hidden; line-height: 0; height: 0; } 			.clearfix				{ display: inline-block; } 			html[xmlns] .clearfix   { display: block; } 			* html .clearfix		{ height: 1%; }</p>
<p>.hide					{ display: none }</p>
<p>.collHead				{ font-weight: bold; font-size: 1.2em } 			.oddRow				    { background-color: #eee; border: 1px solid grey } 			.evenRow				{ background-color: #aaf; border: 1px solid grey }</p>
<p>code.javascript			{ display: block; font-family: "courier new"; white-space: pre-wrap; } 			.seCode					{ border: 1px solid #ccc; margin-top: 8px; font-size:85%; } 			.seCode div.javascript	{ padding: 6px; padding-left: 26px; background: #fff url( resource/img/code_javascript.png ) no-repeat top left; } 			.seCode div.html4strict	{ padding: 6px; padding-left: 26px; background: #fff url( resource/img/code_html.png ) no-repeat top left; }</p>
<p>.imgSurround			{ border: 1px solid #ccc; padding: 8px; margin: 8px; display: inline-block; clear: both } 			.imgComment				{ font-size: 0.9em; margin-top: 4px; padding-top: 4px; border-top: 1px solid #eee }</p>
<p>label.above				{ display: inline-block; font-size: 0.8em; margin-bottom: -5px } 			.mediumText				{ height: 64px; width: 340px } 			input.coll,  			select.coll, 			textarea.coll			{ margin: 1px 4px 8px 0 } 			textarea.coll			{ padding: 2px } 			input.coll.short		{ width: 90px } 			input.coll.medium		{ width: 100px } 			.cp_collection			{ border: 2px solid #eee; border-left: 20px solid #eee; padding: 0 6px 0 6px } 			div.example				{ padding: 10px 0 10px 0; margin: 10px 0 10px 0 } 			div.exampleContainer	{ margin: 0 16px 0 0; border-left: 8px solid #f0f0f0; padding: 8px } 			h5.sourceDesc			{ margin-bottom: 0; margin-top: 12px; padding-bottom: 0; } 		 --><script src="resource/js/jquery-1.3.2.js" type="text/javascript"></script></p>
<p><script src="resource/article/collections/jquery.collections.js" type="text/javascript"></script><br />
<script src="resource/article/collections/collections_demo_0.js" type="text/javascript"></script><br />
 <script src="resource/article/collections/collections_demo_1.js" type="text/javascript"></script><br />
<script src="resource/article/collections/collections_demo_2.js" type="text/javascript"></script><br />
 <script src="resource/article/collections/collections_demo_3.js" type="text/javascript"></script></div>
<div>
<p><a href="resource/article/collections/jquery.collections.js">Download the script</a></p>
<p>It&#8217;s a classic problem: you have a small set of data records that you want your users to interact with at the same time, usually with a need for ordering of the records. I&#8217;ve seen this exact problem pop up in just about every project that I&#8217;ve every worked on. The most obvious solution to the problem is an inline-editable <strong>datagrid</strong>-style widget. Often this provides a &#8220;good enough&#8221; solution, and many UI designers convince their users to integrate this type of widget, as it is relatively easy to do.<br />
This sometimes leads to dis-joined user experiences, inconsistent look &amp; feel, depending on what solution is employed and how much time you spend on integrating it. 			<span id="more-55"></span></p>
<p>First, here are some examples of data grids:</p>
<div class="clearfix">
<div class="imgSurround"><img src="resource/img/article_collections_extgrid01.png" alt="" /></p>
<div class="imgComment">Datagrid from <a href="http://extjs.com">extjs.com</a></div>
</div>
<div class="imgSurround"><img src="resource/img/article_collections_moogrid01.png" alt="" /></p>
<div class="imgComment">Datagrid based on <a href="http://mootools.net/">mootools</a></div>
</div>
<div class="imgSurround"><img src="resource/img/article_collections_paxgrid01.png" alt="" width="620" /></p>
<div class="imgComment">Datagrid from <a href="http://paxjs.com">paxjs.com</a></div>
</div>
</div>
<p>These widgets have the following in common:</p>
<ul>
<li>Data is displayed in a single row by default</li>
<li>When editing a row, the data from other rows is not always accessible</li>
<li>The look and feel is &#8220;like a spreadsheet&#8221;, and usually doesn&#8217;t offer too much in the way of customisation.</li>
</ul>
<p>This is of course not <em>too</em> bad, as long as it is consistent with the rest of your application, and performs the necessary<br />
tasks for your user. Some datagrids allow you to customise colours and fonts, but that is usually about as far as you can take<br />
it without dwelving deeply into customisation and spending lots of time setting up work arounds for how the<br />
grid is laid out and interacts with your data.</p>
<p>So how do you create a good solution, which easily fits in with your design, and back-end api without spending a<br />
bunch of time customising the datagrid script, and laboriously hacking at the CSS?</p>
<h2>The collection manager</h2>
<p>The premise is quite simple, it works a little like a datagrid in that there is a concept of data-rows, but<br />
it doesn&#8217;t matter what HTML you use for each row; this gives us flexibility to customise exactly how the layout<br />
looks, and at the same time has enough smarts to help you manage the collection of items very easily.</p>
<p>To create a collection, you simply setup a <strong>template</strong>, a <strong>target</strong> element, a <strong>add</strong> button and <strong>initialise</strong><br />
the collection using the collections manager script.</p>
<p>Let us start with the most simple of examples.</p>
<div class="example">
<h3>Example: Hello world</h3>
<p>In this example, you can add names &#8211; enter a few, and click the &#8220;Submit form&#8221; button to see how the values map to back-end objects.</p>
<div class="exampleContainer">
<form action="resource/article/collections/collections.php" method="post"><button id="addButton0">Add item</button><br />
<button>Submit form</button></p>
</form>
</div>
<div id="collectionTemplate0" style="display: none">Name:</p>
<input name="name" type="text" /></div>
<h5 class="sourceDesc">The html</h5>
<div class="seCode">
<div class="html4strict" style="font-family: monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&#8216;collectionTarget0&#8242;</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&#8216;clearfix&#8217;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&#8216;clear&#8217;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div&gt;</span></span></p>
<p><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;button</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&#8216;button&#8217;</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&#8216;addButton0&#8242;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>Add item<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/button&gt;</span></span></div>
</div>
<p>We have a div as the target to render the collection manager into, plus an &#8220;add&#8221; button. The clearing div is optional,<br />
depending on your layout requirements. This HTML is inside a standard form tag that submits to collections.php, which simply<br />
shows you the contents of the submitted form.</p>
<h5 class="sourceDesc">The template</h5>
<div class="seCode">
<div class="html4strict" style="font-family: monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&#8216;collectionTemplate0&#8242;</span> <span style="color: #000066;">style</span>=<span style="color: #ff0000;">&#8216;display: none&#8217;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
Name: <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;input</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&#8216;name&#8217;</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&#8216;text&#8217;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span></p>
<p><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div&gt;</span></span></div>
</div>
<p>The template is where things get interesting; it is plain html, BUT, (and it&#8217;s a big BUT), there are no element IDs.<br />
This is because the collections manager script takes the template, and adds IDs to the form elements as needed; it uses<br />
the collection manager&#8217;s <strong>namePattern</strong> to name the field and give it a unique ID. This is a requirement, as we can<br />
have multiple data rows.</p>
<h5 class="sourceDesc">The initialisation script</h5>
<div class="seCode">
<div class="javascript" style="font-family: monospace;">jQuery<span style="color: #66cc66;">(</span> document <span style="color: #66cc66;">)</span>.<span style="color: #006600;">ready</span><span style="color: #66cc66;">(</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">(</span><span style="color: #66cc66;">)</span> <span style="color: #66cc66;">{</span></p>
<p>jQuery<span style="color: #66cc66;">(</span><span style="color: #3366CC;">&#8216;#collectionTarget0&#8242;</span><span style="color: #66cc66;">)</span>.<span style="color: #006600;">collections</span><span style="color: #66cc66;">(</span> <span style="color: #66cc66;">{</span><br />
template: jQuery<span style="color: #66cc66;">(</span><span style="color: #3366CC;">&#8216;#collectionTemplate0&#8242;</span><span style="color: #66cc66;">)</span>,<br />
addButton: jQuery<span style="color: #66cc66;">(</span><span style="color: #3366CC;">&#8216;#addButton0&#8242;</span><span style="color: #66cc66;">)</span></p>
<p><span style="color: #66cc66;">}</span> <span style="color: #66cc66;">)</span>;<br />
<span style="color: #66cc66;">}</span> <span style="color: #66cc66;">)</span>;</div>
</div>
<p>The initialisation script simply brings everything together, it uses the <strong>template</strong> as the query target, specifies the<br />
<strong>template</strong> element, and then the <strong>add</strong> button.</div>
<p>Let us look at a slightly more useful example, a customer profile &#8211; lets assume we have a data structure that maps to this JSON:</p>
<div class="seCode">
<div class="javascript" style="font-family: monospace;"><span style="color: #003366; font-weight: bold;">var</span> customerProfile = <span style="color: #66cc66;">{</span><br />
<span style="color: #000066;">name</span>: <span style="color: #3366CC;">&#8221;</span>,</p>
<p>comments: <span style="color: #3366CC;">&#8221;</span>,<br />
customerType: <span style="color: #66cc66;">[</span><span style="color: #3366CC;">'n'</span>, <span style="color: #3366CC;">'r'</span>, <span style="color: #3366CC;">'v'</span><span style="color: #66cc66;">]</span>,<br />
newsletter: <span style="color: #003366; font-weight: bold;">true</span></p>
<p><span style="color: #66cc66;">}</span>;</div>
</div>
<p>The customerType maps to one of the following values: n = new, r = repeat, v = vip; news letter is true or false.</p>
<div class="example">
<h3>Example 1: Collection manager for customer profiles</h3>
<p>In this example, we start with two rows of example data, and use the default settings for everything else. We also include a<br />
delete button, so that you can remove collection items. Change some of the values, or perhaps add a new row, then click the<br />
&#8220;Submit form&#8221; button to see how the back-end sees your values.</p>
<div>
<form action="resource/article/collections/collections.php"><button id="addButton">Add</button> <button>Submit form</button></p>
</form>
</div>
<div id="collectionTemplate1" class="clearfix cp_collection" style="display: none">
<input name="id" type="hidden" />
<div class="span-3">
<div class="span-3"><label class="above" for="name">Name</label></p>
<input class="coll medium" name="name" type="text" /></div>
<div class="span-3"><label class="above" for="customerType">Customer Type</label></p>
<select class="coll" name="customerType"> <option value="n">New</option> <option value="r">Repeat</option> <option value="v">VIP</option> </select>
</div>
</div>
<div class="span-9">
<p><label class="above" for="comments">Comments</label><br />
<textarea class="mediumText coll" name="comments"></textarea></div>
<div class="span-3"><label class="above">Send newsletter</label></p>
<div>
<input class="coll" name="spam" type="radio" value="true" />Yes</p>
<input class="coll" name="spam" type="radio" value="false" />No</div>
</div>
<div class="span-2 last"><label class="above">Action</label></p>
<p><button>Delete</button></div>
</div>
<h5 class="sourceDesc">The html</h5>
<div class="seCode">
<div class="html4strict" style="font-family: monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&#8216;collectionTarget1&#8242;</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&#8216;clearfix&#8217;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div&gt;</span></span></p>
<p><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&#8216;clear&#8217;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;button</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&#8216;button&#8217;</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&#8216;addButton&#8217;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>Add<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/button&gt;</span></span></div>
</div>
<p>Again, we have a div and an &#8220;add&#8221; button. Also, the HTML is inside a standard form tag that submits to collections.php.</p>
<h5 class="sourceDesc">The template</h5>
<div class="seCode">
<div class="html4strict" style="font-family: monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&#8216;collectionTemplate1&#8242;</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&#8216;clearfix cp_collection&#8217;</span> <span style="color: #000066;">style</span>=<span style="color: #ff0000;">&#8216;display: none&#8217;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span></p>
<p><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;input</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&#8216;id&#8217;</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&#8216;hidden&#8217;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&#8220;span-3&#8243;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span></p>
<p><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&#8220;span-3&#8243;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;label</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&#8216;above&#8217;</span> <span style="color: #000066;">for</span>=<span style="color: #ff0000;">&#8216;name&#8217;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>Name<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/label&gt;</span></span></p>
<p><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;input</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&#8216;coll medium&#8217;</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&#8216;name&#8217;</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&#8216;text&#8217;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span></p>
<p><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&#8220;span-3&#8243;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;label</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&#8216;above&#8217;</span> <span style="color: #000066;">for</span>=<span style="color: #ff0000;">&#8216;customerType&#8217;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>Customer Type<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/label&gt;</span></span></p>
<p><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;select</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&#8216;coll&#8217;</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&#8216;customerType&#8217;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;option</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&#8216;n&#8217;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>New<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/option&gt;</span></span></p>
<p><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;option</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&#8216;r&#8217;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>Repeat<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/option&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;option</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&#8216;v&#8217;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>VIP<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/option&gt;</span></span></p>
<p><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/select&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div&gt;</span></span></p>
<p><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&#8220;span-9&#8243;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;label</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&#8216;above&#8217;</span> <span style="color: #000066;">for</span>=<span style="color: #ff0000;">&#8216;comments&#8217;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>Comments<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/label&gt;</span></span></p>
<p><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;textarea</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&#8216;mediumText coll&#8217;</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&#8216;comments&#8217;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/textarea&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div&gt;</span></span></p>
<p><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&#8220;span-3&#8243;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;label</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&#8216;above&#8217;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>Send newsletter<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/label&gt;</span></span></p>
<p><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;input</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&#8216;coll&#8217;</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&#8217;spam&#8217;</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&#8216;radio&#8217;</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&#8216;true&#8217;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>Yes</p>
<p><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;input</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&#8216;coll&#8217;</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&#8217;spam&#8217;</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&#8216;radio&#8217;</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&#8216;false&#8217;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>No</p>
<p><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&#8220;span-2 last&#8221;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span></p>
<p><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;label</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&#8216;above&#8217;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>Action<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/label&gt;</span></span><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;br</span>/<span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;button</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&#8216;button&#8217;</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&#8216;deleteButton&#8217;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>Delete<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/button&gt;</span></span><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;br</span>/<span style="color: #000000; font-weight: bold;">&gt;</span></span></p>
<p><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div&gt;</span></span></div>
</div>
<p>The template is more complex than the hello world example, but it is just plain HTML with no IDs, just names for the form<br />
fields. You will note that there is also a &#8220;Delete&#8221; button in this template, which allows us to remove items.</p>
<h5 class="sourceDesc">The initialisation script</h5>
<div class="seCode">
<div class="javascript" style="font-family: monospace;">jQuery<span style="color: #66cc66;">(</span>document<span style="color: #66cc66;">)</span>.<span style="color: #006600;">ready</span><span style="color: #66cc66;">(</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">(</span><span style="color: #66cc66;">)</span><span style="color: #66cc66;">{</span></p>
<p>jQuery<span style="color: #66cc66;">(</span><span style="color: #3366CC;">&#8216;#collectionTarget1&#8242;</span><span style="color: #66cc66;">)</span>.<span style="color: #006600;">collections</span><span style="color: #66cc66;">(</span> <span style="color: #66cc66;">{</span><br />
template: jQuery<span style="color: #66cc66;">(</span><span style="color: #3366CC;">&#8216;#collectionTemplate1&#8242;</span><span style="color: #66cc66;">)</span>,<br />
data: <span style="color: #66cc66;">[</span></p>
<p><span style="color: #66cc66;">{</span> id: <span style="color: #CC0000;">1</span>, <span style="color: #000066;">name</span>: <span style="color: #3366CC;">'David Lann'</span>, comments: <span style="color: #3366CC;">'David gets a discount at your discression'</span>, customerType: <span style="color: #3366CC;">'v'</span> <span style="color: #66cc66;">}</span>,</p>
<p><span style="color: #66cc66;">{</span> id: <span style="color: #CC0000;">2</span>, <span style="color: #000066;">name</span>: <span style="color: #3366CC;">'Jill Jones'</span>, comments: <span style="color: #3366CC;">'call on 0295551231, or 0405551599'</span>, spam: <span style="color: #3366CC;">'true'</span> <span style="color: #66cc66;">}</span></p>
<p><span style="color: #66cc66;">]</span>,<br />
addButton: jQuery<span style="color: #66cc66;">(</span><span style="color: #3366CC;">&#8216;#addButton&#8217;</span><span style="color: #66cc66;">)</span>,<br />
deleteButtonName: <span style="color: #3366CC;">&#8216;deleteButton&#8217;</span></p>
<p><span style="color: #66cc66;">}</span> <span style="color: #66cc66;">)</span>;<br />
<span style="color: #66cc66;">}</span> <span style="color: #66cc66;">)</span>;</div>
</div>
<p>The initialisation script now contains some initial data and a reference to the &#8220;Delete&#8221; button. The use of the<br />
<strong>deleteButtonName</strong> parameter specifes that the script will attach a delete function to that button for each<br />
record.</div>
<div class="example">
<h3>Example 2: collection manager with order</h3>
<p>Here we expand on the previous example by adding ordering and move up / down buttons; this is a unique feature that the collection<br />
manager has, compared to standard data grids: a concept of order.<br />
As you move a field up or down, we persist the value of the order fields, so assuming the fields were in the correct order to start<br />
with, we should have the correct order once we submit the form. Note that usually the order field would be hidden, but we&#8217;re showing<br />
it here to make it easier to see what is happening.<br />
Change some of the values, and move the fields around, then click the &#8220;Submit form&#8221; button to see the values, taking<br />
note of the order field values.</p>
<div>
<form action="resource/article/collections/collections.php"><button id="addButton2">Add</button> <button>Submit form</button></p>
</form>
</div>
<div id="collectionTemplate2" class="clearfix cp_collection" style="display: none">
<input name="id" type="hidden" />
<div class="span-3">
<div class="span-3">
<p><label class="above" for="name">Name</label></p>
<input class="coll medium" name="name" type="text" /></div>
<div class="span-3"><label class="above" for="customerType">Customer Type</label></p>
<select class="coll" name="customerType"> <option value="n">New</option> <option value="r">Repeat</option> <option value="v">VIP</option> </select>
</div>
</div>
<div class="span-9"><label class="above" for="comments">Comments</label></p>
<p><textarea class="mediumText coll" name="comments"></textarea></div>
<div class="span-3"><label class="above">Send newsletter</label></p>
<div>
<input class="coll" name="spam" type="radio" value="true" />Yes</p>
<input class="coll" name="spam" type="radio" value="false" />No</div>
<div class="span-3">
<p><label class="above" for="order">Order</label></p>
<input class="coll short orderField" name="order" type="text" /></div>
</div>
<div class="span-2 last"><label class="above">Action</label></p>
<p><button>Delete</button><br />
<button>Up</button></p>
<p><button>Down</button></div>
</div>
<h5 class="sourceDesc">The html</h5>
<div class="seCode">
<div class="html4strict" style="font-family: monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&#8216;collectionTarget2&#8242;</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&#8216;clearfix&#8217;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div&gt;</span></span></p>
<p><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&#8216;clear&#8217;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;button</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&#8216;button&#8217;</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&#8216;addButton2&#8242;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>Add<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/button&gt;</span></span></div>
</div>
<p>Again, we have a div and an &#8220;add&#8221; button. Also, the HTML is inside a standard form tag that submits to collections.php.</p>
<h5 class="sourceDesc">The template</h5>
<div class="seCode">
<div class="html4strict" style="font-family: monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&#8216;collectionTemplate2&#8242;</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&#8216;clearfix cp_collection&#8217;</span> <span style="color: #000066;">style</span>=<span style="color: #ff0000;">&#8216;display: none&#8217;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span></p>
<p><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;input</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&#8216;id&#8217;</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&#8216;hidden&#8217;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&#8220;span-3&#8243;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span></p>
<p><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&#8220;span-3&#8243;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;label</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&#8216;above&#8217;</span> <span style="color: #000066;">for</span>=<span style="color: #ff0000;">&#8216;name&#8217;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>Name<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/label&gt;</span></span></p>
<p><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;input</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&#8216;coll medium&#8217;</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&#8216;name&#8217;</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&#8216;text&#8217;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span></p>
<p><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&#8220;span-3&#8243;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;label</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&#8216;above&#8217;</span> <span style="color: #000066;">for</span>=<span style="color: #ff0000;">&#8216;customerType&#8217;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>Customer Type<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/label&gt;</span></span></p>
<p><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;select</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&#8216;coll&#8217;</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&#8216;customerType&#8217;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;option</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&#8216;n&#8217;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>New<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/option&gt;</span></span></p>
<p><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;option</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&#8216;r&#8217;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>Repeat<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/option&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;option</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&#8216;v&#8217;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>VIP<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/option&gt;</span></span></p>
<p><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/select&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div&gt;</span></span></p>
<p><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&#8220;span-9&#8243;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;label</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&#8216;above&#8217;</span> <span style="color: #000066;">for</span>=<span style="color: #ff0000;">&#8216;comments&#8217;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>Comments<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/label&gt;</span></span></p>
<p><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;textarea</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&#8216;mediumText coll&#8217;</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&#8216;comments&#8217;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/textarea&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div&gt;</span></span></p>
<p><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&#8220;span-3&#8243;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;label</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&#8216;above&#8217;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>Send newsletter<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/label&gt;</span></span></p>
<p><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;input</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&#8216;coll&#8217;</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&#8217;spam&#8217;</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&#8216;radio&#8217;</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&#8216;true&#8217;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>Yes</p>
<p><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;input</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&#8216;coll&#8217;</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&#8217;spam&#8217;</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&#8216;radio&#8217;</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&#8216;false&#8217;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>No</p>
<p><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&#8220;span-3&#8243;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;label</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&#8216;above&#8217;</span> <span style="color: #000066;">for</span>=<span style="color: #ff0000;">&#8216;order&#8217;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>Order<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/label&gt;</span></span></p>
<p><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;input</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&#8216;coll short orderField&#8217;</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&#8216;order&#8217;</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&#8216;text&#8217;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span></p>
<p><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&#8220;span-2 last&#8221;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span></p>
<p><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;label</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&#8216;above&#8217;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>Action<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/label&gt;</span></span><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;br</span>/<span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;button</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&#8216;button&#8217;</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&#8216;deleteButton&#8217;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>Delete<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/button&gt;</span></span><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;br</span>/<span style="color: #000000; font-weight: bold;">&gt;</span></span></p>
<p><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;button</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&#8216;button&#8217;</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&#8216;moveUpButton&#8217;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>Up<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/button&gt;</span></span><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;br</span>/<span style="color: #000000; font-weight: bold;">&gt;</span></span></p>
<p><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;button</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&#8216;button&#8217;</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&#8216;moveDownButton&#8217;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>Down<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/button&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div&gt;</span></span></p>
<p><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div&gt;</span></span></div>
</div>
<p>The template is almost the same as the previous example, except that we now have an order field.</p>
<h5 class="sourceDesc">The initialisation script</h5>
<div class="seCode">
<div class="javascript" style="font-family: monospace;">jQuery<span style="color: #66cc66;">(</span> document <span style="color: #66cc66;">)</span>.<span style="color: #006600;">ready</span><span style="color: #66cc66;">(</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">(</span><span style="color: #66cc66;">)</span> <span style="color: #66cc66;">{</span></p>
<p>jQuery<span style="color: #66cc66;">(</span><span style="color: #3366CC;">&#8216;#collectionTarget2&#8242;</span><span style="color: #66cc66;">)</span>.<span style="color: #006600;">collections</span><span style="color: #66cc66;">(</span> <span style="color: #66cc66;">{</span><br />
template: jQuery<span style="color: #66cc66;">(</span><span style="color: #3366CC;">&#8216;#collectionTemplate2&#8242;</span><span style="color: #66cc66;">)</span>,<br />
<span style="color: #009900; font-style: italic;">//  Initial data</span></p>
<p>data: <span style="color: #66cc66;">[</span><br />
<span style="color: #66cc66;">{</span> id: <span style="color: #CC0000;">1</span>, <span style="color: #000066;">name</span>: <span style="color: #3366CC;">'David Lann'</span>, customerType: <span style="color: #3366CC;">'v'</span>, order: <span style="color: #3366CC;">'1'</span> <span style="color: #66cc66;">}</span>,</p>
<p><span style="color: #66cc66;">{</span> id: <span style="color: #CC0000;">2</span>, <span style="color: #000066;">name</span>: <span style="color: #3366CC;">'Jill Jones'</span>, customerType: <span style="color: #3366CC;">'n'</span>, spam: <span style="color: #3366CC;">'true'</span>, order: <span style="color: #3366CC;">'2'</span> <span style="color: #66cc66;">}</span></p>
<p><span style="color: #66cc66;">]</span>,<br />
addButton: jQuery<span style="color: #66cc66;">(</span><span style="color: #3366CC;">&#8216;#addButton2&#8242;</span><span style="color: #66cc66;">)</span>,<br />
deleteButtonName: <span style="color: #3366CC;">&#8216;deleteButton&#8217;</span>,</p>
<p>beforeAdd: <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">(</span> data, args <span style="color: #66cc66;">)</span> <span style="color: #66cc66;">{</span><br />
<span style="color: #009900; font-style: italic;">//  Set the order, using the collection count</span></p>
<p><span style="color: #003366; font-weight: bold;">var</span> collectionCount = parseInt<span style="color: #66cc66;">(</span> jQuery<span style="color: #66cc66;">(</span> args.<span style="color: #006600;">addButton</span> <span style="color: #66cc66;">)</span>.<span style="color: #006600;">attr</span><span style="color: #66cc66;">(</span> <span style="color: #3366CC;">&#8216;collectionCount&#8217;</span> <span style="color: #66cc66;">)</span>, <span style="color: #CC0000;">10</span> <span style="color: #66cc66;">)</span>;</p>
<p>data<span style="color: #66cc66;">[</span><span style="color: #3366CC;">'order'</span><span style="color: #66cc66;">]</span> = data<span style="color: #66cc66;">[</span><span style="color: #3366CC;">'order'</span><span style="color: #66cc66;">]</span> || collectionCount;<br />
<span style="color: #000066; font-weight: bold;">return</span> data;</p>
<p><span style="color: #66cc66;">}</span>,<br />
bindings: <span style="color: #66cc66;">{</span><br />
<span style="color: #009900; font-style: italic;">//  Move up collection, freezing the order field values; you could</span></p>
<p><span style="color: #009900; font-style: italic;">//  optionally freeze other fields here</span><br />
<span style="color: #3366CC;">&#8216;moveUpButton&#8217;</span>: <span style="color: #66cc66;">{</span></p>
<p>event: <span style="color: #3366CC;">&#8216;click&#8217;</span>,<br />
func: <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">(</span> e, collection <span style="color: #66cc66;">)</span> <span style="color: #66cc66;">{</span></p>
<p>jQuery.<span style="color: #006600;">fn</span>.<span style="color: #006600;">moveUpCollection</span><span style="color: #66cc66;">(</span> collection, <span style="color: #66cc66;">[</span><span style="color: #3366CC;">'order'</span><span style="color: #66cc66;">]</span> <span style="color: #66cc66;">)</span>;</p>
<p><span style="color: #66cc66;">}</span><br />
<span style="color: #66cc66;">}</span>,</p>
<p><span style="color: #009900; font-style: italic;">//  Move down collection, freezing the order field values</span><br />
<span style="color: #3366CC;">&#8216;moveDownButton&#8217;</span>: <span style="color: #66cc66;">{</span></p>
<p>event: <span style="color: #3366CC;">&#8216;click&#8217;</span>,<br />
func: <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">(</span> e, collection <span style="color: #66cc66;">)</span> <span style="color: #66cc66;">{</span></p>
<p>jQuery.<span style="color: #006600;">fn</span>.<span style="color: #006600;">moveDownCollection</span><span style="color: #66cc66;">(</span> collection, <span style="color: #66cc66;">[</span><span style="color: #3366CC;">'order'</span><span style="color: #66cc66;">]</span> <span style="color: #66cc66;">)</span>;</p>
<p><span style="color: #66cc66;">}</span><br />
<span style="color: #66cc66;">}</span></p>
<p><span style="color: #66cc66;">}</span><br />
<span style="color: #66cc66;">}</span> <span style="color: #66cc66;">)</span>;<br />
<span style="color: #66cc66;">}</span> <span style="color: #66cc66;">)</span>;</div>
</div>
<p>The initialisation script now contains some initial data and a reference to the &#8220;Delete&#8221; button. The use of the<br />
<strong>deleteButtonName</strong> parameter specifes that the script will attach a delete function to that button for each<br />
record.</div>
<div class="example">
<h3>Example 3: collection manager for customer profiles with ajax delete</h3>
<p>Yet again we expand on the previous example, this time we add ajax delete&#8230;<br />
Change some of the values, and move the fields around, then click the &#8220;Submit form&#8221; button to see the values, taking<br />
note of the order field values. We have also included the &#8220;namespace&#8221; parameter, which affects how the data is presented<br />
to the back-end, but more about this later.</p>
<div>
<form action="resource/article/collections/collections.php"><button id="addButton3">Add</button> <button>Submit form</button></p>
</form>
</div>
<div id="collectionTemplate3" class="clearfix cp_collection" style="display: none">
<input name="id" type="hidden" />
<div class="span-3">
<div class="span-3"><label class="above" for="name">Name</label></p>
<input class="coll medium" name="name" type="text" /></div>
<div class="span-3"><label class="above" for="customerType">Customer Type</label></p>
<select class="coll" name="customerType"> <option value="n">New</option> <option value="r">Repeat</option> <option value="v">VIP</option> </select>
</div>
</div>
<div class="span-9"><label class="above" for="comments">Comments</label></p>
<p><textarea class="mediumText coll" name="comments"></textarea></div>
<div class="span-3"><label class="above">Send newsletter</label></p>
<div>
<input class="coll" name="spam" type="radio" value="y" />Yes</p>
<input class="coll" name="spam" type="radio" value="n" />No</div>
<div class="span-3">
<p><label class="above" for="order">Order</label></p>
<input class="coll short orderField" name="order" type="text" /></div>
</div>
<div class="span-2 last"><label class="above">Action</label></p>
<p><button>Delete</button><br />
<button>Up</button></p>
<p><button>Down</button></div>
</div>
<h5 class="sourceDesc">The html</h5>
<div class="seCode">
<div class="html4strict" style="font-family: monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&#8216;collectionTarget3&#8242;</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&#8216;clearfix&#8217;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div&gt;</span></span></p>
<p><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&#8216;clear&#8217;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;button</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&#8216;button&#8217;</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&#8216;addButton3&#8242;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>Add<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/button&gt;</span></span></div>
</div>
<p>Again, we have a div and an &#8220;add&#8221; button. Also, the HTML is inside a standard form tag that submits to collections.php.</p>
<h5 class="sourceDesc">The template</h5>
<div class="seCode">
<div class="html4strict" style="font-family: monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&#8216;collectionTemplate3&#8242;</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&#8216;clearfix cp_collection&#8217;</span> <span style="color: #000066;">style</span>=<span style="color: #ff0000;">&#8216;display: none&#8217;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span></p>
<p><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;input</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&#8216;id&#8217;</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&#8216;hidden&#8217;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&#8220;span-3&#8243;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span></p>
<p><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&#8220;span-3&#8243;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;label</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&#8216;above&#8217;</span> <span style="color: #000066;">for</span>=<span style="color: #ff0000;">&#8216;name&#8217;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>Name<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/label&gt;</span></span></p>
<p><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;input</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&#8216;coll medium&#8217;</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&#8216;name&#8217;</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&#8216;text&#8217;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span></p>
<p><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&#8220;span-3&#8243;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;label</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&#8216;above&#8217;</span> <span style="color: #000066;">for</span>=<span style="color: #ff0000;">&#8216;customerType&#8217;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>Customer Type<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/label&gt;</span></span></p>
<p><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;select</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&#8216;coll&#8217;</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&#8216;customerType&#8217;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;option</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&#8216;n&#8217;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>New<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/option&gt;</span></span></p>
<p><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;option</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&#8216;r&#8217;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>Repeat<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/option&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;option</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&#8216;v&#8217;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>VIP<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/option&gt;</span></span></p>
<p><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/select&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div&gt;</span></span></p>
<p><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&#8220;span-9&#8243;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;label</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&#8216;above&#8217;</span> <span style="color: #000066;">for</span>=<span style="color: #ff0000;">&#8216;comments&#8217;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>Comments<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/label&gt;</span></span></p>
<p><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;textarea</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&#8216;mediumText coll&#8217;</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&#8216;comments&#8217;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/textarea&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div&gt;</span></span></p>
<p><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&#8220;span-3&#8243;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;label</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&#8216;above&#8217;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>Send newsletter<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/label&gt;</span></span></p>
<p><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;input</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&#8216;coll&#8217;</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&#8217;spam&#8217;</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&#8216;radio&#8217;</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&#8216;y&#8217;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>Yes</p>
<p><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;input</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&#8216;coll&#8217;</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&#8217;spam&#8217;</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&#8216;radio&#8217;</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&#8216;n&#8217;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>No</p>
<p><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&#8220;span-3&#8243;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;label</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&#8216;above&#8217;</span> <span style="color: #000066;">for</span>=<span style="color: #ff0000;">&#8216;order&#8217;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>Order<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/label&gt;</span></span></p>
<p><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;input</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&#8216;coll short orderField&#8217;</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&#8216;order&#8217;</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&#8216;text&#8217;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span></p>
<p><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&#8220;span-2 last&#8221;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span></p>
<p><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;label</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&#8216;above&#8217;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>Action<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/label&gt;</span></span><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;br</span>/<span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;button</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&#8216;button&#8217;</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&#8216;deleteButton&#8217;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>Delete<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/button&gt;</span></span><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;br</span>/<span style="color: #000000; font-weight: bold;">&gt;</span></span></p>
<p><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;button</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&#8216;button&#8217;</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&#8216;moveUpButton&#8217;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>Up<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/button&gt;</span></span><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;br</span>/<span style="color: #000000; font-weight: bold;">&gt;</span></span></p>
<p><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;button</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&#8216;button&#8217;</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&#8216;moveDownButton&#8217;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>Down<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/button&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div&gt;</span></span></p>
<p><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div&gt;</span></span></div>
</div>
<p>The template is structurally the same as the previous example; of course the names of the fields are different.</p>
<h5 class="sourceDesc">The initialisation script</h5>
<div class="seCode">
<div class="javascript" style="font-family: monospace;">jQuery<span style="color: #66cc66;">(</span> document <span style="color: #66cc66;">)</span>.<span style="color: #006600;">ready</span><span style="color: #66cc66;">(</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">(</span><span style="color: #66cc66;">)</span> <span style="color: #66cc66;">{</span></p>
<p><span style="color: #003366; font-weight: bold;">var</span> config = <span style="color: #66cc66;">{</span><br />
template: jQuery<span style="color: #66cc66;">(</span><span style="color: #3366CC;">&#8216;#collectionTemplate3&#8242;</span><span style="color: #66cc66;">)</span>,<br />
<span style="color: #009900; font-style: italic;">//  Initial data</span></p>
<p>data: <span style="color: #66cc66;">[</span><br />
<span style="color: #66cc66;">{</span> id: <span style="color: #CC0000;">1</span>, <span style="color: #000066;">name</span>: <span style="color: #3366CC;">'David Lann'</span>, customerType: <span style="color: #3366CC;">'v'</span>, order: <span style="color: #3366CC;">'1'</span> <span style="color: #66cc66;">}</span>,</p>
<p><span style="color: #66cc66;">{</span> id: <span style="color: #CC0000;">2</span>, <span style="color: #000066;">name</span>: <span style="color: #3366CC;">'Jill Jones'</span>, customerType: <span style="color: #3366CC;">'n'</span>, spam: <span style="color: #3366CC;">'true'</span>, order: <span style="color: #3366CC;">'2'</span> <span style="color: #66cc66;">}</span></p>
<p><span style="color: #66cc66;">]</span>,<br />
addButton: jQuery<span style="color: #66cc66;">(</span><span style="color: #3366CC;">&#8216;#addButton3&#8242;</span><span style="color: #66cc66;">)</span>,<br />
deleteButtonName: <span style="color: #3366CC;">&#8216;deleteButton&#8217;</span>,</p>
<p>beforeAdd: <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">(</span> data, args <span style="color: #66cc66;">)</span> <span style="color: #66cc66;">{</span><br />
<span style="color: #009900; font-style: italic;">//  Set the order, using the collection count</span></p>
<p><span style="color: #003366; font-weight: bold;">var</span> collectionCount = parseInt<span style="color: #66cc66;">(</span> jQuery<span style="color: #66cc66;">(</span> args.<span style="color: #006600;">addButton</span> <span style="color: #66cc66;">)</span>.<span style="color: #006600;">attr</span><span style="color: #66cc66;">(</span> <span style="color: #3366CC;">&#8216;collectionCount&#8217;</span> <span style="color: #66cc66;">)</span>, <span style="color: #CC0000;">10</span> <span style="color: #66cc66;">)</span>;</p>
<p>data<span style="color: #66cc66;">[</span><span style="color: #3366CC;">'order'</span><span style="color: #66cc66;">]</span> = data<span style="color: #66cc66;">[</span><span style="color: #3366CC;">'order'</span><span style="color: #66cc66;">]</span> || collectionCount;<br />
<span style="color: #000066; font-weight: bold;">return</span> data;</p>
<p><span style="color: #66cc66;">}</span>,<br />
bindings: <span style="color: #66cc66;">{</span><br />
<span style="color: #009900; font-style: italic;">//  Move up collection, freezing the order field values</span></p>
<p><span style="color: #3366CC;">&#8216;moveUpButton&#8217;</span>: <span style="color: #66cc66;">{</span><br />
event: <span style="color: #3366CC;">&#8216;click&#8217;</span>,</p>
<p>func: <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">(</span> e, collection <span style="color: #66cc66;">)</span> <span style="color: #66cc66;">{</span><br />
jQuery.<span style="color: #006600;">fn</span>.<span style="color: #006600;">moveUpCollection</span><span style="color: #66cc66;">(</span> collection, <span style="color: #66cc66;">[</span><span style="color: #3366CC;">'order'</span><span style="color: #66cc66;">]</span> <span style="color: #66cc66;">)</span>;</p>
<p><span style="color: #66cc66;">}</span><br />
<span style="color: #66cc66;">}</span>,</p>
<p><span style="color: #009900; font-style: italic;">//  Move down collection, freezing the order field values</span><br />
<span style="color: #3366CC;">&#8216;moveDownButton&#8217;</span>: <span style="color: #66cc66;">{</span></p>
<p>event: <span style="color: #3366CC;">&#8216;click&#8217;</span>,<br />
func: <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">(</span> e, collection <span style="color: #66cc66;">)</span> <span style="color: #66cc66;">{</span></p>
<p>jQuery.<span style="color: #006600;">fn</span>.<span style="color: #006600;">moveDownCollection</span><span style="color: #66cc66;">(</span> collection, <span style="color: #66cc66;">[</span><span style="color: #3366CC;">'order'</span><span style="color: #66cc66;">]</span> <span style="color: #66cc66;">)</span>;</p>
<p><span style="color: #66cc66;">}</span><br />
<span style="color: #66cc66;">}</span></p>
<p><span style="color: #66cc66;">}</span>,<br />
<span style="color: #009900; font-style: italic;">//      Override the delete function, to send ajax request if necessary</span><br />
deleteFunction: <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">(</span> template, args, data, deleteButton <span style="color: #66cc66;">)</span> <span style="color: #66cc66;">{</span></p>
<p>jQuery<span style="color: #66cc66;">(</span> deleteButton <span style="color: #66cc66;">)</span>.<span style="color: #006600;">text</span><span style="color: #66cc66;">(</span> <span style="color: #3366CC;">&#8216;Deleting&#8230;&#8217;</span> <span style="color: #66cc66;">)</span>.<span style="color: #006600;">attr</span><span style="color: #66cc66;">(</span> <span style="color: #3366CC;">&#8216;disabled&#8217;</span>, <span style="color: #3366CC;">&#8216;disabled&#8217;</span> <span style="color: #66cc66;">)</span>;<br />
<span style="color: #009900; font-style: italic;">//      If we have data, send it to the server to delete, otherwise simply remove</span></p>
<p><span style="color: #003366; font-weight: bold;">var</span> dataLength = <span style="color: #CC0000;">0</span>;<br />
<span style="color: #000066; font-weight: bold;">for</span><span style="color: #66cc66;">(</span> <span style="color: #003366; font-weight: bold;">var</span> x <span style="color: #000066; font-weight: bold;">in</span> data <span style="color: #66cc66;">)</span>dataLength++;<br />
<span style="color: #000066; font-weight: bold;">if</span><span style="color: #66cc66;">(</span> dataLength &gt; <span style="color: #CC0000;">0</span> <span style="color: #66cc66;">)</span> <span style="color: #66cc66;">{</span></p>
<p><span style="color: #009900; font-style: italic;">//      Add delete parameter to the data</span><br />
data<span style="color: #66cc66;">[</span><span style="color: #3366CC;">'action'</span><span style="color: #66cc66;">]</span> = <span style="color: #3366CC;">&#8216;delete&#8217;</span>;<br />
<span style="color: #003366; font-weight: bold;">var</span> request = jQuery.<span style="color: #006600;">ajax</span><span style="color: #66cc66;">(</span> <span style="color: #66cc66;">{</span></p>
<p>type: <span style="color: #3366CC;">&#8216;POST&#8217;</span>,<br />
data: data,</p>
<p>url: <span style="color: #3366CC;">&#8216;collections.php&#8217;</span>,<br />
dataType: <span style="color: #3366CC;">&#8220;text&#8221;</span>,</p>
<p>error: <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">(</span><span style="color: #66cc66;">)</span> <span style="color: #66cc66;">{</span><br />
<span style="color: #000066;">alert</span><span style="color: #66cc66;">(</span> <span style="color: #3366CC;">&#8220;Ajax error occured&#8221;</span> <span style="color: #66cc66;">)</span>;</p>
<p><span style="color: #66cc66;">}</span>,<br />
success: <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">(</span> html <span style="color: #66cc66;">)</span> <span style="color: #66cc66;">{</span> <span style="color: #009900; font-style: italic;">//      Remove collection</span></p>
<p>jQuery.<span style="color: #006600;">fn</span>.<span style="color: #006600;">removeCollection</span><span style="color: #66cc66;">(</span>template, args, data<span style="color: #66cc66;">)</span>;</p>
<p><span style="color: #66cc66;">}</span><br />
<span style="color: #66cc66;">}</span> <span style="color: #66cc66;">)</span>;</p>
<p><span style="color: #66cc66;">}</span> <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #66cc66;">{</span><br />
jQuery.<span style="color: #006600;">fn</span>.<span style="color: #006600;">removeCollection</span><span style="color: #66cc66;">(</span> template, args, data <span style="color: #66cc66;">)</span>;</p>
<p><span style="color: #66cc66;">}</span><br />
<span style="color: #66cc66;">}</span>,<br />
namePattern: <span style="color: #3366CC;">&#8220;contact{number}[{name}]&#8220;</span></p>
<p><span style="color: #66cc66;">}</span>;</p>
<p>jQuery<span style="color: #66cc66;">(</span><span style="color: #3366CC;">&#8216;#collectionTarget3&#8242;</span><span style="color: #66cc66;">)</span>.<span style="color: #006600;">collections</span><span style="color: #66cc66;">(</span>config<span style="color: #66cc66;">)</span>;<br />
<span style="color: #66cc66;">}</span> <span style="color: #66cc66;">)</span>;</div>
</div>
<p>The initialisation script now also has a <strong>deleteFunction</strong> parameter, with a function that ensures that we only<br />
access the back-end if we need to; this allows the back-end to only</div>
<h2>Back end integration</h2>
<p>Of course the collections manager is useless without data from the back-end; it is very<br />
easy to integrate the collection manager, thanks laregly to the <em>namePattern</em> parameter, which allows tight<br />
control of how the fields are named; out of the box, you can quickly integrate with just about any php, python, java<br />
(struts, springBeans), .NET, etc&#8230;</p>
<p>The <strong>namePattern</strong> parameter allows you to specify where the record number and name appears; in the last example,<br />
we use a namePattern like so:</p>
<div class="seCode">
<div class="javascript" style="font-family: monospace;">namePattern: <span style="color: #3366CC;">&#8220;contact{number}[{name}]&#8220;</span></div>
</div>
<p>This creates individual objects for each data row, rather than the default of one array of data rows. This can be particularly<br />
convenient if you have a set number of a type of object, for example if you have exactly four contact objects named &#8220;contact1&#8243;,<br />
&#8230;, &#8220;contact4&#8243;, this will allow you to easliy map directly to those objects.<br />
The default namePattern is:</p>
<div class="seCode">
<div class="javascript" style="font-family: monospace;">namePattern: <span style="color: #3366CC;">&#8220;collection[{number}][{name}]&#8220;</span></div>
</div>
<p>Which will map to one array named &#8220;collection&#8221; of data rows.</p>
<h2><a name="api"></a>API</h2>
<p>Here is a list of options, and what you can do with the collections manager</p>
<ul>
<li><strong>target</strong> &#8211; The target of the collection manager (defaults to jQuery result)</li>
<li><strong>template</strong> &#8211; Element to use for cloning. Note: do NOT give any items IDs, they will be removed</li>
<li><strong>data</strong> &#8211; Optionally include some data, default is 1 record</li>
<li><strong>startCount</strong> &#8211; What number to start the count from.</li>
<li><strong>minItems</strong> &#8211; Minimum number of items to show at any time (default 1)</li>
<li><strong>maxItems</strong> &#8211; Maximum number of items to show (default 10)</li>
<li><strong>namePattern</strong> &#8211; Pattern for naming the form fields (for mapping to back-end objects)</li>
<li><strong>deleteButtonName</strong> &#8211; Name for delete button to use in the template</li>
<li><strong>deleteFunction</strong> &#8211; Delete function override, params: ( template, args, data, deleteButton )</li>
<li><strong>addButton</strong> &#8211; Button to assign the add function to.</li>
<li><strong>bindings</strong> &#8211; name: {event:function}. WIP: we may be able to get rid of the specific addButton and DeleteButton events here.</li>
<li><strong>beforeAdd</strong> &#8211; Function that runs before an item is added, params: ( data, args ), if we return anything, it will be used as data</li>
<li><strong>afterAdd</strong> &#8211; Function that runs after an item is added, params: ( data, args )</li>
<li><strong>beforeRemove</strong> &#8211; Function that runs before an item is removed &#8211; return false to cancel removal of item. Params: ( data, args )</li>
<li><strong>afterRemove</strong> &#8211; Function that runs after an item is removed, params: ( data, args, wasRemoved )</li>
</ul>
</div>
]]></content:encoded>
			<wfw:commentRss>http://jsguy.com/?feed=rss2&amp;p=55</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
