Hi James,

(GGroups crashed, apologies if this is a repost for some.)

For the approach you're using to work, you do need a defer because the
browser needs a brief moment to process the updated DOM elements; see
this article on the unofficial wiki for details:
http://proto-scripty.wikidot.com/prototype:tip-scripting-dynamically-loaded-elements

No biggie, just (to make things easy to read) separate your code to
hook things up into a named function (for instance, 'hookTickets'),
and then use defer in your PeriodicalUpdater options:

    new Ajax.PeriodicalUpdater('dticketlist','data/
fetchliveticketview.php',{
        frequency:300,
        decay:2,
        onSuccess: function() {
            hookTickets.defer();
        }
    });

But there's another problem with the approach of hooking up handlers
on the list items each time you load them:  A memory leak.  Prototype
keeps track of the handlers hooked up via observe() so it can provide
easy ways of unhooking them.  In your quoted code, you'll keep hooking
up more and more handlers without ever releasing the old ones, which
will keep consuming a little bit of extra memory every time the list
updates.  Sure, with a list that updates every 5 minutes and has a
decay, it's maybe not that big a deal, but...

Now, you *could* fix that by using a PeriodicalExecuter instead that
unhooks the old handlers, then requests the updated list; then the
onSuccess for the updated list request hooks up the new ones.  But
that's complicated and a pain to maintain.

So you might consider event delegation instead.  Put your click
handler on the dticketlist element, and you don't have to do
*anything* to hook up the individual ticket items:  Events bubble up
the DOM tree, and so a click on the ticket will also show up as a
click on the dticketlist div.  In an event handler, Prototype ensures
that 'this' is set to the element you set the handler on, but the
Event.element() very handily references the element that was clicked.

With the click handler on dticketlist, your PeriodicalUpdater gets
simpler:

new Ajax.PeriodicalUpdater('dticketlist','data/
fetchliveticketview.php',{
    frequency:300,
    decay:2
});

...and your handler code looks something like this:

function ticketClicked(evt)
{
    var elm;
    var id;

    elm = evt.element();
    if (elm && elm.hasClassName('clickinc'))
    {
        // It's one of our list items
        id = elm.id || '(no id)';
        $('dmain').update('Ticket #' + id + ' clicked');
    }
}

(If you like, you can check the tagName as well, make sure it's a list
item.)

Here's a demonstration page: http://pastie.org/308630
That's not hyper-tested code, but it works correctly on IE6, FF3,
Opera9, and Safari3 (on Windows).

HTH,
--
T.J. Crowder
tj / crowder software / com

On Nov 4, 4:37 pm, "James Hoddinott" <[EMAIL PROTECTED]> wrote:
> So I'm not entirely sure if this is a bind issue, a defer issue or
> something else that I'm unaware of.
>
> The scenario is this; the page loads, when this is done an
> Ajax.PeriodicalUpdater call is made to load the 'dticketlist' with a
> list of live tickets. I want to be able to click on any one of those
> tickets and then load the full ticket data 'dmain'. The javascript I
> have so far is:
>
> Event.observe(window,'load',function() {
>     new Ajax.PeriodicalUpdater('dticketlist','data/fetchliveticketview.php',{
>         frequency:300,
>         decay:2,
>         onSuccess:function(evt) {
>             $$('li.clickinc').invoke('observe','click',function(evt) {
>                 var elm;
>                 var id;
>                 elm = evt.element();
>                 id = elm.id || '(no id)';
>                 $('dmain').update('Updated text after clicking on '+id);
>             })
>         }
>     });
>     .....
>
> });
>
> This doesn't seem to do anything, not does Firebug report any errors.
> As a test, I created a page with the list already in it:
>
> <div id='dtest'><h6>Your Live Tickets</h6>
>  <ul>
>   <li id='M794751' class='clickinc'>M794751</li>
>   <li id='M784800' class='clickinc'>M784800</li>
>   <li id='M796555' class='clickinc'>M796555</li>
>   <li id='M791122' class='clickinc'>M791122</li>
>   <li id='M757562' class='clickinc'>M757562</li>
>   <li id='M747790' class='clickinc'>M747790</li>
>  </ul>
> <div id='dmain'>This will be updated</div>
>
> and used the following javascript:
>
> Event.observe(window,'load',function() {
>     $$('li.clickinc').invoke('observe','click',function(evt) {
>         var elm;
>         var id;
>         elm = evt.element();
>         id = elm.id || '(no id)';
>         $('dmain').update('Updated text after clicking on '+id);
>     });
>
> });
>
> and that works fine. So I don't really know if I need a bind here
> somewhere (having read copious articles and snippets I'm not that much
> wiser on its usage) or if infact I need a defer somewhere once the
> PeriodicalUpdater has run to let the DOM update?
>
> Or of course, I've got this completely wrong :) Any suggestions?
>
> --
> James Hoddinott
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Prototype & script.aculo.us" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/prototype-scriptaculous?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to