Retrieve all records by checkbox in jQuery DataTable - javascript

Is it possible to retrieve all records by checking a checkbox located on the top of DataTable? I mean that I want to add a checkbox and if the user check it, it pass a parameter (for example bool isAll) to the Controller via AJAX and the records are obtained according to isAll parameter by changing the search query. I look at many different sections on Offical Documentation but there is no seem to have this feature. It is something like shown below. Any idea?

If your HTML looks like this:
<table>
<thead>
<tr>
<th><input type="checkbox" onClick="checkAll(this)"></th>
<th >x</th>
<th >y</th>
<th >z</th>
</tr>
</thead>
<tbody>
</tbody>
I would do something like this to check all 'checkboxes' named myCheckBox:
function checkAll(x) {
checkboxes = document.getElementsByName('myCheckBox');
for(var i=0, n=checkboxes.length; i<n; i++) {
checkboxes[i].checked = x.checked;
}
}
Then if you want to send that to your AJAX as a string:
function getCheckedBoxes(chkboxName) {
var checkboxes = document.getElementsByName(chkboxName);
var checkboxesChecked = [];
for (var i=0; i<checkboxes.length; i++) {
if (checkboxes[i].checked) {
checkboxesChecked.push({"ID":checkboxes[i].value});
}
}
return checkboxesChecked.length > 0 ? checkboxesChecked : null;
}
var checkedBoxes = getCheckedBoxes("cluster_checkbox");
var data = JSON.stringify(checkedBoxes);
Then in your AJAX call the var data with the string:
$.ajax({type : "POST",
url : "/new_custCluster.php",
data: {'IDs': data},
}).done(function(result) {
alert("Success");
}).fail(function() {
alert("Failure");
});

Related

Select all rows programmatically and keep selection

How do I select all rows in my Bootgrid table programmatically with JavaScript?
I've added a button in the action bar and i have a function which is looping through all the rows in the JQuery Bootgrid table.
so far, I'm getting all the rows id (data-row-id) in the table, even on other pages in the bootgrid table.
How do i select all the rows from here and keep the selection programmatically?
Thanks
Code Below:
// JS
<script>
$(document).ready(function () {
var count = 0;
var dt = $("#table1").bootgrid({
selection: true,
multiSelect: true,
keepSelection: true,
rowSelect: true
}).on("selected.rs.jquery.bootgrid", function (e, rows) {
var rowIds = [];
for (var i = 0; i < rows.length; i++) {
count++;
}
$('#NumSelected').html(count);
console.log(count);
}).on("deselected.rs.jquery.bootgrid", function (e, rows) {
var rowIds = [];
for (var i = 0; i < rows.length; i++) {
count--;
}
$('#NumSelected').html(count);
console.log(count);
});
var rows = dt.data('.rs.jquery.bootgrid').rows;
// Get all Ids in the table and log
for(var i = 0; i < rows.length; i++)
{
console.log(rows[i].ID);
}
// append button in action bar
$(".bootgrid-header .actionBar").find('.actions.btn-group').append('<button id="selectAll" class="btn btn-default" type="button" title="Select All Clients Listed"><span class="icon glyphicon glyphicon-saved"></span></button>');
// Select all rows in table
// This is not working, I have data paginated in 8 pages (80 rows)
// and the code below only select the data in the first page
// I want to select all rows in the table and keep the selection by using jquery bootgrid
$("#selectAll").click(function () {
$('#table1 tbody > tr').each(function() {
$(this).addClass('active').attr('aria-selected', true);
$(this).find(":checkbox").prop('checked', true);
});
// get all selected rows id in array
var selectedRowsId = $("#table1").bootgrid('getSelectedRows');
console.log(selectedRowsId);
});
});
</script>
// html
<table id="table1">
<thead>
<tr>
<th data-column-id="ID" data-identifier="true" data-type="numeric">ID</th>
<th data-column-id="Name" data-type="string">Name</th>
<th data-column-id="OtherDetails" data-type="string">Other Details</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td>#item.ID</td>
<td>#item.Name</td>
<td>#item.OtherDetails</td>
</tr>
}
</tbody>
</table>
First, it's important to set the values for the grid init (as you have already done correctly)
var dt = $("#table1").bootgrid({
selection: true,
multiSelect: true,
keepSelection: true,
rowSelect: true
...
Second, as of bootgrid Version 1.1.0 you can call the "select" method for selecting all items:
$("#yourGridName").bootgrid("select");
In your case:
$("#table1").bootgrid("select");
(in server-side scenario only the loaded items are selectable.)
So for this, you could generate a JS-function and a HTML-Button:
<button onclick="selectAllItems();">Select all loaded Items</button>
function selectAllItems()
{
$("#table1").bootgrid("select");
}
I've tested it with several pages. All loaded items will be selected and the selection is kept after going forward and backward to several pages.
I'm using the current version of bootgrid: V 1.3.1
In my case, after turning over to a new page I'm loading the new page via AJAX. So only the loaded items could get checked. But the checked checkboxes are kept after loading a new page.
If you want to check certain items, you could select the items with an array of ids:
$("#table1").bootgrid("select", [rowIdsArray]);
For example:
$("#table1").bootgrid("select", [1,3,5,8,9]);
In the bootgrid documentation, it's not very clear, what is meant with "row ids".
I think, it's the "data-row-id" attribute, because the input-tags don't have an id. There is only a class.

Angular is adding an empty array to a 2D array - where/why?

I'm having a bit of a weird problem and there are now 2 people in my office completely stumped by this (so I hope it's not something embarrassingly obvious!).
As an overview, we have a SQLite database that could contain any number of tables, each with any number of rows or columns. We want to display this data in a page in an Electron app.
We have an Angular page in our Electron app (with Express/Node as a backend) which makes some calls to an Express endpoint (which gets data from the SQLite db) and we end up with two 2D arrays of data - one for the table headers ($scope.tableHeaders) and one for the table content ($scope.documentsList).
The code for the calls is below:
$http.get('http://localhost:3000/tableCount').then(function (res) {
if (res.data.numberoftables) {
$scope.count = res.data.numberoftables;
var i;
$scope.documentsList = new Array();
$scope.tableHeaders = new Array();
for (i = 1; i <= $scope.count; i++) {
var tableNo = i;
//loop through tables
***$http.get('http://localhost:3000/doclist/' + tableNo).then(function (resDocs) {
//get table content
if (resDocs.data) {
***$scope.documentsList.push(resDocs.data);
}
});
$http.get('http://localhost:3000/tableColumns/' + tableNo).then(function (resHeads) {
//get table headers
if (resHeads.data) {
$scope.tableHeaders.push(resHeads.data);
}
});
}
}
});
Just for fun, here's our HTML:
<div id="documentTables">
<div ng-repeat="tableID in getNumberArray(count)">
<table st-table="documentsList[tableID]" class="table table-condensed table-hover">
<thead>
<tr st-safe-src="tableHeaders[tableID]">
<th ng-repeat="col in tableHeaders[tableID]">
{{col}}
</th>
</tr>
<tr st-safe-src="tableHeaders[tableID]" colspan="{{tableHeaders[tableID].length}}">
<th colspan="1" ng-repeat="col in tableHeaders[tableID]">
<input id="{{col + 'searchbox' + tableID}}" st-search="col" placeholder="{{col}}" class="input-sm form-control" type="search" />
</th>
</tr>
</thead>
<tbody>
<tr st-safe-src="documentsList[tableID]" ng-repeat="document in documentsList[tableID]">
<td ng-repeat="col in tableHeaders[tableID]">
{{document[col].value}}
</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="{{tableHeaders[tableID].length}}" class="text-center">
<div st-pagination="" st-items-by-page="10" st-displayed-pages="7"></div>
</td>
</tr>
</tfoot>
</table>
</div>
</div>
The problem we're coming across is that no actual data is displayed in the tables. Somewhere between the starred lines (***) in the JS above, an empty array for each table is added. So if we have two tables in our database, we end up with documentsList = Array[4] with documentsList[0] and documentsList[1] being empty arrays. Why/where would this be happening, and how can I fix it?
Note - if you'd like to test this out without our endpoints, try out these variables:
$scope.count = 2;
$scope.tableHeaders = [["TabNo", "Document", "PageNumber", "Date"],["TabNo", "Document", "PageNumber"]];
$scope.documentsList = [];
$scope.documentsList.push(JSON.parse('[{"idANX":1,"pathANX":"Product Overview.pdf","isHeaderANX":1,"isExcludedANX":0,"isNotHyperlinkedANX":0,"isSubHeaderANX":0,"HyperlinkedColumnANX":1,"TabNo":{"colspan":0,"rowspan":0,"hyperlinkedDoc":"","isLastCell":false,"value":"1"},"Document":{"colspan":0,"rowspan":0,"hyperlinkedDoc":"Product Overview.pdf","isLastCell":false,"value":"Product Overview"},"PageNumber":{"colspan":0,"rowspan":0,"hyperlinkedDoc":"","isLastCell":false,"value":"1 - 2"},"Date":{"colspan":0,"rowspan":0,"hyperlinkedDoc":"","isLastCell":true,"value":"18 August 2015"}},{"idANX":2,"pathANX":"Spec.pdf","isHeaderANX":0,"isExcludedANX":0,"isNotHyperlinkedANX":0,"isSubHeaderANX":0,"HyperlinkedColumnANX":1,"TabNo":{"colspan":0,"rowspan":0,"hyperlinkedDoc":"","isLastCell":false,"value":"2"},"Document":{"colspan":0,"rowspan":0,"hyperlinkedDoc":"Spec.pdf","isLastCell":false,"value":"Spec"},"PageNumber":{"colspan":0,"rowspan":0,"hyperlinkedDoc":"","isLastCell":false,"value":"3 - 4"},"Date":{"colspan":0,"rowspan":0,"hyperlinkedDoc":"","isLastCell":true,"value":"1 April 2015"}}]');
$scope.documentsList.push(JSON.parse('[{"idANX":1,"pathANX":"Product Overview.pdf","isHeaderANX":0,"isExcludedANX":0,"isNotHyperlinkedANX":0,"isSubHeaderANX":0,"HyperlinkedColumnANX":1,"TabNo":{"colspan":0,"rowspan":0,"hyperlinkedDoc":"","isLastCell":false,"value":"1"},"Document":{"colspan":0,"rowspan":0,"hyperlinkedDoc":"Product Overview.pdf","isLastCell":false,"value":"Product Overview"},"PageNumber":{"colspan":0,"rowspan":0,"hyperlinkedDoc":"","isLastCell":false,"value":"1 - 2"}},{"idANX":2,"pathANX":"Spec.pdf","isHeaderANX":0,"isExcludedANX":0,"isNotHyperlinkedANX":0,"isSubHeaderANX":0,"HyperlinkedColumnANX":1,"TabNo":{"colspan":0,"rowspan":0,"hyperlinkedDoc":"","isLastCell":false,"value":"2"},"Document":{"colspan":0,"rowspan":0,"hyperlinkedDoc":"Spec.pdf","isLastCell":false,"value":"Spec"},"PageNumber":{"colspan":0,"rowspan":0,"hyperlinkedDoc":"","isLastCell":false,"value":"3 - 4"}}]');
$scope.getNumberArray = function (num) {
var n = new Array(num);
var i;
for (i = 0; i < num; i++) {
n[i] = i;
}
return n;
}
$scope.rowClass = function (row) {
if (row.isSubHeaderANX == 1) {
return 'subheader';
} else if (row.isHeaderANX == 1) {
return 'header';
}
else { return 'doctablerow'; }
}
Also pagination and filtering don't work but that's an issue for when our table actually contains data.
Edit: Probably should have mentioned that this is using angular-smart-table
You should take a look at how asynchronous requests and promises works. To make your code run you could do this: var promises = []; // Creates an array to store the promises
$http.get('http://localhost:3000/tableCount').then(function (res) {
if (res.data.numberoftables) {
$scope.count = res.data.numberoftables;
var i;
$scope.documentsList = new Array();
$scope.tableHeaders = new Array();
var promises = [];
for (i = 1; i <= $scope.count; i++) {
var tableNo = i;
$scope.getHttp(i).then(function(resp){
$scope.documentsList.push(resolutions[0]);
$scope.tableHeaders.push(resolutions[1]);
});
}
}
});
$scope.getHttp = function(tableNo){
var promise;
promise = $http({
url:'http://localhost:3000/doclist/' + tableNo,
method:'get'
});
promises.push(promise);
promise = $http({
url:'http://localhost:3000/tableColumns/' + tableNo,
method:'get'
});
promises.push(promise);
return $q.all(promises);
}
Make the changes accordingly. I did not test it because dont have complete controller.But for sure, if you are looping http, make sure promises are stored.

How to get values of dynamically generated text box and make ajax request to controller in mvc4 and jquery?

I have one table where I am dynamically generating textbox's and binding model values to those textboxe's. Also i have one button. I want to send dynamically generated textbox values in Ajax request. My code is as below.
#foreach (var group in Model.Groups)
{
<table width="100%" border="0" cellspacing="0" cellpadding="0" class="dataTable tableHover">
<tr>
#foreach (var item in group.Items)
{
<th>#item.Label</th>
}
</tr>
<tr>
#foreach (var item in group.Items)
{
<td><input type="text" id="Value" value="#item.Value"></td>
}
</tr>
</table>
}
#foreach (var group in Model.Groups)
{
<tr>
#{ int k = 1; }
#foreach (var item in group.Items)
{
if (k == 1)
{
<td scope="col"> <button type="button" class="btn btn-primary" id="SaveUpdate" onclick="updatemetaData('#item.upld_id,#item.Value');">Save</button></td>
k = 0;
}
}
</tr>
}
this is my jquery function to make ajax request.
function updatemetaData(docid) {
$.ajax(
{
type: "GET",
data: { upld_id: docid },
dataType: "html",
url: '/documentVerification/updatedocDetails',
headers: {
'VerificationToken': forgeryId
},
success: function (data)
{
$('#GridDetails').html("");
$('#GridDetails').html(data);
$("#dialog-formdocumentdata").dialog('open');
}
, error: function (error)
{
}
});
}
</script>
I want to send values of dynamically generated textboxes in ajax call. In the below code 2 text boxe's will generate in all cases.
#foreach (var item in group.Items)
{
<td><input type="text" id="Value" value="#item.Value"></td>
}
Is it possible in jquery to achieve this? Thank you in advance.
I can't spot a computer around. Be careful following code may contain errors.
Use nuget to import Newtonsoft Json assembly.
In the controller add:
using Newtonsoft.Json;
ViewBag.JsonData = JsonConvert.SerializeObject(yourObjectContainingRandomNumbers);
In the view:
#Html.Hidden("inputID", Viewbag.JsonData)
Move jquery reference to the hidden field and things should work.

Execute script after razor syntax is executed

I have some razor syntax which is dynamically generating an html table and populating with data while generating it. I needed to make a jQuery ajax call to my MVC ASP.Net controller to get some data to go in another field in this exact table. Now what I was trying to do is to iterate through the child nodes of this table and append this field cell by cell in these rows after it loads.
However this is not being successful, the table is showing as if it doesn't have any child nodes i.e. the razor syntax is not done executing by that time.
What can I do so that this script for adding the extra field is executed after the html table has been filled up with data? This is the code I have. This is the razor and html syntax.
#if (Model.ToList().Count > 0) {
<table id ="groupTable">
<thead>
<tr>
<th>Group Name</th>
<th>Description</th>
</tr>
</thead>
<tbody id="innerTable">
#foreach (var group in Model) {
// display a link with each GroupName as a list which directs to that group with that id
<tr>
<td> #Html.ActionLink(group.Group.GroupName,"DisplayGroup","Groups", new {id = group.GroupId},null) </td>
<td>
#if(group.Group.Description.Length > 40){
#group.Group.Description.Substring(0, 40)
<span>...</span>
}
else
{
#group.Group.Description.Substring(0, group.Group.Description.Length - 1)
}
</td>
</tr>
}
</tbody>
</table>
}
And this is the script executed on document.ready
$(document).ready( function() {
#foreach (var group in Model)
{
<text>
jQuery.ajax({
type: 'POST',
url: '/Groups/GetInvitedFriends',
data: { groupId: '#group.Group.GroupId' },
success: function (friendMembers) {
$.each(friendMembers, function (index, friendName) {
// append friend Members at row with index index at that cell
var tbody = $('#innerTable')[0];
var trow = tbody.childNodes[index];
if (trow.index() === 0) {
trow.append('<td> Members </td>');
} else {
trow.append('<td>' + friendName + '</td>');
}
});
},
traditional: true
});
</text>
}
})
As the javascript will only be executed on the client browser, you can store the group's id in an javascript array and then in document load, loop on this array to add each of your extra cells.
This is the javascript code :
<script type="text/javascript">
//List of groups id
var groupIds = [];
$(function() {
//Initializing the array with values
#foreach (var group in Model) {
<text>groupIds .push(#group.Group.GroupId);</text>
}
InsertExtraCells(groupIds.pop()); //Insert for the first groupid in the array
});
function InsertExtraCells(groupId) {
jQuery.ajax({
type: 'POST',
url: '/Groups/GetInvitedFriends',
data: { groupId: '#group.Group.GroupId' },
success: function (friendMembers) {
//Do your work
$.each(friendMembers, function (index, friendName) {
// append friend Members at row with index index at that cell
var tbody = $('#innerTable')[0];
var trow = tbody.childNodes[index];
if (trow.index() === 0) {
trow.append('<td> Members </td>');
} else {
trow.append('<td>' + friendName + '</td>');
}
});
//If ids remaining in the array, loop to the next group id
if (groupIds.length > 0) {
InsertExtraCells(groupIds.pop());
}
else {
//Do whatever when finish
}
},
traditional: true
});
}
</script>

Traversing Table with jQuery

I have a table with an HTML attribute on the TR element titled "data-order" which simply holds an integer indicating the order in which to sort the table (descending). Right now the code only checks the row ahead of the TR clicked - what I'm attempting to do is to get it to scan all rows ahead of its position in the table and once it finds a number greater than (not greater than or equal to) then call the swaprow function...
Here is the javascript used to move the row up.
function adjustRank(id, e) {
var url = "/ajax/moveup/" + aid;
var row = $(e).closest("tr").get(0);
var prevRow = $(row).prev().get(0);
var moveUp = false;
var prevRowOrder = parseInt($(prevRow).attr("data-order"));
var rowOrder = parseInt($(row).attr("data-order"));
$.ajax({
type: "POST",
url: url,
data: {aid: aid},
dataType: "json",
success: function ()
{
if(rowOrder + 1 > prevRowOrder) // think this is where I need to traverse the table
swapRows(row, prevRow);
},
failure: function () { alert("Error processing request."); }
});
}
and here are a couple of items in the table for example:
<table id="listings" style="min-height:150px; width:100%;">
<tr id="1" data-order="11"><td>1</td><td align="left"><span onclick="adjustRank('ace93485-cea5-4243-8294-9f3d009aba3d', this)" style="cursor:pointer;">Lindsey Vonn</span></td><td></td></tr>
<tr id="2" data-order="6"><td>2</td><td align="left"><span onclick="adjustRank('9f83aed6-b99a-4674-a8b7-9f3d009aba38', this)" style="cursor:pointer;">Al Horford</span></td><td></td></tr>
<tr id="3" data-order="5"><td>3</td><td align="left"><span onclick="adjustRank('d48a52bd-17e9-4631-9a2e-9f3d009aba39', this)" style="cursor:pointer;">Derek Jeter</span></td><td></td></tr>
</table>
You may use recursion to solve that problem. Please, see the code.
window.adjustRank = function(id, el) {
var orderDiff = 1;
var row = $(el).closest("tr");
var order = parseInt(row.attr("data-order")) + orderDiff;
row.attr("data-order", order);
var prevRow = row.prev();
if(prevRow.get(0)){
moveUp(order, row, prevRow);
}
}
window.moveUp = function(order, row, prevRow){
if(order > parseInt(prevRow.attr("data-order"))){
var prevPrevRow = prevRow.prev();
if(prevPrevRow.get(0)){
moveUp(order, row, prevPrevRow);
} else {
prevRow.before(row);
}
} else {
prevRow.after(row);
}
}
If you get orderDiff via AJAX, then place the code into your AJAX call success function. Please, see this demo

Categories