<?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>UseStrict Consulting &#187; Javascript</title>
	<atom:link href="http://usestrict.net/tag/javascript/feed/" rel="self" type="application/rss+xml" />
	<link>http://usestrict.net</link>
	<description>Professional IT Solutions &#38; Training</description>
	<lastBuildDate>Fri, 10 Feb 2012 12:01:05 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Safari shows a blank page</title>
		<link>http://usestrict.net/2011/03/safari-shows-a-blank-page/</link>
		<comments>http://usestrict.net/2011/03/safari-shows-a-blank-page/#comments</comments>
		<pubDate>Tue, 08 Mar 2011 21:23:55 +0000</pubDate>
		<dc:creator>vinny</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[all sorts]]></category>
		<category><![CDATA[background image]]></category>
		<category><![CDATA[blank page]]></category>
		<category><![CDATA[cache]]></category>
		<category><![CDATA[close]]></category>
		<category><![CDATA[complex solutions]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[end]]></category>
		<category><![CDATA[FireFox]]></category>
		<category><![CDATA[Googled]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[image]]></category>
		<category><![CDATA[Interface]]></category>
		<category><![CDATA[issue]]></category>
		<category><![CDATA[js]]></category>
		<category><![CDATA[lt]]></category>
		<category><![CDATA[none]]></category>
		<category><![CDATA[page]]></category>
		<category><![CDATA[Safari]]></category>
		<category><![CDATA[script tag]]></category>
		<category><![CDATA[script type]]></category>
		<category><![CDATA[something]]></category>
		<category><![CDATA[tag]]></category>
		<category><![CDATA[text]]></category>
		<category><![CDATA[text javascript]]></category>
		<category><![CDATA[trick]]></category>
		<category><![CDATA[type]]></category>
		<category><![CDATA[version]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://usestrict.net/?p=992</guid>
		<description><![CDATA[Safari shows a blank page, no content, due to missing comment close in JavaScript.]]></description>
			<content:encoded><![CDATA[<p>I just ran into something odd and found all sorts of complex solutions (none of which worked for me), so I decided to post this case.</p>
<p>I&#8217;m creating a new version of an interface at work and tested with FireFox during development. When I opened it in Safari, all I got was the background image. No content at all. I Googled and several people reported having the same problem and said that clearing the cache would do the trick. It did not.</p>
<p>In the end, the issue was a missing &#8216;&#8211;&gt;&#8217; inside a <code>script</code> tag.</p>
<pre class="brush:javascript">&lt;script type="text/javascript"&gt; &lt;!-- // open a comment for older browsers - is this actually required still??
/* lots of JS here */

// There should be a close comment (--&gt;)  here!
&lt;/script&gt;</pre>
<p>Safari, not finding the closing comment tag, simply considered all of the HTML to be commented out.</p>
<p>I hope this helps!</p>
<p>&nbsp;</p>
<h3>Book Suggestions:</h3>
<p>&nbsp;</p>
<div>
<script type="text/javascript">
    (function(){
        document.write('<script type="text/javascript" src="http://cb1.cronblocks.com//js/content.js?c=14&#038;t='+(Math.floor(new Date().getTime()/1000))+'&#038;s=client"><\/script>');
    })();
</script>
</div>
]]></content:encoded>
			<wfw:commentRss>http://usestrict.net/2011/03/safari-shows-a-blank-page/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Introduction to Ajax</title>
		<link>http://usestrict.net/2009/08/introduction-to-ajax/</link>
		<comments>http://usestrict.net/2009/08/introduction-to-ajax/#comments</comments>
		<pubDate>Mon, 24 Aug 2009 21:56:08 +0000</pubDate>
		<dc:creator>vinny</dc:creator>
				<category><![CDATA[Ajax]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Perl]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[how to]]></category>

		<guid isPermaLink="false">http://usestrict.net/?p=840</guid>
		<description><![CDATA[Introduction to Ajax, Ajax how-to]]></description>
			<content:encoded><![CDATA[<p>In this article, I provide an explanation of Ajax with a historical introduction. If you are eager to start seeing the code, please scroll down.</p>
<p>&nbsp;</p>
<h3>What’s Ajax?</h3>
<p>&nbsp;</p>
<p>Ajax stands for <em>Asynchronous Javascript And XML</em>. It’s a way to call back-end scripts asynchronously – that is, without impacting user experience/flow. Basically, you don&#8217;t even see the cursor become an hourglass or whatever other &#8220;waiting/processing&#8221; icon your system uses. It&#8217;s not a language, but a technique. As for back-end scripts, you can use whatever you feel more comfortable with: PHP, Perl, Java, JSP, Shell, C, etc. The way to choose which technology to use as back-end is not outside the scope of this article.</p>
<p>&nbsp;</p>
<h3>Historical approach for calling back-end apps</h3>
<p>&nbsp;</p>
<p>Throughout web-development history, the very first way used to achieve back-end processing followed by front-end display was to create a form and set the back-end script as the action to that form. Upon submission, the form fields would be sent to the back-end script as a series of special environment variables, which would then be handled by the programmed logic. The back-end output would be displayed on the screen (either the same page/frame or a different page/frame, depending on the target attribute of the form).</p>
<p>The catch 22 of this approach is that if you want to present another form after processing, that form must be produced by the back-end script, which leads to maintenance mayhem – to add or remove a field, you have to do so in both the original HTML and in the HTML of the back-end script.</p>
<p><span id="more-840"></span></p>
<p>&nbsp;</p>
<h3>Hidden IFRAMES and Javascript to the rescue</h3>
<p>&nbsp;</p>
<p>The natural evolution of the regular form submission was to avoid having to generate HTML from the back-end script. A technique that I eventually came up with (had never seen it before, but it was probably already out there) prior to adhering to Ajax was using a hidden IFRAME as target to a simple form containing an <em>action_cd</em> field and a <em>data</em> field. There would not be a regular submit button, but a set of input elements with <em>onclick</em> or <em>onchange</em> events and a regular (non-submit) button at the end. </p>
<p>In this approach, Javascript did all the work – when the user clicked the pseudo-submit button, an <em>onclick</em> event would read all the input fields and join them like a regular HTTP query (<code>field1=val1&#038;field2=val2</code>…). The <em>action_cd</em> value would be dynamically evaluated and the back-end script would receive the data string and action code and process it. Javascript would perform the submission when, say, a value of a drop-down field was selected, and the output would be a series of dynamically generated Javascript commands inside the IFRAME. Those commands would manipulate the user’s form (e.g. Auto-populate a &#8220;state&#8221; drop-down after selecting a &#8220;country&#8221; value). </p>
<p>Although this approach successfully handled the no-longer-need to submit and reload a form, it still had 2 main downsides: generating and maintaining Javascript code is not a simple task (especially due to having to escape quotes), and the whole procedure was still synchronous – you could see the hourglass, browser process bars, clicking sounds (IE), etc. It&#8217;s much better user experience, but still not the real deal, seamless/transparent back-end processing.</p>
<p>&nbsp;</p>
<h3>The XmlHttpRequest object</h3>
<p>&nbsp;</p>
<p>Javascript back-end calls are made possible thanks to the <em>XmlHttpRequest</em> object that most modern browsers now support. For IE 6 and older, it is done through an ActiveXObject. </p>
<p>&nbsp;</p>
<h3>Javascript code to initialize Ajax object</h3>
<p>&nbsp;</p>
<pre class="brush:javascript">

var xmlHttp; // global variable. It’s important for later on

function GetXmlHttpObject(){

      if (window.XMLHttpRequest){
        // code for IE7+, Firefox, Chrome, Opera, Safari
        return new XMLHttpRequest();
      }

      if (window.ActiveXObject){
        // code for IE6, IE5
        return new ActiveXObject("Microsoft.XMLHTTP");
      }
      return null;
}
</pre>
<p>It&#8217;s important to have a global variable in which to assign the XMLHttpRequest object, since this technique has its shortcomings when dealing with passing variables around. We&#8217;ll understand that better shortly. The function checks for the existence of <strong>window.XMLHttpRequest</strong> which is used in IE7 (finally, it complies to standards!), Firefox, and other non IE browsers, and checks for <strong>window.ActiveXObject</strong> existence for IE6 and 5. I’m not sure if this works on IE4 – it probably does not, but hopefully IE4 is already in extinction. If neither checks work, it returns null, which will be handled in the function calling the XMLHttpObject.</p>
<p>&nbsp;</p>
<h3>Making Synchronous Ajax calls (GET method)</h3>
<p>&nbsp;</p>
<p>Although the hype of Ajax is due to the &#8220;Asynchronosity&#8221; of the technique, it is also capable of making synchronous calls. Synchronous calls are important in cases where you don&#8217;t want to allow the user to do something while the back-end is checking a previous action, but also don&#8217;t want to have to submit the whole form.</p>
<pre class="brush:javascript">

function synch_call() {

      // initialize Ajax object
      var xmlHttp = GetXmlHttpObject(); 

      // Set the URL to your backend script with query vars
      var url = “/url/to/your/backend/script?with=var1&#038;and=var2”;

      // Synchronous call
      xmlHttp.open("GET",url,false); // "false" means asynchronous = false
      xmlHttp.send(null);

      // the code above does the back-end call. Now we handle the response
      // this function continues further down in the tutorial

}
</pre>
<p>Ajax calls can be done using GET or POST methods. I recommend GET methods for small queries, POST for large ones. There used to be a limit of 255 characters on URL fields – not sure if a) this is still true; b) this could apply to these Ajax techniques.</p>
<p>The call to the back-end is done by 2 commands: <strong>xmlHttp.open(Method,url,async)</strong>, and the <strong>xmlHttp.send(null)</strong> calls. For POST method, this is a little different, so we’ll stick to GET calls for the time being.</p>
<p>&nbsp;</p>
<h3>Handling back-end reply</h3>
<p>&nbsp;</p>
<p><em>Asynchronous Javascript And XML</em> isn&#8217;t the perfect name for Ajax. It should be more like Aja<strong>R</strong>, where R stands for Reply. The reason is because the reply can be either an XML structure or a plain text. We use <strong>xmlHttp.responseXML.documentElement</strong> if we’re handling XML, or a plain <strong>xmlHttp.responseText</strong> for plain text. Actually, we can use the latter for XML as well, especially when debugging the code (when you want to pop up the XML reply).</p>
<p>We use a try/catch block to capture any errors:</p>
<pre class="brush:javascript">
function synch_call() {

      // initialize Ajax object
      var xmlHttp = GetXmlHttpObject(); 

      // Set the URL to your backend script with query vars
      var url = “/url/to/your/backend/script?with=var1&#038;and=var2”;

      // Synchronous call

      xmlHttp.open("GET",url,false); // “false” means asynchronous = false
      xmlHttp.send(null);

      // the code above does the back-end call. Now we handle the response
      try {            

            alert("Ajax Response: n"+xmlHttp.responseText); // Just pop-up the reply
            return false;
      }
      catch(e) {
            alert(e); // if error, show it as a pop-up
            return false;
      }
}
</pre>
<p>&nbsp;</p>
<p>To handle the  reply as XML, you need to a) make sure your back-end script outputs an XML structure, and b), replace xmlHttp.reponseText for xmlHttp.responseXML.documentElement.</p>
<p>&nbsp;</p>
<pre class="brush:javascript">
// Just the try/catch block changed        

       try {
              data = xmlHttp.responseXML.documentElement;
        }
        catch(e) {
               alert(e);
               return false;
        }
</pre>
<p>The <code>data</code> variable now holds a DOM object of the XML structure. To access its elements, we use DOM functions. </p>
<p>Example XML structure:</p>
<pre class="brush:xml">
&lt;OUT&gt;
      &lt;STATUS&gt;Success&lt;/STATUS&gt;
      &lt;MSG type="some_type"&gt;This is a test message&lt;/MSG&gt;
&lt;/OUT&gt;
</pre>
<p>Accessing Example XML through DOM:</p>
<pre class="brush:javascript">

      // gets the Success text
      var msg_status = data.getElementsByTagName(‘STATUS’)[0].childNodes[0].nodeValue;

      // Assign MSG object to msg variable
      var msg = data.getElementsByTagName(‘MSG’)[0]; 

      // gets the attribute “type”
      var msg_type = msg.getAttribute(‘type’); 

      // gets the text inside the MSG node
      var msg_text = msg.childNodes[0].nodeValue;
</pre>
<p>&nbsp;</p>
<h3>Putting it all together</h3>
<p>&nbsp;</p>
<pre class="brush:javascript">
function synch_call() {

      // initialize Ajax object
      var xmlHttp = GetXmlHttpObject(); 

      // Set the URL to your backend script with query vars
      var url = “/url/to/your/backend/script?with=var1&#038;and=var2”; 

      // Synchronous call
      xmlHttp.open("GET",url,false); // "false" means asynchronous = false
      xmlHttp.send(null);

      // the code above does the back-end call. Now we handle the response

      try {
            data = xmlHttp.responseXML.documentElement;
       }
       catch(e) {
             alert(e);
             return false;
       }

      // gets the Success text
      var msg_status = data.getElementsByTagName(‘STATUS’)[0].childNodes[0].nodeValue; 

      // Assign MSG object to msg variable
      var msg = data.getElementsByTagName(‘MSG’)[0]; 

      // gets the attribute “type”
      var msg_type = msg.getAttribute(‘type’); 

      // gets the text inside the MSG node
      var msg_text = msg.childNodes[0].nodeValue;
      alert("Got the following backend reply: " + msg_status + "n" + msg + "n" + msg_type + "n" + msg_text);

      return true;
}
</pre>
<p>&nbsp;</p>
<h3>Making Asynchronous Ajax calls (GET method)</h3>
<p>&nbsp;</p>
<p>We saw on page 2 that what controls synchronicity of the Ajax call is the true/false value in the <code>open()</code> command. However, we also need changes in the way we handle the reply. We do that by setting <strong><em>onreadystatechange</em></strong> property on the xmlHttp object.</p>
<p> OnReadyStateChange should be a function that will check the <em><strong>readyState</strong></em> attribute of the xmlHttp object.</p>
<p>&nbsp;</p>
<h3>Understanding readyState</h3>
<p>&nbsp;</p>
<p>readyStates are the way Javascript controls what stage of the process the call is in. It ranges from 0 to 4, where 4 is the completed reply from the back-end script. We normally only care about readyState == 4. Here are the codes and meaning:</p>
<table>
<tr>
<td><strong>Value</strong></td>
<td><strong>State</strong></td>
</tr>
<tr>
<td>0</td>
<td>Uninitialized</td>
</tr>
<tr>
<td>1</td>
<td>Loading</td>
</tr>
<tr>
<td>2</td>
<td>Loaded</td>
</tr>
<tr>
<td>3</td>
<td>Interactive</td>
</tr>
<tr>
<td>4</td>
<td>Complete</td>
</tr>
</table>
<p>&nbsp;</p>
<h3>Setting onreadystatechange</h3>
<p>&nbsp;</p>
<p><code>onreadystatechange</code> can be assigned a anonymous <code>function() {  }</code> block, or a named function. Just be careful with function parameters – to this day, I have not been able to pass any parameters to the functions set to <code>onreadystatechange</code>. Hence the need for some global variables in play.</p>
<p>Let&#8217;s copy over our <code>sync_call()</code> function and make it <code>Async_call()</code></p>
<pre class="brush:javascript">
function Asynch_call() {

      // initialize Ajax object
      var xmlHttp = GetXmlHttpObject(); 

      // Set the URL to your backend script with query vars
      var url = “/url/to/your/backend/script?with=var1&#038;and=var2”;

      // onreadystatechange must be set BEFORE making the call

      // it takes the response handling code that we had in the sync_call() previously
      xmlHttp.onreadystatechange = function() {

            if (xmlHttp.readyState == 4) { // Complete

                  // Now we handle the response within the onreadystatechange
                  try {
                        data = xmlHttp.responseXML.documentElement;
                  }
                  catch(e) {
                        alert(e);
                        return false;
                  }

                  // gets the Success text
                  var msg_status = data.getElementsByTagName(‘STATUS’)[0].childNodes[0].nodeValue; 

                  // Assign MSG object to msg variable
                  var msg = data.getElementsByTagName(‘MSG’)[0]; 

                  // gets the attribute "type"
                  var msg_type = msg.getAttribute('type'); 

                  // gets the text inside the MSG node
                  var msg_text = msg.childNodes[0].nodeValue;

                  alert("Got the following backend reply: " + msg_status + "n" + msg + "n" + msg_type + "n" + msg_text);
                  return true;
            }

      }; // don’t forget the ';' at the end of the function() {} block!!

      // Asynchronous call
      xmlHttp.open("GET",url,true); // 'true' means asynchronous = true
      xmlHttp.send(null);
}
</pre>
<p>&nbsp;</p>
<p>As mentioned before, you can separate the anonymous function assignment into a named function. The good side of this is that your functions get more manageable, but the downside is that you might need global variables in order to share values between the main function and the <code>onreadystatechange,/code> function.</p>
<p>&nbsp;</p>
<pre class="brush:javascript">
function Asynch_call() {

      // initialize Ajax object
      var xmlHttp = GetXmlHttpObject(); 

      // Set the URL to your backend script with query vars
      var url = “/url/to/your/backend/script?with=var1&#038;and=var2”; 

      // onreadystatechange must be set BEFORE making the call

      // it takes the response handling code that we had in the sync_call previously
      xmlHttp.onreadystatechange = handlerfunction; // See separate function below    

      // Asynchronous call
      xmlHttp.open("GET",url,true); // “true” means asynchronous = true
      xmlHttp.send(null);
}

function handlerfunction() {

      if (xmlHttp.readyState == 4) { // Complete – must be global xmlHttp variable

            // Now we handle the response within the onreadystatechange
            try {
                  data = xmlHttp.responseXML.documentElement;
            }
            catch(e) {
                  alert(e);
                  return false;
            }

             // gets the Success text
            var msg_status = data.getElementsByTagName(‘STATUS’)[0].childNodes[0].nodeValue; 

            // Assign MSG object to msg variable
            var msg = data.getElementsByTagName(‘MSG’)[0]; 

            // gets the attribute “type”
            var msg_type = msg.getAttribute(‘type’); 

            // gets the text inside the MSG node
            var msg_text = msg.childNodes[0].nodeValue;

            alert("Got the following back-end reply: " + msg_status + "n" + msg + "n" + msg_type + "n" + msg_text);
            return true;

      }
}
</pre>
<p>&nbsp;</p>
<h3>Parsing forms to create the GET/POST strings</h3>
<p>&nbsp;</p>
<p>Since we are not submitting the form with the usual submit button, we have to handle building the queries ourselves. I came up with a function that mimics the way browsers handle function calls.</p>
<pre class="brush:javascript">
function build_post_string(frm) {

      var str;
      var poststr_array = [];

      if (!frm.id) {
            // assume it's a string. get the form object
            frm = document.getElementById(frm);
      }

      for (i=0;i&lt;frm.elements.length;i++){

            var elem = frm.elements[i];

            if (!elem.id) {
                  // skip any fields that don't have IDs
                  continue;
            }

            if (elem.type == 'radio' || elem.type == 'checkbox') {

                  // only grab radio buttons and checkboxes that are checked
                  if (!elem.checked) {
                        continue;
                  }

            }            

            // get select values
            if (elem.nodeName.match(/SELECT/i) &#038;&#038; elem.multiple) {

                  var sel_array = [];

                  for (var o=0;o&lt;elem.options.length;o++) {

                        if (elem.options[o].selected) {
                              sel_array[sel_array.length] = elem.id+"="+elem.options[o].value;
                        }

                  }

                  var sel_str = sel_array.join('&#038;');

                  // build key/value pairs for SELECTs
                  poststr_array[poststr_array.length] = sel_str;
            }
            else if (elem.nodeName.match(/SELECT/i)) {
                  poststr_array[poststr_array.length] = elem.id+'='+elem.options[elem.selectedIndex].value;
            }
            else {
                  // build key/value pairs for everything else
                  poststr_array[poststr_array.length] = elem.id+"="+elem.value;
            }

      }

      // build and return str
      str = poststr_array.join("&#038;");
      return str;
}
</pre>
<p>This function takes a given form by ID and iterates through all of its elements. It is important that all fields you want in the query have an ID attribute. Otherwise they will be skipped. <strong>The return from this function can be used for both GET and POST requests.</strong></p>
<p>&nbsp;</p>
<h3>Using POST method for Ajax calls</h3>
<p>&nbsp;</p>
<p>So far we saw that making GET calls is pretty straight-forward. POST calls are different in the way that they are not put in the HTTP Header, but rather in a separate packet. In order to do that, we need to set a few header variables:</p>
<pre class="brush:javascript">
function Asynch_call_with_post() {

      // initialize Ajax object
      var xmlHttp = GetXmlHttpObject(); 

      // Set the URL to your backend script with query vars
      var post_str = build_post_string(‘my_form’); 

      var url = “/url/to/your/backend/script?” + post_str;

      // onreadystatechange must be set BEFORE making the call
      // it takes the response handling code that we had in the sync_call previously
      xmlHttp.onreadystatechange = function() {

            if (xmlHttp.readyState == 4) { // Complete

                   // Now we handle the response within the onreadystatechange
                   try {
                         data = xmlHttp.responseXML.documentElement;
                    }
                    catch(e) {
                         alert(e);
                         return false;
                    }

                     // gets the Success text
                     var msg_status = data.getElementsByTagName(‘STATUS’)[0].childNodes[0].nodeValue; 

                      // Assign MSG object to msg variable
                     var msg = data.getElementsByTagName(‘MSG’)[0]; 

                     // gets the attribute “type”
                     var msg_type = msg.getAttribute(‘type’); 

                     // gets the text inside the MSG node
                     var msg_text = msg.childNodes[0].nodeValue;
                     alert("Got the following backend reply: " + msg_status + "n" + msg + "n" + msg_type + "n" + msg_text);
                     return true;
               }

        }; // don't forget the ';' at the end of the function() {} block

        // Asynchronous call
        xmlHttp.open('POST',url, true); // Replace "GET" with "POST"

        // Set headers
        xmlHttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
        xmlHttp.setRequestHeader("Content-length", url.length);
        xmlHttp.setRequestHeader("Connection", "close");

        // Send the packet. Note that it’s no longer null as parameter to send
        xmlHttp.send(url);
}
</pre>
<p>&nbsp;</p>
<h3>Showing/Hiding "Processing…" messages</h3>
<p>&nbsp;</p>
<p>Since Ajax in Asynchronous mode is 100% transparent to the user, it is necessary to handle our own messages asking the user to wait until processing finishes. The simplest way to do this is by using a <code>DIV</code> element with initial display property set as none, or visibility set as hidden (the difference is that <code>visibility="hidden"</code> makes the element still occupy its space in the page, whereas <code>display="none"</code> effectively removes the element from the page and the space that it occupied).</p>
<p>Typically, I include code to show the element in the Ajax function, and code to hide it again in the <em>onreadystatechange</em> function (where readyState == 4). </p>
<pre class="brush:javascript">
        document.getElementById(‘wait_image’).display = ‘block’;
        document.getElementById(‘wait_image’).display = ‘none’;
</pre>
<p>&nbsp;</p>
<h3>Third-Party AJAX Libraries</h3>
<p>&nbsp;</p>
<p>There are several Ajax in a box libraries out there, but I am not comfortable with using them for company applications. The reason being is that Ajax is very powerful and can very well make calls to the maintainer's website to steal/capture sensitive information.  </p>
<p>Google provides Java code that generates Ajax during build – that is a typical example of us not being able to control Ajax code generated. </p>
<p>&nbsp;</p>
<h3>Testing the back-end script</h3>
<p>&nbsp;</p>
<p>There are 2 simple ways of testing the back-end script. With PHP, you can access both GET and POST variables through the <code>$_REQUEST</code> array. Perl CGI doesn’t really care if it’s GET or POST. I don’t know how JSP can handle it. With this being said, I simply have the Ajax alert the URL variable and return false. I then copy the URL variable and paste it in another window to see the output.</p>
<p>I strongly recommend debugging with Firefox – it has a handy error console and also parses the output XML or complains if it’s not built right.</p>
<p>&nbsp;</p>
<h3>Keeping IE from crashing with the XMLs</h3>
<p>&nbsp;</p>
<p>I'm pretty sure that Microsoft IE developers have some satisfaction in making web developers go crazy. That's how I felt when I started working with XML and Ajax, and although my app was working fine in Firefox, it kept crashing bad in IE. After some googling, I found out that I needed to set some headers in order to keep IE from blowing up. I already had the <code>"Content-type: text/xml"</code> header in place, but it appears that IE needs some caching control and expiry headers as well.</p>
<p>This is what I use in PHP:</p>
<pre class="brush:php">
        header("Expires: Fri, 09 Jan 1981 05:00:00 GMT");
        header("Cache-Control: no-store, no-cache, must-revalidate");
        header("Cache-Control: post-check=0, pre-check=0", FALSE); // FALSE means add this Cache-Control line instead of replacing the previous one
        header("Pragma: no-cache");
        header("Content-type: text/xml");
</pre>
<p>In Perl, setting headers is simple: just <code>print</code> them before printing any content. When you're done printing all your headers, print an empty newline to indicate where the page content will go.</p>
<p>I hope you've enjoyed this tutorial. Feel free to paste comments regarding your experience and preferences.</p>
<p>&nbsp;</p>
<h3>Book Suggestions:</h3>
<p>&nbsp;</p>
<div>
<script type="text/javascript">
    (function(){
        document.write('<script type="text/javascript" src="http://cb1.cronblocks.com//js/content.js?c=14&#038;t='+(Math.floor(new Date().getTime()/1000))+'&#038;s=client"><\/script>');
    })();
</script><br />
</script>
</div>
]]></content:encoded>
			<wfw:commentRss>http://usestrict.net/2009/08/introduction-to-ajax/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ajax: Form fields into URL query string</title>
		<link>http://usestrict.net/2009/07/ajax-form-fields-into-url-query-string/</link>
		<comments>http://usestrict.net/2009/07/ajax-form-fields-into-url-query-string/#comments</comments>
		<pubDate>Fri, 31 Jul 2009 09:46:20 +0000</pubDate>
		<dc:creator>vinny</dc:creator>
				<category><![CDATA[Ajax]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Query string]]></category>
		<category><![CDATA[URL Query]]></category>

		<guid isPermaLink="false">http://usestrict.net/?p=818</guid>
		<description><![CDATA[Javascript code to parse form fields into URL query string. To be used with Ajax sites.]]></description>
			<content:encoded><![CDATA[<p>Here&#8217;s a quickie for you Ajax coders who need a function to parse your form fields into a URL query string. It handles input fields (text, hidden, whatever), radio and checkbox elements, and single/multiple select menus. Just make sure that all your form fields have IDs. <del>Multiple choice SELECTs get grouped by pipes (|).</del> <strong>Update:</strong>Modified multiple-choice SELECTs to work like real GETs.</p>
<pre class="brush:javascript">
function build_post_string(frm) {

	var poststr;
	var poststr_array = [];

	if (!frm.id) {
		// assume it's a string. get the form object
		frm = document.getElementById(frm);
	}

	for (i=0;i&lt;frm.elements.length;i++){

		var elem = frm.elements[i];

		if (!elem.id) {
			// skip any fields that don't have IDs
			continue;
		}

		if (elem.type == 'radio' || elem.type == 'checkbox') {
			// only grab radio buttons and checkboxes that are checked
			if (!elem.checked) {
				continue;
			}
		}

		// get select values
		if (elem.nodeName.match(/SELECT/i) &#038;&#038; elem.multiple) {
			//var sel = elem;
			var sel_array = new Array();

			for (var o=0;o&lt;elem.options.length;o++) {

				if (elem.options[o].selected) {
					sel_array[sel_array.length] = elem.id+"="+elem.options[o].value;
				}
			}

			var sel_str = sel_array.join('&#038;');

			// build key/value pairs for SELECTs
			poststr_array[poststr_array.length] = sel_str;
		}
		else if (elem.nodeName.match(/SELECT/i)) {
			poststr_array[poststr_array.length] = elem.id+'='+elem.options[elem.selectedIndex].value;
		}
		else {
			// build key/value pairs for everything else
			poststr_array[poststr_array.length] = elem.id+"="+elem.value;
		}

	}

	// build poststr
	poststr = poststr_array.join("&#038;");
	return poststr;

}
</pre>
<p>&nbsp;</p>
<h3>Book Suggestions:</h3>
<p>&nbsp;</p>
<div>
<script type="text/javascript">
    (function(){
        document.write('<script type="text/javascript" src="http://cb1.cronblocks.com//js/content.js?c=14&#038;t='+(Math.floor(new Date().getTime()/1000))+'&#038;s=client"><\/script>');
    })();
</script>
</div>
]]></content:encoded>
			<wfw:commentRss>http://usestrict.net/2009/07/ajax-form-fields-into-url-query-string/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Perl Crash Course: Introduction to Perl</title>
		<link>http://usestrict.net/2008/10/perl-crash-course-introduction-to-perl/</link>
		<comments>http://usestrict.net/2008/10/perl-crash-course-introduction-to-perl/#comments</comments>
		<pubDate>Sun, 05 Oct 2008 20:16:04 +0000</pubDate>
		<dc:creator>vinny</dc:creator>
				<category><![CDATA[Perl]]></category>
		<category><![CDATA[awk]]></category>
		<category><![CDATA[CGI]]></category>
		<category><![CDATA[cgis]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[combination]]></category>
		<category><![CDATA[common gateway interface]]></category>
		<category><![CDATA[course introduction]]></category>
		<category><![CDATA[Crash]]></category>
		<category><![CDATA[crash course]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[dynamic data]]></category>
		<category><![CDATA[early days of the internet]]></category>
		<category><![CDATA[editor]]></category>
		<category><![CDATA[Extraction]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[html javascript]]></category>
		<category><![CDATA[Interface]]></category>
		<category><![CDATA[interpreter]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[javascript css]]></category>
		<category><![CDATA[mod]]></category>
		<category><![CDATA[perl archive]]></category>
		<category><![CDATA[Perl Course Howto]]></category>
		<category><![CDATA[perl execution]]></category>
		<category><![CDATA[perl interpreter]]></category>
		<category><![CDATA[perl scripts]]></category>
		<category><![CDATA[programmer]]></category>
		<category><![CDATA[report language]]></category>
		<category><![CDATA[Rubbish]]></category>
		<category><![CDATA[script]]></category>
		<category><![CDATA[script perl]]></category>
		<category><![CDATA[shell]]></category>
		<category><![CDATA[shell scripts]]></category>
		<category><![CDATA[soun]]></category>
		<category><![CDATA[template toolkit]]></category>
		<category><![CDATA[text]]></category>
		<category><![CDATA[text manipulation]]></category>
		<category><![CDATA[unix tools]]></category>
		<category><![CDATA[VERY]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[web modules]]></category>

		<guid isPermaLink="false">http://usestrict.wordpress.com/?p=74</guid>
		<description><![CDATA[Perl &#8211; the Practical Extraction and Report Language (or Pathologically Eclectict Rubbish Lister) was created by Larry Wall in the late 1980&#8242;s. It started as a combination of Larry&#8217;s favorite Unix tools such as sed, awk, and shell, and grew to be the best language for text manipulation. I started learning Perl back in 1998 [...]]]></description>
			<content:encoded><![CDATA[<p>Perl &#8211; the Practical Extraction and Report Language (or Pathologically Eclectict Rubbish Lister) was created by <a href="http://www.wall.org/~larry/" target="_blank">Larry Wall </a>in the late 1980&#8242;s. It started as a combination of Larry&#8217;s favorite Unix tools such as sed, awk, and shell, and grew to be the best language for text manipulation.</p>
<p>I started learning Perl back in 1998 by myself. What made it possible for me to do that was that Perl scripts, like shell scripts, are not compiled binaries. You can open it with a (good) text editor and see exactly what the programmer did to make it work. Same thing with HTML, JavaScript, CSS, and all other democratic languages around. No reverse-engineering needed.</p>
<p>Speaking of Web technologies, Perl was considered SO GOOD with manipulating texts, that it was once the #1 language for CGIs. For those of you who don&#8217;t know, CGI stands for Common Gateway Interface and it was the way websites could show dynamic data back in the early days of the Internet. In fact, Perl was so popular with CGIs, that many people didn&#8217;t (and still don&#8217;t) know it could do anything else. On the contrary, although Perl has excellent Web modules such as <a href="http://search.cpan.org/~mramberg/Catalyst-Runtime-5.7014/lib/Catalyst.pm" target="_blank">Catalyst</a>, <a href="http://search.cpan.org/~abw/Template-Toolkit-2.20/lib/Template/Toolkit.pod" target="_blank">Template::Toolkit</a>, <a href="http://search.cpan.org/~drolsky/HTML-Mason-1.45/lib/HTML/Mason.pm">HTML::Mason,</a> and so many others, it&#8217;s not my first choice for Web development (for reasons that are not in the scope of this course). However, I can&#8217;t live without it for anything else.</p>
<p><em><span style="text-decoration:underline;">Perl is portable:</span> </em>you can write one script and run it in just about any Operating System that has a Perl interpreter installed. And you can find Perl interpreters for practically all the OS&#8217;s around.</p>
<p><em><span style="text-decoration:underline;">Perl is fast:</span> </em>although the Perl interpreter needs to read, parse, compile, and run the script on every execution, it&#8217;s still VERY fast by any standard.</p>
<p><em><span style="text-decoration:underline;">Perl gets faster:</span> </em>there are ways to bypass the first 3 stages of the Perl execution, either by using <a href="http://perl.apache.org/" target="_blank">mod_perl </a>for Apache, or by using the <a href="http://search.cpan.org/~smueller/PAR-1.002/lib/PAR.pm" target="_blank">Perl Archive Toolkit</a>, which gives you a precompiled (albeit potentially large) binary of your script.</p>
<p><em><span style="text-decoration:underline;">Perl is Object Oriented:</span> </em>ok, that didn&#8217;t sound right. Perl <span style="text-decoration:underline;"><em>can</em></span> be used from either a procedural or an object oriented scope. In real world applications, you&#8217;re likely to mix both cases to suit your needs.</p>
<p><em><span style="text-decoration:underline;">Perl is extremely high level:</span> </em>this means that given the statements in your script, you are likely to be able to read them as you would plain English. This was done on purpose, of course, given the fact that Larry Wall is a linguist.</p>
<p><span style="text-decoration:underline;"><em>Perl is free:</em></span> you can download it with no cost from several distributors, install, and use for any purpose &#8211; commercial or otherwise and not have to worry about licensing.</p>
<p><em><span style="text-decoration:underline;">Perl is free form:</span></em> you can write the code practically in any way you like and get away with it. This is great as long as you keep in mind that writing good code also means writing clean code. You can seriously hurt your foot if you&#8217;re not careful. Obfuscation is only fun when it&#8217;s intentional.</p>
<p>I can go on forever telling you all that Perl can do, especially if I decide to talk about CPAN, the Comprehensive Perl Archive Network &#8211; a website with over 10,000 modules for everything you can think of, from <a title="Math Modules" href="http://search.cpan.org/search?m=all&amp;q=math" target="_blank">complex math</a> and <a title="Graphic Manipulation in Perl" href="http://search.cpan.org/search?query=GD&amp;mode=all" target="_blank">graphic manipulation</a> to fooling around with the <a href="http://search.cpan.org/search?q=klingon;s=1">Klingon language</a>. You can even use the <a href="http://search.cpan.org/~srezic/Tk-804.028/pod/UserGuide.pod" target="_blank">Perl/Tk</a> to create graphical user interfaces.</p>
<p>If what I said so far was enough to interest you to learn Perl, then keep on reading. There&#8217;s something to the language that feels almost addictive, if you don&#8217;t let all the non-initiated folks make up your mind against it&#8230;</p>
<p style="text-align:right;"><a href="http://usestrict.net/2008/10/05/perl-crash-course/">« TOC</a> | <a href="http://usestrict.net/2008/10/05/perl-crash-course-getting-it-installed-on">Getting it installed on&#8230; »</a></p>
]]></content:encoded>
			<wfw:commentRss>http://usestrict.net/2008/10/perl-crash-course-introduction-to-perl/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

