Scriptacu-list Tutorial(Part 6)

OK if you’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’s session we will look at taking that “Toggle Details” link and make it more context sensitive – “Show Details” to show the details and “Hide Details” to hide them.

Finding a Replacement

This simple requirement was a little trickier than I first thought it would be. My searching through the Scriptaculous classes lead me to SUElement which had a very convenient #update: method. All I had to do was get it to change the text of my anchor text from “Show Detail” to “Hide Detail” when I clicked it. However once this was working I hit the problem of how to toggle it back again afterwards. I didn’t want to call back to the server and I didn’t want to write any Javascript so here’s what I did.

In my #renderContentOn: method in MyContactDetailsView I altered my “Toggle Detail” anchor to read “Show Detail” and added another anchor, “Hide Detail, like so…

renderContentOn: html
html anchor
id: (contact identifier, 'show');
onClick: (html effect
id: (contact identifier);
toggleBlind);
with: 'Show Detail'.
html anchor
id: (contact identifier, 'hide');
onClick: (html effect
id: (contact identifier);
toggleBlind);
with: 'Hide Detail'.

Note here that I also gave the anchors unique id attributes which we will use in a few moments.

If you try this code you will see that you now have 2 links next to the Contact’s name. But they both work for showing or hiding!! What we need to do is hide the “Show Details” link when the details are open and reinstate it when they are closed.

So since we know that our details will start off closed we know we should start with our “Hide Details” link not showing. So do this with a simple style attribute…

...
html anchor
id: (player firstName, 'anchor');
style: 'display: none';
onClick: (html effect...

Now we need to toggle the anchors.

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 #onClick: of both our anchors…

html anchor
id: (contact identifier, 'show');
onClick: (html effect
id: (contact identifier);
toggleBlind),
(html element
id:(contact identifier, 'show');
toggle ),
(html element
id:(contact identifier, 'hide') ;
toggle);
with: 'Show Detail'.

(NB be sure to apply this to the “Hide Details” anchor too).

(NB2 the #toggle on SUElement appears to be superfluous as it toggles by default)

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’s name). But there’s one last goodie on the SUEffect that we can use that will add another little bit of wow to our app – the methods #onBeforeStart: and onAfterFinish:.

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…

renderContentOn: html
html anchor
id: (contact identifier, 'show');
style: 'margin-left:40px';
onClick: (html effect
id: (contact identifier);
toggleBlind;
onBeforeStart: (html element
id:(contact identifier, 'show'));
onAfterFinish:(html element
id:(contact identifier, 'hide')));
with: 'Show Detail'.
html anchor
id: (contact identifier, 'hide');
style: 'margin-left:40px;display:none';
onClick: (html effect
id: (contact identifier);
toggleBlind;
onBeforeStart: (html element
id:(contact identifier, 'hide'));
onAfterFinish:(html element
id:(contact identifier, 'show')));
with: 'Hide Detail'.
self renderDetailsDiv: contact identifier on: html

Last part tomorrow.

Advertisements
Explore posts in the same categories: Scriptaculous, Seaside, Smalltalk

8 Comments on “Scriptacu-list Tutorial(Part 6)”

  1. Ramon Leon Says:

    It may be worth mentioning that when one needs to do something outside the realm of Scriptaculous, that Scriptaculous objects simply asString into JavaScript. Those #onEvent: methods actually take raw JavaScript strings. So one can always just write the necessary script manually inline like so…

    toggleTitleJs := ‘$(“‘, contact identifier, ‘”).innerHTML =
      $(“‘, contact identifier, ‘”).innerHTML.indexOf(”Show”) > -1
       ? ”Hide Detail” : ”Show Detail”’.

    html anchor
      id: contact identifier;
      onClick: toggleTitleJs;
      with: ‘Show Detail’

    There may be a cleaner way to do this, but it’s useful to know how to fall back on handwritten script when necessary.

  2. Sungjin Chun Says:

    I think

    onBeforeStart: (html element
    id:(contact identifier, ’show’));

    shoudl be

    onBeforeStart: (html element
    id:(contact identifier, ’show’); toggle);

    isn’t it?


  3. Hi Sungjin

    You are absolutely correct – we should send toggle to the element.

    However when you have an element in an #onClick: or #onBeforeStart: etc. the toggle is implicit (or at least it is in Seaside 2.7 – I haven’t checked it out in 2.8 yet)

  4. Hooscow Says:

    This is the only part of the tutorial that I cannot seem to get working correctly. When I click on the ‘Show Detail’ legend, the contact view explodes open, but legend still reads ‘Show Detail’ rather than ‘Hide Detail’. Clicking it again collapses the contact view, so that part works. the only that doesn’t get updated is the label; it always reads ‘Show Detail’.

    I’ve copied down the entire method as far as I can tell. I’m using Damien Cassou’s Web image with Squeak 3.10.2

    renderContentOn: html
    html anchor
    id: (contact identifier , ‘show’);
    style: ‘margin-left:40px’;
    onClick: (html effect id: contact identifier; toggleAppear;
    onBeforeStart: (html element id: contact identifier , ‘show’);
    onAfterFinish: (html element id: contact identifier , ‘hide’));
    with: ‘Show Detail’.

    html anchor
    id: (contact identifier , ‘hide’);
    style: ‘margin-left:40px;display:none’;
    onClick: (html effect id: contact identifier; toggleAppear;
    onBeforeStart: (html element id: contact identifier , ‘hide’);
    onAfterFinish: (html element id: contact identifier , ‘show’); toggleAppear);
    with: ‘Hide Details’.

    self renderDetailsDiv: contact identifier on: html


    • Hi Hooscow

      Try removing the extra : toggleAppear

      from the line

      onAfterFinish: (html element id: contact identifier , ’show’)"; toggleAppear");

      I haven’t tried this in seaside 2.8 but I believe it should work.

  5. Hooscow Says:

    Hi objectcentric,

    I tried removing that extra toggleAppear as well. It still doesn’t display Hide Detail’.

    How can I tell which version of Seaside is loaded in the image? The image is Damien Cassou’s, which came pre-loaded.

    Thanks! (This was a great tutorial by the way, I really enjoyed it. I hope you write some more)

  6. Hooscow Says:

    PS: Can you show us how to perform these Ajax actions in jQuery rather than Scriptaculus? I think jQuery is a more appealing Ajax library anyway.

    Thanks!


  7. シーマスター オメガ


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


%d bloggers like this: