<?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>Ryan&#039;s Blog &#187; Dojo</title>
	<atom:link href="http://www.rmauger.co.uk/topics/dojo/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.rmauger.co.uk</link>
	<description>Randomness will get you everywhere.</description>
	<lastBuildDate>Thu, 05 May 2011 14:35:49 +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>Zend Framework, Zend_Dojo and  Dojo Tree</title>
		<link>http://www.rmauger.co.uk/2009/02/zend-framework-zend_dojo-and-dojo-tree/</link>
		<comments>http://www.rmauger.co.uk/2009/02/zend-framework-zend_dojo-and-dojo-tree/#comments</comments>
		<pubDate>Fri, 06 Feb 2009 20:10:30 +0000</pubDate>
		<dc:creator>ryan</dc:creator>
				<category><![CDATA[Dojo]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[Zend Framework]]></category>

		<guid isPermaLink="false">http://www.rmauger.co.uk/?p=18</guid>
		<description><![CDATA[Working on a new CMS at work, I needed to allow a user to insert a page at a point in the site tree. And i thought to myself, well, Dojo has a tree widget, and Zend Framework supports dojo, it can&#8217;t be a difficult task. Unfortunately I was unable to find a &#8216;simple&#8217; method [...]]]></description>
			<content:encoded><![CDATA[<p>Working on a new CMS at work, I needed to allow a user to insert a page at a point in the site tree. And i thought to myself, well, Dojo has a tree widget, and Zend Framework supports dojo, it can&#8217;t be a difficult task.</p>
<p>Unfortunately I was unable to find a &#8216;simple&#8217; method of doing this already documented, so I experimented a little, and threw away some very in-elegant ideas, and finally came up with the following technique, after discovering the <a title="Zend dojo data envelopes" href="http://framework.zend.com/manual/en/zend.dojo.data.html" target="_blank">Zend_Dojo_Data</a>.</p>
<p><span id="more-18"></span></p>
<p>Firstly, I added a method to my tree model to walk the tree, and build an array suitable for turning into the required structure for the json.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">class</span> SiteTree <span style="color: #000000; font-weight: bold;">extends</span> Zend_Db_Table_Abstract
<span style="color: #009900;">&#123;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">//....</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">function</span> _walkTree<span style="color: #009900;">&#40;</span><span style="color: #990000;">Array</span> <span style="color: #000088;">$root</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">,</span> <span style="color: #000088;">$path</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$root</span> <span style="color: #339933;">===</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
       <span style="color: #000088;">$root</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getBranchChildren</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #000088;">$arrNodes</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$i</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$root</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$branch</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$thisPath</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$path</span> <span style="color: #339933;">===</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> ? <span style="color: #0000ff;">'/'</span><span style="color: #339933;">.</span><span style="color: #000088;">$branch</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'branch_name'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'/'</span> <span style="color: #339933;">:</span> <span style="color: #000088;">$path</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$branch</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'branch_name'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'/'</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$key</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$branch</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'parent'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">==</span> <span style="color: #0000ff;">'0'</span><span style="color: #009900;">&#41;</span> ? <span style="color: #000088;">$branch</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'id'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">:</span> <span style="color: #000088;">$i</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$arrNodes</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$key</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'id'</span><span style="color: #009900;">&#93;</span>       <span style="color: #339933;">=</span> <span style="color: #000088;">$branch</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'id'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$arrNodes</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$key</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'label'</span><span style="color: #009900;">&#93;</span>    <span style="color: #339933;">=</span> <span style="color: #000088;">$branch</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'branch_name'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$arrNodes</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$key</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'path'</span><span style="color: #009900;">&#93;</span>     <span style="color: #339933;">=</span> <span style="color: #000088;">$thisPath</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$arrNodes</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$key</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'iconClass'</span><span style="color: #009900;">&#93;</span>     <span style="color: #339933;">=</span> <span style="color: #0000ff;">'folder'</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$arrNodes</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$key</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'children'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$branches</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getBranchChildren</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$branch</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'id'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000088;">$arrNodes</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$key</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'children'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_walkTree<span style="color: #009900;">&#40;</span><span style="color: #000088;">$branches</span><span style="color: #339933;">,</span> <span style="color: #000088;">$thisPath</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #000088;">$i</span><span style="color: #339933;">++;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #b1b100;">return</span> <span style="color: #000088;">$arrNodes</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">//....</span>
&nbsp;
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>This function recursively maps the database into a nested array. Please note, this function will cause many database queries on deep tree structures, so I really would advise you cache the return of this function, so to keep queries to a minimum.</p>
<p>The line &#8220;$key = ($branch['parent'] == &#8217;0&#8242;) ? $branch['id'] : $i;&#8221; is important. For Zend_Dojo_Data to output the correctly formatted json, you need to have an associative array for the top level (root) nodes, and indexed arrays for all of their children.</p>
<p>Next, this data needs to be turned into json for the tree. To do this, I simply created a new action to use as the source for the json, and inserted the following:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> jsonNewpageAction<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    Zend_Dojo<span style="color: #339933;">::</span><span style="color: #004000;">enableView</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">view</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    Zend_Layout<span style="color: #339933;">::</span><span style="color: #004000;">getMvcInstance</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">disableLayout</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$tree</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> SiteTree<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$treeObj</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Zend_Dojo_Data<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'id'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$tree</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getTree</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$treeObj</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setLabel</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'label'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$treeObj</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setMetadata</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'path'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'/'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">view</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">tree</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$treeObj</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">toJson</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Setting the Label is important here, it is used to determine which attribute of each node is its label, next the Metadata attribute &#8220;path&#8221; I used for my customisation of the tree for my own needs, which you will see later. The view script for this action simply echo&#8217;s the tree value.</p>
<p>The next step is to create the view to output your tree. this part is where the real fun begins, as you can get carried away with tweaking the dojo widget if your not careful.</p>
<p>The following lines were added to the action with my form on it. (The tree is not part of the form, I simple made mine interact with a read only element inside it)</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">Zend_Dojo<span style="color: #339933;">::</span><span style="color: #004000;">enableView</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">view</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">view</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">dojo</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">requireModule</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'dojo.data.ItemFileReadStore'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">view</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">dojo</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">requireModule</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'dijit.Tree'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">view</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">dojo</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">requireModule</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'dojo.parser'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>This will add the require statements to the view, so that the required dojo parts are available.</p>
<p>And in the view itself, you need at least the following:</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">&lt;div dojoType=&quot;dojo.data.ItemFileReadStore&quot;  url=&quot;/admin/pages/json-newpage&quot; jsid=&quot;jsonData&quot;&gt;&lt;/div&gt;
&lt;div dojoType=&quot;dijit.tree.ForestStoreModel&quot; jsId=&quot;treeModel&quot; store=&quot;jsonData&quot; rootId=&quot;treeRoot&quot; rootLabel=&quot;Home&quot; childrenAttrs=&quot;children&quot; &gt;&lt;/div&gt;
&nbsp;
&lt;div dojoType=&quot;dijit.Tree&quot; model=&quot;treeModel&quot; labelAttrs=&quot;label&quot; &gt;&lt;/div&gt;</pre></div></div>

<p>The first div, is the part which will read your json from the first action I listed. If you have only a single root node, you may get away without the second div, which is the ForestStoreModel. The ForestStoreModel had me scratching my head for a while, as I had no idea I needed it, and I kept finding errors in my FireBug console. Eventually I found <a title="The dojo model - An explanation of the ForestStoreModel" href="http://dojotoolkit.org/2008/02/24/dijit-tree-and-dojo-data-dojo-1-1-model" target="_blank">this</a> page on the dojo site.</p>
<p>If you were to put all this together now, you would probably end up with a working tree. BUT, it can be improved. In my tree, all the leaves would actually represent folders, but as default they look like little documents, not good at all. So I asked around in IRC, and was told I needed to google getIconClass, which put me on to writing this,</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #339933;">&lt;</span>div dojoType<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;dijit.Tree&quot;</span> model<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;treeModel&quot;</span> labelAttrs<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;label&quot;</span> iconClass<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;dijitFolderOpened&quot;</span><span style="color: #339933;">&gt;</span>
&nbsp;
<span style="color: #339933;">&lt;</span>script type<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;dojo/method&quot;</span> event<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;getIconClass&quot;</span><span style="color: #339933;">&gt;</span>
    <span style="color: #b1b100;">return</span>  <span style="color: #0000ff;">'dijitFolderClosed'</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">&lt;/script&gt;</span>
&nbsp;
<span style="color: #339933;">&lt;/</span>div<span style="color: #339933;">&gt;</span></pre></div></div>

<p>As you can see, a script is inserted INSIDE the container of the tree, and the event attribute tells the script which even it is responsible for overriding.</p>
<p>If you run this now, you will find that all of the folders in the tree are now closed. Not good, as the nice opening and closing folders as you expand/contract elements are lost. This can be changed by adding another attribute to the script:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #339933;">&lt;</span>script type<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;dojo/method&quot;</span> event<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;getIconClass&quot;</span> args<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;item, opened&quot;</span><span style="color: #339933;">&gt;</span>
    <span style="color: #b1b100;">return</span> <span style="color: #009900;">&#40;</span>opened ? <span style="color: #0000ff;">'dijitFolderOpened'</span> <span style="color: #339933;">:</span> <span style="color: #0000ff;">'dijitFolderClosed'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">&lt;/script&gt;</span></pre></div></div>

<p>The args attribute allows arguments from the item firing the event to be passed to the script. so a simple ternary, and you can switch between opened and closed folders.</p>
<h2>Update</h2>
<p>You may also find <a title="Codeutopia.net Zend Framework and Dojo Tree's with Checkboxes" href="http://codeutopia.net/blog/2008/11/21/creating-a-dojo-dijittree-with-checkboxes/" target="_blank">this</a> post at codeutopia.net useful if you are working with tree&#8217;s in Dojo / Zend Framework</p>
]]></content:encoded>
			<wfw:commentRss>http://www.rmauger.co.uk/2009/02/zend-framework-zend_dojo-and-dojo-tree/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>

