John Geliberte John Geliberte - 3 months ago 19
Javascript Question

Restrict 1st table row for datatables

Hi I am currently working on datatables and I wrote a code when a table row has been click there is a specific function that will be called.

The problem is when I click the table row for the table header it also does the function (IT MUST NOT).

Here is a snippet of my code when I click the table row there will be a function called.

$('#response-contact-container').on('click', 'tr', function(){
var table = $('#response-contact-container').DataTable();
var data = table.row(this).data();
$('#edit-contact-settings').modal('hide');
$('.modal-backdrop').remove();

var community_contacts = ['c_id','firstname','lastname','prefix','office','sitename','number','rel'];
var employee_contacts = ['eid','firstname','lastname','nickname','birthday','email','numbers','grouptags'];
var counter = 1;

var container = document.getElementById("contact-settings-wrapper");

while (container.hasChildNodes()) {
container.removeChild(container.lastChild);
}

for(var i=1; i< data.length; i++) {

var label = document.createElement("label");
var input = document.createElement("input");

if (data[0].charAt(0)=="c") {
var t = document.createTextNode(community_contacts[i].capitalize());
label.appendChild(t);
container.appendChild(label);
input.type = "text";
input.name = community_contacts[i];
input.className = "form-control";
input.value = data[i];
container.appendChild(input);
container.appendChild(document.createElement("br"));
} else {
var t = document.createTextNode(employee_contacts[i].capitalize());
label.appendChild(t);
container.appendChild(label);
input.type = "text";
input.name = community_contacts[i];
input.className = "form-control";
input.value = data[i];
container.appendChild(input);
container.appendChild(document.createElement("br"));
}

console.log(data[i]);
counter++;
}
$('#edit-contact').modal('show');
});


I want the header be able to not perform the function under the onclick in jQuery, but I don't want it to disable because I want to use the datatables built in feature that sort the cells.

Thanks

Answer

I interpret your question to be the following: when I click on a table row, can I call a click handler if and only if that row has <td> elements, not <th> elements, i.e. only when it is a non-header row?

To accomplish this, use the jQuery .has() selector. Specifically, in your code, instead of

...on('click', 'tr', ...

use

...on('click', 'tr:has(td)', ...

In the example below, the selected element's currentTarget result shows that it is indeed the row, and not the cell, that is the click's current target. Moreover, it calls the handler function (or not) as follows:

  • when you click on a normal data row, i.e. a row with all <td> cells
  • not when you click on a normal header row, i.e. a row with all <th> cells
  • when you click on a mal-formed row that (inappropriately) contains both <th> and <td> rows

You should never form a table row in the last way. However, that example show how the selector is working. Specifically, even if you click on the <th> cell in that row, the click handler will still fire because you are clicking on a cell in a row that contains at least one <td> cell. That should never be what you want, but it illustrates what's going on in terms of what is actually being selected.

var counter = 0;

$('#myTable').on('click', 'tr:has(td)', function(e) {
  console.log(e.currentTarget);
});

$('#myTable').on('click', 'tr', function(e) {
  counter += 1;
  console.log(counter + ' clicks');
});
table {
    border-collapse: collapse;
}
td, th {
  border: black solid 1px;
  padding: 0.5em;
  text-align: left;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="myTable">
  <tr>
    <th>normal header row - cell #1 - &lt;th&gt;</th>
    <th>normal header row - cell #2 - &lt;th&gt;</th>
  </tr>
  <tr>
    <th>malformed (mixed) row - cell #1 - &lt;th&gt;</th>
    <td>malformed (mixed) row - cell #2 - &lt;td&gt;</td>
  </tr>
  <tr>
    <td>normal data row - cell #1 - &lt;td&gt;</td>
    <td>normal data row - cell #2 - &lt;td&gt;</td>
  </tr>
</table>

Comments