tags:

views:

9917

answers:

2

A user can upload a picture on my site at which point jQuery inserts it into the page with append(). After appending I need to able to determine if there is something there or not, but jQuery's "is:empty" check returns true despite content having been appended. If I reload the page, the "is:empty" check will return false. It seems that jQuery is failing to update the DOM when appending and is then checking against its non-updated model when running "is:empty". Does anybody know if there is a way around this?

EDIT:

Added from the comments -

if ($('#issueimage1'+issueid).is(':empty')) { 
    $('#issueimage1'+issueid).append(responseText); 
} 
elseif ($('#issueimage2'+issueid).is(':empty')) {
    $('#issueimage2'+issueid).append(responseText); 
} 
else { 
    $('#issueimage3'+issueid).append(responseText); 
}

The idea is that the user can add up to three pictures. I have a dedicated element for each picture. It checks each element sequentially to see where to insert. This works fine initially (if, on page load, there are two pictures, it will insert into the third slot). When adding two images without refreshing the page, it fails

+7  A: 

When you say "is:empty" do you mean

$([selector]).is(":empty")

?

It's working ok for me, as demonstrated in this Working Demo

$(function() {
    $("#empty").click(function() {
      alert($('#myDiv').is(':empty'));
    });

    $("#append").click(function() {
      $('#myDiv').append('<span>Appended!</span>');
    });
});

<!-- not all html shown, for brevity -->

<body>
  <div id="myDiv"></div><br/>
  <button id="empty">Check if div empty</button>
  <button id="append">Append to div</button>
</body>

EDIT:

The problem with using :empty is that it also assesses whether an element contains text nodes as well as element nodes, and if it contains text nodes, is not considered empty. I don't think that this is the behaviour you want so we can use .length on a wrapped set of the child elements of a <td> to ascertain whether it has any child element nodes; if the length is 0, then it is considered empty for this purpose (checking .length is the same as using .size() which calls .length, except checking .length directly will be slightly faster).

So, let's say we have a <tr> referenced by this

$('td', this).each(function() {
    // this inside the function will reference the <td>
    // get any child elements and check the length
    if ($('*',this).length === 0) {
        // this <td> is empty!
        // break out of the each loop 
        return false;
    }
});

Here's a Working Demo to show you an example. Add /edit to the URL to see the code and play with it.

jQuery Code (I wrote this in a hurry so could probably be tidied up somewhat)

$('a.select').click(function(e) {
  e.preventDefault();
  var anchor = $(this);  
  var radio;

  $('input:radio[name="imagePicker"]').each(function() {
    if (this.checked === true) {
      radio = $(this);
      return false;
    }
  });

  if (radio === undefined) {
    $('#comment').text('You must select an image').css('color','red');
  }
  else {
    var checked = false;
    var tds = anchor.closest('tr').children('td');
    tds.each(function(i, val) {
      if ($('*', this).length === 0) {
        radio.next().clone(true).appendTo(this);
        $('#comment').text('Appended to td Image ' + i).css('color','green');
        checked = true;
        return false;
      }
    });    
    if (!checked) {
      $('#comment').text('No empty td in this row').css('color','red');
    }  
  }
});

$('input:radio[name="imagePicker"]').click(function() {
  $('#comment').text('');
});

HTML

  <div>
    <div class="imagePicker">
      <input type="radio" name="imagePicker" />
      <img src="http://www.website-designs.com/images/resources_1/icons/Dead.gif" alt="image" />
    </div>
    <div class="imagePicker" >
      <input type="radio" name="imagePicker" />
      <img src="http://www.website-designs.com/images/resources_1/icons/Dead2.gif" alt="image" />
    </div>
    <div class="imagePicker" >
      <input type="radio" name="imagePicker" />
      <img src="http://www.website-designs.com/images/resources_1/icons/Diablo.gif" alt="image" />
    </div>
    <div class="imagePicker" >
      <input type="radio" name="imagePicker" />
      <img src="http://www.website-designs.com/images/resources_1/icons/Ckicken.gif" alt="image" />
    </div>
  </div>
  <br/><br/>
  <span id="comment"></span>
  <br/>
  <table style="margin:10px;">
  <thead>
    <tr>
      <th></th>
      <th>Image 1</th>
      <th>Image 2</th>
      <th>Image 3</th>        
    </tr>
  </thead>
  <tbody>
    <tr>
    <td><a href="#" class="select">Select</a></td>
      <td></td>
      <td></td>
      <td></td>        
    </tr>
    <tr>
      <td><a href="#" class="select">Select</a></td>
      <td></td>
      <td></td>
      <td></td>        
    </tr>
    <tr>
      <td><a href="#" class="select">Select</a></td>
      <td></td>
      <td></td>
      <td></td>        
    </tr>
  </tbody>
  </table>
Russ Cam
Yes, I'm using that syntax. I believe the code is correct as the exact same code returns false (the correct answer) when operating on the original HTML generated at the time of pageload. But when that code runs against HTML appended by jQuery, it returns true.
Jacob
@Jacob - you'll need to post your code, as there may be a problem elsewhere in it
Russ Cam
+1 for adding a live demo
Henrik Opel
A: 

Are you doing

.is(':empty')

?

meder