Results 1 to 5 of 5

Thread: Prototype and Event.observe

  1. #1
    Join Date
    Jan 2007
    Posts
    51
    Thanks
    2
    Thanked 3 Times in 3 Posts

    Default RESOLVED: Prototype and Event.observe

    Anyone here familiar with how Prototype's "Event.observe" works and rules that might need to be followed to use it?

    Here's what I'm getting at:
    1) the page loads
    2) window.onLoad fires, and uses Ajax.Updater to pull in the menu (an HTML file), with the anchors I want to Event.observe
    3) My problem... where do I put the "Event.observe" scripts to observe the anchors? What I'm doing doesn't work.

    Examples:

    http://www.cflhd.gov/testingajax/index.htm
    does not work. The functions are structured in a way that make sense to me, but does not work.

    http://www.cflhd.gov/testingajax/test.htm
    (Ajax in Practice example) works, but not the way I want it to. I want to 'observe' an element that is pulled in on 'window.onLoad'.

    Any help would be greaty appreciated.

    Thanks,

    BN
    Last edited by brentnicholas; 01-23-2008 at 09:44 PM.

  2. #2
    Join Date
    Mar 2005
    Location
    SE PA USA
    Posts
    29,070
    Thanks
    44
    Thanked 3,216 Times in 3,178 Posts
    Blog Entries
    12

    Default

    As you've found out, you cannot observe for an element until it is a part of the document.

    This:

    Code:
    Event.observe('menuTrainingProvided','click', addTrainingProvided, false);
    Basically means that this:

    Code:
    <div id="menuTrainingProvidedDIV">
    	<a href="#" id="menuProfessionalOutreach">
    	<img src="" title="Training Provided Image">
    	Training Provided
    	</a>
    </div>
    shall behave like so:

    Code:
    <div id="menuTrainingProvidedDIV"
    onclick="addTrainingProvided();">
    	<a href="#" id="menuProfessionalOutreach">
    	<img src="" title="Training Provided Image">
    	Training Provided
    	</a>
    </div>
    If you write it like that, you won't even need to 'observe' it. Further, it would probably be better like so:

    Code:
    <div id="menuTrainingProvidedDIV">
    	<a href="#" id="menuProfessionalOutreach"
    	onclick="addTrainingProvided();return false;">
    	<img src="" title="Training Provided Image">
    	Training Provided
    	</a>
    </div>
    or like:

    Code:
    <div id="menuTrainingProvidedDIV"
    onclick="addTrainingProvided();">
    	<a href="#" id="menuProfessionalOutreach"
    	onclick="return false;">
    	<img src="" title="Training Provided Image">
    	Training Provided
    	</a>
    </div>
    - John
    ________________________

    Show Additional Thanks: International Rescue Committee - Donate or: The Ocean Conservancy - Donate or: PayPal - Donate

  3. #3
    Join Date
    Jan 2007
    Posts
    51
    Thanks
    2
    Thanked 3 Times in 3 Posts

    Default

    Thanks for your reply. I agree to all your points.
    What I'm trying to accomplish is to keep all my javascript in an included *.js file included at the top of the page.

    So as a result I need to figure out how to register events for objects that are currently in the DOM. Though may not have been at page load.

    I've outlined the problem a little better in a google forum as well, here it is:
    ------------------------------------------------

    So i'm trying to keep from littering my HTML with <script> tags. I'd
    like all my javascript to be in an included file at the top of the
    page.


    Anway, I understand the following and how it works:


    Code:
    <h2 id="mydiv">Click me!</h2> 
      <script type="text/javascript" language="javascript"> 
         Event.observe('mydiv', 'click', function(e){ alert('clicked 
    me!') }); 
      </script>

    Ok, fine. It follows the rule that an 'Event.observe', must be placed
    after the element being observed. See: http://wiki.script.aculo.us/scriptac.../Event.observe


    However, this litters my HTML with js and tightly couples the UI to
    the behaviour. Bad...

    So I've beek mucking around with this, and it does not work.

    Before I show the code I'll out line it.

    1) The page is called and window.onload calls a function that uses
    Ajax.updater to load the menu into a DIV on the page.

    2) Right below the Ajax.updater in showMainMenu, I try to hold off
    registering the event until the DOM is done loading (just grasping at
    straws here), and attempt to register the event that watches for what
    link you clicked on the menu that was loaded in dspMainMenu.cfm.


    Code:
    /* init section */ 
    window.onload = function() { 
            showMainMenu(); 
    }; 
    
    function showMainMenu() 
    { 
            new Ajax.Updater('workingDIV','dspMainMenu.cfm?#session.UrlToken#', 
            { 
               method: 'get' 
            } 
                    ); 
            Event.observe(window, 'load', function() { 
               Event.observe('menuProfessionalOutreach', 'click', 
    addProfessionalOutreach); 
            }); 
    } 
    
    
    /* actions */ 
    function addProfessionalOutreach(event) { 
            new Ajax.Updater('workingDIV','dsp_addProfessionalOutreach.cfm? 
    #session.UrlToken#', 
            { 
              method: 'get' 
            } 
            ); 
    }
    cotents of dspMainMenu.cfm
    Code:
    <div id="menuProfessionalOutreachDIV">
    	<a href="#" id="menuProfessionalOutreach">
    	<img src="" title="Professional Outreach Image">
    	Professional Outreach
    	</a>
    </div>
    So what am I not doing right here?

    I have a sneaky suspicion that it's something to do with the
    dspMainMenu.cfm not being 'read into' the DOM?? Or evaluated into the
    DOM?

    Should I be using Ajax.Request instead? Ajax.Updater seemed cleaner
    since the call to dspMainMenu.cfm was just being dumped into a DIV and
    didn't need to do much.

    Though maybe my events should be registered in the 'onSuccess'
    function call of Ajax.Request...??

  4. #4
    Join Date
    Jan 2007
    Posts
    51
    Thanks
    2
    Thanked 3 Times in 3 Posts

    Default

    [QUOTE=brentnicholas;127460]

    I was just messing around with seeing what runs and does not run in the scripts and found that if I add the 'alert()' below, the page works fine with no errors.

    Intially I was getting an error at line 3818 - Object Required in the Prototype.js file. I assumed I was just defining my Event.observe incorrectly. Maybe this is a bug in Prototype? I'm still leaning towards me doing something wrong.

    But this observation is interesting...

    Code:
    function showMainMenu() 
    { 
            new Ajax.Updater('workingDIV','dspMainMenu.cfm?#session.UrlToken#', 
            { 
               method: 'get' 
            } 
                    ); 
            Event.observe(window, 'load', function() { 
               alert('in here');   // adding this caused the page to start running fine
               Event.observe('menuProfessionalOutreach', 'click', 
    addProfessionalOutreach); 
            }); 
    }
    cotents of dspMainMenu.cfm
    Code:
    <div id="menuProfessionalOutreachDIV">
    	<a href="#" id="menuProfessionalOutreach">
    	<img src="" title="Professional Outreach Image">
    	Professional Outreach
    	</a>
    </div>

  5. #5
    Join Date
    Mar 2005
    Location
    SE PA USA
    Posts
    29,070
    Thanks
    44
    Thanked 3,216 Times in 3,178 Posts
    Blog Entries
    12

    Default

    There are various ways to deal with this. You could have a document.onclick function that evaluates the id of the element clicked, walking up the DOM tree to the body tag. If it encounters certain id's along the way, certain actions could be performed. This approach bypasses 'observe'.

    Another approach would be to start polling for the added elements with the id's in question at the same time that the imported content is requested, once they are a part of the DOM, 'observe' them.

    I like my previous approach, it is simplest and cleanest, and requires no script tags in the external content. It does however add code to the markup that you apparently want to keep separate. However, the modularity isn't compromised. If, in the future, you want the division with the id:

    menuTrainingProvidedDIV

    to do something different, you need only edit the addTrainingProvided() function. You don't have to touch the markup ever again.
    - John
    ________________________

    Show Additional Thanks: International Rescue Committee - Donate or: The Ocean Conservancy - Donate or: PayPal - Donate

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •