Server Side Paging in JQGrid - jqgrid-asp.net

I am trying to implement Server side paging in JQGrid. Can any body helps me to how to achieve it. Currently client side is working fine in my grid but wanted to change it to server side.

Taken from : http://yassershaikh.com/how-to-use-jqgrid-with-asp-net-mvc/
If you have worked with JqGrid before you will no doubt be familiar with the default parameters passed to any ajax request: “page”, “rows”, “sidx” & “sord”. These parameters correspond to current page, records per page, sort column, and sort order respectively.
The screenshot below, will help you understand this better.
So, to handle this I have prepared a class called ‘JqGridObject’.
public class JqGridObject
{
public string Page { get; set; }
public int PageSize { get; set; }
public string SortColumn { get; set; }
public string SortOrder { get; set; }
public List<Fruit> Data { get; set; }
}
public class Fruit
{
public int Id { get; set; }
public string Name { get; set; }
}
Send json data from controller using this JqGridObject class
public ActionResult GetJqGridData(string page, string rows, string sidx, string sord)
{
var jqGridData = new JqGridObject()
{
Data = GetSomeSampleData(),
Page = page,
PageSize = 3, // u can change this !
SortColumn = sidx,
SortOrder = sord
};
return Json(jqGridData, JsonRequestBehavior.AllowGet);
}
public List<Fruit> GetSomeSampleData()
{
return new List<Fruit>
{
new Fruit{Id = 1, Name = "Apple" },
new Fruit{Id = 2, Name = "Melon" },
new Fruit{Id = 3, Name = "Orange" },
new Fruit{Id = 4, Name = "Grapes" },
new Fruit{Id = 5, Name = "Pineapple" },
new Fruit{Id = 6, Name = "Mango" },
new Fruit{Id = 7, Name = "Bannana" },
new Fruit{Id = 8, Name = "Cherry" }
};
}
JqGrid jquery call.
<script type="text/javascript">
$(document).ready(function () {
$("#myGrid").jqGrid({
url: '#Url.Action("GetJqGridData")',
datatype: 'json',
myType: 'GET',
colNames: ['Id', 'Name'],
colModel: [
{ name: 'Id', index: 'Id' },
{ name: 'Name', index: 'Name' }
],
jsonReader: {
root: 'Data',
id: 'id',
repeatitems: false
},
pager: $('#myPager'),
rowNum: 5,
rowList: [2, 5, 10],
width: 600,
viewrecords: true,
caption: 'Jqgrid MVC Tutorial'
});
});
</script>
<table id="myGrid"></table>
<div id="myPager"></div>

i saw many options for server side pagination in jqgrid , but none of them are efficient for our requirements .
what i did is putting LIMIT :startLimit, :endLimit in Query String.
enable and disable nextPager and prevPager based on the records.
suppose i want to show 5 records for each page,
var startLimit=0;
var endLimit=5;
when user clicks on "NEXT" ,
$("#next_pager").click(function () {
startLimit = startLimit+ endLimit;
// here comes your AJAX call with passing two parameter(startLimit,endLimit)
});
when user clicks on "Previous" ,
$("#prev_pager").click(function (){
if (startLimit == 0)
{
$("#prev_pager").addClass("ui-state-disabled"); //disable previous pager icon
}
else
{
startLimit = startLimit - endLimit;
}
});
to changing the Page Numbers :
Initialize one variable : var pageInputValue=1;
when user clicks on "NEXT" ,
$(".ui-pg-input").val(eval(parseInt(pageInputValue)+1));
pageInputValue = eval(parseInt(pageInputValue)+1);
when user clicks on "Previous" ,
$(".ui-pg-input").val(eval(parseInt(pageInputValue)-1));
pageInputValue = eval(parseInt(pageInputValue)-1);
To change the View Records # Botton Right :
if(eval(startLimit+endLimit) > result)
{
$(".ui-paging-info").text("View "+eval(startLimit+1) +" - "+result+" of "+result);
}
else
{
$(".ui-paging-info").text("View "+eval(startLimit+1) +" - "+eval(startLimit+endLimit)+" of "+result);
}
if you find it useful, make it count.

Related

React-Admin with .net .The response to 'getList' must be like { data : [{ id: 123, ...}, ...] }, but the received data items do not have an 'id' key

I have an ASP.NET Core Web API and a React client. I'm trying to build admin dashboard with React-Admin. My problem is when I receive the data from server, my object are with property Id (uppercase), then in console I'm getting an error
The response to 'getList' must be like { data : [{ id: 123, ...}, ...] }, but the received data items do not have an 'id' key
I tried making new test class with property id (lowercase) in my server and then the problem is gone.
How can I fix this issue?
This is my test class and its working.
public class CityModel
{
public string id { get; set; }
public string Name { get; set; }
}
[HttpGet("Cities")]
public CityModel[] GetCities()
{
var city1 = new CityModel()
{
id = "ahsxge",
Name = "Berlin"
};
var city2 = new CityModel()
{
id = "axhdagw",
Name = "London"
};
var list = new List<CityModel>();
list.Add(city1);
list.Add(city2);
Response.Headers.Add("Access-Control-Expose-Headers", "X-Total-Count");
Response.Headers.Add("X-Total-Count", list.Count.ToString());
return list.ToArray();
}
This is my component in react :
const AppAdmin = () => {
const jwt = localStorage.getItem("jwt");
const httpClient = (url, options = {}) => {
options.user = {
authenticated: true,
token: 'Bearer ' + jwt
};
return fetchUtils.fetchJson(url, options);
};
const dataProvider = jsonServerProvider('https://localhost:44366/api', httpClient);
dataProvider.getList('Cities/Cities', {
pagination: { page: 1, perPage: 15 },
sort: { field: 'Name', order: 'ASC' },
})
.then(response => console.log(response));
return (
<Admin dataProvider={dataProvider}>
<Resource name='Cities/Cities' list={CitiesList} />
</Admin>
)
}
export default AppAdmin
You can configure the json converter to use camelCase serialization int the ConfigureServices method in the Startup.cs file the following way:
services
.AddControllers()
.AddJsonOptions(opts =>
{
opts.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
})
This way you can use PascalCase properties in your c# code (which you should do), but your client will recieve camelCase json properties.

asp.net viewmodel returned to view as ajax object ; how to access the fields and values

I return a viewmodel data from my a controller to view as ajax object, succesfully. I cant figure out how to access the data.
Ajax code in view is
<script>
function GetDepartmentsSections() {
var myData = { CompanyName: $("#CompanyName").val() };
$.ajax({
headers:
{
"RequestVerificationToken": '#GetAntiXsrfRequestToken()'
},
url: "/Shifts/Get_Department_Section",
type: "POST",
data: myData,
success: function (data) {
data.forEach(function (element) {
console.log(element)
});
},
error: function () {
}
});
}
$("#CompanyName").on('change', GetDepartmentsSections);
Here the log displays the data correctly as
department: Object { id: 6, name: "Development", shortName: "DVT", … }
section: Object { id: 7, name: "section1", laModiDate: "2018-03-01", … }
department: Object { id: 9, name: "Finance", shortName: "FIN", … }
section: Object { id: 18, name: "section3", laModiDate: "2018-03-01", … }
and so on...
Now how to access the department and section groups values? I am new to ajax and .net . Got stucked with this for the last few hours. I was expecting something in the line of ...
element.department.id 'or' element.section.name 'and so on...'
The controller is as follows
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Get_Department_Section(string CompanyName)// To select Departments/sections for 'assign shifts'
{
int CompID = await _context.Company.Where(i => i.Name == CompanyName).Select(i => i.ID).FirstOrDefaultAsync();
var DepSec = _context.Department.Where(i => i.CompanyID == CompID).Join(_context.Section, d => d.ID, s => s.DepartmentID, (d, s) =>
new DepSecViewModel { department = d, section = s }).OrderBy(i => i.department.Name).ThenBy(i => i.section.Name);
return Json(await DepSec.ToListAsync());
}
and the View model is as follows
public class DepSecViewModel
{
public Department department { get; set; }
public Section section { get; set; }
}

calling json URL in MVC 4

i made an ASP.NET WEB API which fetch the detail of customer & nutrient in json format. i deployed my API on IIS & it is working fine. Now i want to use the URL of that API on my MVC project.My URL is like this "http:/localhost:12/customernutrient/customernutrient?o=json" and class is like this
public class Header
{
public string api_ver { get; set; }
public int req_type { get; set; }
public int code { get; set; }
public string description { get; set; }
}
public class Customer
{
public int customerId { get; set; }
public string customerName { get; set; }
}
public class Nutrient
{
public int nutrientId { get; set; }
public string nutrientName { get; set;}
}
public class Body
{
public List<Customer> customer { get; set; }
public List<Nutrient> nutrient { get; set; }
}
public class RootObject
{
public Header header { get; set; }
public Body body { get; set; }
}
how with the help of my link i call my API & display the content in some what like label or something.I want to display this data in different labels
{
"header": {
"api_ver": "1.2",
"req_type": 1,
"code": 1,
"description": "Successful output"
},
"body": {
"customer": [
{
"customerId": 1,
"customerName": "Roundys1"
},
{
"customerId": 2049,
"customerName": "Test"
}
],
"nutrient": [
{
"nutrientId": 1,
"nutrientName": "Calcium"
},
{
"nutrientId": 2,
"nutrientName": "Calories"
},
{
"nutrientId": 3,
"nutrientName": "Cholesterol"
},
{
"nutrientId": 4,
"nutrientName": "Dietary Fiber"
},
{
"nutrientId": 5,
"nutrientName": "Iron"
},
{
"nutrientId": 6,
"nutrientName": "Polyunsaturated Fat"
},
{
"nutrientId": 7,
"nutrientName": "Potassium"
},
{
"nutrientId": 8,
"nutrientName": "Protein"
},
{
"nutrientId": 9,
"nutrientName": "Saturated Fat"
},
{
"nutrientId": 10,
"nutrientName": "Sodium"
},
{
"nutrientId": 11,
"nutrientName": "Sugars"
},
{
"nutrientId": 12,
"nutrientName": "Total Carbohydrate"
},
{
"nutrientId": 13,
"nutrientName": "Total Fat"
},
{
"nutrientId": 14,
"nutrientName": "Vitamin A"
},
{
"nutrientId": 15,
"nutrientName": "Vitamin C"
}
]
}
}
please share your possible solution
You can use ajax call to populate your view. assuming that you want to populate the data on click of a button whose id = 'btnpopulatedata'
<script>
$(document).ready(function () {
var itemName = "#btnpopulatedata";
$(itemName).click(function () {
$.ajax({
type: 'GET',
dataType: 'Json',
url: 'http:/localhost:12/customernutrient/customernutrient?o=json',
success: function (data) {
//write your logic to parse Json and populate the view controls.
},
error: function () {
alert("Error);
},
});
});
});
</script>

how to use highcharts in asp.net MVC 4

I'm new in highcharts. I try to use it in my asp.net MVC 4 project. I want to pass information relative to charts from controller to view. I've used session to pass differents categories, the chart appear but without categories. Is there any solution to pass information from controller to view?
this is part of my code:
view:
<script type="text/javascript">
$(function () {
$('#divStat').highcharts({
chart: {
type: 'bar'
},
title: {
text: 'Historic World Population by Region'
},
subtitle: {
text: ''
},
xAxis: {
categories: '#Session["affiche"]',
title: {
text: null
}
},
[...]
});
</script>
controller:
public ActionResult Stat()
{
String[] list = new String[5];
list[0] = "Africa";
list[1] = "America";
list[2] = "Asia";
list[3] = "Europe";
list[4] = "Oceania";
Session["affiche"] = list;
return PartialView("Charts");
}
You have to put "," among the strings to make javascript understand that is an array
#{
string[] theList = (string[])Session["affiche"];
string javascriptArrayString = "";
foreach(string str in theList){
javascriptArrayString += "'"+ str +"',";
}
javascriptArrayString = javascriptArrayString.Substring(javascriptArrayString.Length,javascriptArrayString.Length-1);
}
then:
categories: [#javascriptArrayString],
and the html result will be like :
categories: ['Africa','Asia','America','Europe','Oceania'],
this is a bit rough coding , but i think you'll get the point.

Kendo UI Grid Fires CRUD Operations multiple times

I've seen this problem in many places but I can't seem to find a solution. So I have defined a Kendo grid with CRUD operations the thing is that the previous fired operations get fired again.
Say you delete entry X and then you add entry Y, the create operation fires and after that the delete operation (for X - which has been deleted) fires again. Same thing if you first create an element and then edit another, it edits the 2nd element and then it re-fires the 1st create statement and inserts a duplicate for the 1st inserted element. If you go on an on with several operations a nightmare happens with all the other previous operations being fired and sent to the controller.
My grid is:
function InitializeIPAddressesGrid(userID) {
selectedUserID = userID;
$(".ipAddresses").kendoGrid({
dataSource: IPAdressesDataSource,
sortable: {
mode: "single",
allowUnsort: false
},
remove: function (e) {
this.refresh();
var canDelete = confirm("Are you sure you want to delete this record?");
if (!canDelete) {
e.preventDefault();
}
},
height: 420,
resizable: true,
pageable: {
refresh: true,
pageSize: 10
},
selectable: "row",
toolbar: ["create"],
editable:{mode: "inline", confirmation:false} ,
columns: [{
field: "IpAddress",
title: "IP Address"
},
{
field: "Status",
title: "Status"
},
{
field: "LockedUntil",
title: "Locked until",
template: "#=kendo.toString(LockedUntil, 'yyyy/MM/dd' )#"
},
{ command: ["edit", "destroy"], title: " ", width: "180px" }
]
});
}
var IPAdressesDataSource = new kendo.data.DataSource({
type: "json",
serverPaging: true,
serverSorting: true,
serverFiltering: true,
pageSize: 10,
//scrollable:false,
transport: {
read: {
url: websiteRootUrl + '/PortalAuthorization/GetIPAddressesList',
},
update: {
url: websiteRootUrl + "/PortalAuthorization/UpdateIP",
dataType: "json",
type: 'POST',
complete: function (e) {
if (e.status != 200) {
alert(eval('(' + e.responseText + ')').Message);
}
}
},
create: {
url: websiteRootUrl + "/PortalAuthorization/CreateIP",
dataType: "json",
type: 'POST',
complete: function (e) {
if (e.status != 200) {
alert(eval('(' + e.responseText + ')').Message);
}
}
},
destroy: {
url: websiteRootUrl + "/PortalAuthorization/DeleteIP",
dataType: "json",
type: 'DELETE',
complete: function (e) {
if (e.status != 200) {
alert(eval('(' + e.responseText + ')').Message);
}
}
},
parameterMap: function (options, operation) {
if (operation == "update" && options) {
return {ipAddress: options.IpAddress ,
status: options.Status ,
lockedUntil: kendo.toString(options.LockedUntil, 'yyyy/MM/dd' ),
pkey: options.ID,
databaseID: selectedDatabaseID };
}
else
if (operation == "destroy" && options)
{
return {
databaseID: selectedDatabaseID,
pkey: options.ID,
userIDParam: selectedUserID
};
}
else
if (operation == "create" && options) {
return {ipAddress: options.IpAddress ,
status: options.Status ,
lockedUntil: kendo.toString(options.LockedUntil, 'yyyy/MM/dd' ),
pkey: options.ID,
userIDParam: selectedUserID,
databaseID: selectedDatabaseID };
}
else
{
options.databaseID = selectedDatabaseID;
options.userID = selectedUserID;
return options;
}
}
},
schema: {
model: {
id: "ID",
fields: {
IpAddress: { type: "string" },
Status: { type: "string" },
LockedUntil: { type: "date" }
}
},
data: function (data) {
return data.Items;
},
total: function (data) {
return data.TotalCount;
}
}
});
My controllers are:
public object UpdateIP(int databaseID, long pkey, string status, string lockedUntil, string ipAddress)
{
var database = [...];
DynamicDataRepository repository = [...];
string query = "...";
repository.ExecuteNonQuery(query);
return new HttpResponseMessage(HttpStatusCode.OK);
}
public object DeleteIP(int databaseID, long pkey, int? userIDParam)
{
var database = [...];
DynamicDataRepository repository = [...];
string query = "...";
repository.ExecuteNonQuery(query);
return new HttpResponseMessage(HttpStatusCode.OK);
}
public object CreateIP(int databaseID, long? pkey, string status, string lockedUntil, string ipAddress, int? userIDParam)
{
var database = [...];
DynamicDataRepository repository = [...];
string query = "...";
repository.ExecuteNonQuery(query);
return new HttpResponseMessage(HttpStatusCode.OK);
}
Do you have any ideea? where I've done something wrong? thanks in advance. P.S. the queries in the controllers work fine.
I fixed the problem, followed OnaBai's suggestion of returning the Updated/Created entity, and in the case of a Delete I returned the ID of the deleted entry.
public object UpdateIP(int databaseID, long pkey, string status, string lockedUntil, string ipAddress)
{
var database = [...];
DynamicDataRepository repository = [...];
string query = [...];
IPList updatedIP = new IPList { ID = pkey, IpAddress = ipAddress, Status = status, LockedUntil = DateTime.Today };
return Json(updatedIP, JsonRequestBehavior.AllowGet);
// return new HttpResponseMessage(HttpStatusCode.OK);
}
Only one mention: in the case of a CREATE, the method didn't seem to work so what I did is in the .complete event of the CREATE operation I did a ipGrid.dataSource.read();
ipGrid.refresh(); - so the operation doesn't repeat itself. ( I read that in this case there might be problem with the model definition - setting the ID field - but I did set that one). Many thanks to OnaBai

Resources