<?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>Devin R. Olsen Web Developer &#187; Ajax Tutorials</title>
	<atom:link href="http://www.devinrolsen.com/category/ajax-tutorials/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.devinrolsen.com</link>
	<description>From Developer to Developer Information and Sharing</description>
	<lastBuildDate>Fri, 20 Aug 2010 05:08:59 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>CMS Instant Edit (3 of 3)</title>
		<link>http://www.devinrolsen.com/cms-instant-edit-tutorial-3/</link>
		<comments>http://www.devinrolsen.com/cms-instant-edit-tutorial-3/#comments</comments>
		<pubDate>Fri, 11 Sep 2009 06:56:08 +0000</pubDate>
		<dc:creator>Devin R. Olsen</dc:creator>
				<category><![CDATA[Ajax Tutorials]]></category>
		<category><![CDATA[PHP Tutorials]]></category>
		<category><![CDATA[ajax instant edit]]></category>
		<category><![CDATA[ajax php instant edit]]></category>
		<category><![CDATA[cms]]></category>
		<category><![CDATA[cms instant edit]]></category>
		<guid isPermaLink="false">http://devinrolsen.com/?p=201</guid>
		<description><![CDATA[This is our third installment of the CMS instant edit script. Here we will be talking about our last two languages &#8220;PHP &#38; MySQL&#8221;. PHP is a server side language that preform&#8217;s more complex and secure server side functions such as creating and editing files on the server or storing and retrieving sensitive data from [...]]]></description>
			<content:encoded><![CDATA[<p>This is our third installment of the CMS instant edit script. Here we will be talking about our last two languages &#8220;PHP &amp; MySQL&#8221;. PHP is a server side language that preform&#8217;s more complex and secure server side functions such as creating and editing files on the server or storing and retrieving sensitive data from a database. MySQL is a well uses and popular database that works almost hand and in hand with PHP kind of a match maid in heaven sort of thing.</p>
<p>If you are not familiar with the two server side operations than I suggest you read more about the then at <a href="http://www.tizag.com/phpT/">Tizag.com</a> before trying to fully understand this last tutorial.</p>
<p><strong>NOTE</strong>: This tutorial assumes you will already have a database and table setup in your MySQL. Here is the SQL to create this table.</p>
<pre>CREATE TABLE `cms_demo` (
  `id` tinyint(255) NOT NULL default '0',
  `content` longtext NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;</pre>
<p>Our last goals for our instant edit is to save and retrive information to and from our MySQL database. To do this we must speak to the database with the means of a server side language. PHP is a server side language and in fact speaks most clearly to MySQL than other server side languages such as .asp or aspx</p>
<p>In our last tutorial we created two AJAX functions that open and save information from our database via secure HTTP requests. These two functions both called upon two different server side files. Before we even get into creating these two files we must first talk about how a server side language begins to even speak to a database.</p>
<p>Before we can speak to the database we must first connect to it. The most secure way to do this is to have a third party file that connects to MySQL and get included into both &#8220;openFromDatabase.php&#8221; and &#8220;saveToDatabase.php&#8221;</p>
<p>Make a blank PHP document like so:</p>
<pre>&lt;?php
?&gt;</pre>
<p>Now lets add the portion that connects to our MySQL. Make your document look like this:</p>
<pre>&lt;?php
$dbhost = "MYSQLHOST";
$dbname = "DATABASE NAME";
$dbuser = "DATABASE USER";
$dbpass = "DATABASE PASSWORD";
//Connect to database
mysql_connect( $dbhost, $dbuser, $dbpass)or die("Could not connect: ".mysql_error());
mysql_select_db($dbname) or die("Could Not Select Database Name".mysql_error());
?&gt;</pre>
<p>Ok here we have 4 variables that we use to connect to MySQL.</p>
<ul>
<li><strong>$dbhost</strong> = your web server host name or IP address</li>
<li><strong>$dbname</strong> = MySQL is made up of databases that contain an infinite amount of tables here we declare what the name of the database we want to connect is</li>
<li><strong>$dbuser</strong> = MySQL is typically setup with a admin username in place here you must provide that admin username such as &#8220;root&#8221;</li>
<li><strong>$dbpass</strong> = Lastly MySQL must be provided a password to go along with the admin username in order to fully connect</li>
</ul>
<p>Great the next few lines uses php&#8217;s mysql commands and use our variables to connect to your MySQL database. Once you have finished setting up this connection script save it out as a file called &#8220;db_cnt.php&#8221;.</p>
<p>Now that we have our connection script we can start to write our saveToDatabase.php and openFromDatabase.php files. Start a new blank PHP and add the following:</p>
<pre>&lt;?php
include("db_cnt.php");
$result = mysql_query("SELECT * FROM cms_demo")
or die(mysql_error());
while($row = mysql_fetch_array( $result ))
{
    $responseText = $row['content'];
    echo $responseText;
}
?&gt;</pre>
<p>Ok here we use the PHP function called &#8220;include&#8221; to include our &#8220;db_cnt.php&#8221; and open a connection to our database. Then we create a new variable called &#8220;$results&#8221; and equal it to a mysql_query to our database table called &#8220;cms_demo&#8221;. This portion here &#8220;SELECT * FROM cms_demo&#8221; is stating to grab all records from cms_demo data table.</p>
<p>After we have our query &#8220;$result&#8221; setup we are going to create a while loop. The while loop is similar to JavaScript&#8217;s for loop but much more sophisticated. Here we use the while loop to setup a variable called $row that performs a php function called &#8220;mysql_fetch_array&#8221;.</p>
<p>This &#8220;mysql_fetch_array&#8221; function will use our &#8220;$result&#8221; query to loop through our data table and locate a particular $row or rather &#8220;column&#8221;. To do this we setup a third variable called $responseText and a forth variable called $row. Our &#8220;$row&#8221; variable points to our data table column by name &#8220;content&#8221; then sets it to our &#8220;$responseText&#8221; variable.</p>
<p>Once we have located and captured our data tables column we then &#8220;echo&#8221; it out. Echo is much like JavaScript&#8217;s &#8220;documnet.write&#8221; but only on the server side of things making it 100% cross browser compatible.</p>
<p>Save this file as &#8220;openFromDatabase.php&#8221; and start a new blank PHP document that looks like the following:</p>
<pre>&lt;?php
include("db_cnt.php");
$currentEdit = mysql_real_escape_string($_POST['currentEdit']);
mysql_query("UPDATE cms_demo SET content='$currentEdit' WHERE id ='0'")
or die(mysql_error());
?&gt;</pre>
<p>Here we again add the use the PHP function &#8220;include&#8221; to connect to our database. Next we setup a variable called &#8220;$currentEdit&#8221; and we point it to another PHP function called &#8220;mysql_real_escape_string&#8221;. The &#8220;mysql_real_escape_string&#8221; basically runs the data being sent to our database through a stripping process that removes any harmful characters one might use to attack our database for what ever reason. To run our data through this stripping process we have to include our data being sent from our AJAX post function. We use the &#8220;$_POST['currentEdit']&#8221; to capture the posted data from our AJAX function &#8220;currentEdit&#8221;.</p>
<p>Next we call another &#8220;mysql_query&#8221; but this time we are going to use an &#8220;UPDATE&#8221; to update our data table with the most current edits the user preform&#8217;s. To do this we call the &#8220;UPDATE&#8221; function then point to our data table &#8220;cms_demo&#8221; then use the &#8220;SET&#8221; function to insert our stripped data into the column named &#8220;content&#8221;. For this tutorial and data table we will only have one record in our database that holds our data so we use a &#8220;WHERE&#8221; function to narrow down our location to an id of 0. If you have multiple records in your data table you can change this &#8220;WHERE&#8221; id number to what ever row you would in fact like to instant edit.</p>
<p>Save this file out as &#8220;save2database.php&#8221; and guess what folks you are done!</p>
<p>From DOM scripting to AJAX an JavaScript and MySQL an PHP you have now created a fully working instant edit application.</p>
<p>I really hope this gave my readers some useful insight into the world of internet application developing as well as some great inspiration to run with.</p>
<p><a title="Ajax Instant Edit Script" href="http://devinrolsen.com/wp-content/themes/typebased/demos/ajax/instant-edit/CMS-Instant-Edit.zip">Here is a complete version of the Ajax instant edit</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.devinrolsen.com/cms-instant-edit-tutorial-3/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>CMS Instant Edit (2 of 3)</title>
		<link>http://www.devinrolsen.com/cms-instant-edit-tutorial-2/</link>
		<comments>http://www.devinrolsen.com/cms-instant-edit-tutorial-2/#comments</comments>
		<pubDate>Fri, 11 Sep 2009 06:49:31 +0000</pubDate>
		<dc:creator>Devin R. Olsen</dc:creator>
				<category><![CDATA[Ajax Tutorials]]></category>
		<category><![CDATA[PHP Tutorials]]></category>
		<category><![CDATA[ajax instant edit]]></category>
		<category><![CDATA[ajax php instant edit]]></category>
		<category><![CDATA[cms]]></category>
		<category><![CDATA[cms instant edit]]></category>
		<category><![CDATA[instant edit]]></category>
		<guid isPermaLink="false">http://devinrolsen.com/?p=196</guid>
		<description><![CDATA[This is the second edition to our instant edit tutorial. Today I will be expanding our instant edit to work with Ajax to save and retrieve information from our server side language PHP and a MySQL database.
We left off with a our functions fully created to perform our instant edit via client site DOM scripting. [...]]]></description>
			<content:encoded><![CDATA[<p>This is the second edition to our instant edit tutorial. Today I will be expanding our instant edit to work with Ajax to save and retrieve information from our server side language PHP and a MySQL database.</p>
<p>We left off with a our functions fully created to perform our instant edit via client site DOM scripting. Now we must add functions that will send and retrieve data from our database but doing so with out any page refreshing and at the right spots in our already performing instant edit script.</p>
<p>First lets talk a little about Ajax and what it is. Ajax is a form of performing server side functions through a client side request so we can now talk,send and retrieve information  from our server. Before AJAX, client side requests and server side request were two different worlds that required a page to be sent off to another page that would the preform our server side actions and carry variables out and back to our original page.</p>
<p>With Ajax in our corner we can preform server side actions or requests through one single page and do so with client side requests resulting in the spawn of internet application developing. Ajax requires some routines that use JavaScript to preform our post and get methods to our server side request. I personally use the well put together Ajax library from <a href="http://www.dynamicdrive.com">dynamicdrive.com</a> that <a href="http://devinrolsen.com/wp-content/themes/typebased/scripts/ajax/downloaded/routines.js">can be downloaded here</a>.</p>
<p>We will not go into what makes up these routines as there are many tutorials out on the net on how to build ajax get and post routines instead lets talk about how we can use these routines to our advantage. In our working document we have to link to our Ajax routines.js file you just downloaded by adding the following to your header tags.</p>
<pre>&lt;script type="text/javascript" src="routines.js" &gt;&lt;/script&gt;</pre>
<p>This brings our required routines to our document so we may build with them to create our needs. Ok so this is a good time to think about what our need are going to be with our instant edit. We need to have a location in our database that stores and retrieves our instant edit data. Then when ever the page loads either it being a first visit or refresh we can pull this data from out database to begin edits. After a user has finished editing a paragraph we want to send the edits out to our server and into our database to save the edits permanently.</p>
<p>Let start by creating our function that saves our data to our database. Add the following save function to you instant edit script:</p>
<pre>function saveDoc()
{
	function createpoststring()
	{
		var currentEdit = document.getElementById('pallet').innerHTML;
		var poststr = "currentEdit=" + encodeURI(currentEdit);
		return poststr;
	}
		createpoststring();
		var poststr = createpoststring(); //Get contents to post and create query string first
		ajaxpack.postAjaxRequest("save2database.php", poststr, createpoststring, "html");
}</pre>
<p>This is our saveDoc() function that creates a poststring or rather a secure variable string over to our server side functions via HTTP request. With in this function we have a second function named &#8220;createpoststring()&#8221; and in this function we have two variables.</p>
<p>Our first variable is named &#8220;currentEdit&#8221; and it points to our div container &#8220;pallet&#8221; and grabs its innerHTML. Our second string is the &#8220;poststr&#8221; and its creates our HTTP string by first making up the variable name our server side function will receive &#8220;currentEdit=&#8221; and attaches our innerHTML as a secure encoded URI.</p>
<p>Last we return the posts our of the function upon it ever being performed.</p>
<p>After our &#8220;createpoststring()&#8221; function we must run it by calling to it by means of &#8220;createpoststring();&#8221; so we may gather our encoded string and begin to process it. Our last variable is named poststr and it takes our function &#8220;createpoststring&#8221; and equals its self to its returned encoded string.</p>
<p>The last line of code uses our AJAX routines &#8220;ajaxpack.postAjaxRequest(&#8221;",,&#8221;",);&#8221; to being sending our encode string over to our server side function. When using our AJAX routines we must use a set of commands if you will, that first point to the location of our server side function or rather server side file &#8220;save2database.php&#8221; then use the &#8220;poststr&#8221; variable to attach our encoded string to our AJAX post request. We will then call to our createpoststring to verify that our encoded version is true and ready to process. The last command is prerequisite of &#8220;html&#8221; stating that we wish to only send html type of data.</p>
<p>Great lets move onto building our openDoc function.</p>
<pre>function openDoc()
{
	ajaxpack.getAjaxRequest("openFromDatabase.php", "", processOpenFile, "html");
}
    //LOAD FILE FUNCTION
    function processOpenFile()
    {
        var myajax = ajaxpack.ajaxobj;
        var myfiletype = ajaxpack.filetype;
        if (myajax.readyState == 4)//if request of file completed
        {
            if (myajax.status == 200 || window.location.href.indexOf("http") == -1)
            {
                if (myfiletype == "html")
                {
                    document.getElementById("pallet").innerHTML = myajax.responseText;
                    setParagrahEvent();
                }
                else
                {
                    alert(myajax.responseXML);
                }
            }
        }
    }</pre>
<p>Ok here we have two functions that I like to think of as one. The first function is openDoc and it uses getAjaxRequest routine to call to a server side function or rather file &#8220;openFromDatabase.php&#8221; to process via server side and send it back down to client side.</p>
<p>To process this information back to our client side we must call to the function that will process our server side data by calling to our  &#8220;processOpenFile&#8221; function.</p>
<p>Our &#8220;processOpenFile()&#8221; function is also calling and using our AJAX routines to setup an object that will represent our returning data and process it through a 4 step readyState process. Once we have received our readyState to be equal to our 4 and final step we bring our processed data back down to client side via a HTTP request</p>
<p>Once our data has been properly requested and processed we run it through as simple condition that states if its anything else then &#8220;html&#8221; or rather text then respond with an error. If indeed our requested data is that of html and or text we can place the returned data where ever we wish.</p>
<p>Our goal with the &#8220;openDoc()&#8221; function is to retrieve date from our server on every open of this instant edit script in order to populate our edit area with the most updated paragraph edits. So in order to perform such a thing we want to call a loss request to our openDoc() by adding &#8220;openDoc();&#8221; to our script.</p>
<p>Here is our complete AJAX open and save functions</p>
<pre>openDoc();
function saveDoc()
{
	function createpoststring()
	{
		var currentEdit = document.getElementById('pallet').innerHTML;
		var poststr = "currentEdit=" + encodeURI(currentEdit);
		return poststr;
	}
		createpoststring();
		var poststr = createpoststring(); //Get contents to post and create query string first
		ajaxpack.postAjaxRequest("save2database.php", poststr, createpoststring, "html");
}
function openDoc()
{
	ajaxpack.getAjaxRequest("openFromDatabase.php", "", processOpenFile, "html");
}
//LOAD FILE FUNCTION
function processOpenFile()
{
    var myajax = ajaxpack.ajaxobj;
    var myfiletype = ajaxpack.filetype;
    if (myajax.readyState == 4)//if request of file completed
    {
        if (myajax.status == 200 || window.location.href.indexOf("http") == -1)
        {
            if (myfiletype == "html")
            {
                document.getElementById("pallet").innerHTML = myajax.responseText;
                setParagrahEvent();
            }
            else
            {
                alert(myajax.responseXML);
            }
        }
    }
}</pre>
<p>Great now lets quickly think about how we want to begin to use these two functions. Well we know what we want to preform a openDoc on every loading of our instant edit but what about our saveDoc function. The saveDoc function would most likely want to be done after ever edit is complete even if its to open another edit from a previous edit.</p>
<p>Lets go back to our working instant edit and incorporate our &#8220;saveDoc()&#8221; function. In your removeTextarea() function we want to add our saveDoc() function so make it look like the follow:</p>
<pre>function removeTextarea()
{
    var textarea = document.getElementById('currentEdit');
    var textareaInners = textarea.value;
    if(textareaInners == "")
    {
        alert('Sorry but in this demo you must have at least one character in your paragraph edit!');
        var makeNewP = document.createElement('p');
        var getParent = textarea.parentNode;
        var sibling = textarea.nextSibling;
        var textareaInners = "WE NEED TO HAVE SOME TEXT HERE TO EDIT AND SAVE TO OUR DATABASE!!";
        getParent.insertBefore(makeNewP,sibling);
        makeNewP.innerHTML = textareaInners;
        getParent.removeChild(textarea);
        setParagrahEvent();
        saveDoc();
    }
    else
    {
        var makeNewP = document.createElement('p');
        var getParent = textarea.parentNode;
        var sibling = textarea.nextSibling;
        getParent.insertBefore(makeNewP,sibling);
        makeNewP.innerHTML = textareaInners;
        getParent.removeChild(textarea);
        setParagrahEvent();
        saveDoc();
    }
}</pre>
<p>Ok so remember that upon every completed edit either it be from one edit to another we always close up or &#8220;remove&#8221; our working textarea so what better place to have our saveDoc() function to capture all completed edits then after our working textarea has been removed.</p>
<p>So you may now have tried to run the additions to our instant edit script and may have noticed that nothing is being saved out or retried from our database. This is because we have not created our server side functions or files &#8220;save2database.php&#8221; and &#8220;openFromDatabase.php&#8221;. Is the wizard behind the curtains to our completed instant edit script and begins our journey into our last section for this tutorial:</p>
<h3><a href="http://devinrolsen.com/cms-instant-edit-tutorial-3/">CMS Instant Edit Part 3.</a></h3>
]]></content:encoded>
			<wfw:commentRss>http://www.devinrolsen.com/cms-instant-edit-tutorial-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CMS Instant Edit (1 of 3)</title>
		<link>http://www.devinrolsen.com/cms-instant-edit-tutorial/</link>
		<comments>http://www.devinrolsen.com/cms-instant-edit-tutorial/#comments</comments>
		<pubDate>Fri, 11 Sep 2009 06:22:13 +0000</pubDate>
		<dc:creator>Devin R. Olsen</dc:creator>
				<category><![CDATA[Ajax Tutorials]]></category>
		<category><![CDATA[PHP Tutorials]]></category>
		<category><![CDATA[ajax instant edit]]></category>
		<category><![CDATA[ajax php instant edit]]></category>
		<category><![CDATA[cms]]></category>
		<category><![CDATA[cms instant edit]]></category>
		<guid isPermaLink="false">http://devinrolsen.com/?p=184</guid>
		<description><![CDATA[
Let’s get into some real in depth work today. What better way to demonstrate a little of every language one might use to create internet applications than with the simple instant edit. Instant edit is more times than not is used in content management systems (CMS) to give quick edits to a site owner without [...]]]></description>
			<content:encoded><![CDATA[<p><script src="http://devinrolsen.com/wp-content/themes/typebased/scripts/ajax/instantEditDemo.js" type="text/javascript"></script></p>
<p>Let’s get into some real in depth work today. What better way to demonstrate a little of every language one might use to create internet applications than with the simple instant edit. Instant edit is more times than not is used in content management systems (CMS) to give quick edits to a site owner without having to play with code what so ever. The instant edit might seem simple at first but is a delicate build of<strong> DOM JavaScript, Ajax, PHP and MySQL</strong>. What better way to break down this topic but into these four languages.</p>
<h3>Here is what we are going to build today.</h3>
<div id="pallet">
<h3>Double click any of the following paragraphs to edit them.</h3>
<p>Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.</p>
<p>Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.</p>
<p>Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.</p>
<p>Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.</p></div>
<h3>Let’s start things off with DOM JavaScript.</h3>
<p>Ultimately we the developers have to think about the criteria’s our instant edit is going to have to meet our simple requirements are as follows.</p>
<ul>
<li>Trigger even to start text edit.</li>
<li>Trigger event to end text edit.</li>
<li>Saves to database without page refreshing.</li>
</ul>
<p>DOM is here to help us take care of these first two requirements. DOM is a client side language that give the flexibility to edit, add, delete, and manipulate document elements. So with DOM we will create both our trigger events to start and edit our instant text edit.</p>
<p>In of these first two requirements we face even more requirements and they are as follows:</p>
<ul>
<li>Trigger start event must take place when double clicking a specifically specified pages element.</li>
<li>Trigger end event must take place when double clicking another none specified pages element.</li>
<li>If an edit is still in progress when double clicking another specifically specified pages element we clean up our first edit and begin another.</li>
</ul>
<p>Ok so we have a crude outline of our most basic requirement for our instant edit so now let’s think about how we are going to meet these requirements. Our trigger events would be the most logical place to start so let’s dig in.</p>
<p>Our first trigger event is going to take place when a user double clicks on a specified pages element. So we need to pick what element is going to be our pivoting point from no instant edit to instant edit and back again. As a web developer we have many page elements that encompass content on sites however the most common element that surrounds text would be the paragraph tags (&lt;p&gt;&lt;/p&gt;). So for our instant edit we will be basing our trigger events off the paragraph tags so when our user double clicks a paragraph tag our instant edit will begin or end.</p>
<p>Let start code!!</p>
<p>Start off with our blank document.</p>
<pre>&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
&lt;html xmlns="http://www.w3.org/1999/xhtml"&gt;
&lt;head&gt;
&lt;meta http-equiv="Content-Type" content="text/html; charset=utf-8" /&gt;
&lt;title&gt;Untitled Document&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;/body&gt;
&lt;/html&gt;</pre>
<p>In our header add the following script tags.</p>
<pre>&lt;head&gt;
&lt;meta http-equiv="Content-Type" content="text/html; charset=utf-8" /&gt;
&lt;title&gt;Untitled Document&lt;/title&gt;
    <strong>&lt;script type="text/javascript"&gt;
    &lt;/script&gt;</strong>
&lt;/head&gt;</pre>
<p>Also in your header add the following CSS.</p>
<pre>&lt;style type="text/css"&gt;
	#pallet p:hover {cursor:pointer; border:}
&lt;/style&gt;</pre>
<p>Now in our body add the following.</p>
<pre>&lt;div id="pallet"&gt;
    &lt;p&gt;
        Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat,
        vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim
        qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.
        Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod
        tincidunt ut laoreet dolore magna aliquam erat volutpat.
    &lt;/p&gt;
&lt;/div&gt;</pre>
<p>Ok now back in your script tags lets create our first function. This function will be called the setParagrahEvent() and is our event to turn on our instant edit when double clicking a paragraph tag.</p>
<p>Add the following to our script tags:</p>
<pre><strong>function</strong> setParagrahEvent()
{
 <strong>var</strong> ps = document.getElementById('pallet').getElementsByTagName('p');
 for(var i=0;i&lt;ps.length;i++)
 ps[i].ondblclick=function(){  Limit(this);  }
}</pre>
<p>Ok so lets break down this function.</p>
<p>In our first line of this function we set a variable called &#8220;<strong>ps</strong>&#8221; that is reference or pointing rout to where our script should be looking to locate all the paragraph tags one is going to allow to be edited. Here we point the variable &#8220;ps&#8221; to first our document, then use the <strong>getElementById</strong> to traverse to our documents div container of choice and with the <strong>getElementsByTagName</strong> we point to all paragraph elements.</p>
<p>Our next line of code is what&#8217;s called a &#8220;for loop&#8221; and it sets a numerical variable called &#8220;<strong>i</strong>&#8221; and runs through a loop over our &#8220;<strong>ps</strong>&#8221; variable to locate all paragraph tags in our div container &#8220;pallet&#8221;.</p>
<p>Next line works with our &#8220;for loop&#8221; to add an ondblclick function to each found paragraph in our div container &#8220;pallet&#8221;. The function we add to each found paragraph tag is called <strong>Limit(this)</strong>; and we set it to each paragraph tag to allow our script to not only find all our paragraph elements but bubble up our specifically double clicked paragraph to the top and edit only it, not the rest.</p>
<p>Well now that we have a function called <strong>Limit(this);</strong> floating around our paragraph tags we must write the function its self.</p>
<p>Add the following to our script.</p>
<pre>function Limit(obj){
 var zxce=window.event||arguments.callee.caller.arguments[0];
 if (!zxce) var zxce=window.event;
 zxce.cancelBubble=true;
 if (zxce.stopPropagation) zxce.stopPropagation();
}</pre>
<p>Ok this is a our limit function that receives our found paragraph tags and limits the returned or bubbled up paragraph tag we have double clicked to edit. Once our limit function has found our paragraph tag to edit we can begin to start manipulating our found paragraph tag to edit its contents.</p>
<p>Most likely the text our instant edit will be editing is a long line of text so its wise to use a textarea tag to be our editor for our text. Our textarea should also be unique to the whole document meaning that only one text area with a unique id should exist on the page at any time. So what we want to do is setup a condition that says if any textarea with this unique id is found do this if its not found then do other.</p>
<p>Here is our condition code so add it to our limit function:</p>
<pre>var textarea = document.getElementById('currentEdit');
	 if(textarea == null)
	 {
	 }
	 else
	 {
	 }</pre>
<p>Here we set a new variable call textarea and its pointing to any element in our document that has an id of &#8220;currentEdit&#8221;.<br />
Next we have an if and else conditional statement that&#8217;s set to read as, &#8220;<strong>if textarea is not found then do this, else do that</strong>&#8220;. What goes in between the else curly brackets represents if a textarea that has an id of &#8220;currentEdit&#8221; is indeed found. Everything in the if curly brackets is for if a textarea that has an id of &#8220;currentEdit&#8221; is not found.</p>
<p>Great lets move onto what will be our conditions for both our if and else conditional statement.</p>
<p>So think about this, if no textarea is found we of course want to add one, but what about our else statement? If there is a textarea found we want to remove it right, but what about if a user is trying to double click onto a second edit to end the first edit. To do such a thing we have to be prepared to add a new textarea in both our if and else statements but only in our else do we remove a old textarea before adding a new one.</p>
<p>Make your if and else conditions look like the following:</p>
<pre>	 if(textarea == null)
	 {
		 //INSERT TEXTAREA
		 var makeTextarea = document.createElement('textarea');
		 makeTextarea.setAttribute('id','currentEdit');
		 makeTextarea.style.width="100%";
		 makeTextarea.style.minWidth="100%";
		 var parentElement = obj.parentNode;
		 var nextElement = obj.nextSibling;
		 var elementsInners = obj.innerHTML;
		 makeTextarea.value = elementsInners;
		 parentElement.insertBefore(makeTextarea,nextElement);
		 //REMOVE PARAGRAPH ELEMENT
		 parentElement.removeChild(obj);
		 setParagrahEvent();
	 }
	 else
	 {
		 removeTextarea();
		 //INSERT TEXTAREA
		 var makeTextarea = document.createElement('textarea');
		 makeTextarea.setAttribute('id','currentEdit');
		 makeTextarea.style.width="100%";
		 makeTextarea.style.minWidth="100%";
		 var parentElement = obj.parentNode;
		 var nextElement = obj.nextSibling;
		 var elementsInners = obj.innerHTML;
		 makeTextarea.value = elementsInners;
		 parentElement.insertBefore(makeTextarea,nextElement);
		 //REMOVE PARAGRAPH ELEMENT
		 parentElement.removeChild(obj);
		 setParagrahEvent();
	 }</pre>
<p>Ok calm down and we will go over each part to clear up any confusion to what we are look at here. In both our if and else statements we now have a section call &#8220;INSERT TEXTAREA&#8221; however in the else statement we have an additional &#8220;removeTextarea();&#8221; function. This removeTextarea function will be covered in a bit but its important to see this slight difference between the if and else.</p>
<p>Our &#8220;INSERT TEXTAREA&#8221; works like this.</p>
<ul>
<li>var makeTextarea = document.createElement(&#8217;textarea&#8217;) (<strong>New variable that creates a textarea</strong>)</li>
<li> makeTextarea.setAttribute(&#8217;id&#8217;,'currentEdit&#8217;) (<strong>Sets this new textareas id to &#8220;currentEdit&#8221;</strong>)</li>
<li> makeTextarea.style.width=&#8221;100%&#8221;; (<strong>Sets our textarea width to be 100%</strong>)</li>
<li> makeTextarea.style.minWidth=&#8221;100%&#8221;; (<strong>Sets our textarea min-width to be 100%</strong>)</li>
</ul>
<ul>
<li> var parentElement = obj.parentNode; (<strong>Obj is our  paragraph tag and with parentNode we travers to its parent node</strong>)</li>
<li> var nextElement = obj.nextSibling; (<strong>Sets up another varible that points to our obj paragraph tags next sibling</strong>)</li>
<li> var elementsInners = obj.innerHTML; (<strong>Here we capture our paragraphs innerHTML or text we want to edit</strong>)</li>
<li> makeTextarea.value = elementsInners; (<strong>This grabs our captured innerHTML or text and sets it into our new textarea</strong>)</li>
<li> parentElement.insertBefore(makeTextarea,nextElement); (<strong>This points to obj&#8217;s parent and inserts the textarea after our nextElement</strong>)</li>
</ul>
<p>Ok so in a nut shell we have made a new textarea and set its id to be unique and a few styles. We then set up three new variables call parentElement nextElement and elementsInners to point to our paragraphs tags parent, next sibling and inner text. Next we use the above variables to copy our paragraphs tags inner text into our new textarea and append our new textarea to our document and after our paragraph tags.</p>
<p>Great but we also must remove our paragraph tags from our document so we don&#8217;t end up with our original paragraph tags and also a textarea both containing the text we would like to edit on the same page. To remove our paragraph tags we simple take a look at the other section that both our if and else statement have called &#8220;//REMOVE PARAGRAPH ELEMENT&#8221;.</p>
<pre>//REMOVE PARAGRAPH ELEMENT
parentElement.removeChild(obj);
setParagrahEvent();</pre>
<p>All we are doing here is again using our variable called parentElement and removing our obj variable and we also call to our setParagrahEvent(); to reinstall our double click even for find out selected paragraphs.</p>
<p>So our script should look like this now.</p>
<pre>function setParagrahEvent(){
 var ps=document.getElementById('pallet').getElementsByTagName('p');
 for(var i=0;i&lt;ps.length;i++)
  ps[i].ondblclick=function(){  Limit(this);  }
}
function Limit(obj){
 var zxce=window.event||arguments.callee.caller.arguments[0];
 if (!zxce) var zxce=window.event;
 zxce.cancelBubble=true;
 if (zxce.stopPropagation) zxce.stopPropagation();
 	 //CONVERT OLD EDIT BACK INTO P TAG
	 var textarea = document.getElementById('currentEdit');
	 if(textarea == null)
	 {
		 //INSERT TEXTAREA
		 var makeTextarea = document.createElement('textarea');
		 makeTextarea.setAttribute('id','currentEdit');
		 makeTextarea.style.width="100%";
		 makeTextarea.style.minWidth="100%";
		 var parentElement = obj.parentNode;
		 var nextElement = obj.nextSibling;
		 var elementsInners = obj.innerHTML;
		 makeTextarea.value = elementsInners;
		 parentElement.insertBefore(makeTextarea,nextElement);
		 //REMOVE PARAGRAPH ELEMENT
		 parentElement.removeChild(obj);
		 setParagrahEvent();
	 }
	 else
	 {
		 removeTextarea();
		 //INSERT TEXTAREA
		 var makeTextarea = document.createElement('textarea');
		 makeTextarea.setAttribute('id','currentEdit');
		 makeTextarea.style.width="100%";
		 makeTextarea.style.minWidth="100%";
		 var parentElement = obj.parentNode;
		 var nextElement = obj.nextSibling;
		 var elementsInners = obj.innerHTML;
		 makeTextarea.value = elementsInners;
		 parentElement.insertBefore(makeTextarea,nextElement);
		 //REMOVE PARAGRAPH ELEMENT
		 parentElement.removeChild(obj);
		 setParagrahEvent();
	 }
}</pre>
<p>Ok lets move onto our removeTextarea function.</p>
<p>Add the following to our script:</p>
<pre>function removeTextarea()
{
	 var textarea = document.getElementById('currentEdit');
	 var textareaInners = textarea.value;
	 var innersLength = document.getElementById('currentEdit').value;
	 var innersLength = innersLength.replace(/ /g,"");
  var innersLength = innersLength.replace(/\n/g,"");
	 if(innersLength.length == 0)
	 {
	 }
	 else
	 {
	 }
}</pre>
<p>Ok our removeTextarea function first sets up two variables called textarea that points to our textarea with its unique id &#8220;currentEdit&#8221; and then our second variable called textareaInners points to our textarea&#8217;s value or rather text that may or may not be edited.</p>
<p>We then setup three more variables named &#8220;innerLength&#8221;. The first &#8220;innerLength&#8221; variable points to and grabs our &#8220;currentEdit&#8217;s&#8221; elements value or text. Then we setup another variable of the same name and equal it to our first variable and run a JavaScript replace function to remove all spaces. Our third and last variable is also named &#8220;innersLength and is equal to our second &#8220;innersLenght&#8221; and is also using a &#8220;replace&#8221; function to remove all carriage returns.</p>
<p>We then have a conditional statement that states if &#8220;innersLength.lenght&#8221; is equal to none or &#8220;0&#8243; we do this and if &#8220;innersLenght&#8221; equals any number other than 0 do that.</p>
<p>Its time to think about some things again. if indeed there is no text in our textarea we want to make be sure to replace that nothing with something, other wise we leave an empty paragraph tag. Add the following in the if curly brackets.</p>
<pre>alert('Sorry but you must not remove all text!');
var makeNewP = document.createElement('p');
var getParent = textarea.parentNode;
var sibling = textarea.nextSibling;
var textareaInners = "[EMPTY]";
getParent.insertBefore(makeNewP,sibling);
makeNewP.innerHTML = textareaInners;
getParent.removeChild(textarea);
setParagrahEvent();</pre>
<p>We first call for an alert to notify the user that they have just tried to same an empty textarea and its not allowed. Then we create four variables called makeNewP, getParent, sibling and textareaInners. Our makeNewP creates a new paragraph tag to replace our textarea while our getParent points to our textareas parent node. The sibling variable points to our textarea&#8217;s sibling and our textareaInners gets set to &#8220;[EMPTY]&#8221; to replace our nothing with something.</p>
<p>Ok next we use our getParent variable to inert our new paragraph element before our textarea&#8217;s sibling. We also insert the captured inner text from our textarea back into our new paragraph tag and finally remove our textarea from our document. Again we re-install our setParagrahEvent() to set us up for our next paragraph select.</p>
<p>Lets move onto what goes in between our else curly brackets. Add the following to your else statement.</p>
<pre>var makeNewP = document.createElement('p');
var getParent = textarea.parentNode;
var sibling = textarea.nextSibling;
getParent.insertBefore(makeNewP,sibling);
makeNewP.innerHTML = textareaInners;
getParent.removeChild(textarea);
setParagrahEvent();</pre>
<p>Ok this is exactly the same as our if statement but its not alerting our user about and empty textarea and instead of filling our newly created paragraph tag with &#8220;[<strong>EMPTY</strong>]&#8221; we fill it with our edited text.</p>
<h3>Here is our compleated script</h3>
<pre>function setParagrahEvent(){
 var ps=document.getElementById('pallet').getElementsByTagName('p');
 for(var i=0;i&lt;ps.length;i++)
  ps[i].ondblclick=function(){  Limit(this);  }
}
function Limit(obj){
 var zxce=window.event||arguments.callee.caller.arguments[0];
 if (!zxce) var zxce=window.event;
 zxce.cancelBubble=true;
 if (zxce.stopPropagation) zxce.stopPropagation();
 	 //CONVERT OLD EDIT BACK INTO P TAG
	 var textarea = document.getElementById('currentEdit');
	 if(textarea == null)
	 {
		 //INSERT TEXTAREA
		 var makeTextarea = document.createElement('textarea');
		 makeTextarea.setAttribute('id','currentEdit');
		 makeTextarea.style.width="100%";
		 makeTextarea.style.minWidth="100%";
		 var parentElement = obj.parentNode;
		 var nextElement = obj.nextSibling;
		 var elementsInners = obj.innerHTML;
		 makeTextarea.value = elementsInners;
		 parentElement.insertBefore(makeTextarea,nextElement);
		 //REMOVE PARAGRAPH ELEMENT
		 parentElement.removeChild(obj);
		 setParagrahEvent();
	 }
	 else
	 {
		 removeTextarea();
		 //INSERT TEXTAREA
		 var makeTextarea = document.createElement('textarea');
		 makeTextarea.setAttribute('id','currentEdit');
		 makeTextarea.style.width="100%";
		 makeTextarea.style.minWidth="100%";
		 var parentElement = obj.parentNode;
		 var nextElement = obj.nextSibling;
		 var elementsInners = obj.innerHTML;
		 makeTextarea.value = elementsInners;
		 parentElement.insertBefore(makeTextarea,nextElement);
		 //REMOVE PARAGRAPH ELEMENT
		 parentElement.removeChild(obj);
		 setParagrahEvent();
	 }
}
function removeTextarea()
{
	 var textarea = document.getElementById('currentEdit');
	 var textareaInners = textarea.value;
	 var innersLength = document.getElementById('currentEdit').value;
	 var innersLength = innersLength.replace(/ /g,"");
  	 var innersLength = innersLength.replace(/\n/g,"");
	 if(innersLength.length == 0)
	 {
		alert('Sorry but you must not remove all text!');
		var makeNewP = document.createElement('p');
		var getParent = textarea.parentNode;
		var sibling = textarea.nextSibling;
		var textareaInners = "[EMPTY]";
		getParent.insertBefore(makeNewP,sibling);
		makeNewP.innerHTML = textareaInners;
		getParent.removeChild(textarea);
		setParagrahEvent();
	 }
	 else
	 {
		var makeNewP = document.createElement('p');
		var getParent = textarea.parentNode;
		var sibling = textarea.nextSibling;
		getParent.insertBefore(makeNewP,sibling);
		makeNewP.innerHTML = textareaInners;
		getParent.removeChild(textarea);
		setParagrahEvent();
	 }
}</pre>
<p>Ok a few things to talk about before we move on. In the above demo you can disable all occurrences of a textarea with our unique id by double clicking our body tag and we do this by adding the following to our body tag.</p>
<pre>&lt;body ondblclick="removeTextarea()"&gt;</pre>
<p>Last we must install our setParagraphEvent() by again adding this to our body tag.</p>
<pre>&lt;body onload="setParagrahEvent()" ondblclick="removeTextarea()"&gt;</pre>
<h3><a href="http://devinrolsen.com/cms-instant-edit-tutorial-2/">CMS Instant Edit Part 2.</a></h3>
]]></content:encoded>
			<wfw:commentRss>http://www.devinrolsen.com/cms-instant-edit-tutorial/feed/</wfw:commentRss>
		<slash:comments>20</slash:comments>
		</item>
	</channel>
</rss>
