Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery: Inconsistent behavior of find between div and tbody

I am using the find selector in jQuery by Id. It is behaving differently in case of a div vs tbody. This is a bigger problem - for the sake of clarity here is the reduced version of my original issue

HTML

<div id='iamdiv'>HELLO</div>
<table>
  <tbody id='iamtbody'>
    <tr><td>HELLO TOO</td></tr>
  </tbody>
</table>
<input type='text' id='div'/>
<input type='text' id='tbody'/>

JS

$(document).ready(function() {
  var allcontent = $($('body').html()); // I am deliberately doing this to input a HTML String.
  var $divcontent = allcontent.find('#iamdiv');
  $('#div').val($divcontent.html());
  var $tbodycontent = allcontent.find('#iamtbody');
  $('#tbody').val($tbodycontent.html());
});

Fiddle: https://jsfiddle.net/bragboy/Lt8nua10/1/

I want to display the raw html in the input text boxes, however only the tbody one is getting displayed and not the div. If I use a filter method instead of find - it works for div but not the tbody.

My objective is to have one consistent way of fetching for both tbody and div.

like image 761
bragboy Avatar asked Jun 02 '26 04:06

bragboy


2 Answers

Two issues:

  1. find looks for descendant elements, but #iamdiv is a top-level entry in your allcontents jQuery object.

  2. You're duplicating the elements in the

    var allcontent = $($('body').html());
    

    line, which I'm fairly sure isn't what you want to do. (You've said that's on purpose, to simulate parsing HTML from elsewhere.)

You've said your goal is to use find in both use case (rather than using filter in one and find in the other). To do that, you need to have something else as the root of your allcontent.

You've also said that for some reason you can't change the

var allcontent = $($('body').html());

line, even just to

var allcontent = $("<body>").append($('body').html());

That's okay, you can still add a new root element by adding a line after it, like this:

allcontent = $("<body>").append(allcontent);

Live example:

$(document).ready(function() {
  var allcontent = $($("body").html()); // You've said we can't change this
  // The added line:
  allcontent = $("<body>").append(allcontent);
  var $divcontent = allcontent.find('#iamdiv');
  $('#div').val($divcontent.html());
  var $tbodycontent = allcontent.find('#iamtbody');
  $('#tbody').val($tbodycontent.html());
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id='iamdiv'>HELLO</div>
<table>
  <tbody id='iamtbody'>
    <tr><td>HELLO TOO</td></tr>
  </tbody>
</table>
<input type='text' id='div'/>
<input type='text' id='tbody'/>
like image 98
T.J. Crowder Avatar answered Jun 03 '26 17:06

T.J. Crowder


Use var allcontent = $('body'); instead of var allcontent = $($('body').html());

$(document).ready(function() {
  var allcontent = $('body');
  var $divcontent = allcontent.find('#iamdiv');
  $('#div').val($divcontent.html());
  var $tbodycontent = allcontent.find('#iamtbody');
  $('#tbody').val($tbodycontent.html());
});
input {
  width: 100%; /* just to show the whole content */
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id='iamdiv' class='somthing1'>
  HELLO
</div>
<table>
  <tbody id='iamtbody' class='somthing2'>
    <tr>
      <td>HELLO TOO</td>
    </tr>
  </tbody>
</table>
<input type='text' id='div' />
<br/>
<input type='text' id='tbody' />

After update in question :

You can use .closest() to achieve this. Because the cose that you picked when using $($(body).html()) has the div as on its node.

$(document).ready(function() {
  var allcontent = $($('body').html());
  var $divcontent = allcontent.closest('#iamdiv');
  $('#div').val($divcontent.html());
  var $tbodycontent = allcontent.find('#iamtbody');
  $('#tbody').val($tbodycontent.html());
});
input {
  width: 100%; /* just to show the whole content */
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id='iamdiv' class='somthing1'>
  HELLO
</div>
<table>
  <tbody id='iamtbody' class='somthing2'>
    <tr>
      <td>HELLO TOO</td>
    </tr>
  </tbody>
</table>
<input type='text' id='div' />
<br/>
<input type='text' id='tbody' />
like image 21
Himanshu Tyagi Avatar answered Jun 03 '26 16:06

Himanshu Tyagi



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!