Split Views using Nooku Framework

Harbour with SplitView

Split View showing the boats list in Harbour, our example component

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:

  1. How to create a Ajaxed Split View.
  2. 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

    [...] Read more at the Nooku blog TweetShare View Comments blog comments powered by Disqus /* [...]

  • 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

    [...] This post was mentioned on Twitter by Nooku and others. Nooku said: Just blogged : Creating Split Views using Nooku Framework http://bit.ly/gfdQmP A great tutorial by @stipsan about the power of HMVC #joomla [...]

  • http://twitter.com/mblodau Martin Blodau

    Stian, thanks a lot! This is great stuff and i will try this out right away. :-)

  • http://www.drupal-themes.adodis.com Drupal Themes

    I have heard about the Nooku Framework, but not much. Thanks for sharing this information. I will send this to my programmer and ask he to see how we can get use of this.

  • Luke.

    Great article thanks, I'm really looking forward to learning a lot more about Nooku very soon.
    Do you know if there is a Nooku way to load assets into the head of a document like JDocuments addScript() method?

  • http://johan.janssens.me Johan Janssens

    Thnx Luke ! Assets are loaded into the head of the document automatically by the template filters. All you need to do is add the script and style elements to your template, Nooku does the rest.

    For an example how this works, please have a look at our harbour component (https://nooku.assembla.com/cod.../) or if you need help put your question on the mailing list.

  • http://twitter.com/stipsan Stian Didriksen

    You're welcome! It's a lot of fun to play with ;)

  • Harikaram

    Slightly confused….the first block of code has the following link in the A tag:

    @route('view=boat&layout=compact&slug='.@esca...

    Should that not say “layout=split”?

  • http://johan.janssens.me Johan Janssens

    Thanks ! Excellent catch. I have updated the blog post accordingly.

blog comments powered by Disqus