Send to Printer


ST 4U 116: Adding the Menu Component

August 5, 2011 9:20:56.093

Today's Smalltalk 4 You continues the VA Smalltalk Seaside tutorial with the addition of the menu component (a set of filtering links in this example). You can download the initial domain model as a file out here. If you have trouble viewing it here in the browser, you can also navigate directly to YouTube. To watch now, click on the image below:

Seaside Component.

If you have trouble viewing that directly, you can click here to download the video directly. If you need the video in a Windows Media format, then download that here.

You can also watch it on YouTube:

In this section of the tutorial, we're going to get the menu component working. Along the way, we'll also learn about the important #children method, which should report back all the (non call'd) components that a Seaside UI will display. So let's get started with BlogMenuView. First, you'll need to modify the #initialize method:

	super initialize.
	entries := OrderedCollection new

It will become apparent in a few minutes why that variable needs to be a collection. To set the menu options, we'll go back to class BlogServerView and flesh out the initialization of the menu component. We'll modify the #initialize method, and add #initializeMenuComponent, as shown below:

	"Initialize a newly created instance. This method must answer the receiver."

	super initialize.
	listComponent := BlogListView new.
	self initializeMenuComponent.

	menuComponent := BlogMenuView new.
	menuComponent addEntry: 'All Posts' withAction: [self allPosts].
	menuComponent addEntry: 'Today''s Posts' withAction: [self todaysPosts].

While you accepted that method, you'll notice that a number of the message references are red; that's because we are creating forward . First, let's create the one being called in BlogMenuView - #addEntry:withAction:

addEntry: label withAction: actionBlock

	self entries add: label -> actionBlock

What this does is create an Association object (a key/value pair) which is stored in the collection. We'll then render a set of urls using those entries. To do that, add this rendering method to BlogMenuView:

renderContentOn: html

	self entries do: [:each |
		html anchor
			callback: each value;
			with: each key]
		separatedBy: [html space]

We aren't quite ready yet - we have some menu options for filtering, but we have not specified the filtering code yet! So, we need to add an instance variable to class BlogListView called filterBlock, and add accessing methods for it, as shown below:

adding filters

Now, add the following methods to BlogListView


filterBlock: anObject
	filterBlock := anObject

	filterBlock := [Storage default posts]

	filterBlock := [Storage default posts select: [:each | each timestamp asDate = Date today ]]

Finally, we need to modify the #initialize method in BlogListView

	"set up the initial filter"

	super initialize.
	self setAllPostsFilter

Back in class BlogServerView, we left a reference to the methods we just created - so now we'll hook that up, and add the #children method mentioned back at the top of this section:

	listComponent setAllPostsFilter

	listComponent setTodaysPostsFilter

	^Array with: listComponent with: menuComponent

When we run that (using the Seaside menu, launch the application in the browser), it should almost work - you'll see the menu options, but selecting them has no visible effect. That's because we have not updated the rendering code in BlogListView. Make the #renderContentOn: method in that class use the current filter:

renderContentOn: html
	| posts |
	posts := self filterBlock value.
	posts do: [:each |
		self renderPost: each on: html]

It should do the right thing now! That's as far as we'll go in this section. Next, we'll look at custom sessions.

Need more help? There's a screencast for other topics like this which you may want to watch. Questions? Try the "Chat with James" Google gadget over in the sidebar.

Technorati Tags: , , ,

[st4u116-iPhone.m4v ( Size: 7969139 )]

posted by James Robertson

 Share Tweet This