3

I have already seen How to get an HTML element from a string with jQuery - however, I'm having problems reproducing those results properly. Consider this example:

<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
  <script type="text/javascript" src="../jquery-1.12.3.min.js"></script>
  <style type="text/css">
.dispnone {
  display:none;
}
  </style>
  <script type="text/javascript">
// global var
var myHiddenHTMLstring = ""; // populate ondocready

function OnClickerClick(inbtn) {
  // attempt to generate HTML from string:
  var myHiddenElements = $(myHiddenHTMLstring);
  console.log( myHiddenElements.html() );
}

ondocready = function() {
  console.log("ondocready");
  myHiddenHTMLstring = $("#wrapper").html();
  console.log(myHiddenHTMLstring); // looks OK
  $("#clicker").click(function(){
    OnClickerClick(this);
  });
}
$(document).ready(ondocready);
  </script>
</head>

<body>
  <h1>Hello World!</h1>

  <div id="wrapper" class="dispnone">
    <table id="table1">
      <tr>
       <th> AH </th>
       <th> BH </th>
       <th> CH </th>
       <th> DH </th>
       <th> EH </th>
      </tr>
      <tr>
       <td> A1 </td>
       <td> B1 </td>
       <td> C1 </td>
       <td> D1 </td>
       <td> E1 </td>
      </tr>
    </table>
    <table id="table2">
      <tr>
       <th> HA </th>
       <th> HB </th>
       <th> HC </th>
       <th> HD </th>
       <th> HE </th>
      </tr>
      <tr>
       <td> A2 </td>
       <td> B2 </td>
       <td> C2 </td>
       <td> D2 </td>
       <td> E2 </td>
      </tr>
    </table>
  </div>

  <button id="clicker">Click to check</button>
</body>
</html>

When the page loads, I capture the contents of div id="wrapper" using:

myHiddenHTMLstring = $("#wrapper").html();

When the string is output at that time using console.log, I get exactly what is expected - that is, the entire inner HTML content string of div id="wrapper":

<table id="table1">
  <tbody><tr>
   <th> AH </th>
   <th> BH </th>
   <th> CH </th>
...
   <td> C2 </td>
   <td> D2 </td>
   <td> E2 </td>
  </tr>
</tbody></table>

However, when I click the button, I try to convert this string to HTML elements using the jQuery construct:

var myHiddenElements = $(myHiddenHTMLstring);

... then I immediately try to print its HTML using:

console.log( myHiddenElements.html() );

... however what I get here is not the entire inner HTML content string of div id="wrapper" - but instead, I get this:

  <tbody><tr>
   <th> AH </th>
   <th> BH </th>
   <th> CH </th>
   <th> DH </th>
   <th> EH </th>
  </tr>
  <tr>
   <td> A1 </td>
   <td> B1 </td>
   <td> C1 </td>
   <td> D1 </td>
   <td> E1 </td>
  </tr>
</tbody>

... that is, I only get the inner content of the first table, instead of getting both tables ?!

What am I doing wrong - and how can I convert a HTML string to HTML elements using jQuery, such that the HTML elements contain the entirety of the original HTML string?


EDIT: Forgot to say I tested this on Firefox 43; and also I just tried with tables with proper thead and tbody inserted in both tables - and that doesn't help either, still the same problem persists...

Community
  • 1
  • 1
sdbbs
  • 4,270
  • 5
  • 32
  • 87

2 Answers2

2

Your jQuery is working correctly. myHiddenElements contains both tables as HTML elements. When you write myHiddenElements.html(), what you get is the HTML content of the first element in the selection. So that is the content of the first table in your HTML string.

You can get the innerHTML of both tables by writing something like:

myHiddenElements.find('table').each(function(){
    console.log($(this).html())
});

If you want to get the HTML string from the jQuery object again, you can use one of the methods outlined in this question: jQuery: outer html() . Or you could just use your original string.

If you want to do something else with the HTML, your myHiddenElements string already contains what you need. So things like this will work:

myHiddenElements.find('td').css('color', 'red');
$('#wrapperDiv').append(myHiddenElements);
// etc.
Community
  • 1
  • 1
KWeiss
  • 2,954
  • 3
  • 21
  • 37
  • Many thanks @KWeiss - but what puzzles me is this: when I say `$("#wrapper").html()`, there is only one element, and I get its inner HTML; but when I say `myHiddenElements.html()`, the string does not have one root element, it has two - so the inner HTML of the first is taken. Is that understood correctly? Thanks! – sdbbs Apr 21 '16 at 07:30
  • In other words, to again get the same content string I cannot just use `$(string).html()` - I'd have to first reparent the two tables in `string` to say a `div`, and then ask for `div.html()`, is that correct? – sdbbs Apr 21 '16 at 07:32
1

Create a temporary element, then clone() and append():

$('div').append($(yourHtmlString).clone()).html();
Dr.Knowitall
  • 10,080
  • 23
  • 82
  • 133
  • Thanks @Dr.Knowitall - had no idea that `.clone()` existed, will make sure to check it out... – sdbbs Apr 21 '16 at 07:30