How can i do server side Sorting in JSGrid - javascript

I have implemented jsGrid and did the Filtering server side.Now i want to send sorting parameter to server side and do the sorting on server side on the click of column.
This is how i implemented the grid -
var db = {
loadData: function(filter) {
var bFilter = [];
var d = $.Deferred();
console.log("sorting:", filter.sortField, filter.sortOrder);
for (var prop in filter) {
if (prop != "sortField" && prop != "sortOrder") {
bFilter.push({
"Name": prop,
"Value": filter[prop]
})
} else{
var sorting ={ "Name": filter["sortField"], "Type": filter["sortOrder"] };
}
}
$.ajax({
url: "http://abc/abc",
dataType: "json",
data: JSON.stringify({
"filter": bFilter,
"sorting": sorting
})
}).done(function(response) {
d.resolve(response.value);
});
return d.promise();
},
};
$("#jsGrid").jsGrid({
height: 300,
width: "100%",
filtering: true,
editing: true,
sorting: true,
paging: true,
autoload: true,
pageSize: 2,
pageButtonCount: 5,
deleteConfirm: "Do you really want to delete the client?",
controller: db,
fields: [{
name: "Name",
type: "text",
width: 150
},
{
name: "Age",
type: "number",
width: 50
},
{
name: "Address",
type: "text",
width: 200
},
{
type: "control"
}
]
});
How would i call the same loaddata method on click of header for sorting to do the filtering and sorting together on server side.
How to disable the client side sorting and do it on serve side same like filtering.
If i set sorting:false it removes the click from the column headers.I want to keep that as well.

I was able to solve this by changing the sort function -
jsGrid.loadStrategies.DirectLoadingStrategy.prototype.sort = function () {
var filters = $("#tableId").jsGrid("getFilter");
var sorting = $("#tableId").jsGrid("getSorting");
this._grid.controller.loadData(filters, sorting);
}

Related

How to change the format of a date field in a jsgrid table

Good afternoon, I have this data in a jsgrid table, the fact is that when the database returns the date when displaying it on the page it looks like this: / Date (1614232800000) / what I need is to convert it to DD format / MM / YYYY
Reading the official documentation, there is by default a type of date field as such, but it is possible to modify parameters at will, that being the case, how can I convert the date?
I read all from this, any idea, thank you.
http://js-grid.com/docs/#custom-field
First of all, Thanks.
var MyDateField = function (config) {
jsGrid.Field.call(this, config);
};
MyDateField.prototype = new jsGrid.Field({
css: "date-field", // redefine general property 'css'
align: "center", // redefine general property 'align'
myCustomProperty: "itemTemplate", // custom property
itemTemplate: function (value) {
return new Date(value).toDateString();
}
});
jsGrid.fields.date = MyDateField;
$('#dgrecordsfound').jsGrid({
width: "100%",
height: "350px",
filtering: false,
inserting: false,
editing: false,
sorting: true,
paging: true,
autoload:true,
pageButtonCount: 5,
noDataContent:"No records!",
loadIndication: true,
loadMessage: "Loading, Please wait",
pagercontainer:null,
pageIndex: 1,
pageSize: 6,
pageButtonCount: 15,
pagerFormat: "Pages: {first} {prev} {pages} {next} {last} {pageIndex} de {pageCount}",
pagePrevText: "Prev",
pageNextText: "Next",
pageFirstText: "First",
pageLastText: "Last",
pageNavigatorNextText: "...",
pageNavigatorPrevText: "...",
controller: {
loadData: function () {
return $.ajax({
type: "GET",
datatype: "json",
data: { parname: "#ViewBag.name" , parlastname: "#ViewBag.lastname"},
url: "/asoc/getbyname"
});
},
},
fields: [
{
name: "cod",
title: "Code",
type: "text",
width: 30
},
{
name:"firstname",
title: "firstname",
type: "text",
width: 100
},
{
name: "date",
title: "Date",
type: "date",
myCustomProperty: "itemTemplate",
width: 30
}
],
rowClick: function (itemselected) {
var getdata = itemselected.item;
var fields = Object.keys(getdata);
var textarray = [];
$.each(fields, function (idx, value) {
textarray.push(getdata[value])
});
var url = '#Url.Action("index", "request")' + '/id=1?parCod='+ textarray[1];
window.location.href = url;
}
});

How do I update the data in jsGrid without the ability to use AJAX in the loadData() controller? (The array isn't finished populating yet)

I can display static data data: ary and I'm successful with updating, deleting, inserting, and filtering said static data:
controller: {
loadData: function (filter) {
return $.grep(ary, function (obj, index) {
return
/* conditional logic for filtering here */
});
},
updateItem: function (item) {
//call custom framework function responsible for updating record
appName.doRequest("updateRecord");
},
insertItem: function (item) {
//call custom framework function responsible for inserting record
appName.doRequest("insertRecord");
},
deleteItem: function (item) {
//call custom framework function responsible for deleting record
appName.doRequest("deleteRecord");
},
},
Please note, ary is a global variable. Basically, I can update ary anytime I want through our custom framework; however, it must be outside of the jsGrid controllers, or the array ends up empty.
Why do I have to call the function responsible for populating the array whilst outside of loadData() in order for the array to become accessible? How do I get my array to be available inside of loadData() when I call my company's special function?
The documentation says I can use AJAX requests with deferments/promises, but I don't believe our framework will allow for me to make direct AJAX requests to the backend.
Here's a snippet of the framework:
case "getJobSpecs":
var jsonString, ary = [];
var jsonString = $(data.xmldata).find("tblJobSpecs").text();
ary = JSON.parse(jsonString);
//results from server. I can do anything to the DOM I want here
break;
case "updateRecord":
console.log(data.xmldata);
//results from server. I can do anything to the DOM I want here
break;
case "insertRecord":
console.log(data.xmldata);
//results from server. I can do anything to the DOM I want here
break;
case "deleteRecord":
console.log(data.xmldata);
//results from server. I can do anything to the DOM I want here
break;
Long story short, I was able to reload the grid with an updated array with this simple line:
$("#tblJobSpecs").jsGrid("option", "data", ary)
Observations:
ary is a global var updated through calls in our custom framework; even though I can call the framework from within the loadData() controller to populate ary, it's not available inside the loadData() function, for a reason I do not fully understand.
I no longer define the data option (now, the grid initializes with no data)
$("#tblJobSpecs").jsGrid({
width: "100%",
//height: "400px",
inserting: true,
editing: true,
sorting: true,
selecting: true,
paging: true,
filtering: true,
//data: ary
...
});
After the DB has been modified through updateItem(), insertItem, or delteItem(), I redefine ary via our framework, then ...
... I tell jsGrid to "refresh" the grid with:
$("#tblJobSpecs").jsGrid("option", "data", ary)
You can use arr.filter property and return the returns after checking your conditions,
$("#jsGrid").jsGrid({
height: "90%",
width: "100%",
filtering: true,
editing: false,
sorting: true,
paging: true,
autoload: true,
pageSize: 10,
pageButtonCount: 5,
deleteConfirm: "Do you really want to delete the client?",
controller: {
loadData: function (filter) {
if (gridDataDb != undefined) {
for (var filterItem in filter) {
if (filter[filterItem] === "") {
$("#jsGrid").data("JSGrid").data = gridDataDb;
}
}
}
//this.data = Array.from($("#jsGrid").data("JSGrid").data);
return $.grep($("#jsGrid").data("JSGrid").data, function (client) {
return (!filter.vcm_prescriberidname || client.vcm_prescriberidname.indexOf(filter.vcm_prescriberidname) > -1)
&& (!filter.npid || client.npid.indexOf(filter.npid) > -1)
&& (!filter.vcm_territoryname || client.vcm_territoryname.indexOf(filter.vcm_territoryname) > -1)
&& (!filter.vcm_countryidname || client.vcm_countryidname.indexOf(filter.vcm_countryidname) > -1)
&& (!filter.vcm_statefullname || client.vcm_statefullname.indexOf(filter.vcm_statefullname) > -1)
&& (!filter.vcm_city || client.vcm_city.indexOf(filter.vcm_city) > -1)
&& (!filter.vcm_zip || client.vcm_zip.indexOf(filter.vcm_zip) > -1)
&& (!filter.currmonthsum || client.currmonthsum.indexOf(filter.currmonthsum) > -1)
&& (!filter.lastquartersum || client.lastquartersum.indexOf(filter.lastquartersum) > -1)
&& (!filter.thisyearsum || client.thisyearsum.indexOf(filter.thisyearsum) > -1)
});
}
},
fields: [
{ name: "vcm_prescriberidname", title: "Prescriber Name", type: "text", width: 20 },
{ name: "npid", title: "NPI ID", type: "text", width: 20 },
{ name: "vcm_territoryname", title: "Territory Name", type: "text", width: 20 },
{ name: "vcm_countryidname", title: "Country", type: "text", width: 20 },
{ name: "vcm_statefullname", title: "State", type: "text", width: 20 },
{ name: "vcm_city", title: "City", type: "text", width: 20 },
{ name: "vcm_zip", title: "ZipCode", type: "text", width: 15 },
{ name: "currmonthsum", title: "Curr Month TRx Sum", type: "text", width: 10 },
{ name: "lastquartersum", title: "Last Quarter TRx Sum", type: "text", width: 10 },
{ name: "thisyearsum", title: "Last Year TRx Sum", type: "text", width: 10 },
//{ name: "vcm_prescriberidname", title: "Location", type: "text", width: 7 },
{ type: "control" }
]
});
Look at the above piece of code,
Two key notes:
Load Data through $("#jsGrid").jsGrid("option", "data", your_Data_Array).
Filter out data without Ajax using Array.filter.
NOTE: The filter object reference contains an Object containing all the columns in the jsGrid, So when filters are applied, the respective column with that filter value updated in the respective column is passed to the data set to filter the results.
Let me know if that helps !

How can I load rows in JsGrid table that got from php file?

I tried to load rows of data from a table in MySQL. I used jsgrid with PHP.
My two php files connect to the localhost datanase and select rows from the tables using mysqli functions, and copy the result of the query into an array and send by json_encode() to an HTML file where I put the jsgrid code.
Then, I call the html file into other PHP file by <iframe> html tag.
The names of PHP files are:
newsConf, controll and getnewscat
HTML file: basic.html
in controll.php:
public function newsConfig(){
$this->CONN = new Conn();//class from external page to connect DB
try{
$dfnet = $this->CONN->open_connect();
$qnco = mysqli_query($dfnet,"select * from category");
if(!$qnco) return "";
else{
while($qncoarray = mysqli_fetch_row($qnco)){
//here I try copy rows into array
$nnopCo[] = array(
'ID' => $qncoarray['ID'],
'Name' => $qncoarray['Name']
);
}
return $nnopCo;
}
$this->CONN->close_connect($dfnet);
}
catch(Exception $er){
}
in getnewscat.php:
<?php require_once "../../bin/controll.php";
$db_controll = new Controll();
$cat_news = new ArrayObject($db_controll->newsConfig());
header('Content-type: application/json');
echo json_encode($cat_news->getArrayCopy());
?>
in basic.html: is the same file from jsgrid demo, but I change the code in javascript and canceled the db.js file
$(function() {
$("#jsGrid").jsGrid({
height: "70%",
width: "50%",//100%
selecting: false,
filtering: false,
editing: false,
sorting: false,
paging: true,
autoload: true,
pageSize: 15,
pageButtonCount: 5,
controller: {
loadData: function(clients){
var d = $.Deferred();
$.ajax({url: "../bin/getnewscat.php", dataType: "json",function(obj){
for (var i = 0; i < obj.length; i++) {
/*res[i]=data.i;
i++;*/
clients = {
"ID": obj.ID,
"Name": obj.Name
};
}
}
}).done(function(response) {
d.resolve(response.value);
});
return d.promise();
}
In newsConf.php: that file should call basic.html and give the result
by this:
<iframe name="demo" src="jsgrid-1.2.0/demos/basic.html"></iframe>
But the result is empty and I don't know why?, however I change the code but it didn't yield success.
What have I missed here?
Update
See my update below.
The done function should work. Remove success handler and put your mapping into done handler. Then put a debugger into done handler to ensure what you get in a response. Then map the response accordingly and resolve the deferred.
loadData: function(clients){
var d = $.Deferred();
$.ajax({
url: "../bin/getnewscat.php"
}).done(function(response) {
// put a debugger here to ensure that your response have 'value' field
var clients = $.map(response.value, function(item) {
return {
ID: item.SomeID,
Name: item.SomeName
};
});
d.resolve(clients);
});
return d.promise();
}
I'm not sure whether you need a mapping or not. Maybe you can remove it in the end. But do everything in the done handler and check the format of the response.
Sorry for my delay, but I think I got where's my mistake!
I fixed it and I got what I missed,
In controll.php file, I used mysqli_fetch_row() function, but I forgot I send the data in a named array, so I changed it to mysqli_fetch_assoc() function.
and about basic.html I changed it to:
<script>
$(function() {
{
$("#jsGrid").jsGrid({
height: "70%",
width: "50%",//100%
selecting: false,
filtering: false,
editing: false,
sorting: false,
paging: true,
autoload: true,
pageSize: 15,
pageButtonCount: 5,
controller: {
loadData: function(filter) {
//here how I fix it!
return $.ajax({url: "../bin/getnewscat.php",data:filter
});
}
},
////////////////////////////////////////////////////////////
fields: [
{ name: "ID", type: "number", width: 50 },
{ name: "Name", type: "text", width: 50},
{ type: "control", modeSwitchButton: false, deleteButton: false }
]
});
$(".config-panel input[type=checkbox]").on("click", function() {
var $cb = $(this);
$("#jsGrid").jsGrid("option", $cb.attr("id"), $cb.is(":checked"));
});
});
</script>
but I think it's not secure, how could I make it more secure?
I was having the same issue. However once I added the return to $.ajax line all I get is blank lines but the grid is trying to render something. See image below.
PHP Code Below:
$sql = "SELECT e.estimateid, e.customerid, e.compid, cu.first_name,cu.last_name,e.reference_num, e.estimate_date, e.expiry_date, e.hours, e.sales_person, e.project_name
FROM estimates AS e INNER JOIN company AS c ON e.compid = c.compid
INNER JOIN customers AS cu ON e.customerid = cu.customerid";
$resultsE = $conn->query($sql);
$rows = array();
while ($r = $resultsE->fetch_assoc()){
$rows[] = $r;
}
$data = array($rows);
}
//header("Content-Type: application/json"); //If I uncomment this line the Grid says No Results.
echo json_encode($data);
JS Code Below:
$(function() {
$("#jsGrid").jsGrid({
height: "90%",
width: "98%",
filtering: true,
inserting: false,
editing: false,
sorting: true,
paging: true,
autoload: true,
pageSize: 10,
pageButtonCount: 5,
//deleteConfirm: "Do you really want to delete client?",
controller: {
loadData: function(filter) {
return $.ajax({url: "/js/jsgrid/estimates/index.php",data: filter });
},
/*insertItem: function(item) {
return $.ajax({
type: "POST",
url: "/estimates/",
data: item
});
},
updateItem: function(item) {
return $.ajax({
type: "PUT",
url: "/estimates/",
data: item
});
},
deleteItem: function(item) {
return $.ajax({
type: "DELETE",
url: "/estimates/",
data: item
});
}*/
},
fields: [
{ name: "estimateid", type: "number", width: 10, title: "EstId" },
{ name: "customerid", type: "number", width: 10, title: "CustId" },
{ name: "compid", type: "number", width: 10, title: "CompId"},
{ name: "first_name", type: "text", width: 50, title: "First Name" },
{ name: "last_name", type: "text", width: 50, title: "Last Name" },
{ name: "reference_num", type: "text", width: 12, title: "Ref.#" },
{ name: "estimate_date", type: "text", width: 12, title: "Est. Date" },
{ name: "expiry_date", type: "text", width: 12, title: "Exp. Date" },
{ name: "hours", type: "number", width: 10, title: "Hours" },
{ name: "sales_person", type: "text", width: 50, title: "Sales" },
{ name: "project_name", type: "text" , width: 50, title: "Project"},
{ type: "control" }
]
});
});

Telerik Datasource Json Server Paging Not Working

I'm working on a Hybrid app built with Json data. There's a small problem though. I can't figure out how to get the paging to work for the Datasource.
The json structure looks like this.
{
"respond":1,
"paging":{
"stillmore":1,
"perpage":10,
"callpage":1,
"next":2,
"previous":0,
"pages":6,
"result":"52"
},
"message":"",
"result":[
{Main Data}
]
}
Here's my DataSource structure
var dataSource = new kendo.data.DataSource({
transport: {
read: {
url: "JsonURL",
dataType: "json",
jsonp: "$callback",
cache: true
},
serverFiltering: true,
filter: { logic: "paging", filters: [ { field: "name", operator: "startswith", value: "Jane" } ] },
parameterMap: function (data, type) {
return kendo.stringify(data);
if (type == "read") {
// send take as "$top" and skip as "$skip"
return {
$callpage: data.page,
$perpage: data.pageSize
}
}
}
},
schema: {
data: "result", // twitter's response is { "results": [ /* results */ ] }
total: "paging.result",
},
sort: {
field: "ID",
dir: "desc"
},
serverPaging: true,
serverSorting: true,
pageSize: 20
});
It's not paging. I have about 100 results, and the server only displays 20 every page. When you want to load the next 20, nothing happens. It gets stuck on the loading gif.
I can't seem to figure it out. How can I enable server paging with this Json return?
Any tips would be welcome! Thanks!
You have mistake in your code in:
parameterMap: function (data, type) {
// DELETE THIS LINE: return kendo.stringify(data);
if (type == "read") {
// send take as "$top" and skip as "$skip"
return {
callpage: data.page,
perpage: data.pageSize
}
}
}
You return return kendo.stringify(data); immediately and you can't use your custom binding for page number.
Try to delete this line as I show you above

Lazy Load with Scrollable {Virtual:true} not working in Kendo UI Grid

I am facing an issue to implement lazy loading in kendo ui grid.
I added scrollable virtual property and backend server side code to handle it but issues is after adding scrollable property I am unable to see scroll bar in my Grid.
Even the selected rows (20 page size) disappears off the bottom of the grid into the hidden overflow area.
Here is my code.
var managecustomerGrid = $("#customerGrid").kendoGrid({
dataSource: {
schema: {
data: "results",
total : "totalRecords",
model: {
id: "SRNUMBER",
fields: {
SRNUMBER : {type: 'number'},
CUSTOMERNAME : {type: 'string'},
DATEPAID : {type: 'string'}
}
}
},
serverPaging: true,
serverSorting: true,
serverFiltering: true,
pageSize: 20,
batch: false,
transport: {
read: {
type: "POST",
url: "/customer/customer.cfc",
dataType: "json",
error: function (xhr, error) {
alert('Error In Getting Customer Information.');
}
},
parameterMap: function(options, type) {
return {
ntPageNumber: options.page,
ntRowLimit: options.pageSize,
vcSortOrder: JSON.stringify(options.sort),
vcFilterCondition: JSON.stringify(options.filter)
}
}
}
},
toolbar: kendo.template($("#template").html()),
height: 600,
scrollable: {
virtual: true
},
filterable: {
operators: {
string: {
contains: "Contains",
startswith: "Starts with",
endswith: "Ends with",
eq: "Is equal to",
doesnotcontain: "Doesn't contain"
}
}
},
sortable: true,
columns: [
{ field: "SRNUMBER", title: "SR No.", width: "80px", template: "<span id='#=SRNUMBER#'>#=SRNUMBER#</span>"},
{ field: "CUSTOMERNAME", title: "Customer Name", width: "110px"},
{ field: "DATEPAID", title: "Date", width: "110px"},
{ command: ["edit","detail","cancel"], title: " ", title: "Actions", width: "130px", filterable: false, sortable: false}
]
});
Please let me know if any one find any issues. I am unable to get it.
The kendo grid does not really support Lazy Loading out of the box. It may be easier to instead just make a blank scroll-able grid (without paging), and then to populate the data with ajax calls. You can use $.merge() to append data to the data array with little to no impact on performance.
$.ajax({
url: '/getNextData',
data: { filter: 'foo', lastLoaded: $("#Grid").data("kendoGrid").dataSource.at($("#Grid").data("kendoGrid").dataSource.total()-1).ID },
dataType: "json",
success: function (newData) {
$("#Grid").data("kendoGrid").dataSource.data($.merge($("#Grid").data("kendoGrid").dataSource.data(), newData))
},
error: function (e) { console.log(e); }
});
In this ajax example I load the next data based on the current last item in the grid and a filter. I just append the response to the currently loaded data.
I faced the same issue, my problem was the controller code. Here I am posting my controller hoping it would help someone someday
public JsonResult GetJson(int? projectid,int skip, int take, int pageSize, int page)
{
using (sqlCon)
{
var myData = sqlCon.Query<Device>("Select * from workbook.dbo.TargetList", new { projectid = projectid });
var data = myData .Skip(skip).Take(pageSize).ToList();
var total = myData .Count();
var json = new { data = myData };
var jsonResult = Json(new {data= data, total= total}, JsonRequestBehavior.AllowGet);
jsonResult.MaxJsonLength = int.MaxValue;
return jsonResult;
}
}

Categories

Resources