<?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>The Curmudgeoclast &#187; javascript</title>
	<atom:link href="http://techblog.daveastels.com/tag/javascript/feed/" rel="self" type="application/rss+xml" />
	<link>http://techblog.daveastels.com</link>
	<description>This sucks, wouldn&#039;t it be cool if...?</description>
	<lastBuildDate>Mon, 18 Jan 2010 22:30:05 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Using TinyMCE with Rails/AJAX</title>
		<link>http://techblog.daveastels.com/2006/10/29/using-tinymce-with-rails-ajax/</link>
		<comments>http://techblog.daveastels.com/2006/10/29/using-tinymce-with-rails-ajax/#comments</comments>
		<pubDate>Sun, 29 Oct 2006 19:56:00 +0000</pubDate>
		<dc:creator>dastels</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://techblog.daveastels.com/?p=56</guid>
		<description><![CDATA[Our current project is basically a very structured (i.e. niche/focused/custom) content management system.  There are a few places where we want to give the client the ability to edit some HTML page content.  The client is tech-savvy, but not in the  &#8220;I enjoy slinging HTML&#8221; way.  Ergo, we needed WYSIWYG HTML [...]]]></description>
			<content:encoded><![CDATA[<p>Our current project is basically a very structured (i.e. niche/focused/custom) content management system.  There are a few places where we want to give the client the ability to edit some HTML page content.  The client is tech-savvy, but not in the  &#8220;I enjoy slinging HTML&#8221; way.  Ergo, we needed WYSIWYG HTML editing capability.  After some research we decided that TinyMCE was the way to go.  We just had to make it work the way we wanted it to.</p>
<p>Here are my notes on getting <a href="http://tinymce.moxiecode.com/">TinyMCE</a> working nicely in a Rails/AJAX environment.</p>
<p>Start by grabbing the rails plugin (and read the material) from <a href="http://wiki.rubyonrails.org/rails/pages/HowToUseTinyMCE">here</a> and install it as per the instructions.</p>
<p>Allowable options to uses_tiny_mce are documented <a href="http://tinymce.moxiecode.com/tinymce/docs/reference_configuration.html">here</a>&#8230; there are lots of them</p>
<p>I figured that having followed the directions in the above, my work was over.  In fact it was just beginning.  The above will work fine if you have a page, with a textarea that you want to be WYSIWYG.   Our requirements were a bit more involved.  The textarea in question was in a partial that was rendered via a remote updater call (via a link_to_remote in a list on the page).  The main issue here is that the textarea didn&#8217;t exist when the page was rendered&#8230; so TinyMCE had to be hooked up to it later&#8230; when it was injected into the DOM tree.  Some digging through support forums and I found what I needed.  This required a bit of java script in the partial&#8230; <strong>after</strong> the textarea:</p>
<blockquote>
<pre>&lt;%= form_remote_tag :url =&gt; {:action =&gt; 'edit_page', :id =&gt; @page},
                    :before =&gt; "tinyMCE.triggerSave(true,true)" %&gt;
  &lt;b&gt;Page Content:&lt;/b&gt;&lt;br /&gt;
  &lt;%= text_area :page, :content, :rows =&gt; 15, :cols =&gt; 150 %&gt;
  &lt;br /&gt;&lt;br /&gt;
  &lt;%= submit_tag "Update" %&gt;
  &lt;script type="text/javascript"&gt;
  //&lt;![CDATA[
    tinyMCE.execCommand('mceAddControl', true, 'page_content');
  //]]&gt;
  &lt;/script&gt;
&lt;%= end_form_tag %&gt;</pre>
</blockquote>
<p>The next issue was getting the contents out of TinyMCE and accessible to the parameter construction for the remote call.  After a bit of research I ended up with the following:</p>
<blockquote>
<pre>&lt;%= form_remote_tag :url =&gt; {:action =&gt; 'edit_page', :id =&gt; @page},
                    :before =&gt; "tinyMCE.triggerSave(true,true)" %&gt;</pre>
</blockquote>
<p>Normally the save is trigger by a page unload, I needed to force it to happen before the remote call happened.  Putting the call to force (aka trigger) the save in the <code>:before</code> script of the form submission remote call worked great.  So now I had a bigger problem.  TinyMCE was getting hooked up to the textarea.  If the user picked another page item from the list, the div would be refilled with a different rendering of the partial&#8230; with a different textarea node.  The old textarea would be gone&#8230; out from under TinyMCE.  I needed a way to reconnect to the new textarea.  More digging turned up <a href="http://www.rorlach.de/mediawiki/samples/sample009.php">this example</a>.  It gave me the final bit of the puzzle.  My final solution includes the following in <code>application.js</code>:</p>
<blockquote>
<pre>bTextareaWasTinyfied = false; //this should be global, could be stored in a cookie...

function setTextareaToTinyMCE(sEditorID) {
	var oEditor = document.getElementById(sEditorID);
	if(oEditor &amp;&amp; !bTextareaWasTinyfied) {
		tinyMCE.execCommand('mceAddControl', true, sEditorID);
		bTextareaWasTinyfied = true;
	}
	return;
}

function unsetTextareaToTinyMCE(sEditorID) {
	var oEditor = document.getElementById(sEditorID);
	if(oEditor &amp;&amp; bTextareaWasTinyfied) {
		tinyMCE.execCommand('mceRemoveControl', true, sEditorID);
		bTextareaWasTinyfied = false;
	}
	return;
}</pre>
</blockquote>
<p>These two functions are used to disconnect from an existing textarea and reconnect to the newly rendered one.  In the list item that causes the rendering:</p>
<blockquote>
<pre>&lt;%= link_to_remote "&lt;span class=\"listTitle\"&gt;#{page.title}&lt;/span&gt;",
                   {:update =&gt; "editPage",
                    :url =&gt; {:action =&gt; :get_page, :id =&gt; page},
                    :before =&gt; "Effect.Fade('editPage',
                                            {duration: 0.25,
                                             queue: 'end',
                                             afterFinish: function(effect) {
                                               unsetTextareaToTinyMCE('page_content')}})",
                    :complete =&gt; "Effect.Appear('editPage', {duration: 0.5, queue: 'end'})"},
                    :title =&gt; "Edit #{page.title}"  %&gt;</pre>
</blockquote>
<p>To avoid visual weirdness the <em>disconnect</em> is delayed until the fade has completed.  Once the new version of the partial has been loaded, it&#8217;s faded back in.  The relavant bit of the partial is here:</p>
<blockquote>
<pre>&lt;%= form_remote_tag :url =&gt; {:action =&gt; 'edit_page', :id =&gt; @page},
                    :before =&gt; "tinyMCE.triggerSave(true,true)" %&gt;
  &lt;b&gt;Page Content:&lt;/b&gt;&lt;br /&gt;
  &lt;%= text_area :page, :content, :rows =&gt; 15, :cols =&gt; 150 %&gt;
  &lt;br /&gt;&lt;br /&gt;
  &lt;%= submit_tag "Update" %&gt;
  &lt;script type="text/javascript"&gt;
  //&lt;![CDATA[
    setTextareaToTinyMCE('page_content');
  //]]&gt;
  &lt;/script&gt;
&lt;%= end_form_tag %&gt;</pre>
</blockquote>
<p>The last thing was to add a Done/Cancel button to the form:</p>
<blockquote>
<pre>&lt;input type="button"
       value="Done"
       onclick="Effect.Fade('editPage',
                            {duration: 0.25,
                             queue: 'end',
                             afterFinish: function(effect) {
                               unsetTextareaToTinyMCE('page_content')
                             }})" /&gt;</pre>
</blockquote>
<p>Now I have a WYSIWYG textarea in a partial that&#8217;s rendered via a remote call.. and it all works smoothly and exactly as required.</p>
]]></content:encoded>
			<wfw:commentRss>http://techblog.daveastels.com/2006/10/29/using-tinymce-with-rails-ajax/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>BDD-style JavaScript testing</title>
		<link>http://techblog.daveastels.com/2006/08/30/bdd-style-javascript-testing/</link>
		<comments>http://techblog.daveastels.com/2006/08/30/bdd-style-javascript-testing/#comments</comments>
		<pubDate>Wed, 30 Aug 2006 22:53:00 +0000</pubDate>
		<dc:creator>dastels</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[bdd]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://techblog.daveastels.com/?p=74</guid>
		<description><![CDATA[BDD-style JavaScript testing:
&#8220;Borrowing from Behaviour Driven Development techniques, especially the RSpec framework I&#8217;ve added some new features to script.aculo.us™ testing library.&#8221;
(Via mir.aculo.us.)
Check it out!
]]></description>
			<content:encoded><![CDATA[<p><a href="http://mir.aculo.us/articles/2006/08/29/bdd-style-javascript-testing">BDD-style JavaScript testing</a>:</p>
<blockquote><p>&#8220;Borrowing from <a href="http://en.wikipedia.org/wiki/Behavior_driven_development">Behaviour Driven Development</a> techniques, especially the <a href="http://rspec.rubyforge.org/">RSpec framework</a> I&#8217;ve added some new features to <a href="http://script.aculo.us/">script.aculo.us</a>™ testing library.&#8221;</p></blockquote>
<p>(Via <a href="http://mir.aculo.us/">mir.aculo.us</a>.)</p>
<p>Check it out!</p>
]]></content:encoded>
			<wfw:commentRss>http://techblog.daveastels.com/2006/08/30/bdd-style-javascript-testing/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
