views:

86

answers:

6

Hello All,

I implemented a Ajax callback function to update a div (announcement) in my web page.

It works fine, but the current issue is that the Ajax call function update the announcement div, however, after rewrite the content, the Javascript functions in this content are not load it. Therefore, my toggle function in table does not work after update content.

My ajax call function

setInterval("_checkUpdate()", 2000); //2 seconds one call.

function _checkUpdate() {
    var callback=new Object();
    callback.success=this.checkUpdateonExternalSuccess;
    callback.failure=this.checkUpdateonExternalFailure;
    YAHOO.util.Connect.asyncRequest('GET' , '/ci/ajaxCustom/ajaxCheckUpdate',callback);
};

On success, it update the content to rewrite to my Div

function checkUpdateonExternalSuccess (o){
    if(o.responseText!==undefined) {
        var str=o.responseText;
        if(str !== 'nocontent') {
            document.getElementById('updateContent').innerHTML=str;  (Write the new content to my div)
            location.reload(); //Reload the whole page, i do not want that
        }
    }
};

It works, it write the new content with Javascript, but the Javascript functions are not load it.

Javascript:

$(document).ready(function() {
  //First hide all the contects except the headcontent
  $(".content").hide();
  $(".headContent").show();

  //If user click on the head title, it hide/show content
  $(".headTitle").click(function () {
     collapseHeadContent();//reset all
      var aParentTD= $(this).closest("td");
      var aHeadContent = aParentTD.find (".headContent");
      aHeadContent.toggle();
  });

  // If uses click on the title, it has toggle event for the content
  $(".title").click(function () {
      collapseContent(); //First reset all
      var aParentTD = $(this).closest("td");
      var aContent  = aParentTD.find(".content");  // Content in the same TD with Title
      aContent.toggle();
  });

});

function collapseContent() {
    //find the Head content to hide and reset of content
    $(".headContent").hide();
    $(".content").hide();
}

function collapseHeadContent() {   
    $(".content").hide();
}

HTML:

<div id="annoucementTableDiv">
     <table id="annoucementTable">
  <tbody id="tdContent">
      <tr>
   <td><span id="tdtitle"><a class="headTitle"> Forbidden: Error 403</a></span> <br />
       <span class="annfrom">PLC team  - 19/08/2010 at 10:30<br /> </span>
       <br />
       <span class="headContent"><P>Due to scheduled maintenance, HOME showed the error 403:<br/>
    This is now resolved and customers can update again as normal </P>
       </span>
   </td>
     </tr>
  </tbody>
  <tbody id="tdContent">
      <tr>
   <td>
       <span id="tdtitle">
    <a class="title">Downloading maps</a>
       </span> <img src="/euf/assets/themes/standard/images/layout/important.png" class="alert_icon" alt="alert"></img><br />
       <span class="annfrom">Sent by 2nd line  - 05/11/2009 at 15:30<br /> </span>
       <span class="content">Since this morning it has been reported that multiple customers are again receiving this error message.<br /><br />This error has been escalated to the relevant teams with the highest priority and is currently being looked into.
    An estimated time for a fix is not yet available but we will keep you updated.
       </span>
       <br />
   </td>
     </tr>
  </tbody>
     </table>
 </div>

If I do location.reload, the Javascript functions work. But I do not want to refresh the page.

Any ideas, thanks.

Regards,
Qing

A: 

Sounds like you need the live function. It is quite straight forward.

  $('.title').live('click', function() {
       collapseContent(); //First reset all
      var aParentTD = $(this).closest("td");
     var aContent  = aParentTD.find(".content");  // Content in the same TD with Title
     aContent.toggle();

   });

Basically adds the click handler to all title elements. Even if another loads the event is still associated with it. You can use this for all elements that are loaded by AJAX during the life of the page. So you do the same for the head element and so on.

Vincent Ramdhanie
+1  A: 

Since you're also hiding/showing things, I recommend you change you're ready handler into a named function then call it on document.ready, like this:

function loadFunc() {
  $(".content").hide();
  $(".headContent").show();
}

$(function() {
  loadFunc():

  $(".headTitle").live('click', function () {
     collapseHeadContent();
     $(this).closest("td").find(".headContent").toggle();
  });

  $(".title").live('click', function () {
      collapseContent();
      $(this).closest("td").find(".content").toggle();
  });
});

This also uses .live() to set your click functions up once. Then when you do your AJAX load, you can just call loadFunc again to do hiding/showing or any other work, like this:

function checkUpdateonExternalSuccess (o){
    if(o.responseText!==undefined) {
        var str=o.responseText;
        if(str !== 'nocontent') {
            document.getElementById('updateContent').innerHTML=str;
            loadFunc();
        }
    }
};
Nick Craver
Awesome, it works. I do not know live function in JQuery, Do you know whether YUI have something similar.
QLiu
A: 

Take a look at this solution, is the same problem

Uoli
A: 

I dont know about YUI but you could try unbinding existing toggle() handlers and rebind them after every succesfull ajax update..?

Not ideal but I guess it'd work.

conqenator
A: 

In a project I'm writing at the moment, I insert HTML and Javascript content separately. The HTML is inserted as usual into innerHTML. And I got the javascript in a JS file which I load into my document during runtime like this:

var newScript = document.createElement('script');
newScript.type = 'text/javascript';
newScript.src = 'myJavascriptFile.js';
headID.appendChild(newScript);
Eric J. Francois
A: 

Wrap your table related code into a function and call it once on document.ready and after you ajax-request. Avoid triggering document.ready as suggested by Uoli, because it can cause unpredictable side effects as all your $(document).ready(function() { blocks will be executed again.

Vprimachenko