One of the features of Seaside is the ability to embed one component inside another component. In this video of chapter 10 of the tutorial “Learning Web Development with Seaside” we enhance the Los Boquitas application with a new component embedded in an existing component.

We launch the Seaside One-Click Experience and then create a new domain class, LBEvent, with instance variables for who, what, when, and where. We use Smalltalk’s refactoring tool to add getter and settor methods for each of the instance variables. The tools shows us the methods that will be added and when we accept the new methods there are eight methods in the ‘accessing’ category.

We create a method to compare events. This allows sorting by the date/time of the event. We create an initialize method that sets each of the instance variables to a reasonable default value.

Now we need a place to save the events. In most applications this would require setting up a relational database but Smalltalk provides a simpler approach–we can create a class instance variable that will hold a collection of events. We can create a class-side method to return the collection. Note that this method includes a “lazy initialization” in which the variable is assigned an initial value if it is unassigned.

Now we add a class-side method to create some sample events. We have included in the method an expression in a comment that when executed will call the method to be evaluated, creating the sample events.

Now we create a new web component that will be used to display the the event list. While it is not necessary, we can register the component as a root-level application so that we can see that it works. We add a minimal render method and then view it in a web browser.

This component will make use of a built-in Seaside component for rendering tabular data. To do this we will create four methods that define the columns of the report. We then create an initialize method that defines a WATableReport with the four columns. Now we can replace our render method with something that renders the table. When we view the application in a web browser, we see that we have a table with four rows.

Now that we have a component to render the events, we will modify our main component to reference this new report. We will add an instance variable, ‘mainArea’ to our main component. We then modify the sidebar to add an anchor that loads our new scheduling copmonent into the main area instance variable.

When we view the application in a web browser, we see that the ‘Events’ link exists, but clicking on it does not have any visible impact. This is because we are not using the instance variable yet. We modify the method that renders the main area so that if there is a component in the instance variable, we render that component. Otherwise we render the image. When we return to the web browser and restart the application, we see that clicking on the ‘Events’ link changes the main area.

We then modify the sidebar so that the heading says ‘Menu’ and there is another anchor labeled ‘Home’. When we view the page in a web browser, we see that the ‘Home’ and ‘Events’ links are run up against each other. This can be fixed by adding a break between them. Now when we view the application in a web browser we can switch between Home and Events.

The use of a conditional, or if statement, in the render method suggests that some refactoring might be needed. We will create a new component, LBHome, that simply displays the image of children playing soccer.

Now return to the main component and add an initialize method to set the main area to the new home component. This allows us to simplify the render main method so that it always renders the main area.

We can then make a simple modification to the sidebar menu so that clicking the ‘Home’ link installs a home component. Viewing the application in a web browser confirms that our refactoring has not broken anything.

Now we would like to be able to do something with an event. We will add an ‘Action’ column to the report that offers a ‘delete’ link. We modify the initialize method so that we have five columns instead of four. When we view the application in a web browser we see that each event has a delete link.

When we click on one of the delete links, Seaside gives us an error: “Components not found while processing callbacks.” As suggested in the error report, a likely cause is that we did not implement the #’children’ method. This method lets the Seaside framework know about subcomponents we have displayed in our rendering process. It turns out that we need to add a children method to the Schedule Component, since it references a WATableReport, and to the main copmonent since it references the schedule component.

Now, when we click on the delete link we get a MessageNotUnderstood error because we are sending a message, #’delete:’, but there is no method to implement that message. Adding that method is simple enough. We simply remove the specified event from the list of all the events.

We can return to the web browser and click refresh. This resends the web request and we see that the list of events is down from three to two. At this point it would be nice to have a JavaScript confirmation to validate the delete. We modify the column so that it includes an on-click event. We can return to our web browser and see that the delete attempt requires a confirmation. Cancelling the delete leaves the event. Confirming the delete removes the event.

At this point we can save our code and quit the Seaside One-Click Experience.