I am currently trying to change asp.net GridView Control to jQuery DataTable with Ajax. In my project, the home page has a justified image grid as shown below:
Each picture works as a link, when the user clicks on a specific image it will redirect the user to another page based on a product Id.
The jQuery DataTable code works for a regular table that has rows & columns. But I want to create my own table inside that jQuery DataTable in order to get the same image grid + links mentioned above.
My code is like this:
1- In Code behind (Default.aspx.cs) I use a simple web method to retrieve data from Database.
[WebMethod]
public static SalesOrderDetail[] BindDatatable()
{
DataTable dt = new DataTable();
List<PDetail > details = new List<PDetail>();
using (SqlConnection con = new SqlConnection(#"server=Server\SQLEXPRESS;integrated security=true;database=MyDb"))
{
using (SqlCommand cmd = new SqlCommand("SELECT Id, PName,ImgUrl FROM Products ORDER BY Id", con))
{
con.Open();
SqlDataAdapter da = new SqlDataAdapter(cmd);
da.Fill(dt);
foreach (DataRow dtrow in dt.Rows)
{
PDetail p = new PDetail();
p.Id = Convert.ToInt16(dtrow["Id"].ToString());
p.PName= dtrow["PName"].ToString();
p.ImgUrl = Convert.ToInt16(dtrow["ImgUrl"].ToString());
details.Add(p);
}
}
}
return details.ToArray();
}
2- In (Default.aspx) page , there is one table:
<table class="table table-striped table-bordered table-hover" id="TableId"
cellspacing="0" align="center" width="100%">
</table>
3- The jQuery DataTable code looks like this:
$(document).ready(function ()
{
$('#TableId').DataTable(
{
"language":
{
"processing": "<div class='overlay custom-loader-background'><i class='fa fa-cog fa-spin custom-loader-color'></i></div>"
},
"processing": true,
"serverSide": true,
"ajax":{
url: "Default.aspx/GetData",
contentType: "application/json",
type: "GET",
dataType: "JSON",
data: function (d) {
return d;
},
dataSrc: function (json) {
json.draw = json.d.draw;
json.recordsTotal = json.d.recordsTotal;
json.recordsFiltered = json.d.recordsFiltered;
json.data = json.d.data;
var return_data = json;
return return_data.data;
}
}, success: function (data) {
for (var i = 0; i < data.d.length; i++) {
$("#TableId").append("<tr><td><img src="+data.d[i].ImgUrl+"></td></tr>");
}
}
});
});
By the way, the above code is server side processing (paging).
Can anyone tell me or guide me some instructions?
Thanks
I don't recommend you to use the jQuery DataTable for your requirement. Usually this is used instead of HTML tables due to their user-friendliness in handling data. However this implementation should work fine for you. I will give you a couple of links that might suit you for an image grid too at the bottom.
$('#TableId').DataTable({
"processing": true, // show progress bar while loading
"serverSide": true, // process is done on server side
"pageLength": 12, // page size
"ajax": {
"url": "", // your url here
"type": "POST", // since you need to pass data for the request
"datatype": "json",
"data": function (d) {
d.parameter1 = "some value";
d.parameter2 = "another value";
}
},
"columns": [
{
"data": "ImageName",
"name": "Image_Name",
"className": "className",
"defaultContent": "Image Not Found"
},
{
"data": null,
"className": "class1 class2",
"orderable": false,
"render": function (data, type, row) {
var someUrl = "example.com/api/" + data.someVal;
return '< a href="'+ someUrl +'" id="'+ data.Id +'"><img src="'+ data.imageUrl + '" ></a>;
}
},
]
});
Justified,js
Masonry
I personally haven't used these but worth giving a try :)
Related
I am replacing a jQuery DataTable that performs client side processing. I would like to add a Details column, such as the following:
When one of the Details buttons is clicked, the Details View for that particular record is opened.
The following is the code that used to accomplish this:
<td class="action-button-column">#Html.RenderLinkAsButton(ButtonTypes.View, Url.Action("Details", "Controller", new {id = model.Id, area = "Area"}), Enums.ButtonSize.Small)</td>
Can I use/add RenderLinkAsButton in a DataTable column?
I know that I can use the following code to create a button that will perform the same thing:
columns: [
{
data: "Id",
title: "Details",
render: function (data) {
var myUrl = '#Url.Action("Details", "Controller")?Id=' + data;
return '';
}
}
]
However, I would like to include the icon, in this case an opened folder, to be consistent with other Index Views that use client side processing DataTables.
I just had to add the following with a leading space: fa-folder-open
columns: [
{
data: "Id",
title: "Details",
render: function (data) {
var myUrl = '#Url.Action("Details", "Controller")?Id=' + data;
return '';
}
}
]
I'm trying to bind jQuery DataTable by calling mvc action method using AJAX call and trying to populate the table using JSON data but it gets stuck on loading. Am I missing something?
Also, how can I implement server side Paging, Searching and Sorting in jQuery DataTable.
function initDataTable(ClientId)
{
var assetListVM;
$(function () {
assetListVM = {
dt: null,
init: function () {
var ClientId = $('#ddlClient').val();
dt = $('#records-data-table').dataTable({
"serverSide": true,
"processing": true,
"ajax": {
"type": "POST",
"dataType": "json",
"url": "#Url.Action("GetProcessingData", "Processing")?clientId=" + ClientId,
"success": function (data) {
alert(data);
console.log(data);
},
"error": function(){
alert("Error");
}
},
"columns": [
{ "title": "Co Num",
"data": "CompanyNo",
"searchable": true },
{ "title": "Cycle Date",
"data": "CycleDate",
"searchable": true },
{ "title": "Policy Number",
"data": "PolicyNo",
"searchable": true },
{ "title": "Issue Date",
"data": "IssueDate",
"searchable": true },
{ "title": "Transaction Date",
"data": "TransactionDate"
},
{ "title": "Transaction Amt",
"data": "TransactionAmount"
},
{ "title": "Item Code",
"data": "ItemCode"
},
{ "title": "Account",
"data": "Account"
},
{ "title": "Owner Name",
"data": "OwnerName"
}
],
"lengthMenu": [[10, 25, 50, 100], [10, 25, 50, 100]],
});
}
}
// initialize the datatables
assetListVM.init();
});
}
Below is my action method:
public ActionResult GetProcessingData(int clientId)
{
ClientSummary ClientSUM = new ClientSummary();
List<PolicyDownload> LstPData = new List<PolicyDownload>();
DataTable dtProcessingData = new DataTable();
try
{
using (DLpolicyDownload objDLpolicyDownload = new DLpolicyDownload())
{
dtProcessingData = objDLpolicyDownload.GetProcessingRecordDetails(clientId);
if (dtProcessingData != null)
{
foreach (DataRow dr in dtProcessingData.Rows)
{
PolicyDownload pData = new PolicyDownload();
pData.CompanyNo = Convert.ToInt32(dr["CO_NUM"]);
pData.CycleDate = Convert.ToString(dr["CYCLE_DATE"]);
pData.PolicyNo = Convert.ToString(dr["POLICY_NUMBER"]);
pData.IssueDate = Convert.ToString(dr["ISSUE_DATE"]);
pData.TransactionDate = Convert.ToString(dr["TRANSACTION_DATE"]);
pData.TransactionAmount = Convert.ToDouble(dr["TRANSACTION_AMOUNT"]);
pData.ItemCode = Convert.ToInt32(dr["ITEM_CODE"]);
pData.Account = Convert.ToString(dr["ACCOUNT"]);
pData.OwnerName = Convert.ToString(dr["OWNER_NAME"]);
LstPData.Add(pData);
}
}
}
}
catch (Exception ex)
{
if (logChoice)
{
log.Error(ex.Message, ex);
}
}
var data = from s in LstPData
select s;
return Json(new { data = data }, JsonRequestBehavior.AllowGet);
}
Below is the JSON output of this action method:
{"data":[{"PolicyDownloadID":0,"ImportDate":null,"CycleDate":"10/23/2017","CompanyID":0,"CompanyNo":40,"PolicyNo":"L0000001","PlanCode":null,"InsuranceType":null,"IssueDate":"05/02/2011","TransactionDate":"08/03/2017","TransactionAmount":7545.59,"ItemCode":0,"Account":"SBEN","Mode":null,"ModeAmount":0,"PayerName":null,"OwnerName":"CERNY, RAYMOND C","InsuredName":null,"PayeeName":null,"JointOwner":null,"SBC":0,"SBCAmount":0,"IsActive":false,"CreatedOn":"\/Date(-62135575200000)\/"},{"PolicyDownloadID":0,"ImportDate":null,"CycleDate":"10/23/2017","CompanyID":0,"CompanyNo":6,"PolicyNo":"FGL01234","PlanCode":null,"InsuranceType":null,"IssueDate":"07/23/2010","TransactionDate":"08/02/2017","TransactionAmount":26999.62,"ItemCode":0,"Account":"SBEN","Mode":null,"ModeAmount":0,"PayerName":null,"OwnerName":"BURNHAM, STEVEN L","InsuredName":null,"PayeeName":null,"JointOwner":null,"SBC":0,"SBCAmount":0,"IsActive":false,"CreatedOn":"\/Date(-62135575200000)\/"}]}
Below is the screenshot where it stuck:
It is calling my action method but unable to bind the JSON data.
success function - Must not be overridden as it is used internally in DataTables.
So remove success function and try once, hope it will help you.
DataTables requires json in certain format, look at Ajax tab in DataTables Documentation. Your answer in action don't corresponds to this format.
Try to add wrapper class (real or anonymous) with "data" field, which will be your list of objects.
Few things to take care while implementing server side datatable:
Your datatable in view must match number of columns coming with data.
The column names which you are mentioning in datatable should be same as in database table.
For implementing server side searching, add in a row textboxes below header row for each column. you need to bind each textbox keyup event for relevent column and pass it to server and rebind datatable
I'm developing a web application with Telerik Kendo in Razor. Here is my problem:
I have a variable that I set as a type List<class>.
#{
ViewBag.Title = "Home Page";
var dpdminst = new DB();
var data = dpdminst.getdata();}
I want to be able to use this variable (data) to set my DataSource in my Javascript:
<script>
var displaydata = #data
$(document).ready(function () {
$("#grid").kendoGrid({
height: 550,
groupable: true,
sortable: true,
pageable: {
refresh: true,
pageSizes: true,
buttonCount: 5
},
dataSource: {
data:displaydata,
schema: {
model: {
fields: {
amount: { type: "string" },
}
}
},
columns:["amount"]
}
});
});
</script>
Does anyone know if this can be done?
Here is my JsonResult:
public JsonResult GetJsonData()
{
var DBinst = new DB();
var TradeData = DBinst.tradedata();
var json = JsonConvert.SerializeObject(TradeData);
var result = new JsonResult()
{
Data = json
};
return result;
}
Have an action method which returns the data you want in JSON format. in your document.ready event, make an ajax call to get this data and then you can set it as your data source.
public ActionResult GetJsonData()
{
var dpdminst = new DB();
var data = dpdminst.getdata();
return Json(data,JsonRequestBehaviour.AllowGet);
}
and in your view use the getJSON method to get data from this action method and use that as needed. You may format the incoming json as per your UI requirements
$(document).ready(function () {
$.getJSON("#Url.Action("GetJsonData","YourControllerName")",function(data){
// you have your json data in the "data" variable.
// now you may use it to set the data source of your grid library
});
});
If you dont want to deal with ajax/json, then I would try to achieve what you want as follows:
<script>
var displaydata = [
#foreach (var record in dpdminst.getdata())
{
#: { amount: '#record' },
}
];
$(document).ready(function () {
$("#grid").kendoGrid({
height: 550,
groupable: true,
sortable: true,
pageable: {
refresh: true,
pageSizes: true,
buttonCount: 5
},
dataSource: {
data:displaydata,
schema: {
model: {
fields: {
amount: { type: "string" },
}
}
},
},
columns:["amount"]
});
});
</script>
Also please notice that you had columns:["amount"] in a wrong place, also this code has to be in your cshtml for razor syntax to work properly.
I have been trying to pull in information from my web API into my application.
Currently i am just trying to pull in data not submit it yet. The API is working and running as a service on my system.
It is returning data in json format an example of the data returned by the WEB API.
[
{
"$id": "1",
"id": "6c32e378-0f06-45da-9dda-0515c813cd5d",
"application_name": "FDB INTERFACE",
"description": "Interface for FDB decision support",
"active": true,
"tbl_update_header": []
},
{
"$id": "2",
"id": "58f68624-3803-43ff-b866-0a507ea85459",
"application_name": "HPM",
"description": "Helix Health Practice Manager",
"active": true,
"tbl_update_header": []
},
This is my page just to try and get the some data to display
<html>
<head>
<title></title>
<script src="~/Scripts/jquery-2.1.1.js"></script>
<script type="text/javascript">
$.ajax({
type: "GET",
url: "http://localhost:9981/API/Application",
processData: true,
data: {},
dataType: "json",
error: function (jqXHR, textStatus, errorThrown) {
// debug here
alert(jqXHR);
},
//error: function(error, data){
// console.log(error)
//},
success: function (data) {
//Clear the div displaying the results
$("productView").empty();
//Create a table and append the table body
var $table = $('<table border="2">');
var $tbody = $table.append('<tbody />').children('tbody');
//data - return value from the web api method
for (var i = 0; i < data.lenght; i++) {
//adda new row to the table
var $trow = $tbody.append('<tr />').children('tr:last');
//add a new column to display name
var $tcol = $trow.append('<td/>').children('td:last').append(data[i].id);
//add a new column to display description
var $tcol = $trow.append('<td/>').children('td:last').append(data[i].description);
}
//display the table in the div
$table.appendTo('#productView');
}
});
</script>
</head>
<body>
<div id="productView"></div>
</body>
</html>
The page loaded but is empty and no error is returned from any section.
I run the web page from chrome/FF/IE none of them show error in dev mode and VS shows no errors. I am not sure if i am parsing the data wrong or calling to the wrong part of the json to display the data.
I must be doing something silly at this point but just cant get pass this part.
you can also set this property in your js file before ajax call
$.support.cors = true;
There is a typo in your success method...
success: function (data) {
//Clear the div displaying the results
$("productView").empty();
//Create a table and append the table body
var $table = $('<table border="2">');
var $tbody = $table.append('tbody /').children('tbody');
//data - return value from the web api method
for (var i = 0; i < data.length; i++){
//adda new row to the table
var $trow=$tbody.append('<tr />').children('tr:last');
//add a new column to display name
var $tcol = $trow.append('<td/>').children('td:last').append(data[i].application_name);
//add a new column to display description
var $tcol = $trow.append('<td/>').children('td:last').append(data[i].description);
//add a new column to display active
var $tcol = $trow.append('<td/>').children('td:last').append(data[i].active);
}
//display the table in the div
$table.appendTo('#productView');
It should be data.length and not data.lenght.
Success. The issue was with CORS. also with the spelling mistake of data.length
The code works fine and the results are what i was wanting to get . Thank you all for your assist.
To fix the issue i had to enable CORS in iis server side to allow cross domain access.
Your code above has a success function, but not an error function.
Try setting an error function, and then see what happens :
data: {},
dataType: "json",
error: function(jqXHR, textStatus, errorThrown ) {
// debug here
alert(jqXHR);
},
success: function() ...
I have problems with memory leaks.
I display a table (with DataTables plugin) in my Html page following a select tag (Select2) that has an event change().
I noticed some memory leaks with the task manager (IE or FireFox).
My code works well, the only problem is memory leaks.
Here is my Html code, I have 2 tables, the second (table_statistic_10_ligne) is displayed when I click on one row of my first table (table_statistic_10), it displays the details of this row :
<body>
<select id="Select2" name="D1" style="margin-right :50px">
</select>
<script>
$("#Select2").change(function () { selectStat10(Select2.options[Select2.selectedIndex].value) });
</script>
<table id="table_statistic_10" class="display">
<caption class="caption">Detail van verkopen</caption>
<thead>
</thead>
<tbody>
</tbody>
</table>
<br />
<br />
<table id="table_statistic_10_ligne" class="display">
<thead>
</thead>
<tbody>
</tbody>
</table>
<script type="text/javascript">
fillSlectTagStat10();
</script>
</body>
Here is my javascript code, in the success, I retrieve the values (retrieved from a web service in C#) and I fill them in the datatables :
function getStatistic10(dstart, dend, nam) {
var response;
var allstat10 = [];
if (typeof myTabLigne10 != 'undefined') {
myTabLigne10.fnClearTable();
}
$.ajax({
type: 'GET',
url: 'http://localhost:52251/Service1.asmx/Statistic_10_Entete',
data: { "start": JSON.stringify(dstart), "end": JSON.stringify(dend), "name": JSON.stringify(nam) },
contentType: 'application/json; charset=utf-8',
dataType: 'json',
success: function (msg) {
response = msg.d;
for (var i = 0; i < response.Items.length; i++) {
var j = 0;
allstat10[i] = [response.Items[i].Nom, response.Items[i].Date, response.Items[i].Piece, response.Items[i].Tiers, number_format(response.Items[i].AmoutHT, 2, ',', ' '), number_format(response.Items[i].AmountTTC, 2, ',', ' '), response.Items[i].Quantite];
}
if (typeof myTabEntete10 != 'undefined') {
myTabEntete10.fnClearTable();
}
fillDataTableEntete10(allstat10, dstart, dend);
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert("error loading statistic 10");
alert("Status: " + textStatus + "\n" + "Error: " + errorThrown);
}
});
}
Filling dataTables code :
function fillDataTableEntete10(data, dstart, dend) {
if ($("#table_statistic_10").css("visibility") == "hidden")
$("#table_statistic_10").css("visibility", "visible");
myTabEntete10 = $('#table_statistic_10').dataTable({
'aaData': data,
'aoColumns': [
{ "sTitle": "Nom" },
{ "sTitle": "Date" },
{ "sTitle": "Piece" },
{ "sTitle": "Tiers" },
{ "sTitle": "AmoutHT" },
{ "sTitle": "AmountTTC" },
{ "sTitle": "Quantite" }
],
"sPaginationType": "full_numbers",
"iDisplayLength": 10,
"bJQueryUI": true,
"bDestroy": true,
"bPaginate": true,
"bLengthChange": false,
"bFilter": true,
"bSort": false,
"bInfo": false,
"bAutoWidth": false,
"sDom": '<"top"f<"clear">>rt<"bottom"ilp<"clear">>'
});
I have approximately 10 values (customer) in the select tag (Select2). But one customer has about 20.000 rows that I fill in the datatables. And when I selected several times this customer, I see that the memory increases.
I used fnClearTable() but it doesn't work.
Have you an idea because I'm a little lost?
EDIT : I solved the problem, I updtate the DataTables with fnClearTable() and fnAddData(). But now, the problem is with my click event, I have memory leaks because of this code :
myTabEntete10.$('tr').bind('click',function () {
var data = myTabEntete10.fnGetData(this);
$('tr').removeClass('row_selected');
$(this).addClass('row_selected');
loadData10(dstart, dend, data[2], data[3]);
delete data;
});
Why?
I solved the problem.
I replace the DataTables in the existing.
if (typeof myTabEntete10 != 'undefined') {
$('body').off("click", '#table_statistic_10 tbody tr');
myTabEntete10.fnClearTable();
myTabEntete10.fnAddData(allstat10);
} else {
fillDataTableEntete10(allstat10, dstart, dend);
}
And I use the bDeferRenderoption of DataTables, see here.