<?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:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Objective Life</title>
	<atom:link href="http://objectcentric.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://objectcentric.wordpress.com</link>
	<description>Smalltalk on Smalltalk and Life</description>
	<pubDate>Wed, 28 Feb 2007 16:14:44 +0000</pubDate>
	<generator>http://wordpress.org/?v=MU</generator>
	<language>en</language>
			<item>
		<title>Classic Singleton</title>
		<link>http://objectcentric.wordpress.com/2007/02/28/classic-singleton/</link>
		<comments>http://objectcentric.wordpress.com/2007/02/28/classic-singleton/#comments</comments>
		<pubDate>Wed, 28 Feb 2007 16:14:44 +0000</pubDate>
		<dc:creator>objectcentric</dc:creator>
		
		<category><![CDATA[Design Patterns]]></category>

		<category><![CDATA[Objects]]></category>

		<category><![CDATA[Smalltalk]]></category>

		<guid isPermaLink="false">http://objectcentric.wordpress.com/2007/02/28/classic-singleton/</guid>
		<description><![CDATA[February is nearly out and I haven&#8217;t posted for a few weeks so I thought I&#8217;d just throw in my thoughts on the use and misuse of Singletons!   Many of my colleagues working in Java pepper their code with static methods and use them as placeholders for pure function calls.  Some would [...]]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>February is nearly out and I haven&#8217;t posted for a few weeks so I thought I&#8217;d just throw in my thoughts on the use and misuse of <a href="http://en.wikipedia.org/wiki/Singleton_pattern" title="Singleton" target="_blank">Singletons</a>!   Many of my colleagues working in Java pepper their code with static methods and use them as placeholders for pure function calls.  Some would argue that the language encourages this.</p>
<p>I&#8217;ve also seen the same thing in Smalltalk code - since the class side only exists once in the image it is in effect a Singleton and therefore we can use this to our advantage and write class methods to achieve the Singleton effect.   So if you want to create a WidgetFactory as a Singleton you can simply add class methods to WidgetFactory that return widgets for you (e.g. #getWidget:).   But just because you can doesn&#8217;t mean you should!</p>
<p><span id="more-20"></span></p>
<p>So why not?</p>
<p><strong>Responsibility Design</strong></p>
<p>Good software objects have clearly defined responsibilities.  The class side of an object has two basic contracts with the rest of your application&#8230;</p>
<ol>
<li>To deliver properly formed instances of itself.</li>
<li>To manage state that is shared across all instances of the class</li>
</ol>
<p>The class side should not be responsible for delivering instances of other classes. The class side of a WidgetFactory can return an instance of a WidgetFactory but it should not return a Widget.  It&#8217;s not its responsibility.</p>
<p><strong>Object Domain Model</strong></p>
<p>It sounds obvious but an object software is made up of objects.  Classes are not part of your domain model.  They are meta objects that describe the shape and contents of your domain objects.  If there is a need for a Singleton to perform a task like &#8220;create new Widgets based on some criteria&#8221; then this should be the responsibility of a WidgetFactory or the WidgetFactory (if you only want one of them in your image) but it is not the responsibility of the &#8220;WidgetFactory Class&#8221;.  There is no such thing as a &#8220;WidgetFactory Class&#8221; in your domain model (unless of course your domain is meta programming)</p>
<p><strong>Extensibility</strong></p>
<p>As you design you can often be pretty sure that you want the WidgetFactory to be a Singleton (i.e. there will only ever be one WidgetFactory in the entire image).  But what happens down the line when you discover the need for a second WidgetFactory (like the first but maybe implementing a slightly different WidgetContruction strategy).  If all of your Widget creational methods (e.g. #getWidget <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> are implemented as instance methods you can easily allow your application to create a second WidgetFactory which all your code will work with unaltered.</p>
<p>If you implemented #getWidget: as a class method on WidgetFactory you&#8217;ve now got a refactoring job to do.  You can&#8217;t have a second WidgetFactory class - Smalltalk won&#8217;t let you and what&#8217;s more all your clients of #getWidget: are calling the class side. Ouch!</p>
<p><strong>So how so you code a Singleton in Smalltalk?</strong></p>
<p>Well first you define a class variable to hold the single instance - (I usually name this &#8220;Instance&#8221;)</p>
<blockquote><p><code>Object subclass: #WidgetFactory<br />
instanceVariableNames: &#8221;<br />
classVariableNames: &#8216;Instance&#8217;<br />
poolDictionaries: &#8221;<br />
category: &#8216;WidgetsRUs-Model&#8217;</code></p></blockquote>
<p>Then I create a class method #getInstance which returns the contents of &#8220;Instance&#8221; (lazy initializing if necessary)</p>
<blockquote><p><code>class&gt;&gt;#getInstance<br />
^Instance ifNil: [Instance := self basicNew ].</code></p></blockquote>
<p>Finally I stop #new from returning another instance of my class</p>
<blockquote><p><code>class&gt;&gt;#new<br />
^self shouldNotImplement</code></p></blockquote>
<p>Some people are tempted to make class&gt;&gt;#new return Instance although I prefer not to as this sets a false expectation on the reader of any client code that a new instance is being returned.</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/objectcentric.wordpress.com/20/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/objectcentric.wordpress.com/20/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/objectcentric.wordpress.com/20/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/objectcentric.wordpress.com/20/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/objectcentric.wordpress.com/20/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/objectcentric.wordpress.com/20/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/objectcentric.wordpress.com/20/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/objectcentric.wordpress.com/20/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/objectcentric.wordpress.com/20/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/objectcentric.wordpress.com/20/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/objectcentric.wordpress.com/20/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/objectcentric.wordpress.com/20/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=objectcentric.wordpress.com&blog=659562&post=20&subd=objectcentric&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://objectcentric.wordpress.com/2007/02/28/classic-singleton/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Why Wouldn&#8217;t You Use Seaside?</title>
		<link>http://objectcentric.wordpress.com/2007/02/07/why-wouldnt-you-use-seaside/</link>
		<comments>http://objectcentric.wordpress.com/2007/02/07/why-wouldnt-you-use-seaside/#comments</comments>
		<pubDate>Wed, 07 Feb 2007 14:03:40 +0000</pubDate>
		<dc:creator>objectcentric</dc:creator>
		
		<category><![CDATA[Seaside]]></category>

		<category><![CDATA[Smalltalk]]></category>

		<guid isPermaLink="false">http://objectcentric.wordpress.com/2007/02/07/why-wouldnt-you-use-seaside/</guid>
		<description><![CDATA[I picked up seaside for the first time 2 months ago and having played with the stuff I guess I&#8217;m intrigued by the question &#8220;why wouldn&#8217;t you use seaside?&#8220;.

Maybe it&#8217;s fundalmental to all conversion experiences to hold your new found beliefs as &#8220;patently obvious&#8221; but there must be reasons why people write web applications in [...]]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>I picked up seaside for the first time 2 months ago and having played with the stuff I guess I&#8217;m intrigued by the question &#8220;<em>why wouldn&#8217;t you use seaside?</em>&#8220;.</p>
<p><span id="more-19"></span><br />
Maybe it&#8217;s fundalmental to all conversion experiences to hold your new found beliefs as &#8220;patently obvious&#8221; but there must be reasons why people write web applications in other languages and frameworks rather than using seaside. A few (non technical) thoughts then on comparative religion and why people don&#8217;t write webapps in seaside.</p>
<ol>
<li>Inadequate Evangelism<br />
&#8220;They do not believe because they have not heard!&#8221; Maybe the nature of people who get a buzz from seaside are just not the type to market there ideas well. (Actually its an interesting point as to whether seasiders want to evangelise this stuff - maybe there is some kind of inherently gnostic view that this is for the special chosen ones and would be too powerful in the hands of the masses.)</li>
<li>A Poor Image<br />
In a post modern world Image is everything. Thirty years ago we might have been able to argue the relative technical merits of different solutions and draw locigal conclusions. Not so now. Image is king. Java does the whole coffee (beans, jars etc) thing really well it&#8217;s image says &#8220;This is cool cafe culture programming&#8221;. Squeak <em>Aubergines </em>really don&#8217;t give the same message. Add to that the &#8220;child&#8217;s play&#8221; look and feel (and name) of Squeak and the secular Javarists will snort at our childish and unsophisticated beliefs.</li>
<li>The Lack of a Sacred Text.<br />
I&#8217;m sat in bed with my copy of &#8220;Programming the Ruby Way&#8221; knowing that this is a mere shadow of what a &#8220;holy book&#8221; should look like but hey some Ruby evangelist gave it me on a street mission in our town and I guess I ought to read it.</li>
<li>False Religion<br />
There are just so many &#8220;Annointed Languages&#8221; out there and &#8220;denominational frameworks&#8221;. And of course in a world of no absolutes they must all be true. Is it possible to declare that we have found &#8220;the truth that sets you free&#8221;. Does it make us arrogant &#8220;we know better than you&#8221; sorts or are we merely errant software developers who have accepted our failure to deliver, repented of it and found our coding salvation in Seaside. (For my part I feel a little like the prodigal son who eventually realised he was eating Java pig-swill and returned home)</li>
<li>Old Time Religion<br />
Smalltalk - yes I remember that. Didn&#8217;t they used to believe that everything was created from Object and there were no types. Still no-one really believes that anymore do they! Didn&#8217;t that chap prove that all things began with a Java Applet that evolved into a Servlet then a JSP that got cross-bred with some HTML - And I&#8217;m sure there was something about an infinite number of monkey&#8217;s typing it. <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </li>
</ol>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/objectcentric.wordpress.com/19/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/objectcentric.wordpress.com/19/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/objectcentric.wordpress.com/19/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/objectcentric.wordpress.com/19/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/objectcentric.wordpress.com/19/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/objectcentric.wordpress.com/19/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/objectcentric.wordpress.com/19/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/objectcentric.wordpress.com/19/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/objectcentric.wordpress.com/19/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/objectcentric.wordpress.com/19/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/objectcentric.wordpress.com/19/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/objectcentric.wordpress.com/19/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=objectcentric.wordpress.com&blog=659562&post=19&subd=objectcentric&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://objectcentric.wordpress.com/2007/02/07/why-wouldnt-you-use-seaside/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Scriptacu-list Tutorial(Part 7)</title>
		<link>http://objectcentric.wordpress.com/2007/01/26/scriptacu-list-tutorialpart-7/</link>
		<comments>http://objectcentric.wordpress.com/2007/01/26/scriptacu-list-tutorialpart-7/#comments</comments>
		<pubDate>Fri, 26 Jan 2007 09:24:58 +0000</pubDate>
		<dc:creator>objectcentric</dc:creator>
		
		<category><![CDATA[Scriptaculous]]></category>

		<category><![CDATA[Seaside]]></category>

		<category><![CDATA[Smalltalk]]></category>

		<guid isPermaLink="false">http://objectcentric.wordpress.com/2007/01/26/scriptacu-list-tutorialpart-7/</guid>
		<description><![CDATA[To complete our application we will allow our users to upload a picture of the contact so that it appears on the details drop down.

Got the Picture?
OK first we need to be able to upload a picture.
We will return to our MyContactEditor and modify the #renderContentOn: method to make the form a multipart form and [...]]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>To complete our application we will allow our users to upload a picture of the contact so that it appears on the details drop down.</p>
<p><span id="more-18"></span></p>
<p><strong>Got the Picture?</strong></p>
<p>OK first we need to be able to upload a picture.</p>
<p>We will return to our MyContactEditor and modify the #renderContentOn: method to make the form a multipart form and add a file upload field.</p>
<blockquote><p><code>renderContentOn: html<br />
html heading: &#8216;Contact Details&#8217;.<br />
html form<br />
multipart;<br />
with:<br />
[<br />
self renderLabel: 'First Name: ' withInput: [html textInput on: #firstName of: contact] on: html.<br />
self renderLabel: &#8216;Surname: &#8216; withInput: [html textInput on: #surname of: contact] on: html.<br />
self renderLabel: &#8216;Date of Birth: &#8216; withInput: [html dateInput on: #dateOfBirth of: contact] on: html.<br />
self renderLabel: &#8216;Telephone: &#8216; withInput: [html textInput on: #telephoneNumber of: contact] on: html.<br />
self renderLabel: &#8216;Email: &#8216; withInput: [html textInput on: #emailAddress of: contact] on: html.<br />
self renderLabel: &#8216;Photograph &#8216; withInput: [html fileUpload callback: [:file | self attachPhotograph: file]] on: html.<br />
html span class: &#8216;button&#8217;;<br />
with: [html submitButton on: #save of: self].<br />
html span class: &#8216;button&#8217;;<br />
with: [html submitButton on: #cancel of: self].<br />
] </code></p></blockquote>
<p>Now we need to code the #attachPhotograph: method that the uploaded file gets passed to.</p>
<blockquote><p><code>attachPhotograph: aFile<br />
| form sizedForm fileName tempStream|<br />
aFile ifNotNil:[<br />
tempStream := RWBinaryOrTextStream with: aFile contents.<br />
tempStream binary.<br />
form := ImageReadWriter formFromStream: tempStream.<br />
sizedForm := form scaledToSize: 100@100.<br />
fileName := contact identifier, '-photo.gif'.<br />
GIFReadWriter putForm: sizedForm onOverwritableFileNamed: 'FileRoot', FileDirectory slash, fileName.]</code></p></blockquote>
<p>This method takes the binary input stream and uses <strong>ImageReadWriter </strong>to obtain the &#8220;form&#8221; i.e. the picture. We then resize the picture to 100px by 100px and save it as a gif name <em>fredbloggs</em>-photo.gif (where <em>fredbloggs </em>is my contact&#8217;s identifier). I save the file in the directory <em>FileRoot </em>which I declared as my Document Root directory for my application.</p>
<p><strong>Let&#8217;s see it Then</strong></p>
<p>Now the final step is to amend the #renderDetailsDiv:on: method in <strong>MyContactDetailView</strong> so that it includes the image from our document root.</p>
<blockquote><p><code>renderDetailsDiv: aString on: html<br />
html div id: aString;<br />
style: &#8216;display: none&#8217;;<br />
with: [<br />
html div<br />
style: 'clear:both';<br />
with: [</code></p>
<p>html image<br />
style: 'float: left; margin-right:10px';<br />
altText: ('Picture of ', contact fullName);<br />
resourceUrl: '/', contact identifier, '-photo.gif' .<br />
].<br />
html render: &#8216;Name: &#8216;, contact fullName.<br />
html break.<br />
html render: &#8216;Birthday: &#8216;, contact dateOfBirth printString.<br />
html break.<br />
html render: &#8216;Telephone: &#8216;, contact telephoneNumber.<br />
html break.<br />
html render: &#8216;Email: &#8216;. contact emailAddress.<br />
html break.<br />
]</p></blockquote>
<p>Job done! (Apart from getting a good CCS/Graphic designer to make it look super cool - If anyone wishes to contribute one I&#8217;d be more than happy to replace my rather basic one in session 3.)</p>
<p>If you stuck with me all the way to the end then I hope you found it worthwhile. And if your just starting out on Seaside I&#8217;d just like to encourage you to blog your progress. It really helps to crystallize your thinking and their are others out there who can add new insights as you go.</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/objectcentric.wordpress.com/18/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/objectcentric.wordpress.com/18/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/objectcentric.wordpress.com/18/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/objectcentric.wordpress.com/18/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/objectcentric.wordpress.com/18/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/objectcentric.wordpress.com/18/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/objectcentric.wordpress.com/18/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/objectcentric.wordpress.com/18/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/objectcentric.wordpress.com/18/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/objectcentric.wordpress.com/18/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/objectcentric.wordpress.com/18/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/objectcentric.wordpress.com/18/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=objectcentric.wordpress.com&blog=659562&post=18&subd=objectcentric&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://objectcentric.wordpress.com/2007/01/26/scriptacu-list-tutorialpart-7/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Scriptacu-list Tutorial(Part 6)</title>
		<link>http://objectcentric.wordpress.com/2007/01/25/scriptacu-list-tutorialpart-6/</link>
		<comments>http://objectcentric.wordpress.com/2007/01/25/scriptacu-list-tutorialpart-6/#comments</comments>
		<pubDate>Thu, 25 Jan 2007 14:15:52 +0000</pubDate>
		<dc:creator>objectcentric</dc:creator>
		
		<category><![CDATA[Scriptaculous]]></category>

		<category><![CDATA[Seaside]]></category>

		<category><![CDATA[Smalltalk]]></category>

		<guid isPermaLink="false">http://objectcentric.wordpress.com/2007/01/25/scriptacu-list-tutorialpart-6/</guid>
		<description><![CDATA[OK if you&#8217;ve stuck with me so far you should have a functioning application with a Scriptaculous effect that you have achieved with very few keystrokes (very few indeed if you just copied my code!). We are nearly at the end of our journey - just 2 more sessions to go. So for today&#8217;s session [...]]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>OK if you&#8217;ve stuck with me so far you should have a functioning application with a Scriptaculous effect that you have achieved with very few keystrokes (very few indeed if you just copied my code!). We are nearly at the end of our journey - just 2 more sessions to go. So for today&#8217;s session we will look at taking that &#8220;Toggle Details&#8221; link and make it more context sensitive - &#8220;Show Details&#8221; to show the details and &#8220;Hide Details&#8221; to hide them.</p>
<p><span id="more-17"></span></p>
<p><strong>Finding a Replacement</strong></p>
<p>This simple requirement was a little trickier than I first thought it would be. My searching through the Scriptaculous classes lead me to <strong>SUElement </strong>which had a very convenient <em>#update:</em> method. All I had to do was get it to change the text of my anchor text from &#8220;Show Detail&#8221; to &#8220;Hide Detail&#8221; when I clicked it. However once this was working I hit the problem of how to toggle it back again afterwards. I didn&#8217;t want to call back to the server and I didn&#8217;t want to write any Javascript so here&#8217;s what I did.</p>
<p>In my <em>#renderContentOn:</em> method in <strong>MyContactDetailsView </strong>I altered my &#8220;Toggle Detail&#8221; anchor to read &#8220;Show Detail&#8221; and added another anchor, &#8220;Hide Detail, like so&#8230;</p>
<blockquote><p><code>renderContentOn: html<br />
html anchor<br />
id: (contact identifier, &#8217;show&#8217;);<br />
onClick: (html effect<br />
id: (contact identifier);<br />
toggleBlind);<br />
with: &#8216;Show Detail&#8217;.<br />
html anchor<br />
id: (contact identifier, &#8216;hide&#8217;);<br />
onClick: (html effect<br />
id: (contact identifier);<br />
toggleBlind);<br />
with: &#8216;Hide Detail&#8217;.</code></p></blockquote>
<p>Note here that I also gave the anchors unique id attributes which we will use in a few moments.</p>
<p>If you try this code you will see that you now have 2 links next to the Contact&#8217;s name. But they both work for showing or hiding!! What we need to do is hide the &#8220;Show Details&#8221; link when the details are open and reinstate it when they are closed.</p>
<p>So since we know that our details will start off closed we know we should start with our &#8220;Hide Details&#8221; link not showing. So do this with a simple style attribute&#8230;</p>
<blockquote><p><code>...<br />
html anchor<br />
id: (player firstName, &#8216;anchor&#8217;);<br />
<strong>style: &#8216;display: none&#8217;;</strong><br />
onClick: (html effect&#8230;</code></p></blockquote>
<p>Now we need to toggle the anchors.</p>
<p>The Scriptaculous effect looks great on our big drop-down details box but is probably overkill for hiding and showing a link text. Instead of using SUEffect we are going to use the SUElement I mentioned earlier. We concatenate our element toggle actions into the <em>#onClick:</em> of both our anchors&#8230;</p>
<blockquote><p><code>html anchor<br />
id: (contact identifier, &#8217;show&#8217;);<br />
onClick: (html effect<br />
id: (contact identifier);<br />
toggleBlind),<br />
(html element<br />
id:(contact identifier, &#8217;show&#8217;);<br />
toggle ),<br />
(html element<br />
id:(contact identifier, &#8216;hide&#8217;) ;<br />
toggle);<br />
with: &#8216;Show Detail&#8217;.</code></p></blockquote>
<p>(NB be sure to apply this to the &#8220;Hide Details&#8221; anchor too).</p>
<p>(NB2 the <em>#toggle</em> on <strong>SUElement </strong>appears to be superfluous as it toggles by default)</p>
<p>Now our links toggle the text correctly and that should be good enough (you might want to add a little CSS to get some space between the Link and our Contact&#8217;s name). But there&#8217;s one last goodie on the <strong>SUEffect </strong>that we can use that will add another little bit of wow to our app - the methods <em>#onBeforeStart:</em> and <em>onAfterFinish:</em>.</p>
<p>With these two methods we can make our links hide and appear either side of the opening of the details box. So our finished method looks like this&#8230;</p>
<blockquote><p><code>renderContentOn: html<br />
html anchor<br />
id: (contact identifier, &#8217;show&#8217;);<br />
style: &#8216;margin-left:40px&#8217;;<br />
onClick: (html effect<br />
id: (contact identifier);<br />
toggleBlind;<br />
onBeforeStart: (html element<br />
id:(contact identifier, &#8217;show&#8217;));<br />
onAfterFinish:(html element<br />
id:(contact identifier, &#8216;hide&#8217;)));<br />
with: &#8216;Show Detail&#8217;.<br />
html anchor<br />
id: (contact identifier, &#8216;hide&#8217;);<br />
style: &#8216;margin-left:40px;display:none&#8217;;<br />
onClick: (html effect<br />
id: (contact identifier);<br />
toggleBlind;<br />
onBeforeStart: (html element<br />
id:(contact identifier, &#8216;hide&#8217;));<br />
onAfterFinish:(html element<br />
id:(contact identifier, &#8217;show&#8217;)));<br />
with: &#8216;Hide Detail&#8217;.<br />
self renderDetailsDiv: contact identifier on: html</code></p></blockquote>
<p>Last part tomorrow.</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/objectcentric.wordpress.com/17/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/objectcentric.wordpress.com/17/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/objectcentric.wordpress.com/17/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/objectcentric.wordpress.com/17/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/objectcentric.wordpress.com/17/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/objectcentric.wordpress.com/17/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/objectcentric.wordpress.com/17/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/objectcentric.wordpress.com/17/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/objectcentric.wordpress.com/17/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/objectcentric.wordpress.com/17/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/objectcentric.wordpress.com/17/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/objectcentric.wordpress.com/17/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=objectcentric.wordpress.com&blog=659562&post=17&subd=objectcentric&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://objectcentric.wordpress.com/2007/01/25/scriptacu-list-tutorialpart-6/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Scriptacu-list Tutorial(Part 5)</title>
		<link>http://objectcentric.wordpress.com/2007/01/24/scriptacu-list-tutorialpart-5/</link>
		<comments>http://objectcentric.wordpress.com/2007/01/24/scriptacu-list-tutorialpart-5/#comments</comments>
		<pubDate>Wed, 24 Jan 2007 09:41:12 +0000</pubDate>
		<dc:creator>objectcentric</dc:creator>
		
		<category><![CDATA[Scriptaculous]]></category>

		<category><![CDATA[Seaside]]></category>

		<category><![CDATA[Smalltalk]]></category>

		<guid isPermaLink="false">http://objectcentric.wordpress.com/2007/01/24/scriptacu-list-tutorialpart-5/</guid>
		<description><![CDATA[Its time to get our little Contact List application into the Web2.0 era by adding a funky Scriptaculous dropdown on our contact list.  The really cool thing  is  that we are going to do all this without writing a single line of Javascript (Lukas Renggli has already done that for us.  Much [...]]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Its time to get our little Contact List application into the Web2.0 era by adding a funky Scriptaculous dropdown on our contact list.  The really cool thing  is  that we are going to do all this without writing a single line of Javascript (<a href="http://www.lukas-renggli.ch/" title="Lukas Renggli's website">Lukas Renggli </a>has already done that for us.  Much respect Lukas!) - it&#8217;s Smalltalk all the way for us!</p>
<p><span id="more-16"></span></p>
<p><strong>Full Contact<br />
</strong></p>
<p>Before we get on to dealing with our views I want to add a couple of methods to <strong>MyContact</strong>.  First I want to add a <em>#fullName</em> method like so.</p>
<blockquote><p><code>fullName<br />
^firstName, &#8216; &#8216;, surname</code></p></blockquote>
<p>&#8230;we have already coded something like this when we rendered the list in <strong>MyAddressBookView </strong>but as we are going to use it again it makes sense to create a method for it.  (You can go back and make the list view use it if you like).  You may already have encountered some errors in concatenating a nil object to a string.  We can prevent that with some defensive code in <em>#fullName</em> if we wish which is another good reason to create it as a separate method. (I&#8217;ll leave the defensive code up to you!).</p>
<p>Secondly iwant to add an <em>#identifier</em> method to act as a key to my contact.   I will do this very crudely like this&#8230;</p>
<blockquote><p><code>identifier<br />
^self fullName asLowercase onlyLetters </code></p></blockquote>
<p>&#8230;we&#8217;re going to use this identifier later as an id attribute on a div in our HTML.</p>
<p><strong>Down to Details</strong></p>
<p>We are now going to create a new class to show our Contact&#8217;s details.</p>
<ol>
<li>Create the class <strong>MyContactDetailsView </strong>as a subclass of <strong>WAComponent </strong>and give it an instance variable of <strong><em>contact</em></strong>.</li>
<li>We need to create a convenience constructor <em>#on:</em> as a class method <strong>MyContactDetailsView</strong>.  We&#8217;ve already done this for <strong>MyContactEditor </strong>so I&#8217;m going let you figure this step for yourself.</li>
<li>As we mentioned in an earlier session Seaside allows you to refactor your html into smaller more useable chunks.  So before we dive into our <em>#renderContentOn:</em> method we will create another method <em>#renderDetailsDiv:on:</em> that it will call.<br />
<blockquote><p><code>renderDetailsDiv: aString on: html<br />
html div id: aString;<br />
with: [		html render: 'Name: ', contact fullName.<br />
html break.<br />
html render: 'Birthday:  ', contact dateOfBirth printString.<br />
html break.<br />
html render: 'Telephone: ', contact telephoneNumber.<br />
html break.<br />
html render: 'Email: '. contact emailAddress.<br />
html break.<br />
]</code></p></blockquote>
<p>&#8230;this very simply creates a new div with an id attribute containing our contact&#8217;s <em>identifier</em>.  This id attribute will be used by the Scriptaculous Javascript later on to hide and show the div.</li>
<li>Now we need to create our <em>#renderContentOn:</em> method and make it call <em>#renderDetailsDiv:on:</em>&#8230;<br />
<blockquote><p><code>renderContentOn: html<br />
self renderDetailsDiv: contact identifier  on: html</code></p></blockquote>
<p>&#8230;this is not the finished article yet but its good enough to let us test that all is well, so we&#8217;ll leave it here and come back shortly.</li>
<li>The last thing that we need to do before we can give our code a quick test is to add a line of code into the <em>#renderContentOn:</em> method in <strong>MyAddressBookView</strong>.  Remember the <em>#inject:into:</em> call we coded last time?  Well now we need to modify it so it looks like this&#8230;<br />
<blockquote><p><code>	self addressBook contacts inject: 1 into: [:index :contact |<br />
html div class: ('row', (index\\2) printString );<br />
with: [<br />
html anchor<br />
callback: [self showContact: contact];<br />
with: (contact firstName , &#8216; &#8216;, contact surname ).<br />
<strong>html render: (MyContactDetailView on: contact).</strong><br />
].<br />
index + 1.<br />
].</code></p></blockquote>
</li>
</ol>
<p>Before we move on let&#8217;s just give our code a quick test.  We should see that for each Conact in our list we are displaying their details under their name.</p>
<p><strong>Getting Animated</strong><br />
Now we are going to animate our details div so it toggles smoothly in and out of view.</p>
<p>Open up that one line <em>#renderContentOn:</em> method in <strong>MyContactDetailsView </strong>and add the following lines at the top of the method&#8230;</p>
<blockquote><p><code>html anchor<br />
style: &#8216;margin-left: 40px&#8217;;<br />
onClick: (html effect<br />
id: (contact identifier);<br />
perform: #toggleBlind);<br />
with: &#8216;Toggle Detail&#8217;.</code></p></blockquote>
<p>What we&#8217;ve done here is added a new hyperlink &#8220;Toggle Detail&#8221; which when clicked will call a Scriptaculous <em>#toggleBlind</em> effect on the div who&#8217;s id attribute is the contacts identifier.</p>
<p>Test your app again and see what happens.  Nothing eh!?</p>
<p>We have one last thing to do.  We need to include the Scriptaculous library for our application.  From the browser select &#8220;Configure&#8221; from the Seaside toolbar at the bottom of the screen (If you&#8217;ve got my CSS installed you might struggle to see it - sorry!).  Add the <strong>SULibrary </strong>to your Application and save the configuration.  Now test your Application again - how cool is that!</p>
<p>Just before we close for today we will just do one more thing.  Our Contact list would look much better if the details started off hidden. So lets make it happen by modifying our <em>#renderDetailsDiv:on:</em> method in MyContactDetailsView like so&#8230;</p>
<blockquote><p><code>renderDetailsDiv: aString on: html<br />
html div id: aString;<br />
<strong>style: &#8216;display: none&#8217;;</strong><br />
with: [		html render: 'Name: ', contact fullName.<br />
html break.<br />
html render: 'Birthday:  ', contact dateOfBirth printString.<br />
html break.<br />
html render: 'Telephone: ', contact telephoneNumber.<br />
html break.<br />
html render: 'Email: '. contact emailAddress.<br />
html break.<br />
]</code></p></blockquote>
<p><strong>Homework</strong><br />
Before the next session open up a Class Browser on <strong>SUEffect </strong>and play around with the other things it can do.</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/objectcentric.wordpress.com/16/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/objectcentric.wordpress.com/16/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/objectcentric.wordpress.com/16/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/objectcentric.wordpress.com/16/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/objectcentric.wordpress.com/16/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/objectcentric.wordpress.com/16/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/objectcentric.wordpress.com/16/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/objectcentric.wordpress.com/16/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/objectcentric.wordpress.com/16/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/objectcentric.wordpress.com/16/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/objectcentric.wordpress.com/16/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/objectcentric.wordpress.com/16/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=objectcentric.wordpress.com&blog=659562&post=16&subd=objectcentric&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://objectcentric.wordpress.com/2007/01/24/scriptacu-list-tutorialpart-5/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Scriptacu-list Tutorial(Part 4)</title>
		<link>http://objectcentric.wordpress.com/2007/01/23/scriptacu-list-tutorialpart-4/</link>
		<comments>http://objectcentric.wordpress.com/2007/01/23/scriptacu-list-tutorialpart-4/#comments</comments>
		<pubDate>Tue, 23 Jan 2007 09:47:48 +0000</pubDate>
		<dc:creator>objectcentric</dc:creator>
		
		<category><![CDATA[Seaside]]></category>

		<category><![CDATA[Smalltalk]]></category>

		<guid isPermaLink="false">http://objectcentric.wordpress.com/2007/01/23/scriptacu-list-tutorialpart-4/</guid>
		<description><![CDATA[Time&#8217;s tight today so I will just introduce my technique for creating alternating rows into our contact list.

Injecting a Little Class 
Last time we added a CSS to improve the look of our application but our list needs a little something extra.  It is very common when presenting a list to make each row [...]]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Time&#8217;s tight today so I will just introduce my technique for creating alternating rows into our contact list.</p>
<p><span id="more-15"></span></p>
<p><strong>Injecting a Little Class </strong></p>
<p>Last time we added a CSS to improve the look of our application but our list needs a little something extra.  It is very common when presenting a list to make each row appear in alternating colors.  Today we will acheive this effect with our contact list.</p>
<p>The principal is simple and makes use of the class attributes and our CSS.  All we need to do is display a row with a class attribute of &#8220;row0&#8243; then display the next with &#8220;row1&#8243;, the next with &#8220;row0&#8243;, then &#8220;row1&#8243; again and so on.</p>
<p>So here&#8217;s my solution using a Collection&#8217;s clever and often ignored #inject:into: method.</p>
<p>Select the #renderContentOn: method in MyAddressBookView and replace the following code&#8230;</p>
<blockquote><p><code>	self addressBook contacts do: [:contact |<br />
html div class: ('row');<br />
with: [<br />
html anchor<br />
callback: [self showContact: contact];<br />
with: (contact firstName , &#8216; &#8216;, contact surname ).<br />
].<br />
].</code></p></blockquote>
<p>&#8230;with &#8230;</p>
<blockquote><p><code>	self addressBook contacts inject: 1 into: [:index :contact |<br />
html div class: ('row', (index\\2) printString );<br />
with: [<br />
html anchor<br />
callback: [self showContact: contact];<br />
with: (contact firstName , &#8216; &#8216;, contact surname ).<br />
].<br />
index + 1.<br />
].</code></p></blockquote>
<p>What we have done here is injected a counter into the loop and used a bit of modulo arithmetic to calculate the remainder of our index when divided by 2.  At the end of the loop we increment the index so the new value can be injected back in next time.</p>
<p>Hopefully the .row0 and .row1 definitions are already in the stylesheet from last time.</p>
<p>You can easily extend this technique to alternate over more than 2 styles.</p>
<p>Next time we will get into Scriptaculous to make our little app look really cool!</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/objectcentric.wordpress.com/15/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/objectcentric.wordpress.com/15/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/objectcentric.wordpress.com/15/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/objectcentric.wordpress.com/15/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/objectcentric.wordpress.com/15/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/objectcentric.wordpress.com/15/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/objectcentric.wordpress.com/15/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/objectcentric.wordpress.com/15/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/objectcentric.wordpress.com/15/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/objectcentric.wordpress.com/15/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/objectcentric.wordpress.com/15/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/objectcentric.wordpress.com/15/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=objectcentric.wordpress.com&blog=659562&post=15&subd=objectcentric&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://objectcentric.wordpress.com/2007/01/23/scriptacu-list-tutorialpart-4/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Scriptacu-list Tutorial(Part 3)</title>
		<link>http://objectcentric.wordpress.com/2007/01/22/scriptacu-list-tutorialpart-3/</link>
		<comments>http://objectcentric.wordpress.com/2007/01/22/scriptacu-list-tutorialpart-3/#comments</comments>
		<pubDate>Mon, 22 Jan 2007 16:46:52 +0000</pubDate>
		<dc:creator>objectcentric</dc:creator>
		
		<category><![CDATA[Design Patterns]]></category>

		<category><![CDATA[Objects]]></category>

		<category><![CDATA[Seaside]]></category>

		<category><![CDATA[Smalltalk]]></category>

		<guid isPermaLink="false">http://objectcentric.wordpress.com/2007/01/22/scriptacu-list-tutorialpart-3/</guid>
		<description><![CDATA[So we&#8217;ve got a simple Contact List working but there are two big problems.

When I&#8217;m editing the contact the data changes even if I click &#8220;Cancel&#8221;.
It doesn&#8217;t look very pretty.

Today we are going to fix this&#8230;

A Little Memento
Our problem with the data changing even when we click cancel is a common one in &#8220;pass by [...]]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>So we&#8217;ve got a simple Contact List working but there are two big problems.</p>
<ol>
<li>When I&#8217;m editing the contact the data changes even if I click &#8220;Cancel&#8221;.</li>
<li>It doesn&#8217;t look very pretty.</li>
</ol>
<p>Today we are going to fix this&#8230;</p>
<p><span id="more-14"></span></p>
<p><strong>A Little Memento</strong></p>
<p>Our problem with the data changing even when we click cancel is a common one in &#8220;pass by reference&#8221; object oriented languages.  In the editor view you are working with exactly the same object as you were looking at in the list view.</p>
<p>We can solve this with a Design Pattern called &#8220;Memento&#8221;.  There are a few different ways  of implementing Memento in Smalltalk (including the use of #become:,  which I love to show to Java programmers but generally don&#8217;t recommend implementing in real systems).  What I will present here is a use of Memento that goes like this.</p>
<ol>
<li>From the list view the user selects an <strong>Contact </strong>to edit.</li>
<li>The System takes a copy of the <strong>Contact</strong>&#8217;s current state (a <em>memento</em>).</li>
<li>The System opens an editor on the original <strong>Contact</strong></li>
<li>If the user clicks &#8220;Save&#8221; the system simply returns to the list view as all the data changes happened in the editor.</li>
<li>If the user clicks &#8220;Cancel&#8221; then we copy back the stored data from our <em>memento </em>into our <strong>Contact</strong></li>
</ol>
<p>(NB Some people prefer to let the editor work on the copy rather than the original object and then do nothing if Canceled or copy the new state if Saved)</p>
<p>So on to the code.  First we need replace #showContact: in MyAddressBookView with&#8230;</p>
<blockquote><p><code>showContact: aContact<br />
| contactEditor memento|<br />
memento := aContact copy.<br />
contactEditor := MyContactEditor on: aContact.<br />
(self call: contactEditor) ifFalse: [aContact resetFromMemento: memento]</code></p></blockquote>
<p>Then we need to create a new #resetFromMemento: method in MyContact&#8230;</p>
<blockquote><p><code>resetFromMemento: aMemento<br />
dateOfBirth := aMemento dateOfBirth.<br />
emailAddress := aMemento emailAddress.<br />
firstName := aMemento firstName.<br />
surname := aMemento surname.<br />
telephoneNumber  := aMemento telephoneNumber.</code></p></blockquote>
<p>&#8230;and that&#8217;s all there is to it.</p>
<p><strong>Improving my Looks</strong></p>
<p>Before we can really show off our new app we need to get rid of that clunky browser default font and make it look a bit nicer.  We will do this by adding a very simple CSS stylesheet.  (I&#8217;m not a graphic artist or css expert so please don&#8217;t expect too much of this).</p>
<p>Seaside lets you code your CSS in a number of different ways but I concur with <a href="http://onsmalltalk.com/programming/smalltalk/pragmatic-css-and-javascript-in-seaside/" title="Pragmatic CSS and Javascript in Seaside">Ramon Leon&#8217;s conclusions</a> that externalising CSS to a file is best.  So here&#8217;s our CSS&#8230;</p>
<blockquote><p><code>body { background-color: #fff;<br />
font-family: &#8220;Trebuchet MS&#8221;}<br />
div{<br />
padding: 2px;<br />
}<br />
.row1 {<br />
background-color: #99d ;<br />
color: #fff;<br />
}<br />
.row0 {<br />
background-color: #67d ;<br />
color: #fff;<br />
}<br />
.row {<br />
background-color: #67d ;<br />
color: #fff;<br />
}<br />
a{<br />
color: #ccf;<br />
font-weight: bold;<br />
text-decoration: none;<br />
}<br />
h1{<br />
color: orange;<br />
}<br />
.field{<br />
margin-left:30px<br />
}</code></p></blockquote>
<p>&#8230;which we need to save as &#8220;main.css&#8221; on the document root of our application.  (This is most probably in the directory from which you startup squeak unless you have reconfigured your web server.  See <a href="http://www.shaffer-consulting.com/david/Seaside/GettingSoftware/index.html" title="A Seaside tutorial by C. David Shaffer">David Shaffer&#8217;s tutorial</a> for more on configuring the web server)</p>
<p>We now need to make our web pages include a link to the CSS.  We can achieve this by overriding the #updateRoot: method on our <strong>MyAddressBookView </strong>and our <strong>MyContactEditor </strong>as follows&#8230;</p>
<blockquote><p><code>updateRoot: aRoot<br />
super updateRoot: aRoot.<br />
aRoot linkToStyle: &#8216;/main.css&#8217;</code></p></blockquote>
<p>&#8230;but since you are adding the same method to two classes you really should refactor  the hierarchy here by introducing a <strong>MyAddressBookBaseView </strong>class as a subclass of <strong>WAComponent</strong>.  You can then make <strong>MyAddressBookView </strong>and <strong>MyContactEditor </strong>subclass this new class and move #updateRoot: into it.</p>
<p><strong>Homework  !</strong></p>
<p>So we now have an application that works and looks good too!  (Well it will if you put a bit more effort int the CSS :-)).</p>
<p>Your homework for today is to grab the nearest Java or .Net developer and challenge them to build the same app as quickly as you have done!</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/objectcentric.wordpress.com/14/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/objectcentric.wordpress.com/14/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/objectcentric.wordpress.com/14/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/objectcentric.wordpress.com/14/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/objectcentric.wordpress.com/14/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/objectcentric.wordpress.com/14/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/objectcentric.wordpress.com/14/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/objectcentric.wordpress.com/14/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/objectcentric.wordpress.com/14/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/objectcentric.wordpress.com/14/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/objectcentric.wordpress.com/14/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/objectcentric.wordpress.com/14/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=objectcentric.wordpress.com&blog=659562&post=14&subd=objectcentric&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://objectcentric.wordpress.com/2007/01/22/scriptacu-list-tutorialpart-3/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Scriptacu-list Tutorial(Part 2)</title>
		<link>http://objectcentric.wordpress.com/2007/01/18/scriptacu-list-tutorialpart-2/</link>
		<comments>http://objectcentric.wordpress.com/2007/01/18/scriptacu-list-tutorialpart-2/#comments</comments>
		<pubDate>Thu, 18 Jan 2007 16:13:26 +0000</pubDate>
		<dc:creator>objectcentric</dc:creator>
		
		<category><![CDATA[Seaside]]></category>

		<category><![CDATA[Smalltalk]]></category>

		<guid isPermaLink="false">http://objectcentric.wordpress.com/2007/01/18/scriptacu-list-tutorialpart-2/</guid>
		<description><![CDATA[So we&#8217;ve got our first cut domain model and now its time to add our views.  Today we are going to add another two classes MyAddressBookView and MyContactEditor&#8230;
  MyAddressBookView

We begin by creating  MyAddressBookView as a sublcass of WAComponent with an instance variable of addressBook.  (NB by using an instance variable it [...]]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>So we&#8217;ve got our first cut domain model and now its time to add our views.  Today we are going to add another two classes MyAddressBookView and MyContactEditor&#8230;</p>
<p><span id="more-13"></span>  <strong>MyAddressBookView</strong></p>
<ol>
<li>We begin by creating  <strong><em>MyAddressBookView </em></strong>as a sublcass of <strong><em>WAComponent</em></strong> with an instance variable of <strong><em>addressBook</em></strong>.  (NB by using an instance variable it will mean that your address book gets reset for every session.  If you&#8217;re not happy with that you can use a class variable instead)</li>
<li>Once again we will lazy initialize our variable<br />
<blockquote><p><code> addressBook<br />
    ^addressBook ifNil: [addressBook := MyAddressBook new]<br />
</code></p></blockquote>
</li>
<li>Now we will create our rendering method.  We start simple by coding a heading&#8230;<br />
<blockquote><p><code>renderContentOn: html<br />
 html heading: &#8216;Contacts&#8217; level: 1.</code></p></blockquote>
</li>
<li>Then we add some more lines that will iterate over our collection of contacts and for each one display their name as a hyperlink to a page where their details can be edited&#8230;<br />
<blockquote><p><code>self addressBook<br />
contacts do: [:contact |<br />
html div class: ('row');<br />
with: [<br />
html anchor<br />
callback: [self showContact: contact];<br />
with: (contact firstName , &#8216; &#8216;, contact surname )]]</code></p></blockquote>
</li>
<li>Lastly we will add a few lines to create a button which will allow us to create a new Contact&#8230;<br />
<blockquote><p><code>html form: [<br />
html span class: 'button';<br />
with: [html submitButton on: #addContact of: self]] </code></p></blockquote>
<p>(Note here the the on: aSymbol of: anObject is a convenience method that uses aSymbol to derive a label for the button and the method to perform.  Neat eh!)</li>
<li>Before this code can run we need to define the two methods that called in the <em>renderContentOn:</em> method above.  First we will define the <strong>addContact:</strong> method<br />
<blockquote><p><code>addContact<br />
| contactEditor contact |<br />
contact := MyContact  new.<br />
contactEditor := MyContactEditor  on: contact.<br />
(self call: contactEditor) ifTrue: [self addressBook addContact: contact]</code></p></blockquote>
<p>&#8230;this is all pretty straightforward except to point out that we will only add our new contact if the editor replies <em><strong>true</strong> </em>(as a result of clicking save)</li>
<li>Finally for this class we will add our <strong>showContact:</strong> method&#8230;<br />
<blockquote><p><code>showContact: aContact<br />
self call: (MyContactEditor on: aContact) </code></p></blockquote>
<p>&#8230;managing save and cancel for new contacts is easy.  For editing it is a little more involved.  Next time we will alter this method to implement a memento for the contact</li>
</ol>
<p><strong>MyContactEditor</strong></p>
<ol>
<li>Now we need to create the editor for our contacts.  Again we create  <em><strong>MyContactEditor </strong></em>as a subclass of <em><strong>WAComponent </strong></em>this time with an instance variable of <em><strong>contact</strong></em>.</li>
<li>Now create the accessors for the <em><strong>contact </strong></em>variable like we did for the variables in our domain classes last time.</li>
<li>We are now going to create a class method that will deliver us a new Editor with the contact already populated&#8230;<br />
<blockquote><p><code>on: aContact<br />
^self new<br />
contact: aContact ;<br />
yourself</code></p></blockquote>
</li>
<li>One of the most powerful things about seaside is the ability to factor your html into small callable methods.  When creating a form I often repeat the same pattern for each input field; I create a <em>div</em>; I put a label for the field inside a &#8220;label&#8221; <em>span</em>; I put an input field inside a &#8220;field&#8221; <em>span</em>.  So lets create a method that will do that for us&#8230;<br />
<blockquote><p><code>renderLabel: aLabel withInput: anInputFieldBlock on: html<br />
html div class: &#8216;row&#8217;;<br />
with: [<br />
html span<br />
class: 'label';<br />
with: aLabel .<br />
html span<br />
class: 'field';<br />
with: anInputFieldBlock].</code></p></blockquote>
</li>
<li>Now we can use this in our rendering&#8230;<br />
<blockquote><p><code>renderContentOn: html<br />
html heading: &#8216;Contact Details&#8217;.<br />
html form<br />
with:<br />
[<br />
self renderLabel: 'First Name: ' withInput: [html textInput on: #firstName of: contact] on:  html.<br />
self renderLabel: &#8216;Surname: &#8216; withInput: [html textInput on: #surname of: contact] on:  html.<br />
self renderLabel: &#8216;Date of Birth: &#8216; withInput: [html dateInput on: #dateOfBirth of: contact] on:  html.<br />
self renderLabel: &#8216;Telephone: &#8216; withInput: [html textInput on: #telephoneNumber of: contact] on:  html.<br />
self renderLabel: &#8216;Email: &#8216; withInput: [html textInput on: #emailAddress of: contact] on:  html.<br />
html span class: &#8216;button&#8217;;<br />
with: [html submitButton on: #save of: self].<br />
html span class: &#8216;button&#8217;;<br />
with: [html submitButton on: #cancel of: self].<br />
]</code></p></blockquote>
</li>
<li>Finally we need to create the <strong><em>save </em></strong>and <strong><em>cancel </em></strong>methods called by our buttons&#8230;<br />
<blockquote><p><code>save<br />
self answer: true</code></p></blockquote>
<blockquote><p><code>cancel<br />
self answer: false</code></p></blockquote>
</li>
</ol>
<p>If you got through all that OK then open up a workspace and evaluate <code>MyAddressBookView registerAsApplication: 'AddressBook'</code> and hopefully you can then try out your app (most probably on http://localhost:8080/seaside/AddressBook)</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/objectcentric.wordpress.com/13/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/objectcentric.wordpress.com/13/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/objectcentric.wordpress.com/13/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/objectcentric.wordpress.com/13/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/objectcentric.wordpress.com/13/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/objectcentric.wordpress.com/13/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/objectcentric.wordpress.com/13/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/objectcentric.wordpress.com/13/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/objectcentric.wordpress.com/13/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/objectcentric.wordpress.com/13/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/objectcentric.wordpress.com/13/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/objectcentric.wordpress.com/13/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=objectcentric.wordpress.com&blog=659562&post=13&subd=objectcentric&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://objectcentric.wordpress.com/2007/01/18/scriptacu-list-tutorialpart-2/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Scriptacu-list Tutorial(Part 1)</title>
		<link>http://objectcentric.wordpress.com/2007/01/17/scriptacu-list-tutorialpart-1/</link>
		<comments>http://objectcentric.wordpress.com/2007/01/17/scriptacu-list-tutorialpart-1/#comments</comments>
		<pubDate>Wed, 17 Jan 2007 12:02:08 +0000</pubDate>
		<dc:creator>objectcentric</dc:creator>
		
		<category><![CDATA[Scriptaculous]]></category>

		<category><![CDATA[Seaside]]></category>

		<category><![CDATA[Smalltalk]]></category>

		<guid isPermaLink="false">http://objectcentric.wordpress.com/2007/01/17/scriptacu-list-tutorialpart-1/</guid>
		<description><![CDATA[Learning Seaside is fun and there are a number of good tutorials out there (but beware that some don&#8217;t use the latest Seaside 2.7 release) and a number of good blogs (I especially recommend Ramon Leon&#8217;s Blog). But it can still be a bit tricky to find examples of exactly what you want. What I&#8217;d [...]]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Learning Seaside is fun and there are a number of good <a target="_blank" href="//http://www.seaside.st/Tutorial/" title="Seaside Tutorials">tutorials </a>out there (but beware that some don&#8217;t use the latest Seaside 2.7 release) and a number of good blogs (I especially recommend <a target="_blank" href="http://onsmalltalk.com" title="On Smalltalk">Ramon Leon&#8217;s Blog</a>). But it can still be a bit tricky to find examples of exactly what you want. What I&#8217;d like to do over the next couple of posts is provide a worked example of a commonly used presentation technique with an extra <a href="http://script.aculo.us/" title="Scriptaculous website">Scriptaculous </a>twist.</p>
<p><span id="more-8"></span></p>
<p><strong>The Big Picture</strong></p>
<p>One of the first things I look to do in a web framework is to create a page showing a list of items with each item having a hyperlink to a maintenance page for the item. It&#8217;s a pattern I use again and again in web applications but nothing does it as well as Seaside.</p>
<p>So I&#8217;ll whet your appetite today by showing you the screens we will build over the next few days.</p>
<p>The application is a simple Contact List. So first we have a page for editing contact details&#8230;</p>
<p><a href="http://objectcentric.files.wordpress.com/2007/01/editpage1.jpg" title="Contact Details Page"><img src="http://objectcentric.files.wordpress.com/2007/01/editpage1.jpg" alt="Contact Details Page" /></a></p>
<p>We then want a list of all our contacts looking something like&#8230;</p>
<p><a href="http://objectcentric.files.wordpress.com/2007/01/listpage.jpg" title="Contact List Page"><img src="http://objectcentric.files.wordpress.com/2007/01/listpage.jpg" alt="Contact List Page" /></a></p>
<p>Finally we will add a nice scriptaculous effect to show and hide contact details in-line&#8230;<br />
<img src="http://objectcentric.files.wordpress.com/2007/01/listdetails.jpg" alt="Scriptaculist" /><br />
<strong>Getting Started</strong></p>
<p>So for a simple start today we&#8217;ll create our domain model in Squeak. We will create two classes MyAddressBook and MyContact&#8230;</p>
<ol>
<li>Create a new category for your classes, say, MyContacts</li>
<li>In your category create a new class <strong><em>MyAddressBook </em></strong>(for now you can simply subclass Object) with an instance variable <strong><em>contacts</em></strong></li>
<li>Create a getter for contacts that lazy initializes to an empty OrderedCollection&#8230;<br />
<blockquote><p><code><br />
contacts<br />
^contacts ifNil: [contacts := OrderedCollection new]<br />
</code></p></blockquote>
</li>
<li>We will also create an instance method to add a contact to the address book (We won&#8217;t bother with deleting contacts - you never know when they will come in useful ;-))<br />
<blockquote><p><code>addContact: aContact<br />
self contacts add: aContact</code></p></blockquote>
</li>
<li>Now create another new class <em><strong>MyContact </strong></em>with instance variables <em><strong>firstName</strong></em>, <em><strong>surname</strong></em>, <em><strong>dateOfBirth</strong></em>, <em><strong>telephoneNumber </strong></em>and <em><strong>emailAddress</strong></em></li>
<li>Create a setter and getter method for each variable. E.g.<br />
<blockquote><p><code>firstName: aString<br />
firstName:= aString<br />
</code></p></blockquote>
<blockquote><p><code>firstName<br />
^firstName</code></p></blockquote>
</li>
<li>For simplicity we will lazy initialize dateOfBirth to be today&#8217;s date.<br />
<blockquote><p><code>dateOfBirth<br />
^dateOfBirth ifNil: [dateOfBirth:= Date today]<br />
</code></p></blockquote>
</li>
</ol>
<p class="MsoNormal"><span style="font-size:9pt;font-family:Century;"></span>That will probably do for starters - no Seaside yet just everyday Smalltalk . We will pick up here later.</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/objectcentric.wordpress.com/8/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/objectcentric.wordpress.com/8/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/objectcentric.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/objectcentric.wordpress.com/8/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/objectcentric.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/objectcentric.wordpress.com/8/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/objectcentric.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/objectcentric.wordpress.com/8/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/objectcentric.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/objectcentric.wordpress.com/8/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/objectcentric.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/objectcentric.wordpress.com/8/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=objectcentric.wordpress.com&blog=659562&post=8&subd=objectcentric&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://objectcentric.wordpress.com/2007/01/17/scriptacu-list-tutorialpart-1/feed/</wfw:commentRss>
	
		<media:content url="http://objectcentric.files.wordpress.com/2007/01/editpage1.jpg" medium="image">
			<media:title type="html">Contact Details Page</media:title>
		</media:content>

		<media:content url="http://objectcentric.files.wordpress.com/2007/01/listpage.jpg" medium="image">
			<media:title type="html">Contact List Page</media:title>
		</media:content>

		<media:content url="http://objectcentric.files.wordpress.com/2007/01/listdetails.jpg" medium="image">
			<media:title type="html">Scriptaculist</media:title>
		</media:content>
	</item>
		<item>
		<title>They Want it All</title>
		<link>http://objectcentric.wordpress.com/2007/01/12/they-want-it-all/</link>
		<comments>http://objectcentric.wordpress.com/2007/01/12/they-want-it-all/#comments</comments>
		<pubDate>Fri, 12 Jan 2007 13:00:24 +0000</pubDate>
		<dc:creator>objectcentric</dc:creator>
		
		<category><![CDATA[Croquet]]></category>

		<category><![CDATA[Scratch]]></category>

		<category><![CDATA[Smalltalk]]></category>

		<guid isPermaLink="false">http://objectcentric.wordpress.com/2007/01/12/they-want-it-all/</guid>
		<description><![CDATA[So I sat down last night with my 9 year old boy who&#8217;s got in his head some ideas about a game he wants to write.  We open up Scratch and I start to show him what it can do.
First I animate my cat and get him walking around.
&#8220;But it has to be a [...]]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>So I sat down last night with my 9 year old boy who&#8217;s got in his head some ideas about a game he wants to write.  We open up Scratch and I start to show him what it can do.</p>
<p>First I animate my cat and get him walking around.</p>
<p>&#8220;But it has to be a monkey Dad, not a cat&#8221;</p>
<p>&#8220;OK we&#8217;ll make him a monkey&#8221; - we select the cat and change his costume.  Cool.</p>
<p>&#8220;But the monkey has to go into the tree house, Dad.&#8221;</p>
<p>&#8220;OK.  Lets create a background with a tree house.&#8221;  - we build our stage and add a tree house with a ladder.  When the monkey gets to the ladder he climbs it and gets to the house.</p>
<p>&#8220;Now he needs to go through the door and be in the lounge&#8221;</p>
<p>We make it happen.  I smile smuggly at what we&#8217;ve acheived and tell him that&#8217;s it for tonight.</p>
<p>&#8220;OK but tomorrow I want to get my friends on the internet to come and join me with their monkeys in the lounge&#8221;</p>
<p>I swallow hard and explain how I can&#8217;t do that with Scratch.</p>
<p>The kids of today just want it all!  Maybe tomorrow I&#8217;ll show him Croquet.</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/objectcentric.wordpress.com/7/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/objectcentric.wordpress.com/7/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/objectcentric.wordpress.com/7/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/objectcentric.wordpress.com/7/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/objectcentric.wordpress.com/7/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/objectcentric.wordpress.com/7/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/objectcentric.wordpress.com/7/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/objectcentric.wordpress.com/7/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/objectcentric.wordpress.com/7/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/objectcentric.wordpress.com/7/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/objectcentric.wordpress.com/7/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/objectcentric.wordpress.com/7/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=objectcentric.wordpress.com&blog=659562&post=7&subd=objectcentric&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://objectcentric.wordpress.com/2007/01/12/they-want-it-all/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>