title: DataTables hidden row details example - the table header is misplaced (test case attached)
body: <p>I'm trying to create a table where more details can be seen when the plus-image is clicked - similar to the <a href="http://www.datatables.net/release-datatables/examples/api/row_details.html" rel="nofollow noreferrer">DataTables hidden row details example</a></p>
  
  <p>Unfortunately there is a warning being printed as JavaScript alert and also the table header is misplaced - as if there would be too many or not enough table cells in it:</p>
  
  <p><img src="https://i.stack.imgur.com/HYLhz.png" alt="enter image description here"></p>
  
  <p>I have prepared a simple test case, which will work instantly, when you save it to a file and open it in a browser:</p>
  
  <pre><code>&lt;!DOCTYPE HTML&gt;
  &lt;html&gt;
  &lt;head&gt;
      &lt;link type="text/css" rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1/themes/redmond/jquery-ui.css"&gt;
      &lt;link type="text/css" rel="stylesheet" href="https://ajax.aspnetcdn.com/ajax/jquery.dataTables/1.9.4/css/jquery.dataTables_themeroller.css"&gt;
      &lt;script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"&gt;&lt;/script&gt;
      &lt;script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1/jquery-ui.min.js"&gt;&lt;/script&gt;
      &lt;script type="text/javascript" src="https://ajax.aspnetcdn.com/ajax/jquery.dataTables/1.9.4/jquery.dataTables.min.js"&gt;&lt;/script&gt;
      &lt;script type="text/javascript"&gt;
  
          var data = [
              {"Total":17,"A":0,"B":0,"Details":{"BSN":"1147387861","ProjectName":"R127","StationName":"D"},"C":0,"D":17,"Test":"GSM_1900_GMSK_TXPOWER_HP_H","Measurement":"MEASUREMENT"},
              {"Total":8,"A":0,"B":0,"Details":{"BSN":"1147387861","ProjectName":"R127","StationName":"D"},"C":0,"D":8,"Test":"TX_PWR_64_54","Measurement":"POWER"}
          ];
  
          $(function() {
  
              function fnFormatDetails(oTable, nTr) {
                  var aData = oTable.fnGetData(nTr);
                  var sOut = '&lt;table bgcolor="yellow" cellpadding="8" border="0" style="padding-left:50px;"&gt;';
                  sOut += '&lt;tr&gt;&lt;td&gt;BSN:&lt;/td&gt;&lt;td&gt;' + aData['Details']['BSN'] + '&lt;/td&gt;&lt;/tr&gt;';
                  sOut += '&lt;tr&gt;&lt;td&gt;Station:&lt;/td&gt;&lt;td&gt;' + aData['Details']['StationName'] + '&lt;/td&gt;&lt;/tr&gt;';
                  sOut += '&lt;tr&gt;&lt;td&gt;Project:&lt;/td&gt;&lt;td&gt;' + aData['Details']['ProjectName'] + '&lt;/td&gt;&lt;/tr&gt;';
                  sOut += '&lt;/table&gt;';
  
                  return sOut;
              }
  
              var fails = $('#fails').dataTable({
                  bJQueryUI: true,
                  sPaginationType: 'full_numbers',
                  aaData: data,
                  aaSorting: [[2, 'desc']],
                  aoColumns: [
                      { mDataProp: 'Test',        bSearchable: true,  bSortable: true },
                      { mDataProp: 'Measurement', bSearchable: true,  bSortable: true },
                      { mDataProp: 'Total',       bSearchable: false, bSortable: true },
                      { mDataProp: 'A',           bSearchable: false, bSortable: true },
                      { mDataProp: 'B',           bSearchable: false, bSortable: true },
                      { mDataProp: 'C',           bSearchable: false, bSortable: true },
                      { mDataProp: 'D',           bSearchable: false, bSortable: true },
                  ]
              });
  
              var th = document.createElement('th');
              var td = document.createElement('td');
              td.innerHTML = '&lt;img src="http://www.datatables.net/release-datatables/examples/examples_support/details_open.png" class="details"&gt;';
  
              $('#fails tbody th').each(function() {
                  this.insertBefore(th, this.childNodes[0]);
              });
  
              $('#fails tbody tr').each(function() {
                  this.insertBefore(td.cloneNode(true), this.childNodes[0]);
              });
  
              $('#fails tbody').on('click', 'td img.details', function() {
                  var nTr = $(this).parents('tr')[0];
                  if (fails.fnIsOpen(nTr)) {
                      this.src = 'http://www.datatables.net/release-datatables/examples/examples_support/details_open.png';
                      fails.fnClose(nTr);
                  } else {
                      this.src = 'http://www.datatables.net/release-datatables/examples/examples_support/details_close.png';
                      fails.fnOpen(nTr, fnFormatDetails(fails, nTr), 'details');
                  }
              });
          });
  
      &lt;/script&gt;
  &lt;/head&gt;
  &lt;body&gt;
  
  &lt;table id="fails" cellspacing="0" cellpadding="4" width="100%"&gt;
      &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;Test&lt;/th&gt;
          &lt;th&gt;Measurement&lt;/th&gt;
          &lt;th&gt;Total&lt;/th&gt;
          &lt;th&gt;A&lt;/th&gt;
          &lt;th&gt;B&lt;/th&gt;
          &lt;th&gt;C&lt;/th&gt;
          &lt;th&gt;D&lt;/th&gt;
      &lt;/tr&gt;
      &lt;/thead&gt;
      &lt;tbody&gt;
      &lt;/tbody&gt;
  &lt;/table&gt;
  
  &lt;/body&gt;
  &lt;/html&gt;
  </code></pre>
  
  <p>Does anybody please have an idea, how to fix this?</p>
  
  <p>I've tried adding/removing <code>&lt;th&gt;Details&lt;/th&gt;</code> in the HTML body, but it didn't help.</p>
  
  <p>I've also asked this question at the <a href="http://www.datatables.net/forums/discussion/17283/datatables-hidden-row-details-example-the-table-header-is-misplaced-test-case-attached" rel="nofollow noreferrer">DataTables forum</a>.</p>
  
  <p><strong>UPDATE:</strong></p>
  
  <p>I've received helpful comments by DataTables author and have decided to just prepend the plus-image to the contents of the first cell in each row - instead of adding a new cell to each row.</p>
  
  <p>Unfortunately I have a new problem: the plus-image is displayed, but the orinigal text (the Test name) is gone:</p>
  
  <p><img src="https://i.stack.imgur.com/5R5yp.png" alt="enter image description here"></p>
  
  <p>Here is my new code (the plus-image is prepended by <code>propTest</code>):</p>
  
  <pre><code>&lt;!DOCTYPE HTML&gt;
  &lt;html&gt;
  &lt;head&gt;
      &lt;link type="text/css" rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1/themes/redmond/jquery-ui.css"&gt;
      &lt;link type="text/css" rel="stylesheet" href="https://ajax.aspnetcdn.com/ajax/jquery.dataTables/1.9.4/css/jquery.dataTables_themeroller.css"&gt;
      &lt;script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"&gt;&lt;/script&gt;
      &lt;script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1/jquery-ui.min.js"&gt;&lt;/script&gt;
      &lt;script type="text/javascript" src="https://ajax.aspnetcdn.com/ajax/jquery.dataTables/1.9.4/jquery.dataTables.min.js"&gt;&lt;/script&gt;
      &lt;script type="text/javascript"&gt;
  
          var data = [
              {"Total":17,"A":0,"B":0,"Details":{"BSN":"1147387861","ProjectName":"R127","StationName":"D"},"C":0,"D":17,"Test":"GSM_1900_GMSK_TXPOWER_HP_H","Measurement":"MEASUREMENT"},
              {"Total":8,"A":0,"B":0,"Details":{"BSN":"1147387861","ProjectName":"R127","StationName":"D"},"C":0,"D":8,"Test":"TX_PWR_64_54","Measurement":"POWER"}
          ];
  
          function propTest(data, type, val) {
              if (type === 'set') {
                  console.log(val); // for some reason prints "null"
                  data.name = val;
                  data.display = '&lt;img src="http://www.datatables.net/release-datatables/examples/examples_support/details_open.png" width="20" height="20" class="details"&gt; ' + val;
                  return;
              }
  
              if (type === 'display') {
                  return data.display;
              }
  
              // 'sort', 'type', 'filter' and undefined
              return data.name;
          }
  
          $(function() {
  
              function fnFormatDetails(oTable, nTr) {
                  var aData = oTable.fnGetData(nTr);
                  var sOut = '&lt;table bgcolor="yellow" cellpadding="8" border="0" style="padding-left:50px;"&gt;';
                  sOut += '&lt;tr&gt;&lt;td&gt;BSN:&lt;/td&gt;&lt;td&gt;' + aData['Details']['BSN'] + '&lt;/td&gt;&lt;/tr&gt;';
                  sOut += '&lt;tr&gt;&lt;td&gt;Station:&lt;/td&gt;&lt;td&gt;' + aData['Details']['StationName'] + '&lt;/td&gt;&lt;/tr&gt;';
                  sOut += '&lt;tr&gt;&lt;td&gt;Project:&lt;/td&gt;&lt;td&gt;' + aData['Details']['ProjectName'] + '&lt;/td&gt;&lt;/tr&gt;';
                  sOut += '&lt;/table&gt;';
  
                  return sOut;
              }
  
              var fails = $('#fails').dataTable({
                  bJQueryUI: true,
                  sPaginationType: 'full_numbers',
                  aaData: data,
                  aaSorting: [[2, 'desc']],
                  aoColumns: [
                      { mData: propTest,      bSearchable: true,  bSortable: true },
                      { mData: 'Measurement', bSearchable: true,  bSortable: true },
                      { mData: 'Total',       bSearchable: false, bSortable: true },
                      { mData: 'A',           bSearchable: false, bSortable: true },
                      { mData: 'B',           bSearchable: false, bSortable: true },
                      { mData: 'C',           bSearchable: false, bSortable: true },
                      { mData: 'D',           bSearchable: false, bSortable: true }
                  ]
              });
  
              $('#fails tbody').on('click', 'td img.details', function() {
                  var nTr = $(this).parents('tr')[0];
                  if (fails.fnIsOpen(nTr)) {
                      this.src = 'http://www.datatables.net/release-datatables/examples/examples_support/details_open.png';
                      fails.fnClose(nTr);
                  } else {
                      this.src = 'http://www.datatables.net/release-datatables/examples/examples_support/details_close.png';
                      fails.fnOpen(nTr, fnFormatDetails(fails, nTr), 'details');
                  }
              });
          });
  
      &lt;/script&gt;
  &lt;/head&gt;
  &lt;body&gt;
  
  &lt;table id="fails" cellspacing="0" cellpadding="4" width="100%"&gt;
      &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;Test&lt;/th&gt;
          &lt;th&gt;Measurement&lt;/th&gt;
          &lt;th&gt;Total&lt;/th&gt;
          &lt;th&gt;A&lt;/th&gt;
          &lt;th&gt;B&lt;/th&gt;
          &lt;th&gt;C&lt;/th&gt;
          &lt;th&gt;D&lt;/th&gt;
      &lt;/tr&gt;
      &lt;/thead&gt;
      &lt;tbody&gt;
      &lt;/tbody&gt;
  &lt;/table&gt;
  
  &lt;/body&gt;
  &lt;/html&gt;
  </code></pre>