sdbbs sdbbs - 5 months ago 11
Javascript Question

Replacing a jQuery selected range of cells?

In the code below, let's call it

test.htm
, upon load I get rendered a table:

ffox1

Then, if I click on any of the header cells, a script runs that iterates over the table rows with the jQuery selector "
#mytable > tbody > tr
", and then it uses a chained filter, "
td:gt(0):lt(2)
", to select a range of
td
cells in each row. So, if our columns are indexed
0,1,2,3,4
, then
gt(0)
will select
1,2,3,4
- and the chained
lt(2)
will be applied to 0:
1
,1:
2
,2:
3
,3:
4
, and so only 0:
1
,1:
2
will remain, or in terms of original column indexes,
1,2
are selected.

To this selection, I want to toggle a class that changes background color, but I would also like to replace the content of the two cells. So I'm trying:

$( "td:gt(0):lt(2)", $thisRow ).toggleClass( "viol" );
$( "td:gt(0):lt(2)", $thisRow ).html("<td>AAAAA</td><td>BBBB</td>");


and the toggling of the class (standalone) works, but the replacement doesn't:

ffox2

So, instead of replacing the two cells with two other cells - I end up splitting each of the cells, because
.html()
gets applied to each element of the collection, and furthermore it changes the inner HTML of the element.

So, assuming in a row iteration loop, I have access to replacement strings like
<td>AAAAA</td><td>BBBB</td>
for a range of cells, how can I replace a range of cells with the content described by this HTML string? To be clear, in the context of this example I'd want the result to be:

ffox3

The code for
test.htm
:

<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> -->
<script type="text/javascript" src="https://code.jquery.com/jquery-1.12.3.min.js"></script>
<style type="text/css">
.a1 {
border-style: solid;
border-width: 1px;
font-size: 1em;
height:auto;
}
.viol { background-color: #DCE0FF; }
</style>
<script type="text/javascript">
function TableHeadListener(inevobj) {
console.log("TableHeadListener", inevobj);
ToggleTdRangeClass();
}
function ToggleTdRangeClass() {
$('#mytable > tbody > tr').each(function() {
$thisRow = $(this);
$( "td:gt(0):lt(2)", $thisRow ).toggleClass( "viol" );
$( "td:gt(0):lt(2)", $thisRow ).html("<td>AAAAA</td><td>BBBB</td>"); // AAA/BBB becomes html of each matched cell individually;!
});
}
createTable = function() {
var htmlTblString = '<table border="1" id="mytable">\n\
<thead>\n\
<tr>\n\
<th>Row h, cell h1</th>\n\
<th>Row h, cell h2</th>\n\
<th>Row h, cell h3</th>\n\
<th>Row h, cell h4</th>\n\
<th>Row h, cell h5</th>\n\
</tr>\n\
</thead>\n\
<tbody>\n\
<tr>\n\
<td>Row d1, cell d1-1</td>\n\
<td>Row d1, cell d1-2</td>\n\
<td>Row d1, cell d1-3</td>\n\
<td>Row d1, cell d1-4</td>\n\
<td>Row d1, cell d1-5</td>\n\
</tr>\n\
<tr>\n\
<td>Row d2, cell d2-1</td>\n\
<td>Row d2, cell d2-2</td>\n\
<td>Row d2, cell d2-3</td>\n\
<td>Row d2, cell d2-4</td>\n\
<td>Row d2, cell d2-5</td>\n\
</tr>\n\
</tbody>\n\
</table>\n';
$("#content").html(htmlTblString);
// add events:
var mtb = $("#mytable");
mtb.find('th').each(function() { $(this).on('click', null, this, TableHeadListener); });
}

ondocready = function() {
createTable();
}
$(document).ready(ondocready);
</script>
</head>

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

<div id="content" class="a1"></div>

</body>
</html>

Answer

One way you can do this is store the values you want on an array[] and then set it to each td element based on the order of the array. Check this:

$('#mytable > tbody > tr').each(function() {
  var txt = ['AAAA','BBBB'],
      count = 0;
  $thisRow = $(this);
  $("td:gt(0):lt(2)", $thisRow).toggleClass("viol");
  $("td:gt(0):lt(2)", $thisRow).each(function(){
    $(this).html(txt[count]);
    count++
  })
});
.a1 {
  border-style: solid;
  border-width: 1px;
  font-size: 1em;
  height: auto;
}
.viol {
  background-color: #DCE0FF;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<table border="1" id="mytable">
  <thead>
    <tr>
      <th>Row h, cell h1</th>
      <th>Row h, cell h2</th>
      <th>Row h, cell h3</th>
      <th>Row h, cell h4</th>
      <th>Row h, cell h5</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Row d1, cell d1-1</td>
      <td>Row d1, cell d1-2</td>
      <td>Row d1, cell d1-3</td>
      <td>Row d1, cell d1-4</td>
      <td>Row d1, cell d1-5</td>
    </tr>
    <tr>
      <td>Row d2, cell d2-1</td>
      <td>Row d2, cell d2-2</td>
      <td>Row d2, cell d2-3</td>
      <td>Row d2, cell d2-4</td>
      <td>Row d2, cell d2-5</td>
    </tr>
  </tbody>
</table>