Split Views using Nooku Framework
A month ago Martin asked a very interesting question on Twitter.
Possible to load a detail view & it’s related list view besides each other in the tab of a third view with the “H” of HMVC?
Short answer, yes offcourse ! Luckily our blog doesn’t have a 140 char limit so I can also show you how. In this tutorial I will explain:
- How to create a Ajaxed Split View.
- How to render that Split View from a module.
We will use the overlays we learned about in my previous blog post, and apply this to create the Split View.
What’s a Split View?
Split Views are a common UI pattern that involves subviews that relate to one another. Usually that means a list to the left that loads data into the right hand view when you select an item.
The code used in this tutorial is from the Split View implementation in Harbour, describing how I did it and how you can accomplish it in your own extension.
Step 1 – HTML and CSS
There are many different Split View layouts, the kind we’ll be making is usually called “split” as it’s a 25/75 layout with a list to the left and details to the right.
Boats view
So we’ll create a new layout in our plural view here:
/com_harbour/views/boats/tmpl/split.php
In this layout we essentially need to load our assets, create an unordered list of links and have a <div> container as a placeholder for the details view.
<ul class="mod-harbour-boats">
<? foreach ($boats as $boat) : ?>
<li>
<a title="<?= @escape($boat->title) ?>" href="<?= @route('view=boat&layout=split&slug='.@escape($boat->slug)); ?>#boat-overlay">
<img alt="" src="media://com_harbour/images/flags/<?= @escape($boat->flag);?>" />
<?= @escape($boat->title) ?>
</a>
</li>
<? endforeach; ?>
</ul>
<div id="boat-overlay">
<?= KFactory::tmp('site::com.harbour.controller.boat')->read() ?>
</div>
Boat view, details of a boat
Next we need the boat view, which will contain the details of a boat and will be loaded when you click on a link in the unordered list of links we just created. /com_harbour/views/boat/tmpl/split.php
<div id="boat-overlay">
<?= @template('simple') ?>
</div>
As you can see it’s just a div wrap around the “simple” layout, with the id “boat-overlay”.
It’s important to note that each link got a #boat-overlay hash. KOverlay use that to know what part of the html in the Ajax response that you want in your details view. For more details on how this works see my previous post.
That’s why our second layout got a div wrapper with a matching id.
Let’s make it look good
To make it look more like a real Split View, create a CSS file here:
/media/com_harbour/css/split.css
.mod-harbour-boats, #boat-overlay {
float: left;
height: 400px;
margin: 0;
}
.mod-harbour-boats {
width: 25%;
}
#boat-overlay {
width: 75%;
overflow: hidden;
}
#boat-overlay #boat {
float: none;
}
.mod-harbour-boats {
padding: 0;
overflow-x: hidden;
}
.mod-harbour-boats li {
background: none;
display: block;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
.mod-harbour-boats li a {
display: block;
height: 32px;
font-size: 12px;
font-weight: bold;
line-height: 32px;
text-indent: 15px;
}
Step 2 – KOverlay and a little bit of MooTools
Start off by creating the following js file:
/media/com_harbour/js/split.js
$$('.mod-harbour-boats').each(function(list){
list.getElements('a').addEvent('click', function(event){
new Event(event).stop();
list.getElements('li.active').removeClass('active');
this.getParent().addClass('active');
var overlay = $('boat-overlay');
//KOverlay reads the href value when making the request
overlay.setProperty('href', this.getProperty('href'));
//Instantiate KOverlay with evalScripts false to prevent duplicated events
new KOverlay(overlay, "{evalScripts: false}");
});
});
The javascript is super simple. We get the <div id=”boat-overlay”> from our first layout, since this is were we want the ajax to be outputted. Then we give the overlay the same href value as the link we just clicked.
And finally we initialize KOverlay, passing it our overlay div and letting KOverlay do all the work. That’s a wrap! At this point we got a fully working Split View powered by ajax.
Step 3 – Reusing the Split View elsewhere
How do I render this from another view or from a module? Thanks to Nooku strict naming conventions and out of the box HMVC, we can guess our way to it easily.
We know that the view is “boats” and the layout is “split”. The controller action that’s called when you go to &view=boats is called “browse” since you’re browsing a list of items.
So by that we can assume that we only have to use the factory to get the “boat” controller, override its default layout to “split” and execute “browse”.
All that is done with just a few words:
echo KFactory::tmp('site::com.harbour.controller.boat')
->layout('split')
->browse();
You can see it in use in the current mod_harbour module in the Harbour trunk:
/trunk/harbour/code/site/modules/mod_harbour
If you’ve heard about HMVC before but still not quite sure what it is, then I can tell you that what you’re looking at is one practical example of how HMVC works.
Not only does it help reduce the amount of code, but more importantly it makes all your code predictable for yourself as much as others.
Conclusion
Split Views is just one example on how strict conventions and design patterns really helps you focus on what matters the most when creating great software that people enjoy using.
Now, go have fun coding in the Disneyland of code already!
-
http://www.torkiljohnsen.com/2010/12/28/split-views-using-nooku-framework/ Torkil Johnsen » Split views using Nooku Framework
-
http://topsy.com/blog.nooku.org/2010/12/split-views-using-nooku-framework/?utm_source=pingback&utm_campaign=L2 Tweets that mention Just blogged : Creating Split Views using Nooku Framework A great tutorial by about the power of HMVC #joomla — Topsy.com
-
http://twitter.com/mblodau Martin Blodau
-
http://www.drupal-themes.adodis.com Drupal Themes
-
Luke.
-
http://johan.janssens.me Johan Janssens
-
http://twitter.com/stipsan Stian Didriksen
-
Harikaram
-
http://johan.janssens.me Johan Janssens
