One click: multiple Scriptaculousness

I’m using Transition FX as a way for a page to start off showing a little content, with clickable headings then opening up progressively deeper levels of information. (Lots of people have used the same kind of thing for FAQ pages.)

It’s all lovely. But I want more.

The thing I’d really like is for one click to slide down the new div, and show another div at the same time. This second div would contain some kind of status symbol, maybe a disclosure triangle or a simple ‘click to open’/‘click to close’ message.

And once that’s working, I’d also like to add a new link, somewhere else on the page, to close up all the opened divs with a single click.

Is there an action out there that allows me to do this?
Or, failing that, has anyone done similar stuff with Scriptaculous (or another framework). I’ve seen that Scriptaculous can handle multiple events, but the documentation I’ve seen on the web is very brief.

Thanks


freewaytalk mailing list
email@hidden
Update your subscriptions at:
http://freewaytalk.net/person/options

The Freeway FX actions are not set to create this, but certainly Prototype and Scriptaculous can do it. The key thing is to either create a custom function that calls the effects you want to have happen, or create a button that fires a “synthetic event” which your effects can then listen for and react to.

It depends a lot on your design which approach you take, the first will work in a static, defined page, the second will allow you to further modify the page and still have the effect happen (because you won’t be setting a static list of elements in code).

Could you post a link to a page that shows the elements, and mark it up with “stickies” showing what you want to have happen?

Walter


freewaytalk mailing list
email@hidden
Update your subscriptions at:
http://freewaytalk.net/person/options

Hi Walter

Thanks for your ideas.

You can see the current state of development of this site here:
http://message-design.co.uk/eecf/

You can see how the first section, “Plan” opens up to a nest of three levels.
Your synthetic event sounds more appropriate. When this site is finished there will be around 100 divs on the page that can be opened in this way, so I don’t want to have to list them all in the code.


freewaytalk mailing list
email@hidden
Update your subscriptions at:
http://freewaytalk.net/person/options

Wow, this is going to be fun to script!

Looking at the way it’s scripted right now, it’s going to take some un-doing first to make this more possible. The FX Actions use inline scripting (onclick=“do something here”), which makes it more difficult to override or hook into the effects and make them work in concert.

Unobtrusive JavaScript would use something more indirect, like a classname on the clickable headers, perhaps, or just the level of hierarchy within the document, to signal the same thing.

Using that, you could make all of the third-level DIVs roll up like this:

var close_third_level = function(){
    $$('div.outer div div').select(function(elm){ 
        return elm.visible(); 
    }).each(function(elm){ 
        Effect.BlindUp(elm,{queue:'end'});
    });
};

//or if you tagged them all with a classname:

var close_third_level = function(){
    $$('div.third_level').select(function(elm){ 
        return elm.visible(); 
    }).each(function(elm){ 
        Effect.BlindUp(elm,{queue:'end'});
    });
};

//and then you call either one of those like this

$('closeButton').observe('click',close_third_level);

That’s just one example. The key to being able to use a technique like this is going to be structure. You’re going to need to have a deliberate and predictable nesting strategy so that the structure of the elements determines what happens after a click.

If you wanted to have a click on a top-level header cause the next two levels to spill open, then you’d need to nest them within each other something like this:

<div class="block">
    <h3>Click me</h3> 
    <div>
        <p>Second level content here</p>
        <div>
            <p>Third level content here</p>
        </div>
    </div>
</div>

And repeat that for each section. Then the JavaScript to make this live would look something like this (untested):

//set up a smart slide up/down function
var toggle_slide = function(elm){
    if(elm.visible()) return Effect.SlideUp(elm);
    return Effect.SlideDown(elm);
}

//hide all the children so you can show them later
$$('div.block div').invoke('hide');

//listen to clicks on the headers
$$('div.block h3').each(function(elm){
    var block = elm.up('div');
    elm.observe('click',function(evt){
        block.select('div').each(function(elm){
            toggle_slide(elm);
        });
    });
});

That one little block of code would handle as many different div.block constructions as you could put on the page. Each block would listen for a click on its h3, and when it “heard” one, it would respond by sliding down the divs inside it.

With a little more work, you could make all the other divs roll up first whenever you clicked on an h3 (so only one would remain open at a time), or you could have a separate control to roll up all the divs on the page when you click it.

The first step will be to remove all the inline scripting generated by the Freeway FX Actions. Then apply the Protaculous Action to the page, and set it to use scriptaculous-packed as its library. From there you can start adding your scripts in either of the Function Body dialogs.

Walter


freewaytalk mailing list
email@hidden
Update your subscriptions at:
http://freewaytalk.net/person/options

Hi Walter

Thanks very much for all this.

I’ll let you know when I’ve digested it and started trying to apply it.


freewaytalk mailing list
email@hidden
Update your subscriptions at:
http://freewaytalk.net/person/options

On 10 Feb 2010, 2:56 am, waltd wrote:

That’s just one example. The key to being able to use a technique like this is going to be structure. You’re going to need to have a deliberate and predictable nesting strategy so that the structure of the elements determines what happens after a click.

If you wanted to have a click on a top-level header cause the next two levels to spill open, then you’d need to nest them within each other something like this:

I’ve started looking at the code for this website outside Freeway. You can see the current example here:

http://www.message-design.co.uk/eecf4/

It’s a little more complex than your example (though similarly nested), in terms of having extra div wrappers (some of which I think are needed for the Scriptaculous).
Will the javascript still work do you think?

Mine is more like this (though even this leaves out some of the divs!):

<div class="block">
<div>
  <h3>Click me</h3> 
</div>

  <div>
    <div>
      <p>Second level content here</p>
        <div>
           <div>
            <p>Third level content here</p>
          </div>
        </div>
     </div>
  </div>
</div>

What kind of thing can the javascript target? Can you listen for clicks on

and then slide open the div directly below?

I guess I need to get rid of all the div wrappers around my head tags. I put them in so that I can easily put extra divs within them and make their whole width (not just the words) clickable. But if I make the head tags display:block will this make their whole width clickable? Can I then nest other divs inside the head tags?

Also, can the structure in the html be used by the CSS to target the styles, instead of using classes, as I have? So that if some text is a child of a div with a certain id (at some given level of nesting) it gets a certain style?

And would this whole thing be better structured as a list? Can you still put

etc tags inside a list, or would that just be making extra work for little reward?


freewaytalk mailing list
email@hidden
Update your subscriptions at:
http://freewaytalk.net/person/options

Sounds like you’re making progress. As a certain Jedi master once
said, “You’ve taken your first step into a larger world”.

On Mar 1, 2010, at 5:14 AM, jeff wrote:

On 10 Feb 2010, 2:56 am, waltd wrote:

That’s just one example. The key to being able to use a technique
like this is going to be structure. You’re going to need to have a
deliberate and predictable nesting strategy so that the structure
of the elements determines what happens after a click.

If you wanted to have a click on a top-level header cause the next
two levels to spill open, then you’d need to nest them within each
other something like this:

I’ve started looking at the code for this website outside Freeway.
You can see the current example here:

http://www.message-design.co.uk/eecf4/

It’s a little more complex than your example (though similarly
nested), in terms of having extra div wrappers (some of which I
think are needed for the Scriptaculous).
Will the javascript still work do you think?

Mine is more like this (though even this leaves out some of the
divs!):

Click me

 <div>
   <div>
     <p>Second level content here</p>
       <div>
          <div>
           <p>Third level content here</p>
         </div>
       </div>
    </div>
 </div>

What kind of thing can the javascript target? Can you listen for
clicks on

and then slide open the div directly below?

JavaScript can target anything, really. You can say “when I click
this, the third DIV from the bottom will open”, without knowing how
many elements are in the container. But much more certainly, you can
say “the element with this ID will do something when I click over
here”. That relies on the native construction getElementById(), which
is aliased and extended in Prototype as the “dollar” function:

$('someDivIdHere') //=> returns a reference to that DIV,
			// and extends it with all the Prototype methods

Whenever you draw a DIV in Freeway, it gets an ID. If you want to act
on more than one thing at a time, you can add a classname to each
element in your group, and then act on the class all at once. That’s
what the “double-dollar” function is for in Prototype, and underneath
it, the native JS construction getElementsByTagName().

$$('div.foo') //=> returns an array of all DIVs on the page
		//with the classname 'foo', or an empty array

I guess I need to get rid of all the div wrappers around my head
tags. I put them in so that I can easily put extra divs within them
and make their whole width (not just the words) clickable. But if I
make the head tags display:block will this make their whole width
clickable?

Yes, although head tags are display:block already. You may be thinking
that you need to add a link to the head in order to make it a click
target. If you do that, then you have to make the link display block
to get the effect you want. But that’s not necessary either.

Freeway doesn’t make it possible to add an ID to an H tag. So you have
to get a little bit creative. You do have an ID on the DIV that holds
the H tag, so you can address that head by DOM traversal. Ideally, you
would write a single function that can apply to many different heads
rather than writing a separate function for each head, but if you
wanted to address one particular head, you could do this:

$('parentDivId').down('h2') ...

or

$$('#parentDivId > h2').first() ...

Can I then nest other divs inside the head tags?

You can, but not easily within Freeway. (Actually, I haven’t tried
that, it might work, but I have to ask a big WHY?) A head is a
semantic element as well as a structural and styling element. If you
nest a DIV inside it, you are removing any hierarchical clues from
whatever is inside that DIV, and shifting everything up to the level
of a head. Imagine a PowerPoint where everything was written at the
same ginormous font size, no variety. That’s more or less what you’re
doing to the browser or any other state machine that tries to make
sense of the content. You might want to try making a cut-down example
of what you’re intending and run it through the W3 validator to see
what it makes of it.

Also, can the structure in the html be used by the CSS to target the
styles, instead of using classes, as I have? So that if some text is
a child of a div with a certain id (at some given level of nesting)
it gets a certain style?

Sure, that’s very simple.

div#divId ul li ul li //=> targets only the second level list elements
		// in the div with the ID 'divId'

And would this whole thing be better structured as a list? Can you
still put

etc tags inside a list, or would that just be making
extra work for little reward?

You can put nearly any sort of tag inside a list item tag. (As a side
note, I hope you only ever have one H1 tag on any given page. You can
have as many H2-6 as you like.) A list would offer quite a bit of
semantic structure to the page, although it’s debatable whether it
would be a significant difference from a normal inline layout for this
particular construction.

Walter


freewaytalk mailing list
email@hidden
Update your subscriptions at:
http://freewaytalk.net/person/options

Thanks very much Walter, this is all so useful.

Before I go away and start building this again, I have few more questions…

If I stick with divs rather than a list how do I do something like:

div#divId ul li ul li //=> targets only the 
second level list elements
    // in the div with the ID 'divId'

using only divs, so I can target my CSS neatly?

And how does that targeting fit into the javascript so I can do

$('someDivIdHere') //=> returns a reference to that DIV,
        // and extends it with all the Prototype methods

on my nested divs?

And lastly, I have currently got clickable full width

tags with mouse-over feedback using a div wrapper and onmouseover on that wrapper. It would be neater to use the link html to get the mouse-over effect automatically, but these heads aren’t actually links (merely triggers for javascript events). So can you use the link code but with no actual link to give the same effect?

Thanks.


freewaytalk mailing list
email@hidden
Update your subscriptions at:
http://freewaytalk.net/person/options

On Mar 1, 2010, at 9:14 AM, jeff wrote:

Thanks very much Walter, this is all so useful.

Before I go away and start building this again, I have few more
questions…

If I stick with divs rather than a list how do I do something like:

div#divId ul li ul li //=> targets only the
second level list elements
// in the div with the ID ‘divId’

using only divs, so I can target my CSS neatly?

Well, if you are drawing all of these divs in Freeway, then they all
have IDs, so you could target them directly. But if you wanted to
avoid writing a separate accessor for each DIV, you could either give
each one a classname, or you could use their level in the hierarchy to
do the same thing:

$$('#yourMainContainer div div')

would gather the elements that are second-generation divs within the
main container, for example.

And how does that targeting fit into the javascript so I can do

$(‘someDivIdHere’) //=> returns a reference to that DIV,
// and extends it with all the Prototype methods

on my nested divs?

If you use the double-dollar accessor to get a collection of elements,
each element in that collection will already be extended with all the
Prototype methods, and then you use one of the Iterator functions to
map common functionality across that collection, or you use one of the
“finder” methods to get just the one or ones you want specifically.
You can read more about this at the Prototype API: Prototype API Documentation | Enumerable (Deprecated URL)

And lastly, I have currently got clickable full width

tags with
mouse-over feedback using a div wrapper and onmouseover on that
wrapper. It would be neater to use the link html to get the mouse-
over effect automatically, but these heads aren’t actually links
(merely triggers for javascript events). So can you use the link
code but with no actual link to give the same effect?

If you could guarantee that all of your clients were using a standards-
compatible browser (and thus, also rode a unicorn to work) then you
could simply use the :hover pseudo-selector in CSS to provide that
feedback. Since you can’t guarantee that, you will need to use
JavaScript to give this feedback.

Example here: Example

Walter

Thanks.


freewaytalk mailing list
email@hidden
Update your subscriptions at:
http://freewaytalk.net/person/options


freewaytalk mailing list
email@hidden
Update your subscriptions at:
http://freewaytalk.net/person/options

Thanks again.
I’ll see where this gets me. I’m getting the hang of the html and the css, but the javascript is a bit of a mystery.


freewaytalk mailing list
email@hidden
Update your subscriptions at:
http://freewaytalk.net/person/options