Use Jquery Instead of Functions to Access Data From Table - javascript

Forever, we have been using javascript functions to pass data from a table to whatever we need to do with that row of data. For example, take this table:
<table class="table table-hover table-striped">
<thead>
<tr>
<th>Name</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr>
<td>Jack</td>
<td>edit</td>
</tr>
<tr>
<td>Dan</td>
<td>edit</td>
</tr>
<tr>
<td>Mark</td>
<td>edit</td>
</tr>
</tbody>
</table>
Normally, we would just have the following function to do something with the data that changes by row (typically passing an id, but sometimes there could be a bunch of args in the function). This function could do a variety for things - not just these examples of course.
function myfunc(f_ID, f_Name) {
alert(f_ID + "_" + f_Name);
$.colorbox({ iframe: true, overlayClose: true, opacity: .70, inline: false, fixed: true, title: "Colorbox Title", href: "/mypage.asp?id=" + f_ID + "&name=" + f_Name });
}
OR
function myfunc(f_ID, f_Name) {
if (confirm("Are you sure that you would like to permanently delete id # " + f_ID + " for " + f_Name + "?")) {
window.location = "/mypage.asp?id=" + f_ID + "&name=" + f_Name
}
}
I know that it's probably not the best to mix Jquery and old school JS like this (maybe it's fine??), so there must be a better way to access this data.
I was thinking that I could use "data-" tags, but the issue is how do you actually get the value when there are multiple rows? I cannot use an ID since it's unique and if I added a class, how do I access the data from the call?
Any help would be greatly appreciated, thank you!
UPDATE
This worked as the answer for my sitaution. Thanks #Quentin!
<a class="testlink" href="#" data-id="1234">edit</a>
$("a.testlink").on("click", myAction);
function myAction(event) {
event.preventDefault();
alert($(this).data("id"));
}

First: Work out what you want to happen if the JS isn't available.
An ordinary link will do.
edit
You don't need the id and the name separately in your code, you only used them in the URL, which appears in the page itself, and you can read the URL from the link directly.
this (in an event handler) refers to the element that was used to trigger the event.
jQuery(function() {
$("a").on("click", openColorBox);
function openColorBox(event) {
event.preventDefault();
var url = this.href;
$.colorbox({
iframe: true,
overlayClose: true,
opacity: .70,
inline: false,
fixed: true,
title: "Colorbox Title",
href: url
});
}
});
If you really needed to pass additional data, then you could read it from data attributes via:
edit
…
function openColorBox(event) {
event.preventDefault();
alert( jQuery(this).data("somedata") );
… but traversing the DOM …
var name = jQuery(this).parents("tr").find("td:first-child").text();
… or using attributes designed for the specific data you are using (if they exist) would be better.

Related

How to redraw a Datatable that uses server side processing using only the existing data in the datatable?

I'm trying to delete a row from a Datatable that uses server side processing (removing the row data and the row/tr visually) based on the value of certain attribute of the row.
I'm using the remove() function to do it and it removes the row data, but visually the table stills the same.
So I added the draw() function but it reinitializes the table, including the data.
So, how can I "redraw" the table after removing a row from the Datatable that uses server side processing? Is there any other function like draw() to redraw the table but using only the existing data in the datatable?
$("#tableSelector").DataTable()
.rows( function ( idx, data, node ) {
return data.attribute_value == value_to_delete;
} )
.remove()
.draw();
Finally, I found the solution.
I followed this thread then read about the DataTable's property "dataSrc".Then with this information searched for something similar in Stack Overflow and found this.
So the trick to do what I asked for was to use a variable to filter the row which I want to ignore in the ajax call.
I've reused the code provided in the referred question. And this is the result:
HTML:
<table id="example" class="display" cellspacing="0" width="100%">
<thead>
<tr>
<th>Name</th>
<th>Email</th>
<th>Subject</th>
<th>Status</th>
<th>Message</th>
<th>Details</th>
</tr>
</thead>
</table>
JS:
$(document).ready(function() {
function loadDataTable(excluded_name = undefined){
$("#example").DataTable().destroy();
$('#example').DataTable({
// "processing" : true,
"ajax" : {
"url" : "https://api.myjson.com/bins/12uwp2",
"dataSrc": (json) => {
if(excluded_name !== undefined){
return json.filter((item) => item.name !== excluded_name)
}else{
return json
}
}
},
"columns" : [ {
"data" : "name"
}, {
"data" : "email"
}, {
"data" : "subject"
}, {
"data" : "status"
},{
"data" : "message"
},
{
"mData": "Details",
"mRender": function (data, type, row) {
return "<a class='delete' data-name='"+ row.name + "' data-id=" + row.id + " href='/Details/" + row.id + "'>Delete</a>";
}
}]
});
}
$(document).on("click", ".delete", function(e) {
e.preventDefault()
let excluded_name = $(this).data("name")
alert("Excluding this name in the next load: " + excluded_name);
loadDataTable(excluded_name);
})
loadDataTable();
});
Fiddle: https://jsfiddle.net/ek94mh1x/4/
Note: This is a client side "delete", I know this could be done with server side processing, but in my case I was only allowed to do it in the client side.
Additionally, in case you need to delete multiple rows you could use an array as a parameter and follow the same logic.
I hope this could help someone.

reload datatable after ajax success

I use JQuery DataTable. I send data to datatable onclick in json file at ajax succes .the first click everything is good,But the next click I get only the right data ANd wrong value of dataTables_info it display always the first value of dataTables_info And paginatio AND row too from the first result.
This is the first display of data in datatable:
ALL the next Click I get only right data:
For this exemple they are one result showing in picture below but everything else(info ,show,pagination) belong to first search showing in the first picture :
In the second Exemple When I click at any page of pagination I get the content of the first page result!!
This is my function ONclick:
$ ( '#ButtonPostJson' ).on('click',function() {
$("tbody").empty();
var forsearch = $("#searchItem").val();
$.ajax({
processing: true,
serverSide: true,
type: 'post',
url: 'searchData.json',
dataType: "json",
data: mysearch,
/* bRetrieve : true,*/
success: function(data) {
$.each(data, function(i, data) {
var body = "<tr>";
body += "<td>" + data.name + "</td>";
..........................
..........................
body += "</tr>";
$('.datatable-ajax-source table').append(body);
})
;
/*DataTables instantiation.*/
$('.datatable-ajax-source table').dataTable();
},
error: function() {
alert('Processus Echoué!');
},
afterSend: function(){
$('.datatable-ajax-source table').dataTable().reload();
/* $('.datatable-ajax-source table').dataTable({bRetrieve : true}).fnDestroy();
$(this).parents().remove();
$('.datatable-ajax-source table').dataTable().clear();*/
}
});
});
I try everything and i dont know what I miss.
I use this jquery for datatable:
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.2/jquery-ui.min.js"></script>
Thanks.
Use like it
$('#product_table').DataTable().ajax.reload();
Get table id first, like:
var table=('#tableid').Datatable();
table.draw();
just put these lines after ajax success function to reload datatable
On a button clik you dont need to empty your table body and make initiate the datatable again with the ajax.
you just have to call your ajax again as you have already initiate on document ready function
just use
$("#Table_id").ajax.reload();
check the below link, you will have better idea.
https://datatables.net/reference/api/ajax.reload()
Let me know if this doesn't help you
I had this same problem. I found a function I wrote on a project that deals with this. Here is a simple 2 column table I made.
<table id="memberships" class="table table-striped table-bordered table-hover" width="100%">
<thead>
<tr>
<th>Member Name</th>
<th>Location</th>
</tr>
</thead>
<tfoot>
<tr>
<th>Member Name</th>
<th>Location</th>
</tr>
</tfoot>
</table>
This is my script to populate it:
function drawTable(){
var table = $('#memberships').DataTable();
table.destroy();
value = $("#memberName").val();
console.log("member name-->>" + value);
$('#memberships').DataTable({
responsive:true,
pageLength: 50,
ajax:{
"url": `//BACKEND API CALL`,
"type":"get",
"dataSrc": 'members'//my data is in an array called members
},
columns: [
{"data": "name_display" },
{"targets": 0,
"data": "membershipID",
"render": function ( data, type, full, meta ) {
return '<button type="button" class="btn btn-info btn-block"
onclick="editMember(' + data + ')">Edit Member</button><button
type="button" class="btn btn-danger btn-block"
onclick="deleteMember(' + data + ')">Delete</button>';
}
}
]
});
$.fn.dataTable.ext.errMode = 'none';
}
You can ignore my column render function. I needed 2 buttons based on the data returned. The key was the table.destroy in the function. I created the table in a variable called table. I destroy it right in this initialization because it allowed me to use this same function over and over. The first time it destroys an empty table. Each call after that destroys the data and repopulates it from the ajax call.
Hope this helps.
Update: After playing with datatables alot more I found that setting table to a variable in a global scope to your function allows you to use reload.
var table = $('#memberships').DataTable({});
Then
table.ajax.reload();
should work.
I created this simple function:
function refreshTable() {
$('.dataTable').each(function() {
dt = $(this).dataTable();
dt.fnDraw();
})
}
use below code..it perfectly work, it keep your pagination without lose current page
$("#table-example").DataTable().ajax.reload(null, false );
$('.table').DataTable().ajax.reload();
This works for me..
$("#Table_id").ajax.reload(); did not work.
I implemented -
var mytbl = $("#Table_id").datatable();
mytbl.ajax.reload;
.reload() is not working properly untill we pass some parameter
var = $("#example").DataTable() ;
datatbale_name.ajax.reload(null, false );
Try This i hope it will work
$("#datatable_id").DataTable().ajax.reload();

Put a button in front of all rows in jQuery DataTables

I am using jQuery DataTables. It is being populated with JSON data from a database. I can't figure out how to display a button or link in front of each record. I want to make it so that when the user clicks on that button then that particular record gets added in the database, so the button or link should contain an ID. Please help sort out my problem.
Below is the code I'm using:
var oTable = $('#jsontable').dataTable();
$.ajax({
url: 'process.php?method=fetchdata',
dataType: 'json',
success: function(s) {
console.log(s);
oTable.fnClearTable();
for (var i = 0; i < s.length; i++) {
oTable.fnAddData([
s[i][3],
s[i][4],
s[i][0], // this contains id
]);
}
},
error: function(e) {
console.log(e.responseText);
}
});
<table id="jsontable" class="display table table-bordered" cellspacing="0" width="100%">
<thead>
<tr>
<th>Class Number</th>
<th>Subject</th>
<th>ADD</th>
</tr>
</thead>
</table>
I hope this is help
oTable = $('#jsontable').dataTable({
"fnRowCallback": function (nRow, aaData, iDisplayIndex) {
//nRow Row Object
//aaData Param
//iDisplayIndex Row Index
$('td:eq(0)', nRow).html("<input type='button'>Button</input>");
return nRow;
}
});
Do you mean to do something like this? (Also, this may be for an older version of datatables, now that I think about it. This is syntax for version 1.9, and I would guess you're using a more recent version (1.10+) The syntax may be a little different, but it should be documented in the api docs.
$('#jsontable').dataTable({
"sAjaxSource" : "process.php?method=fetchdata",
"aoColumns" : [
{ "mData": function(source) {
return '<input type="button" value=' + source[0] + '/>';
}},
{ "mData": function(source) {
return source[1];
}},
{ "mData": function(source) {
return source[2];
}}
}
});
Obviously, your button can look however you want, you probably don't want the id stored on the value. You can do what you need with it.

Jquery Loop through table with multiple class

I am trying to loop through the table after the AJAX call is finished using the Jquery. But I am not able to loop through that.
My HTML Looks like this :
<table id="planyourwork" class="data-view plan-internal displayTable">
<thead>All Headers</thead>
<tbody>
<tr class="odd">
<td class="invisible"></td>
....
....
<td class="cell-status"></td>
</tr>
<tr class="odd">
<td class="invisible"></td>
....
....
<td class="cell-status"></td>
</tr>
<tr class="odd">
<td class="invisible"></td>
....
....
<td class="cell-status"></td>
</tr>
<tbody>
In JS file after calling the AJAX
$('.data-view > tbody > tr > td.cell-status').each(function() {
trying to add tool tip
}
When I debug, I see that Loop is not getting through. Debugger is stopping at data-view, but not looping through.
Please help me to resolve this problem
Below is the whole On Click event
filterBtn.click(function() {
loadData();
$('#planyourworktd.cell-status').each(function() {
var typeCell = $(this);
var tooltip = typeCell.parent().find('td.fullNotes').html();
alert("tooltip");
typeCell.attr('title', tooltip);
typeCell.tooltip({track: true,show: 100});
});
return false;
});
// Load the request and planner data
function loadData() {
$.ajax({
type: 'post',
url: url,
data: data,
cache: false,
success: function(html) {
initResults();
enableButtons();
},
error: function(jqXHR, textStatus, errorThrown) {
filterBtn.removeClass('invisible');
},
async: true
});
}
And DOM structure is quite complicated, when I run this in Fiddle it works but not on Page. I am not sure why? Thank you every one for helping me to resolve this.
Please Note : Syntax check may be typo error as I am removing production code, sorry for that.
There are a few mistakes in your html a javascript but I can't be sure whether it was when you typed it up here.
Anyways
'' is not closed, you have another '' instead of ''
You javascript is not closed properly, here is how it should look
$('.data-view > tbody > tr > td.cell-status ').each(function() {
console.log(this);
});
Notice the extra ');' at the end.
Now when I make these changes the output is fine.
I solved the problem. Its quite "sad", I missed few bits here. I am using struts 2 and AJAX call. and when an AJAX call is done, my event is called but by the time it is called data is not loaded. Reason is when an AJAX call is made, data is populated as "tile" which runs on its own. Rest of the elements are populated and data is loaded in parallel. Changing the location of the page solved the problem. Thank you for all your help.

Redirect action with parameters in JQuery

In my ASP.Net project I'm trying to redirect a page to other action after select a row table and click on a button. So I have this code:
JQuery:
function editItem(tableId, url) {
if ($("#" + tableId + " .selected").exists()) {
var thisRowId = $("#" + tableId + " .selected").attr("id");
window.location.replace(url, { operation: "edit", carId: thisRowId });
}
};
//more code
View (ManagementCar):
#model myProject.Model.Car.Car[]
<table class="table" id="tableCars">
<thead>
#*some code to header*#
</thead>
<tbody>
foreach (var item in Model)
{
<tr id="#(item.Id)" onclick="selectRow('tableCars', '#(item.Id)')">
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.OwnerName)
</td>
<td>
#(item.IsSold == true ? "Yes" : "No")
</td>
</tr>
}
</tbody>
</table>
<br />
<button id="btEdit" type="button" class="disable" onclick="editItem('tableCars','CarOperation')">Edit</button>
Controller:
[HttpGet]
public ActionResult CarOperation(string operation, int carId)
{
//some code...
return RedirectToAction("ManagementCar", "Backoffice");
}
But I have a Server Error after redirect saying carId parameter is null. I debug my jquery and that parameter isn't null. I tried also doing
$.get(url, { operation: "edit", carId: thisRowId });
instead
window.location.replace(url, { operation: "edit", carId: thisRowId });
but it don't redirect.
How can I solve this?
set it by giving it a new value like this.
window.location = window.location.replace(url, "shouldBeAstringNotAJsonObject");
The problem with using window.location is that the referrer is not passed on the request as this behaviour simply mimics a new request as if you had typed the URL into the address bar. If you intend to use website analytics, a reliable referrer will be quite important. I use jQuery to generate a dynamic link upon which I call click().
var url = '/my/url';
$('')[0].click();
Notice I click() the underlying element not the jQuery selected object, the reason being that a jQuery click only raises the event and the href is not navigated to whereas indexing to the element and clicking that will cause the same behaviour you would expect as if you had actually clicked a link on the page.
I have put together a jQuery.navigate plugin that neatly wraps this up and abstracts your site map away from your UI logic, which you might find useful. For example, using my plugin would mean you could remove your editItem function altogether and simply change your markup to something like this?
<tr id="#(item.Id)" onclick="$.navigate('to', 'edit', { id : '#(item.Id)' })">
Ok, I finally solved the problem with a new url routing config and the following code:
My RouteConfig:
routes.MapRoute(
name: "ManipulatingCar",
url: "{controller}/{action}/{operation}/{carId}"
);
My JQuery:
editItem = function (tableId, url) {
if ($("#" + tableId + " .selected").exists()) {
var thisRowId = $("#" + tableId + " .selected").attr("id");
var fullUrl = url + "/edit/" + thisRowId;
window.location = fullUrl;
}
};
Basically, controller action parameters must match with the configurations specified in RouteConfig.cs

Categories

Resources