jQuery dataTable error Cannot read property 'mData' of undefined - javascript

I have following dataTable which has 6 columns.
After rendering the table I am initializing .DataTable(). But getting the error:
'mData' of undefined TypeError: Cannot read property 'mData' of undefined
As mentioned in few of the posts , I have added tfoot but still have the error.
$(document).ready(function() {
$('#pTable').DataTable();
});
<link href="https://cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css" rel="stylesheet"/>
<script src="https://code.jquery.com/jquery-3.3.1.js"></script>
<script src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>
<table id="pTable" class="display" style="width:100%">
<thead>
<tr>
<th>Status</th>
<th>Name</th>
<th>NOK</th>
<th>Phone</th>
<th>IsEnabled</th>
<th>Add/Edit</th>
</tr>
</thead>
<tbody>
<tr>
<td class="text-muted" data-bind="text: ID, visible: false" style="display: none;">288f60e3-0d8f-4a4a-92f9-4f4eeb737909</td>
<td><span class="label label-accent">Active</span></td>
<td class="text-muted" data-bind="text: NAME">Buddy1</td>
<td class="text-muted" data-bind="text: NOK">SomeOne</td>
<td class="text-muted" data-bind="text: SYMPTOMS">12354475541</td>
<td class="text-muted">
<div class="pretty p-round p-fill p-icon">
<input type="checkbox" data-bind="value: ISENABLED, checked: ISENABLED, event: { change: $parent.togglePatients}" value="true">
<div class="state p-primary">
<i class="icon fa fa-check"></i>
<label data-bind="text: ISENABLED">true</label>
</div>
</div>
</td>
<td class="text-muted">
<div class="btn-group pull-right">
<button data-bind="click: $parent.showPatients" type="button" class="btn btn-default btn-xs" data-toggle="modal" data-target="#PatientsModal">
<i class="fa fa-edit"></i> Edit
</button>
</div>
</td>
</tr>
<tr>
<td class="text-muted" data-bind="text: ID, visible: false" style="display: none;">ae2dc252-4940-455e-a528-766f3d7d8fe9</td>
<td><span class="label label-accent">Active</span></td>
<td class="text-muted" data-bind="text: NAME">Buddy2</td>
<td class="text-muted" data-bind="text: NOK">SomeOne Else</td>
<td class="text-muted" data-bind="text: SYMPTOMS">0564654654734</td>
<td class="text-muted">
<div class="pretty p-round p-fill p-icon">
<input type="checkbox" data-bind="value: ISENABLED, checked: ISENABLED, event: { change: $parent.togglePatients}" value="false">
<div class="state p-primary">
<i class="icon fa fa-check"></i>
<label data-bind="text: ISENABLED">false</label>
</div>
</div>
</td>
<td class="text-muted">
<div class="btn-group pull-right">
<button data-bind="click: $parent.showPatients" type="button" class="btn btn-default btn-xs" data-toggle="modal" data-target="#PatientsModal">
<i class="fa fa-edit"></i> Edit
</button>
</div>
</td>
</tr>
</tbody>
<tfoot>
<tr>
<th>Status</th>
<th>Name</th>
<th>Patients</th>
<th>Phone</th>
<th>IsEnabled</th>
<th>Add/Edit</th>
</tr>
</tfoot>
</table>

You had 6 ths but had 7 tds in both of the rows. The number of th must match with the number of td. Adding a hidden th fixed it
$(document).ready(function() {
$('#pTable').DataTable();
});
<link href="https://cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css" rel="stylesheet"/>
<script src="https://code.jquery.com/jquery-3.3.1.js"></script>
<script src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>
<table id="pTable" class="display" style="width:100%">
<thead>
<tr>
<th style="display:none"></th>
<th>Status</th>
<th>Name</th>
<th>NOK</th>
<th>Phone</th>
<th>IsEnabled</th>
<th>Add/Edit</th>
</tr>
</thead>
<tbody>
<tr>
<td class="text-muted" data-bind="text: ID, visible: false" style="display: none;">288f60e3-0d8f-4a4a-92f9-4f4eeb737909</td>
<td><span class="label label-accent">Active</span></td>
<td class="text-muted" data-bind="text: NAME">Buddy1</td>
<td class="text-muted" data-bind="text: NOK">SomeOne</td>
<td class="text-muted" data-bind="text: SYMPTOMS">12354475541</td>
<td class="text-muted">
<div class="pretty p-round p-fill p-icon">
<input type="checkbox" data-bind="value: ISENABLED, checked: ISENABLED, event: { change: $parent.togglePatients}" value="true">
<div class="state p-primary">
<i class="icon fa fa-check"></i>
<label data-bind="text: ISENABLED">true</label>
</div>
</div>
</td>
<td class="text-muted">
<div class="btn-group pull-right">
<button data-bind="click: $parent.showPatients" type="button" class="btn btn-default btn-xs" data-toggle="modal" data-target="#PatientsModal">
<i class="fa fa-edit"></i> Edit
</button>
</div>
</td>
</tr>
<tr>
<td class="text-muted" data-bind="text: ID, visible: false" style="display: none;">ae2dc252-4940-455e-a528-766f3d7d8fe9</td>
<td><span class="label label-accent">Active</span></td>
<td class="text-muted" data-bind="text: NAME">Buddy2</td>
<td class="text-muted" data-bind="text: NOK">SomeOne Else</td>
<td class="text-muted" data-bind="text: SYMPTOMS">0564654654734</td>
<td class="text-muted">
<div class="pretty p-round p-fill p-icon">
<input type="checkbox" data-bind="value: ISENABLED, checked: ISENABLED, event: { change: $parent.togglePatients}" value="false">
<div class="state p-primary">
<i class="icon fa fa-check"></i>
<label data-bind="text: ISENABLED">false</label>
</div>
</div>
</td>
<td class="text-muted">
<div class="btn-group pull-right">
<button data-bind="click: $parent.showPatients" type="button" class="btn btn-default btn-xs" data-toggle="modal" data-target="#PatientsModal">
<i class="fa fa-edit"></i> Edit
</button>
</div>
</td>
</tr>
</tbody>
<tfoot>
<tr>
<th>Status</th>
<th>Name</th>
<th>Patients</th>
<th>Phone</th>
<th>IsEnabled</th>
<th>Add/Edit</th>
</tr>
</tfoot>
</table>

Number of headers thead tr th and number of cells in the tbody tr td should be same in each row(Same with the footer too). Once you do this this error will be removed.
'<table id="pTable" class="display" style="width:100%">
<thead>
<tr>
<th>Status</th>
<th>Name</th>
<th>NOK</th>
<th>Phone</th>
<th>IsEnabled</th>
<th>Add/Edit</th>
<th>Some Heading</th>
</tr>
</thead>
<tbody>
<tr>
<td class="text-muted" data-bind="text: ID, visible: false" style="display: none;">288f60e3-0d8f-4a4a-92f9-4f4eeb737909</td>
<td><span class="label label-accent">Active</span></td>
<td class="text-muted" data-bind="text: NAME">Buddy1</td>
<td class="text-muted" data-bind="text: NOK">SomeOne</td>
<td class="text-muted" data-bind="text: SYMPTOMS">12354475541</td>
<td class="text-muted">
<div class="pretty p-round p-fill p-icon">
<input type="checkbox" data-bind="value: ISENABLED, checked: ISENABLED, event: { change: $parent.togglePatients}" value="true">
<div class="state p-primary">
<i class="icon fa fa-check"></i>
<label data-bind="text: ISENABLED">true</label>
</div>
</div>
</td>
<td class="text-muted">
<div class="btn-group pull-right">
<button data-bind="click: $parent.showPatients" type="button" class="btn btn-default btn-xs" data-toggle="modal" data-target="#PatientsModal">
<i class="fa fa-edit"></i> Edit
</button>
</div>
</td>
</tr>
<tr>
<td class="text-muted" data-bind="text: ID, visible: false" style="display: none;">ae2dc252-4940-455e-a528-766f3d7d8fe9</td>
<td><span class="label label-accent">Active</span></td>
<td class="text-muted" data-bind="text: NAME">Buddy2</td>
<td class="text-muted" data-bind="text: NOK">SomeOne Else</td>
<td class="text-muted" data-bind="text: SYMPTOMS">0564654654734</td>
<td class="text-muted">
<div class="pretty p-round p-fill p-icon">
<input type="checkbox" data-bind="value: ISENABLED, checked: ISENABLED, event: { change: $parent.togglePatients}" value="false">
<div class="state p-primary">
<i class="icon fa fa-check"></i>
<label data-bind="text: ISENABLED">false</label>
</div>
</div>
</td>
<td class="text-muted">
<div class="btn-group pull-right">
<button data-bind="click: $parent.showPatients" type="button" class="btn btn-default btn-xs" data-toggle="modal" data-target="#PatientsModal">
<i class="fa fa-edit"></i> Edit
</button>
</div>
</td>
</tr>
</tbody>
<tfoot>
<tr>
<th>Status</th>
<th>Name</th>
<th>Patients</th>
<th>Phone</th>
<th>IsEnabled</th>
<th>Add/Edit</th>
<th>Some Heading</th>
</tr>
</tfoot>
'

Related

Is there a way to combine these similar jQuery event listener functions?

I have multiple jquery event listener functions that either show or hide a checkmark button based on if there is any input in the input box. The functions are practically identical minus the ID names. I'm wondering if there's a way to combine these similar functions into one, maybe using a for loop or forEach method? Any advice on how to achieve this is greatly appreciated!
Code is listed down below but I also made a codepen sample.
$("#chwValue").on("input", function() {
$("#addChw").removeAttr("style");
if ($(this).val() === "") {
$("#addChw").hide();
}
});
$("#eleValue").on("input", function() {
$("#addEle").removeAttr("style");
if ($(this).val() === "") {
$("#addEle").hide();
}
});
$("#stmValue").on("input", function() {
$("#addStm").removeAttr("style");
if ($(this).val() === "") {
$("#addStm").hide();
}
});
$("#hhwValue").on("input", function() {
$("#addHhw").removeAttr("style");
if ($(this).val() === "") {
$("#addHhw").hide();
}
});
$("#gasValue").on("input", function() {
$("#addGas").removeAttr("style");
if ($(this).val() === "") {
$("#addGas").hide();
}
});
$("#wtrValue").on("input", function() {
$("#addWtr").removeAttr("style");
if ($(this).val() === "") {
$("#addWtr").hide();
}
});
$("#peakChwValue").on("input", function() {
$("#addPeakChw").removeAttr("style");
if ($(this).val() === "") {
$("#addPeakChw").hide();
}
});
$("#laborValue").on("input", function() {
$("#addLabor").removeAttr("style");
if ($(this).val() === "") {
$("#addLabor").hide();
}
});
.checkMark:hover {
cursor: pointer;
transition: transform 0.2s;
transform: scale(1.1)
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css" />
<table id="tableData" class="table text-light text-end table-borderless inputTable">
<thead>
<tr class='text-center bordered'>
<th></th>
<th class="bordered" scope="col">CHW
<span class='units'>[tonhr]</span>
</th>
<th class="bordered" scope="col">ELE
<span class='units'>[kWh]</span>
</th>
<th class="bordered" scope="col">STM
<span class='units'>[lb]</span>
</th>
<th class="bordered" scope="col">HHW
<span class='units'>[mmbtu]</span>
</th>
<th class="bordered" scope="col">GAS
<span class='units'>[CCF]</span>
</th>
<th class="bordered" scope="col">WTR
<span class='units'>[kgal]</span>
</th>
<th class="bordered" scope="col">Peak CHW
<span class='units'>[ton]</span>
</th>
<th class="bordered" scope="col">Labor
<span class='units'>[Hours]</span>
</th>
</tr>
</thead>
<tbody>
<tr>
<th style="width: 100px" class="bordered">Baseline</th>
<td class="text-center inputBorder">
<input type="text" id="chwValue" class="chwInput">
</td>
<td class="text-center inputBorder">
<input type="text" id="eleValue" class="eleInput">
</td>
<td class="text-center inputBorder">
<input type="text" id="stmValue" class="stmInput">
</td>
<td class="text-center inputBorder">
<input type="text" id="hhwValue" class="hhwInput">
</td>
<td class="text-center inputBorder">
<input type="text" id="gasValue" class="gasInput">
</td>
<td class="text-center inputBorder">
<input type="text" id="wtrValue" class="wtrInput">
</td>
<td class="text-center inputBorder">
<input type="text" id="peakChwValue" class="peakChwInput">
</td>
<td class="text-center inputBorder">
<input type="text" id="laborValue" class="laborInput">
</td>
</tr>
<tr class='text-center borderTop'>
<td></td>
<td>
<i id="addChw" style="display: none" class="far fa-check-circle fa-3x checkMark"></i>
</td>
<td>
<i id="addEle" style="display: none" class="far fa-check-circle fa-3x checkMark"></i>
</td>
<td>
<i id="addStm" style="display: none" class="far fa-check-circle fa-3x checkMark"></i>
</td>
<td>
<i id="addHhw" style="display: none" class="far fa-check-circle fa-3x checkMark"></i>
</td>
<td>
<i id="addGas" style="display: none" class="far fa-check-circle fa-3x checkMark"></i>
</td>
<td>
<i id="addWtr" style="display: none" class="far fa-check-circle fa-3x checkMark"></i>
</td>
<td>
<i id="addPeakChw" style="display: none" class="far fa-check-circle fa-3x checkMark"></i>
</td>
<td>
<i id="addLabor" style="display: none" class="far fa-check-circle fa-3x checkMark"></i>
</td>
</tr>
</tbody>
</table>
You can try something like this:
var mappings = { //Need a better name
'#chwValue': '#addChw',
'#hhwValue': '#addHhw'
// Add the rest of the mappings here
}
Object.keys(mappings).forEach(function(key) {
var value = mappings[key];
$(key).on("input", function() {
$(value).removeAttr("style");
if ($(this).val() === "") {
$(value).hide();
}
});
});
Give all the inputs a common class. Give them an attribute that refers to the related addXxx element.
$(".inputValue").on("input", function() {
let rel = $($(this).data("add"));
rel.removeAttr("style");
if ($(this).val() === "") {
rel.hide();
}
});
.checkMark:hover {
cursor: pointer;
transition: transform 0.2s;
transform: scale(1.1)
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="tableData" class="table text-light text-end table-borderless inputTable">
<thead>
<tr class='text-center bordered'>
<th></th>
<th class="bordered" scope="col">CHW
<span class='units'>[tonhr]</span>
</th>
<th class="bordered" scope="col">ELE
<span class='units'>[kWh]</span>
</th>
<th class="bordered" scope="col">STM
<span class='units'>[lb]</span>
</th>
<th class="bordered" scope="col">HHW
<span class='units'>[mmbtu]</span>
</th>
<th class="bordered" scope="col">GAS
<span class='units'>[CCF]</span>
</th>
<th class="bordered" scope="col">WTR
<span class='units'>[kgal]</span>
</th>
<th class="bordered" scope="col">Peak CHW
<span class='units'>[ton]</span>
</th>
<th class="bordered" scope="col">Labor
<span class='units'>[Hours]</span>
</th>
</tr>
</thead>
<tbody>
<tr>
<th style="width: 100px" class="bordered">Baseline</th>
<td class="text-center inputBorder">
<input type="text" id="chwValue" class="chwInput inputValue" data-add="#addChw">
</td>
<td class="text-center inputBorder">
<input type="text" id="eleValue" class="eleInput inputValue" data-add="#addEle">
</td>
<td class="text-center inputBorder">
<input type="text" id="stmValue" class="stmInput inputValue" data-add="#addStm">
</td>
<td class="text-center inputBorder">
<input type="text" id="hhwValue" class="hhwInput inputValue" data-add="#addHhw">
</td>
<td class="text-center inputBorder">
<input type="text" id="gasValue" class="gasInput inputValue" data-add="#addGas">
</td>
<td class="text-center inputBorder">
<input type="text" id="wtrValue" class="wtrInput inputValue" data-add="#addWtr">
</td>
<td class="text-center inputBorder">
<input type="text" id="peakChwValue" class="peakChwInput inputValue" data-add="#addPeakChw">
</td>
<td class="text-center inputBorder">
<input type="text" id="laborValue" class="laborInput inputValue" data-add="#addLabor">
</td>
</tr>
<tr class='text-center borderTop'>
<td></td>
<td>
<i id="addChw" style="display: none" class="far fa-check-circle fa-3x checkMark">x</i>
</td>
<td>
<i id="addEle" style="display: none" class="far fa-check-circle fa-3x checkMark">x</i>
</td>
<td>
<i id="addStm" style="display: none" class="far fa-check-circle fa-3x checkMark">x</i>
</td>
<td>
<i id="addHhw" style="display: none" class="far fa-check-circle fa-3x checkMark">x</i>
</td>
<td>
<i id="addGas" style="display: none" class="far fa-check-circle fa-3x checkMark">x</i>
</td>
<td>
<i id="addWtr" style="display: none" class="far fa-check-circle fa-3x checkMark">x</i>
</td>
<td>
<i id="addPeakChw" style="display: none" class="far fa-check-circle fa-3x checkMark">x</i>
</td>
<td>
<i id="addLabor" style="display: none" class="far fa-check-circle fa-3x checkMark">x</i>
</td>
</tr>
</tbody>
</table>
To achieve this in a more DRY manner you can relate the cells in the columns by their index. When an input element raises an input event you can capture its index within the parent tr, then retrieve the corresponding icon cell from the following row by that same index. Something like this:
let $iconCells = $('.icon-row td');
$('.input-row input').on('input', e => {
let $input = $(e.target)
let index = $input.closest('td').index();
$iconCells.eq(index).find('i').toggle($input.val().length > 0);
});
.checkMark:hover {
cursor: pointer;
transition: transform 0.2s;
transform: scale(1.1)
}
.icon-row i {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css" />
<table id="tableData" class="table text-light text-end table-borderless inputTable">
<thead>
<tr class='text-center bordered'>
<th></th>
<th class="bordered" scope="col">
CHW
<span class='units'>[tonhr]</span>
</th>
<th class="bordered" scope="col">
ELE
<span class='units'>[kWh]</span>
</th>
<th class="bordered" scope="col">
STM
<span class='units'>[lb]</span>
</th>
<th class="bordered" scope="col">
HHW
<span class='units'>[mmbtu]</span>
</th>
<th class="bordered" scope="col">
GAS
<span class='units'>[CCF]</span>
</th>
<th class="bordered" scope="col">
WTR
<span class='units'>[kgal]</span>
</th>
<th class="bordered" scope="col">
Peak CHW
<span class='units'>[ton]</span>
</th>
<th class="bordered" scope="col">
Labor
<span class='units'>[Hours]</span>
</th>
</tr>
</thead>
<tbody>
<tr class="input-row">
<th style="width: 100px" class="bordered">Baseline</th>
<td class="text-center inputBorder">
<input type="text" name="chwValue" class="chwInput" />
</td>
<td class="text-center inputBorder">
<input type="text" name="eleValue" class="eleInput" />
</td>
<td class="text-center inputBorder">
<input type="text" name="stmValue" class="stmInput" />
</td>
<td class="text-center inputBorder">
<input type="text" name="hhwValue" class="hhwInput" />
</td>
<td class="text-center inputBorder">
<input type="text" name="gasValue" class="gasInput" />
</td>
<td class="text-center inputBorder">
<input type="text" name="wtrValue" class="wtrInput" />
</td>
<td class="text-center inputBorder">
<input type="text" name="peakChwValue" class="peakChwInput" />
</td>
<td class="text-center inputBorder">
<input type="text" name="laborValue" class="laborInput" />
</td>
</tr>
<tr class="text-center borderTop icon-row">
<td></td>
<td><i class="far fa-check-circle fa-3x checkMark"></i></td>
<td><i class="far fa-check-circle fa-3x checkMark"></i></td>
<td><i class="far fa-check-circle fa-3x checkMark"></i></td>
<td><i class="far fa-check-circle fa-3x checkMark"></i></td>
<td><i class="far fa-check-circle fa-3x checkMark"></i></td>
<td><i class="far fa-check-circle fa-3x checkMark"></i></td>
<td><i class="far fa-check-circle fa-3x checkMark"></i></td>
<td><i class="far fa-check-circle fa-3x checkMark"></i></td>
</tr>
</tbody>
</table>
Store the relationships in an array of objects and iterate through.
let objs = [
{'chwValue': 'addChw'},
{'eleValue': 'addEle'},
{'stmValue': 'addStm'},
{'hhwValue': 'addHhw'},
{'gasValue': 'addGas'},
{'wtrValue': 'addWtr'},
{'peakChwValue': 'addPeakChw'},
{'laborValue': 'addLabor'}];
objs.forEach(e => {
let [input, el] = Object.entries(e)[0];
$(`#${input}`).on("input", function() {
$(`#${el}`).removeAttr("style");
if ($(this).val() === "") $(`$${el}`).hide();
});
});
.checkMark:hover {
cursor: pointer;
transition: transform 0.2s;
transform: scale(1.1)
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css" integrity="sha512-iBBXm8fW90+nuLcSKlbmrPcLa0OT92xO1BIsZ+ywDWZCvqsWgccV3gFoRBv0z+8dLJgyAHIhR35VZc2oM/gI1w==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<table id="tableData" class="table text-light text-end table-borderless inputTable">
<thead>
<tr class='text-center bordered'>
<th></th>
<th class="bordered" scope="col">CHW
<span class='units'>[tonhr]</span>
</th>
<th class="bordered" scope="col">ELE
<span class='units'>[kWh]</span>
</th>
<th class="bordered" scope="col">STM
<span class='units'>[lb]</span>
</th>
<th class="bordered" scope="col">HHW
<span class='units'>[mmbtu]</span>
</th>
<th class="bordered" scope="col">GAS
<span class='units'>[CCF]</span>
</th>
<th class="bordered" scope="col">WTR
<span class='units'>[kgal]</span>
</th>
<th class="bordered" scope="col">Peak CHW
<span class='units'>[ton]</span>
</th>
<th class="bordered" scope="col">Labor
<span class='units'>[Hours]</span>
</th>
</tr>
</thead>
<tbody>
<tr>
<th style="width: 100px" class="bordered">Baseline</th>
<td class="text-center inputBorder">
<input type="text" id="chwValue" class="chwInput">
</td>
<td class="text-center inputBorder">
<input type="text" id="eleValue" class="eleInput">
</td>
<td class="text-center inputBorder">
<input type="text" id="stmValue" class="stmInput">
</td>
<td class="text-center inputBorder">
<input type="text" id="hhwValue" class="hhwInput">
</td>
<td class="text-center inputBorder">
<input type="text" id="gasValue" class="gasInput">
</td>
<td class="text-center inputBorder">
<input type="text" id="wtrValue" class="wtrInput">
</td>
<td class="text-center inputBorder">
<input type="text" id="peakChwValue" class="peakChwInput">
</td>
<td class="text-center inputBorder">
<input type="text" id="laborValue" class="laborInput">
</td>
</tr>
<tr class='text-center borderTop'>
<td></td>
<td>
<i id="addChw" style="display: none" class="far fa-check-circle fa-3x checkMark"></i>
</td>
<td>
<i id="addEle" style="display: none" class="far fa-check-circle fa-3x checkMark"></i>
</td>
<td>
<i id="addStm" style="display: none" class="far fa-check-circle fa-3x checkMark"></i>
</td>
<td>
<i id="addHhw" style="display: none" class="far fa-check-circle fa-3x checkMark"></i>
</td>
<td>
<i id="addGas" style="display: none" class="far fa-check-circle fa-3x checkMark"></i>
</td>
<td>
<i id="addWtr" style="display: none" class="far fa-check-circle fa-3x checkMark"></i>
</td>
<td>
<i id="addPeakChw" style="display: none" class="far fa-check-circle fa-3x checkMark"></i>
</td>
<td>
<i id="addLabor" style="display: none" class="far fa-check-circle fa-3x checkMark"></i>
</td>
</tr>
</tbody>
</table>
How about this?
$("#chwValue, #eleValue, #stmValue, #hhwValue, #gasValue, #wtrValue, #peakChwValue, #laborValue").on("input", function() {
//get the id selector from the id value (everything before 'Value')
let idName = $(this).attr('id').split('Value')[0]
//capitalize the first character
idName = idName[0].toUpperCase() + idName.slice(1);
//add the id selector dynamically
$("#add"+idName).removeAttr("style");
if ($(this).val() === "") {
$("#add"+idName).hide();
}
});
$("#chwValue, #eleValue, #stmValue, #hhwValue, #gasValue, #wtrValue, #peakChwValue, #laborValue").on("input", function() {
//get the id selector from the id value (everything before 'Value')
let idName = $(this).attr('id').split('Value')[0]
//capitalize the first character
idName = idName[0].toUpperCase() + idName.slice(1);
//add the id selector dynamically
$("#add"+idName).removeAttr("style");
if ($(this).val() === "") {
$("#add"+idName).hide();
}
});
.checkMark:hover {
cursor: pointer;
transition: transform 0.2s;
transform: scale(1.1)
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css" />
<table id="tableData" class="table text-light text-end table-borderless inputTable">
<thead>
<tr class='text-center bordered'>
<th></th>
<th class="bordered" scope="col">CHW
<span class='units'>[tonhr]</span>
</th>
<th class="bordered" scope="col">ELE
<span class='units'>[kWh]</span>
</th>
<th class="bordered" scope="col">STM
<span class='units'>[lb]</span>
</th>
<th class="bordered" scope="col">HHW
<span class='units'>[mmbtu]</span>
</th>
<th class="bordered" scope="col">GAS
<span class='units'>[CCF]</span>
</th>
<th class="bordered" scope="col">WTR
<span class='units'>[kgal]</span>
</th>
<th class="bordered" scope="col">Peak CHW
<span class='units'>[ton]</span>
</th>
<th class="bordered" scope="col">Labor
<span class='units'>[Hours]</span>
</th>
</tr>
</thead>
<tbody>
<tr>
<th style="width: 100px" class="bordered">Baseline</th>
<td class="text-center inputBorder">
<input type="text" id="chwValue" class="chwInput">
</td>
<td class="text-center inputBorder">
<input type="text" id="eleValue" class="eleInput">
</td>
<td class="text-center inputBorder">
<input type="text" id="stmValue" class="stmInput">
</td>
<td class="text-center inputBorder">
<input type="text" id="hhwValue" class="hhwInput">
</td>
<td class="text-center inputBorder">
<input type="text" id="gasValue" class="gasInput">
</td>
<td class="text-center inputBorder">
<input type="text" id="wtrValue" class="wtrInput">
</td>
<td class="text-center inputBorder">
<input type="text" id="peakChwValue" class="peakChwInput">
</td>
<td class="text-center inputBorder">
<input type="text" id="laborValue" class="laborInput">
</td>
</tr>
<tr class='text-center borderTop'>
<td></td>
<td>
<i id="addChw" style="display: none" class="far fa-check-circle fa-3x checkMark"></i>
</td>
<td>
<i id="addEle" style="display: none" class="far fa-check-circle fa-3x checkMark"></i>
</td>
<td>
<i id="addStm" style="display: none" class="far fa-check-circle fa-3x checkMark"></i>
</td>
<td>
<i id="addHhw" style="display: none" class="far fa-check-circle fa-3x checkMark"></i>
</td>
<td>
<i id="addGas" style="display: none" class="far fa-check-circle fa-3x checkMark"></i>
</td>
<td>
<i id="addWtr" style="display: none" class="far fa-check-circle fa-3x checkMark"></i>
</td>
<td>
<i id="addPeakChw" style="display: none" class="far fa-check-circle fa-3x checkMark"></i>
</td>
<td>
<i id="addLabor" style="display: none" class="far fa-check-circle fa-3x checkMark"></i>
</td>
</tr>
</tbody>
</table>

Get the value of first column of an html table

I have an HTML table with the following table structure. When I click on the span element in the last column I expect to get the value of first td in the same row.
<tbody>
<tr >
<td >1</td>
<td>75</td>
<td>NA</td>
<td>700</td>
<td >
<span onclick="deleterec()" >
<i class="fa fa-square-o fa-stack-2x"></i>
<i class="fa fa-remove fa-stack-1x" style="line-height: 20px;"></i>
</span>
</td>
</tr>
<tr >
<td>76</td>
<td>100</td>
<td>NA</td>
<td>600</td>
<td >
<span onclick="deleterec()" >
<i class="fa fa-square-o fa-stack-2x"></i>
<i class="fa fa-remove fa-stack-1x" style="line-height: 20px;"></i>
</span>
</td>
</tr>
<tr >
<td>101</td>
<td ">NA</td>
<td>200</td>
<td>500</td>
<td >
<span onclick="deleterec()" >
<i class="fa fa-square-o fa-stack-2x"></i>
<i class="fa fa-remove fa-stack-1x" style="line-height: 20px;"></i>
</span>
</td>
</tr>
</tbody>
This is my javascript code , which I used
function deleterec(){
var tr=$(this).closest('tr');
var x=tr.children('td:first-child').text();
}
However, it doesn't return the value of first column. How can I achieve this?
Pass this in onclick function as below, also check how to get first td text simply.
function deleterec(obj){
var tr=$(obj).parents('tr').find('td:first-child').text();
console.log(tr);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<table>
<tbody>
<tr >
<td >1</td>
<td>75</td>
<td>NA</td>
<td>700</td>
<td >
<span onclick="deleterec(this)" >
<i class="fa fa-square-o fa-stack-2x"></i>
<i class="fa fa-remove fa-stack-1x" style="line-height: 20px;"></i>
</span>
</td>
</tr>
<tr >
<td>76</td>
<td>100</td>
<td>NA</td>
<td>600</td>
<td >
<span onclick="deleterec(this)" >
<i class="fa fa-square-o fa-stack-2x"></i>
<i class="fa fa-remove fa-stack-1x" style="line-height: 20px;"></i>
</span>
</td>
</tr>
<tr >
<td>101</td>
<td>NA</td>
<td>200</td>
<td>500</td>
<td >
<span onclick="deleterec(this)" >
<i class="fa fa-square-o fa-stack-2x"></i>
<i class="fa fa-remove fa-stack-1x" style="line-height: 20px;"></i>
</span>
</td>
</tr>
</tbody>
</table>
you can also avoid jquery too.
const deleterec = () => {
let elm = event.target;
while (elm.tagName !== "TR") {
elm = elm.parentElement;
}
const td = elm.querySelector("td");
console.log(td.innerText);
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<table>
<tbody>
<tr>
<td>1</td>
<td>75</td>
<td>NA</td>
<td>700</td>
<td>
<span onclick="deleterec()">
<i class="fa fa-square-o fa-stack-2x"></i>
<i class="fa fa-remove fa-stack-1x" style="line-height: 20px;"></i>
</span>
</td>
</tr>
<tr>
<td>76</td>
<td>100</td>
<td>NA</td>
<td>600</td>
<td>
<span onclick="deleterec()">
<i class="fa fa-square-o fa-stack-2x"></i>
<i class="fa fa-remove fa-stack-1x" style="line-height: 20px;"></i>
</span>
</td>
</tr>
<tr>
<td>101</td>
<td>NA</td>
<td>200</td>
<td>500</td>
<td>
<span onclick=" deleterec()">
<i class="fa fa-square-o fa-stack-2x"></i>
<i class="fa fa-remove fa-stack-1x" style="line-height: 20px;"></i>
</span>
</td>
</tr>
</tbody>
</table>
function deleterec(index) {
let row = document.querySelectorAll('.tr');
console.log(row);
console.log(row[index]);
}
span {
cursor: pointer;
}
i {
pointer-events: none;
}
<table>
<tbody class="table">
<tr class="tr">
<td>1</td>
<td>75</td>
<td>NA</td>
<td>700</td>
<td>
<span onclick="deleterec(0)">
<i class="fa fa-square-o fa-stack-2x"></i>
<i class="fa fa-remove fa-stack-1x" style="line-height: 20px"
>span</i
>
</span>
</td>
</tr>
<tr class="tr">
<td>1</td>
<td>75</td>
<td>NA</td>
<td>700</td>
<td>
<span onclick="deleterec(1)">
<i class="fa fa-square-o fa-stack-2x"></i>
<i class="fa fa-remove fa-stack-1x" style="line-height: 20px"
>span</i
>
</span>
</td>
</tr>
<tr class="tr">
<td>1</td>
<td>75</td>
<td>NA</td>
<td>700</td>
<td>
<span onclick="deleterec(2)">
<i class="fa fa-square-o fa-stack-2x"></i>
<i class="fa fa-remove fa-stack-1x" style="line-height: 20px"
>span</i
>
</span>
</td>
</tr>
</tbody>
</table>
You can pass an index inside a function. or if you create a row dynamically then pass an index.
function deleterec(obj){
var ab = $(obj).closest('tr').find('td:first-child').text()
console.log(ab);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<table id='ids'>
<tbody>
<tr>
<td>1</td>
<td>75</td>
<td>NA</td>
<td>700</td>
<td>
<span onclick="deleterec(this)" >
<i class="fa fa-remove" style="line-height: 20px;"></i>
</span>
</td>
</tr>
<tr>
<td>76</td>
<td>100</td>
<td>NA</td>
<td>600</td>
<td>
<span onclick="deleterec(this)" >
<i class="fa fa-remove" style="line-height: 20px;"></i>
</span>
</td>
</tr>
<tr>
<td>101</td>
<td>NA</td>
<td>200</td>
<td>500</td>
<td>
<span onclick="deleterec(this)" >
<i class="fa fa-remove" style="line-height: 20px;"></i>
</span>
</td>
</tr>
</tbody>
</table>

Everytime i clicked on .approvers > a I can't get the tr id name

I have this code
<tr class="job-order__row" id="accounting" style="display:none;">
<td>1</td>
<td>Doe</td>
<td>John</td>
<td>Accounting Personnel</td>
<td>
<div class="actions pull-right approvers">
<i class="fa fa-close" title="remove approvers"></i>
</div>
</td>
</tr>
<tr class="job-order__row" id="hr" style="display:none;">
<td>2</td>
<td>Doe</td>
<td>Luke</td>
<td>HR Personnel</td>
<td>
<div class="actions pull-right approvers">
<i class="fa fa-close" title="remove approvers"></i>
</div>
</td>
</tr>
<tr class="job-order__row" id="crm" style="display:none;">
<td>3</td>
<td>Doe</td>
<td>Mark</td>
<td>CRM Personnel</td>
<td>
<div class="actions pull-right approvers">
<i class="fa fa-close" title="remove approvers"></i>
</div>
</td>
</tr>
and the javascript/jquery code
$(document).on('click', '.approvers > a', function(e) {
e.preventDefault();
var $id = $('.approvers > a').parents('tr').attr('id');
$('#'+$id).hide();
});
The problem is, when i try to click on any of .approvers > a this part here
$('.approvers > a').parents('tr').attr('id'); of the code only return the Id name "crm".
What I want to do is everytime i clicked on .approvers > a I will get the tr id name.
Anyone has the same problem?
Thanks
What #Tushar said is use $(this) for refer to the element clicked and closest() for get the first parent element.
$(document).on('click', '.approvers > a', function(e) {
e.preventDefault();
var $id = $(this).closest('tr').attr('id');
alert($id)
$('#'+$id).hide();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr class="job-order__row" id="accounting" style="">
<td>1</td>
<td>Doe</td>
<td>John</td>
<td>Accounting Personnel</td>
<td>
<div class="actions pull-right approvers">
<i class="fa fa-close" title="remove approvers"></i>click
</div>
</td>
</tr>
<tr class="job-order__row" id="hr" style="">
<td>2</td>
<td>Doe</td>
<td>Luke</td>
<td>HR Personnel</td>
<td>
<div class="actions pull-right approvers">
<i class="fa fa-close" title="remove approvers"></i>click
</div>
</td>
</tr>
<tr class="job-order__row" id="crm" style="">
<td>3</td>
<td>Doe</td>
<td>Mark</td>
<td>CRM Personnel</td>
<td>
<div class="actions pull-right approvers">
<i class="fa fa-close" title="remove approvers"></i>click
</div>
</td>
</tr>
</table>
Use below code it will give you clicked item tr/row id.
$("table tr").on('click', function (e) {
console.log(e.currentTarget.id);
});

How to Move selected table tr's to another table?

I have got two tables mytable1 and mytable2
I am trying to move the checked tr rows (from table mytable1) to different table mytable2
I have tried as following
$(document).ready(function() {
$(document).on("click", ".movemultiple", function(event)
{
$('.mytable1 > tbody > tr').each(function() {
$(this).find('td:eq(0) .updatecheckboxvalueindb:checked')
});
});
});
.fa fa-check
{
background-color:red!importnt
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table class="mytable1 table table-bordered table-hover" id="videosfromtagstable">
<thead>
<tr class="existingvideos">
<th>Action</th>
<th>Name</th>
<th>File</th>
<th>Badge</th>
<th>Equipments</th>
</tr>
</thead>
<tbody class="connectedSortable ui-sortable">
<tr video-id="37" title="" class="newvideos exercises-add-table-content">
<td class="removecheckboxtd" style="vertical-align: middle ; display:block;"><label class="mt-checkbox mt-checkbox-outline"><input class="new-checkbox updatecheckboxvalueindb" value="new_flag" type="checkbox"><span></span></label></td>
<td>crunches</td>
<td>ht4_970_979.mp4</td>
<td>
<span class="btn btn-sm btn-success btn-circle">Push Ups</span>
</td>
<td><i class="fa fa-check"></i></td>
</tr>
<tr video-id="38" title="" class="newvideos exercises-add-table-content">
<td class="removecheckboxtd" style="vertical-align: middle ; display:block;"><label class="mt-checkbox mt-checkbox-outline"><input class="new-checkbox updatecheckboxvalueindb" value="new_flag" type="checkbox"><span></span></label></td>
<td>Sit Ups</td>
<td>ht4_970_345.mp4</td>
<td>
<span class="btn btn-sm btn-success btn-circle">Push Ups</span>
</td>
<td><i class="fa fa-check"></i></td>
</tr>
</tbody>
</table>
<br><br>
<button type="button" class="btn red default movemultiple">Move </button>
<br><br>
<table class="mytable2 table table-bordered table-hover" id="videosexistingtable">
<tbody class="connectedSortable ui-sortable">
<tr class="existingvideos">
<th>Name</th>
<th>File</th>
<th>Badge</th>
<th>Equipments</th>
<th>Action</th>
</tr>
<tr class="existingvideos" video-id="34">
<td>Push Ups</td>
<td>ht4_970_285.mp4</td>
<td>
<span class="btn btn-sm btn-success btn-circle">Push Ups</span>
</td>
<td>
<i class="fa fa-check"></i>
</td>
<td class="deletevidetd"><a data-videoid="34" class="fa fa-trash remove-delete-icon deletevideo" title="Delete"></a></td>
</tr>
</tbody>
</table>
Could you please let me know how to do this ?
http://jsfiddle.net/o2gxgz9r/1879/
You could use jQuery .closest() to get the closest table row (or table cell) and jQuery .remove() to remove the table cell with the checkbox from DOM:
$(document).ready(function () {
$(document).on('click', '.movemultiple', function() {
var $myTable2Body = $('.mytable2 tbody');
$('.mytable1 .updatecheckboxvalueindb:checked').each(function(index, item) {
var $checkbox = $(item);
$myTable2Body.append($checkbox.closest('tr'));
$checkbox.closest('td').remove();
});
});
});
.fa fa-check
{
background-color:red!importnt
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table class="mytable1 table table-bordered table-hover" id="videosfromtagstable">
<thead>
<tr class="existingvideos">
<th>Action</th>
<th>Name</th>
<th>File</th>
<th>Badge</th>
<th>Equipments</th>
</tr>
</thead>
<tbody class="connectedSortable ui-sortable">
<tr video-id="37" title="" class="newvideos exercises-add-table-content">
<td class="removecheckboxtd" style="vertical-align: middle ; display:block;"><label class="mt-checkbox mt-checkbox-outline"><input class="new-checkbox updatecheckboxvalueindb" value="new_flag" type="checkbox"><span></span></label></td>
<td>crunches</td>
<td>ht4_970_979.mp4</td>
<td>
<span class="btn btn-sm btn-success btn-circle">Push Ups</span>
</td>
<td><i class="fa fa-check"></i></td>
</tr>
<tr video-id="38" title="" class="newvideos exercises-add-table-content">
<td class="removecheckboxtd" style="vertical-align: middle ; display:block;"><label class="mt-checkbox mt-checkbox-outline"><input class="new-checkbox updatecheckboxvalueindb" value="new_flag" type="checkbox"><span></span></label></td>
<td>Sit Ups</td>
<td>ht4_970_345.mp4</td>
<td>
<span class="btn btn-sm btn-success btn-circle">Push Ups</span>
</td>
<td><i class="fa fa-check"></i></td>
</tr>
</tbody>
</table>
<br><br>
<button type="button" class="btn red default movemultiple">Move </button>
<br><br>
<table class="mytable2 table table-bordered table-hover" id="videosexistingtable">
<tbody class="connectedSortable ui-sortable">
<tr class="existingvideos">
<th>Name</th>
<th>File</th>
<th>Badge</th>
<th>Equipments</th>
<th>Action</th>
</tr>
<tr class="existingvideos" video-id="34">
<td>Push Ups</td>
<td>ht4_970_285.mp4</td>
<td>
<span class="btn btn-sm btn-success btn-circle">Push Ups</span>
</td>
<td>
<i class="fa fa-check"></i>
</td>
<td class="deletevidetd"><a data-videoid="34" class="fa fa-trash remove-delete-icon deletevideo" title="Delete"></a></td>
</tr>
</tbody>
</table>
JSFiddle
like this?
$(document).on("click", ".movemultiple", function(event){
$('.updatecheckboxvalueindb:checked').parents('tr').appendTo('.mytable2').find('.removecheckboxtd').remove();
});
check out the fiddle : http://jsfiddle.net/h9q8o340/

Selenium Webdriver - elements only with exact value identification , js/html

I am wondering about one thing.
Have a UI html table with two records and would like to click on a record only with exact value.
Something like for instance:
SELECT record WHERE tr data-user LIKE "testuser1"
Is it possible to do that in some simple way ?
<table class="table table-striped">
<thead>
<tr>
<th>
<input type="checkbox" disabled="">
</th>
<th data-sort="status">Status
<i class="fa fa-sort-"></i>
</th>
<th data-sort="name">Name
<i class="fa fa-sort-"></i>
</th>
<th data-sort="position">Position
<i class="fa fa-sort-"></i>
</th>
<th data-sort="userCode">ID
<i class="fa fa-sort-asc"></i>
</th>
<th data-sort="email">e-mail
<i class="fa fa-sort-"></i>
</th>
</tr>
</thead>
<tbody>
<tr data-user="testuser1">
<td>
<input type="checkbox" disabled="">
</td>
<td>
<div class="toggle btn btn-default off btn-sm" data-toggle="toggle" style="width: 76px; height: 30px;">
<input data-user-code="a.anpilov" class="status-toggle" type="checkbox" data-toggle="toggle" data-on="Active" data-off="Inactive" data-size="small">
<div class="toggle-group">
<label class="btn btn-primary btn-sm toggle-on">Active</label>
<label class="btn btn-default btn-sm active toggle-off">Inactive</label><span class="toggle-handle btn btn-default btn-sm"></span></div>
</div>
</td>
<td class="plain">
testuser1
</td>
<td class="plain">
testuser1
</td>
<td class="plain">
testuser1
</td>
<td class="plain">
testuser1
</td>
</tr>
<tr data-user="testuser2">
<td>
<input type="checkbox" disabled="">
</td>
<td>
<div class="toggle btn btn-default off btn-sm" data-toggle="toggle" style="width: 76px; height: 30px;">
<input data-user-code="a.puchaujara" class="status-toggle" type="checkbox" data-toggle="toggle" data-on="Active" data-off="Inactive" data-size="small">
<div class="toggle-group">
<label class="btn btn-primary btn-sm toggle-on">Active</label>
<label class="btn btn-default btn-sm active toggle-off">Inactive</label><span class="toggle-handle btn btn-default btn-sm"></span></div>
</div>
</td>
<td class="plain">
testuser2
</td>
<td class="plain">
testuser2
</td>
<td class="plain">
testuser2
</td>
<td class="plain">
testuser2
</td>
</tr>
</tbody>
</table>
Tried to do it like that:
getDriver().findElement(By.xpath("//div[#id='content'//div[#class='container'//table[#class='table table-striped'//following::tbody//tr[#data-user='testuser1']")).click();
but did not work ... :(
Maybe you can use xpath expression using value attribute. For example, to select certain element with id and value and click on it:
driver.findElement(By.xpath("//*[#id='" + yourId + "' and #value='" + yourValue + "']")).click();
Or a td whith a text inside (be aware that td tag has no value, it has a text inside):
driver.findElement(By.xpath("//td[text()='" + yourTdText + "']")).click();
If you can build an unique xpath to identify what you are looking for this should be your best option even if you don't know the id or the tag type.
Subject to close.
Final solution:
getDriver().findElement(By.xpath("//tr[#data-user='testuser1']")).click();

Categories