Iterate through selected rows in Datatables - javascript

I'm using Datatables and mark ids of my table with
<tr data-id='1'>
tags. I want to get the ids of selected rows. I tried this but it doesn't seem to work:
var $issueID = $(my_table.rows('.selected').nodes()).data('id');
$.each($issueID, function (value, index ) {
alert(value);
});
If I want to do it for a single row it works fine if I use
row().node()
but I can't get it right for many rows.

This should do the trick:
var selectedIds = [];
var my_table = $('#my_table').DataTable();
my_table.rows('.selected').every( function() {
selectedIds.push(this.data().id);
});
As Mike mentioned in a comment, notice that a capital D which is used to initialise the DataTable here. $().DataTable() returns a DataTables API instance, while $().dataTable() will also initialise a DataTable, but returns a jQuery object.

While searching for the same answer I came across this article. I modified the code in your question to find a working solution.
var inactiveRecord = $(my_table.rows('.selected').nodes());
$.each(inactiveRecord, function (idx, value) {
alert($(value).data('id'));
});

You should use a Class to do this in addition to your data-id.
JQUERY
$('.row').each( function() {
var value = $(this).attr('data-id');
alert(value);
})
HTML
<tr class="row" data-id="1">
<td></td>
</tr>
<tr class="row" data-id="2">
<td></td>
</tr>
<tr class="row" data-id="3">
<td></td>
</tr>
or without a Class you could just use
$('tr').each( function() {
var value = $(this).attr('data-id');
alert(value);
})
I recommend adding a class to tr so you don't accidentally get it mixed up with other rows that may not need to be counted.

Related

how to get all next <tr> data-id on click a <tr>(selected tr)

I want the data-id of all next tr of selected tr in an array. I use this code but this is not a good one.
var ids = Array.prototype.slice.call($("tr.selected").nextAll('tr'));
alert(ids)
.map(function (tr) {
return tr.getAttribute('data-id')
});
Use jQuery map() and get() methods
// iterate over elements using map and generate array elelements
var res = $("tr.selected").nextAll('tr').map(function(){
// get data attribute value
return $(this).data('id');
// get the result object as an array using get method
}).get();
If you want to get all siblings attribute value then use siblings() method instead.
var res = $("tr.selected")
// get all sibling tr
.siblings()
// iterate over elements using map and generate array elelements
.map(function(){
// get data attribute value
return $(this).data('id');
// get the result object as an array using get method
}).get();
In fact the code may look like that:
var ids = $('tr.selected').nextUntil('.selected').map(function() {
return $(this).data('id');
}).get();
So as a demo, consider the following example:
$('tr.selected').each(function() {
var ids = $(this).nextUntil('.selected').map(function() {
return $(this).data('id');
}).get();
console.log( ids );
});
.selected {
background: #ccc;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<table border="1">
<tr data-id="1"><td>Row 1</td></tr>
<tr data-id="2" class="selected"><td>Row 2</td></tr>
<tr data-id="3"><td>Row 3</td></tr>
<tr data-id="4"><td>Row 4</td></tr>
<tr data-id="5" class="selected"><td>Row 5</td></tr>
<tr data-id="6"><td>Row 6</td></tr>
<tr data-id="7"><td>Row 7</td></tr>
</table>

Unable to add style class or access elements' attributes from jquery each loop

I have a table, which looks like this:
<table id="ctoTable" class="table table-bordered">
<thead> ... </thead>
<tbody>
<tr></tr>
<tr id="kpi#1" class="js-editable"></tr>
<tr id="kpi#2" class="js-editable"></tr>
<tr id="kpi#3" class="js-editable"></tr>
<tr id="kpi#4" class="js-editable"></tr>
<tr id="kpi#5" class="js-editable"></tr>
<tr id="kpi#6" class="js-editable"></tr>
<tr id="kpi#7" class="js-editable"></tr>
<tr id="kpi#8" class="js-editable"></tr>
<tr id="kpi#9" class="js-editable"></tr>
<tr id="kpi#76" class="js-editable"></tr>
<tr id="kpi#77" class="js-editable"></tr>
<tr></tr>
</tbody>
and I would like to be make some kind of filter which allows me to show and hide some of the rows. I was pretty sure that I could do it on this way but unfortunately it does not work. Not only that I am not able to add/remove classes, I can't event get an attribute of an th.
jQuery(document).ready(function($) {
$( "#hideRows" ).click(function() {
var rows = $('.js-editable');
$.each(rows, function(index, item) {
console.log(item);
//item.addClass("hideElement"); //try to add the class to the tr
console.log(item.attr("id")); //try to print tr id in console
});
});
});
as a result only the first row will be printed out
<tr id="kpi#1" class="js-editable"></tr>
and than the method breaks without any errors logged.
Could someone expain to me what is happening here and how could I fix this issue.
The problem is item inside the loop is a dom element reference not a jQuery object so you can't access jQuery methods directly from item.
Instead you need to get a jQuery object reference for item by passing it to jQuery like $(item) and then you can use jQuery methods like
jQuery(document).ready(function ($) {
$("#hideRows").click(function () {
var rows = $('.js-editable');
rows.each(function (index, item) {
console.log(item);
//$(item).addClass("hideElement"); //try to add the class to the tr
console.log($(item).attr("id")); //try to print tr id in console
});
});
});
But if you just want to add a class there is no need to use a loop
jQuery(document).ready(function ($) {
$("#hideRows").click(function () {
var rows = $('.js-editable');
rows.addClass("hideElement");
});
});
Also note then it is better to use .each() instead of $.each() to iterate over jQuery object.
If you write item.attr, it will return an error, because, by this way item is not a jQuery object.
Change it like this:
$(item).attr("id")
console.log($(item).attr("id")) instead of console.log(item.attr("id"))
jQuery(document).ready(function($) {
$( "#hideRows" ).click(function() {
var rows = $('.js-editable');
$.each(rows, function(index, item) {
console.log(item);
//item.addClass("hideElement"); //try to add the class to the tr
console.log($(item).attr("id")); //try to print tr id in console
});
});
});
DEMO

Retrieve data attribute of a selector class as an array

I am running a PHP + JQuery + DataTables page. Everything went fine and I have a similar mark up from the following:
.......
<tbody>
<tr data='1'>
....
</tr>
<tr data='2'>
....
</tr>
<tr data='1'>
....
</tr>
<tr data='8'>
....
</tr>
<tr data='2'>
....
</tr>
<tr data='7'>
....
</tr>
<tr data='7'>
....
</tr>
.
.
.
</tbody>
I need to get all the data attribute of all the tr in an array, well in the case of the above table, its:
var data_values = [1, 2, 8, 7];
I think that the logic may somewhat starts with $('tr').attr('data') but it returns undefined. I've performed already a query to the database and it also returns an array:
var database_returned_values = [2, 8];
My goal from the start is to remove the tr elements that are not found in the database_returned_values array. My solution is to subtract database_returned_values array from data_values. The difference will be the trs to remove. But I cannot even start to fetch data_values. How can I retrieve the data attributes of all tr and put it in an array or are there any easier way to do this?
In this case, the trs to remove are those which have data attribute of [1, 7];
You can use each() to iterate all the tr:
var data = new Array();
$("table tbody tr").each(function(){
if($.inArray($(this).attr("data")) == -1) // check if not in array
data.push($(this).attr("data"))
})
The data property needs to have something after it.
<tr data-id='7'>
And then jQuery has a nice method you can use called data.
$("tr").data("id")
You can get all the trs, then iterate them. Then, you have to read the data-* attribute (you should'n use only data="anything") and add to an empty array. Then, remove duplicates.
As long as you are using jQuery, you can do this with:
<table>
<tr data-id="1"></tr>
<tr data-id="3"></tr>
<tr data-id="1"></tr>
<tr data-id="4"></tr>
<tr data-id="4"></tr>
<tr data-id="7"></tr>
</table>
var ids = [];
$("table tr").each(function(index, item) {
ids.push($(item).data("id"));
})
alert($.unique(ids));
Fiddle: http://jsfiddle.net/chrisbenseler/s8pytwdz/
Then, iterate this new array ($.unique(ids)) and check whatever you need to check.

How to get html table values from multiple columns with single checkbox and submit to servlet?

I have html data table. I want to get values from multiple columns with single checkbox and when click on submit button values should go to servlet. Please help how to do this?
function refile(){
$('#resend').click(function() {
$("input:checked").each(function () {
var id = $(this).attr("id");
var messagePayload = $('#'+id).val();
var messageType = $('#msgType'+id).val();
alert("Payload Alert:"+ messagePayload);
alert("MessageType Alert:"+ messageType);
$.ajax({
type: "POST",
url: "http://localhost:8080/InterfaceMonitoring/ResendServlet",
data: {
messagePayload:messagePayload,
messageType:messageType
}
});
});
});
}
<c:otherwise>
<c:forEach items="${msgs}" var="msg" varStatus="count">
<tr id="check">
<td>
<input type="checkbox" id ="payloadMsg${count.index}" name="payload" value="${msg.messagePayload}">
</td>
<td></td>
<td>${msg.dob}</td>
<td></td>
<td>${msg.name}</td>
<td></td>
<td>
<div class="accordion">
<h3>Payload</h3>
<div id="payloadMsg${count.index}">${msg.messagePayload}</div>
</div>
</td>
<td></td>
<td>
<div id="msgType${count.index}">${msg.messageType}</div>
</td>
</tr>
</c:forEach>
</c:otherwise>
The problem is the way you try to get messageType.
Since you're using the ID of the input element, and prefixing it with #msgType it results in #msgTypepayloadMsgX so that element will never be found.
And since it's a DIV you're looking for you should use .html() to get the content.
Try adding data-index="${count.index}" to each input[checkbox] and get it in the script using $(selector).data('index') so that you can query for $('#msgType' + index)
And you should not make an ajax request for each row. Instead store the payloadMessage and messageType in an object and send it all to the backend at once, after iterating all rows.
An example could be:
Javascript
function refile(){
$('#resend').click(function() {
var payloads = [];
$('input:checked').each(function () {
var $this = $(this),
index = $this.data('index'),
$type = $('#msgType' + index);
payloads.push({
messageType: $type.html(),
messagePayload: $this.val()
});
});
if (payloads.length === 0) {
return;
}
$.ajax({
type: 'POST',
url: 'http://localhost:8080/InterfaceMonitoring/ResendServlet',
data: {
'payload': payloads
}
});
});
}
HTML
<tr id="check">
<td><input type="checkbox" id="payloadMsg${count.index}" data-index="${count.index}" name="payload" value="${msg.messagePayload}"></td>
<td></td>
<td>${msg.dob}</td>
<td></td>
<td>${msg.name}</td>
<td></td>
<td>
<div class="accordion">
<h3>Payload</h3>
<!-- Note that this ID is conflicting with the input#payloadMsg${count.index} -->
<div id="payloadMsg${count.index}">${msg.messagePayload}</div>
</div>
</td>
<td></td>
<td>
<div id="msgType${count.index}">${msg.messageType}</div>
</td>
</tr>
So, from what I've seen, on the front-end, at least, your code SHOULD work, but you've made it REALLY complex. . . . more complicated than you need it to be, I think. Again, while it should work, simplifying it will mean that there are much fewer places in the code where something could go wrong.
I think the best way to do this is make it easy on yourself:
flag the <div> elements that you want to retrieve with a class value that you can use to get their values (rather than relying on the unique IDs)
make the "unique" identifier of the message at the highest level in the table as you can (in this case, the <tr>
simplify your HTML attributes . . . you've got a lot of duplicate data and excess identifiers in your table structure. Try something like this:
HTML
<c:otherwise>
<c:forEach items="${msgs}" var="msg" varStatus="count">
<tr id="payloadMsg${count.index}">
<td>
<input type="checkbox" name="payload">
</td>
<td></td>
<td class="msg-dob">${msg.dob}</td>
<td></td>
<td class="msg-name">${msg.name}</td>
<td></td>
<td>
<div class="accordion">
<h3>Payload</h3>
<div class="msg-payload">${msg.messagePayload}</div>
</div>
</td>
<td></td>
<td>
<div class="msg-type">${msg.messageType}</div>
</td>
</tr>
</c:forEach>
</c:otherwise>
Once you've set that up, you have a much more simple structure, with all of the values that you could ever need, clearly identified. Now, you can pretty easily you can pretty easily get to the values that you need, using jQuery . . . just update your existing code to be something like this:
$(document).ready(function() {
$('#resend').click(function() {
$("input:checked").each(function () {
var currRow = $(this).closest("tr");
var currPayload = currRow.find(".msg-payload").text();
var currType = currRow.find(".msg-type").text();
alert("Payload Alert:"+ currPayload );
alert("MessageType Alert:"+ currType );
$.ajax({
type: "POST",
url: "http://localhost:8080/InterfaceMonitoring/ResendServlet",
data: {
messagePayload: currPayload,
messageType: currType
}
});
});
});
});
NOTE: You were using .val() instead of .text() to retrieve the text in the "type" <div> . . . .val() is only used with input elements.
Not knowing what you are doing on the back-end with this data, I can't really help you make sure that it is storing it correctly, but removing the reliance on the indexes to find the data that you want, should help simplify your logic a lot.
Also, if you ever want any other data from the row, you can capture it pretty easily now . . . for example:
var currMsg = currRow.attr("id");
var currDOB = currRow.find(".msg-dob").text();
var currName = currRow.find(".msg-name").text();
. . . after you have set the currRow value in your code, of course. :)
So, give that a try and see how things go. On the front-end, you should be good with this, at that point, you would need to just focus on the back-end and make sure that everything is working there.

How to select a row from dynamic table on mouseclick event

How can get a row's value on mouse click or checking the checkbox preferably from the below given html table?
Here is the js for getting values for my table from a xml using spry
var ds1 = new Spry.Data.XMLDataSet("xml/data.xml", "rows/row");
var pv1 = new Spry.Data.PagedView( ds1 ,{ pageSize: 10 , forceFullPages:true, useZeroBasedIndexes:true});
var pvInfo = pv1.getPagingInfo();
Here is the Div with spry region containing the table that gets populated from pv1 (see js part)
<div id="configDiv" name="config" style="width:100%;" spry:region="pv1">
<div spry:state="loading">Loading - Please stand by...</div>
<div spry:state="error">Oh crap, something went wrong!</div>
<div spry:state="ready">
<table id="tableDg" onclick="runEffect('Highlight', 'trEven', {duration: 1000, from: '#000000', to: '#805600', restoreColor: '#805600', toggle:true}, 'Flashes a color as the background of an HTML element.')"
style="border:#2F5882 1px solid;width:100%;" cellspacing="1" cellpadding="1">
<thead>
<tr id="trHead" style="color :#FFFFFF;background-color: #8EA4BB">
<th width="2%"><input id="chkbHead" type='checkbox' /></th>
<th width="10%" align="center" spry:sort="name"><b>Name</b></th>
<th width="22%" align="center" spry:sort="email"><b>Email</b></th>
</tr>
</thead>
<tbody spry:repeat="pv1">
<tr class="trOdd"
spry:if="({ds_RowNumber} % 2) != 0" onclick="ds1.setCurrentRow('{ds_RowID}');"
style="color :#2F5882;background-color: #FFFFFF">
<td><input type="checkbox" id="chkbTest" class = "chkbCsm"></input></td>
<td width="10%" align="center"> {name}</td>
<td width="22%" align="center"> {email}</td>
</tr>
<tr class="trEven" name="trEven" id="trEven"
spry:if="({ds_RowNumber} % 2) == 0" onclick="ds1.setCurrentRow('{ds_RowID}');"
style="color :#2F5882;background-color: #EDF1F5;">
<td><input type="checkbox" class = "chkbCsm"></input></td>
<td id="tdname" width="10%" align="center"> {name}</td>
<td width="22%" align="center"> {email}</td>
</tr>
</tbody>
</table>
</div>
</div>
I am trying the below code but still I am not getting the alert and hence none of the answers are also not working. I know the syntax n all are everything correct, but i am not able to figure out what is the problem here!
//inside $(document).ready(function()
$("#chkbHead").click(function() {
alert("Hi");
});
My page has other tables too for aligning some contents. So when I use the below code it works perfectly on those tables except the one in the question. It might be the problem because there are only 2 tr in the table which gets populated by a spry dataset and hence not getting identified properly. May be, I am not sure, just trying to help improve my understanding
$('tr').click(function() {
alert("by");
});
The values of a Row you will get with:
$('#tableDg tbody tr').live( 'click', function (event) {
$(this).find('td').each( function( index, item ) {
if ( $(this).has(':checkbox') ) {
alert( $(this).find(':checkbox').val() );
} else {
alert( $(this).text() );
}
};
});
What exactly do you mean by value of a table row? You can get the inner html of a table row like this:
var html = '';
$('tr').click(function() {
html = $(this).html();
});
You can get attributes of the table row (e.g. it's Id) like so:
var id = '';
$('tr').click(function() {
id = $(this).attr('id');
});
Alternatively you can get the value of nested elements such as a text input like so:
var text = '';
$('tr').click(function() {
text = $(this).find('#myTextBox').val();
});
EDIT
This is how to change the checked attribute of a checkbox nested in a table row:
$('tr').click(function() {
$(this).find('input:checkbox').attr('checked', 'checked');
// alternatively make it unchecked
$(this).find('input:checkbox').attr('checked', '');
});
EDIT
As the table rows are being loaded dynamically - the $().click() event binding method will not work, because when you are calling it - the table rows do not exist, so the click event cannot be bound to them. Instead of using $().click use the jQuery live method:
$('tr').live('click', function() {
// do stuff
});
This binds the click event to all current table rows and all table rows that may be added in the future. See the jQuery docs here
you have to use Spry Observer,
something like this:
function funcObserver(notificationState, notifier, data) {
var rgn = Spry.Data.getRegion('configDiv');
st = rgn.getState();
if (notificationState == "onPostUpdate" && st == 'ready') {
// HERE YOU CAN USE YOUR JQUERY CODE
$('#tableDg tbody tr').click(function() {
$(this).find('input:checkbox').attr('checked', 'checked');
// alternatively make it unchecked
$(this).find('input:checkbox').attr('checked', '');
});
}
}
Spry.Data.Region.addObserver("configDiv", funcObserver);

Categories

Resources