views:

33

answers:

2

I'm attempting to hide all li's within a div which is dynamically generated when a use clicks a button. The content of the div is pulled through an Ajax call and I then assign to a div on the page.

For some reason though, any attempt to alter the style with jQuery doesn't have any affect. I notice I also have to apply $(selector).live('click, callback) when attempting to trigger a click.

$.ajax({
 url: "admin.php",
 cache: false,
 data: ({
  'module':'data',
  'action':'actionName',
  'clientname':formatted
 }),
 success: function(data) {
  $('#outputDiv').html(data);
 },
 error: function(XMLHttpRequest, textStatus, errorThrown) {
  if(textStatus == "error") {
   $('#outputDiv').append("Sorry, but there was an error");
  }
 }
});

The 'data' variable returned to the success method is a nested list set e.g. <ul id='tree'><il><a></a></li></ul> etc

What I'm trying to do after the load is hide all children in this case I'd call $(' #tree > li').hide(); A trigger will then occur when the use clicks the anchor tag with:

$('a.viewdetails').click(function() {
$(this).next('ul').toggle();
});

Edit 1

So now I've implemented the solution mentioned below but I can't get the load to function correctly, it doesn't appear to send the url parameters, formatted is generated above and can consist of spaces etc:

var containerDiv = $('div#clientBusinessUnits'),
    liClickHandler = function(e) {
        $('a.viewdetails').click(function() {
            alert('1');
        });
    },
    loadCompleteHandler = function(responseText, textStatus, XMLHttpRequest) {
        console.log(responseText);
        console.log(textStatus);
        $('li', containerDiv).click(liClickHandler);
    };
    containerDiv.load("admin.php?module=data&action&getData&clientname="+formatted, loadCompleteHandler);
+2  A: 

It is because the Code is only run once after the script is loaded. If you change you html via an ajax call you need to rerun the code to hide the lis. To accomplish this you can put the code into a function and call this function once the site is loaded and once the site gets updated, you can do this if you call this function from within the callback function of the ajax call.

jigfox
+3  A: 

Any event handlers bound to specific elements - before the elements exist on the page - won't work.

The .live() method helps with that, in that it will let you bind event handlers in advance, to elements that match a selector after elements have been dynamically inserted.

So, without knowing your actual code, a solution for your problem would be to, either

  1. Consequently use .live() for your event binding (might imply performance issues on deeply nested pages),
  2. Bind your event handlers after you have created your elements dynamically (i.e. bind the handlers in a callback funtion of your ajax method).

Roughly sketched example:

var
  $containerDiv = $('div#container'),
  liClickHandler =
    function(e)
    {
      // hide your li element, or whatever you want to do on click events
    },
  loadCompleteHandler =
    function(responseText, textStatus, XMLHttpRequest)
    {
      $('li', $containerDiv).click(liClickHandler);
    };

$containerDiv
  .load(
    urlToPhpScript,
    loadCompleteHandler
  );
Thomas
+1, this is the way to go, and note that for CSS changes, go for #2. `$(selector).css('color', 'blue');` doesn't actually alter the stylesheet (although that *can* be done with js, it's a bit tricky) - it simply runs the selector, loops over all the objects found, and applies that style to them individually. if you want the same to happen to objects that weren't around when that code was executed, you'll need to execute that code again.
David Hedlund
Hmm I see, I suspected it had something to do with this which explains why when I use .live() it works. I'm a bit unsure how to go about performing the actions suggested. The situation I have is that an Ajax call is made, this fires off to a Php script, the script returns a nested set of lists for display of hierarchical information. I only want the top level sets to be displayed which is where I thought I could use $('#list > #tree > li').hide(); to do this. I could simply apply a display: none; on all top-level list items but I'd prefer to learn the approach you've mentioned.
@user275074: Sure, it's not that complicated. You'd have to give us an idea about your code (I don't think we actually need your PHP code), so we can see what Ajax method you're using. Alternatively, check out http://api.jquery.com for the method you're using. You're looking for the *onsuccess callback*.
Thomas
Do you have any examples of how to achieve this?
I'll post some code......