<?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>Perplexed Labs &#187; ajax</title>
	<atom:link href="http://blog.perplexedlabs.com/tag/ajax/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.perplexedlabs.com</link>
	<description>web development war stories from the frontlines to the backend</description>
	<lastBuildDate>Sat, 24 Jul 2010 16:27:40 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>jQuery 1.4 Released</title>
		<link>http://blog.perplexedlabs.com/2010/01/14/jquery-1-4-released/</link>
		<comments>http://blog.perplexedlabs.com/2010/01/14/jquery-1-4-released/#comments</comments>
		<pubDate>Thu, 14 Jan 2010 20:57:24 +0000</pubDate>
		<dc:creator>Matt</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Django]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://blog.perplexedlabs.com/?p=405</guid>
		<description><![CDATA[Many (awesome) changes http://blog.jquery.com/2010/01/14/jquery-14-released/. View the release notes here: http://jquery14.com/day-01/jquery-14 Related posts:jQuery 1.4.2 Released jQuery 1.4 Alpha 1 Released jQuery 1.4a2 (Alpha 2) Released


Related posts:<ol><li><a href='http://blog.perplexedlabs.com/2010/02/20/jquery-1-4-2-released/' rel='bookmark' title='Permanent Link: jQuery 1.4.2 Released'>jQuery 1.4.2 Released</a></li>
<li><a href='http://blog.perplexedlabs.com/2009/12/05/jquery-1-4-alpha-1-released/' rel='bookmark' title='Permanent Link: jQuery 1.4 Alpha 1 Released'>jQuery 1.4 Alpha 1 Released</a></li>
<li><a href='http://blog.perplexedlabs.com/2009/12/19/jquery-1-4a2-alpha-2-released/' rel='bookmark' title='Permanent Link: jQuery 1.4a2 (Alpha 2) Released'>jQuery 1.4a2 (Alpha 2) Released</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>Many (awesome) changes <a href="http://blog.jquery.com/2010/01/14/jquery-14-released/">http://blog.jquery.com/2010/01/14/jquery-14-released/</a>.</p>
<p>View the release notes here: <a href="http://jquery14.com/day-01/jquery-14">http://jquery14.com/day-01/jquery-14</a></p>


<p>Related posts:<ol><li><a href='http://blog.perplexedlabs.com/2010/02/20/jquery-1-4-2-released/' rel='bookmark' title='Permanent Link: jQuery 1.4.2 Released'>jQuery 1.4.2 Released</a></li>
<li><a href='http://blog.perplexedlabs.com/2009/12/05/jquery-1-4-alpha-1-released/' rel='bookmark' title='Permanent Link: jQuery 1.4 Alpha 1 Released'>jQuery 1.4 Alpha 1 Released</a></li>
<li><a href='http://blog.perplexedlabs.com/2009/12/19/jquery-1-4a2-alpha-2-released/' rel='bookmark' title='Permanent Link: jQuery 1.4a2 (Alpha 2) Released'>jQuery 1.4a2 (Alpha 2) Released</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.perplexedlabs.com/2010/01/14/jquery-1-4-released/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>PHP jQuery AJAX Javascript Long Polling</title>
		<link>http://blog.perplexedlabs.com/2009/05/04/php-jquery-ajax-javascript-long-polling/</link>
		<comments>http://blog.perplexedlabs.com/2009/05/04/php-jquery-ajax-javascript-long-polling/#comments</comments>
		<pubDate>Mon, 04 May 2009 14:00:14 +0000</pubDate>
		<dc:creator>Matt</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[lighttpd]]></category>
		<category><![CDATA[long polling]]></category>
		<category><![CDATA[nginx]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.perplexedlabs.com/?p=217</guid>
		<description><![CDATA[Background "Long polling" is the name used to describe a technique which: An AJAX request is made (utilizing a javascript framework such as jQuery) The server waits for the data requested to be available, loops, and sleeps (your server-side PHP script) This loop repeats after data is returned to the client and processed (usually in [...]


Related posts:<ol><li><a href='http://blog.perplexedlabs.com/2008/11/07/real-time-ajax-javascript-progress-bar/' rel='bookmark' title='Permanent Link: Real-time &#8220;AJAX&#8221; JavaScript Progress Bar'>Real-time &#8220;AJAX&#8221; JavaScript Progress Bar</a></li>
<li><a href='http://blog.perplexedlabs.com/2009/02/05/dynamic-javascript-script-insertion-for-embedding/' rel='bookmark' title='Permanent Link: PHP Dynamic JavaScript SCRIPT Insertion for Embedding'>PHP Dynamic JavaScript SCRIPT Insertion for Embedding</a></li>
<li><a href='http://blog.perplexedlabs.com/2008/02/12/php-fast-large-megabyte-data-transfer-between-sessions/' rel='bookmark' title='Permanent Link: PHP fast, large (megabyte), data transfer between sessions'>PHP fast, large (megabyte), data transfer between sessions</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<h3>Background</h3>
<p>"Long polling" is the name used to describe a technique which:</p>
<ul>
<li>An AJAX request is made (utilizing a javascript framework such as jQuery)
<li>The server waits for the data requested to be available, loops, and sleeps (your server-side PHP script)
<li>This loop repeats after data is returned to the client and processed (usually in your AJAX request's onComplete callback function)
</ul>
<p>This essentially simulates a continuous real-time stream from the client to the server.  It can be more efficient than a regular polling technique because of the reduction in HTTP requests.  You're not asking over and over and over again for new data - you ask once and wait for an answer.  In most cases this reduces the latency in which data becomes available to your application.</p>
<p>There are a variety of use cases in which this technique can be handy.  At the top of the list are real-time web-based chat applications.  Each client executes a long polling loop for chat and user events (sign on/sign off/new message).  <a href="http://www.meebo.com">Meebo</a> is perhaps the greatest example of this.</p>
<p>It's important to note some of the server side technical limitations of long polling.  Because connections remain open for considerably longer time than a typical HTTP request/response cycle you want your web server to be able to handle a large number of simultaneous connections.  Apache isn't the best candidate for this type of situation.  <a href="http://nginx.net/">nginx</a> and <a href="http://www.lighttpd.net/">lighttpd</a> are two lightweight web servers built from the ground up to handle a high volume of simultaneous connections.  Both support the FastCGI interface and as such can be configured to support PHP.  Again, Meebo uses lighttpd.</p>
<p>For similar reasons - it's also a good idea to choose a different sub-domain to handle long polling traffic.  Because of client side browser limitations you don't want long polling connections interfering with regular HTTP traffic delivering page and media resources for your application.</p>
<h3>Implementation</h3>
<p><a href="http://www.jquery.com">jQuery</a> makes implementation a breeze.</p>
<pre class="brush: jscript;">
var lpOnComplete = function(response) {
	alert(response);
	// do more processing
	lpStart();
};

var lpStart = function() {
	$.post('/path/to/script', {}, lpOnComplete, 'json');
};

$(document).ready(lpStart);
</pre>
<p>Straightforward.  When the document is ready the loop begins.  Each iteration the returned data is processed and the loop is restarted.</p>
<p>On the server side - just like we discussed earlier:</p>
<pre class="brush: php;">
$time = time();
while((time() - $time) &lt; 30) {
	// query memcache, database, etc. for new data
	$data = $datasource-&gt;getLatest();

	// if we have new data return it
	if(!empty($data)) {
		echo json_encode($data);
		break;
	}

	usleep(25000);
}
</pre>
<p>Actually, a couple points of interest here.  We don't actually loop <em>infinitely</em> server side.  You may have noticed the logic for the while loop - if we've executed for more than 30 seconds we discontinue the loop and return nothing.  This nearly eliminates the possibility of substantial memory leaks.  Also, if we didn't put a cap on execution time we would need to print a "space" character and flush output buffers every iteration of the loop to keep PHP abreast to the status of this process/connection.  <strong>Without output being sent PHP cannot determine if the connection was lost via connection_status() or connection_aborted()</strong>.  As a result this could lead to a situation where there are an increasing number of "ghost" processes eating up server resources.  Not good!</p>
<p>That pretty much sums it up!  Not that difficult, right?</p>
<p>As always, questions/comments are welcome, hope this helps!</p>


<p>Related posts:<ol><li><a href='http://blog.perplexedlabs.com/2008/11/07/real-time-ajax-javascript-progress-bar/' rel='bookmark' title='Permanent Link: Real-time &#8220;AJAX&#8221; JavaScript Progress Bar'>Real-time &#8220;AJAX&#8221; JavaScript Progress Bar</a></li>
<li><a href='http://blog.perplexedlabs.com/2009/02/05/dynamic-javascript-script-insertion-for-embedding/' rel='bookmark' title='Permanent Link: PHP Dynamic JavaScript SCRIPT Insertion for Embedding'>PHP Dynamic JavaScript SCRIPT Insertion for Embedding</a></li>
<li><a href='http://blog.perplexedlabs.com/2008/02/12/php-fast-large-megabyte-data-transfer-between-sessions/' rel='bookmark' title='Permanent Link: PHP fast, large (megabyte), data transfer between sessions'>PHP fast, large (megabyte), data transfer between sessions</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.perplexedlabs.com/2009/05/04/php-jquery-ajax-javascript-long-polling/feed/</wfw:commentRss>
		<slash:comments>28</slash:comments>
		</item>
		<item>
		<title>Real-time &#8220;AJAX&#8221; JavaScript Progress Bar</title>
		<link>http://blog.perplexedlabs.com/2008/11/07/real-time-ajax-javascript-progress-bar/</link>
		<comments>http://blog.perplexedlabs.com/2008/11/07/real-time-ajax-javascript-progress-bar/#comments</comments>
		<pubDate>Fri, 07 Nov 2008 18:05:19 +0000</pubDate>
		<dc:creator>Matt</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[iframe]]></category>
		<category><![CDATA[long polling]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[progress bar]]></category>

		<guid isPermaLink="false">http://www.perplexedlabs.com/?p=43</guid>
		<description><![CDATA[I've been developing a stock market screener with some advanced functionality.  Some of the parameters a user might enter, because of their complexity or sheer volume of data required to calculate, would cause the screener to run for considerable amounts of time before returning results.  The opportunity to create a progress bar presented itself.  EVERY [...]


Related posts:<ol><li><a href='http://blog.perplexedlabs.com/2009/05/04/php-jquery-ajax-javascript-long-polling/' rel='bookmark' title='Permanent Link: PHP jQuery AJAX Javascript Long Polling'>PHP jQuery AJAX Javascript Long Polling</a></li>
<li><a href='http://blog.perplexedlabs.com/2009/02/05/dynamic-javascript-script-insertion-for-embedding/' rel='bookmark' title='Permanent Link: PHP Dynamic JavaScript SCRIPT Insertion for Embedding'>PHP Dynamic JavaScript SCRIPT Insertion for Embedding</a></li>
<li><a href='http://blog.perplexedlabs.com/2008/11/12/javascript-event-handler/' rel='bookmark' title='Permanent Link: JavaScript Event Handler'>JavaScript Event Handler</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>I've been developing a stock market screener with some advanced functionality.  Some of the parameters a user might enter, because of their complexity or sheer volume of data required to calculate, would cause the screener to run for considerable amounts of time before returning results.  The opportunity to create a progress bar presented itself.  <strong>EVERY DEVELOPER LOVES CREATING PROGRESS BARS</strong>.</p>
<p>The technique is fairly straightforward.  Here's an overview:</p>
<ol>
<li>Dynamically create a hidden IFRAME</li>
<li>Post to the IFRAME</li>
<li>Backend script outputs (in real-time) individual &lt;SCRIPT&gt; tags to the IFRAME.</li>
<li>Each &lt;SCRIPT&gt; tag contains a single function call to the parent of the IFRAME ( parent.myFuncName(); )</li>
<li>Parent JavaScript function updates the status bar with newly passed parameters</li>
</ol>
<p>A bit of background information.  The "processing" thead is initiated when a user hits the 'Screen' button.  It's an AJAX request to a PHP backend.  While executing, for each iteration, it sets status variables in memcache.  These are the variables that our "status" thread will be able to fetch.</p>
<p><span style="color: #c0c0c0;"><em><strong>Note: </strong>There are a variety of ways I can think of to use this same technique to achieve a real-time progress bar satisfying different situations.  For example, your "processing" thread can be your "status" thread if, for each iteration, it outputs the necessary calls we'll discuss below.  That would allow you to avoid the situation of delivering status data to a seperate thread via memcache (or some other technology).</em></span></p>
<p>I previously had been using an AJAX long-polling technique to achieve this.  If you're not familiar with AJAX long-polling it's essentially when you make a subsequent AJAX request on completion of the prior request to achieve a simulated, continual, "stream" from a server.  The problem in using this technique for a progress bar is two-fold:</p>
<ol>
<li>Multiple, continual, repeated requests to a web server.</li>
<li>The data "stream" is pseudo real-time and is affected by variations in each request's latency.  Not very pretty.</li>
</ol>
<p>All examples below utilize the Prototype JavaScript library.</p>
<p><strong>Create the hidden IFRAME</strong></p>
<pre class="brush: jscript;">
// create status iframe
var statusFrame = new Element('iframe', { id: 'statusFrame', name: 'statusFrame' }).hide();
$$('body')[0].appendChild(statusFrame);
</pre>
<p><strong>Post to the IFRAME</strong></p>
<pre class="brush: jscript;">
// create status form
var statusForm = new Element('form', { action: '/stocks/screenstatus', method: 'post', target: 'statusFrame' });
$$('body')[0].appendChild(statusForm);

// post to iframe
statusForm.submit();
</pre>
<p><strong>Backend script snippet to output &lt;SCRIPT&gt; tags</strong></p>
<pre class="brush: php;">
public function screenstatus()
{
	while(1) {
		//status string
		$status = Mcache::get('status');

		// how many have been processed
		$c = Mcache::get('c');

		// how many results
		$rc = Mcache::get('rc');

		// total
		$t = Mcache::get('t');

		echo '&lt;script type=&quot;text/javascript&quot;&gt;parent.updateStatus(&quot;'.$status.'&quot;, '.(int)$c.', '.(int)$rc.', '.(int)$t.');&lt;/script&gt;'.&quot;\n&quot;;
		flush();

		if(($status === false) || ($status === 'canceled') || ($status === 'complete')) {
			break;
		}

		usleep(25000);
	}
}
</pre>
<p><strong>Parent JavaScript function to update progress bar</strong></p>
<p>I chose to use a div with a background color and a dynamically adjusted width as the visual element for my progress bar.  Initially the width is set to 0.  In each updateStatus() call the width is adjusted to the current % of the whole (which in my case is 675px, the final desired width of the progress bar).</p>
<p>To overlay text I have a 2nd div styled 'position: relative;' with negative 'top' and 'bottom-margin'.  This positions the textual div on top of the progress bar div.</p>
<pre class="brush: css;">
#statusProgressBar {
width: 0px;
height: 29px;
background: #f4f4f4;
}
#statusProgress {
position: relative;
top: -29px;
left: 0;
text-align: center;
width: 675px;
padding-top: 3px;
height: 26px;
margin-bottom: -29px;
color: #00a;
font-size: 10px;
}
</pre>
<pre class="brush: xml;">
&lt;div id=&quot;statusProgressBar&quot;&gt;&lt;/div&gt;
&lt;div id=&quot;statusProgress&quot;&gt;&lt;/div&gt;
</pre>
<pre class="brush: jscript;">
function updateStatus(status, c, rc, t)
{
	var statusHTML;
	var progressBarWidth;

	if(status == 'initializing') {
		$('statusProgressBar').setStyle({ width: '0px' });
		statusHTML = '&lt;span id=&quot;top&quot;&gt;Initializing...&lt;/span&gt;';
	} else if(status == 'canceled') {
		$('statusProgressBar').setStyle({ width: '0px' });
		statusHTML = '&lt;span id=&quot;top&quot;&gt;Canceled... '+number_format(c / t * 100, 2)+'% Complete&lt;/span&gt;';
	} else {
		if(t) {
			statusHTML = '&lt;span id=&quot;top&quot;&gt;'+rc+' result(s) ('+number_format((c ? (rc / c) : 0) * 100, 2)+'%)&lt;/span&gt;&lt;br/&gt;&lt;span id=&quot;bot&quot;&gt;'+c+' of '+t+' processed ('+number_format(c / t * 100, 2)+'%)&lt;/span&gt;';
		} else {
			statusHTML = '&lt;span id=&quot;top&quot;&gt;0 result(s)&lt;/span&gt;';
		}
		progressBarWidth = Math.floor(675 * (c / t));
		$('statusProgressBar').setStyle({ width: progressBarWidth+'px' });
	}

	$('statusProgress').update(statusHTML);
}
</pre>
<p>You'll notice that the updateStatus() function calls number_format().  It's functionally equivalent to PHP's number_format().  Here is the JavaScript code below:</p>
<pre class="brush: jscript;">
function number_format( number, decimals, dec_point, thousands_sep ) {
    // http://kevin.vanzonneveld.net
    // +   original by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)
    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +     bugfix by: Michael White (http://getsprink.com)
    // +     bugfix by: Benjamin Lupton
    // +     bugfix by: Allan Jensen (http://www.winternet.no)
    // +    revised by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)
    // +     bugfix by: Howard Yeend
    // *     example 1: number_format(1234.5678, 2, '.', '');
    // *     returns 1: 1234.57     

    var n = number, c = isNaN(decimals = Math.abs(decimals)) ? 2 : decimals;
    var d = dec_point == undefined ? &quot;.&quot; : dec_point;
    var t = thousands_sep == undefined ? &quot;,&quot; : thousands_sep, s = n &lt; 0 ? &quot;-&quot; : &quot;&quot;;
    var i = parseInt(n = Math.abs(+n || 0).toFixed(c)) + &quot;&quot;, j = (j = i.length) &gt; 3 ? j % 3 : 0;

    return s + (j ? i.substr(0, j) + t : &quot;&quot;) + i.substr(j).replace(/(\d{3})(?=\d)/g, &quot;$1&quot; + t) + (c ? d + Math.abs(n - i).toFixed(c).slice(2) : &quot;&quot;);
}
</pre>
<p>I hope you found some of this code useful.  I welcome comments and criticism!</p>


<p>Related posts:<ol><li><a href='http://blog.perplexedlabs.com/2009/05/04/php-jquery-ajax-javascript-long-polling/' rel='bookmark' title='Permanent Link: PHP jQuery AJAX Javascript Long Polling'>PHP jQuery AJAX Javascript Long Polling</a></li>
<li><a href='http://blog.perplexedlabs.com/2009/02/05/dynamic-javascript-script-insertion-for-embedding/' rel='bookmark' title='Permanent Link: PHP Dynamic JavaScript SCRIPT Insertion for Embedding'>PHP Dynamic JavaScript SCRIPT Insertion for Embedding</a></li>
<li><a href='http://blog.perplexedlabs.com/2008/11/12/javascript-event-handler/' rel='bookmark' title='Permanent Link: JavaScript Event Handler'>JavaScript Event Handler</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.perplexedlabs.com/2008/11/07/real-time-ajax-javascript-progress-bar/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
	</channel>
</rss>
