I want to add grouping to my jqGrid. I have a simple model:
public class ViolationViewModel
{
[JqGridColumnFormatter(JqGridColumnPredefinedFormatters.Date, SourceFormat = "d.m.Y H:i:s", OutputFormat = "d.m.Y H:i")]
public DateTime FixationTime { get; set; }
public string OrderNumber { get; set; }
public string ViolationType { get; set; }
}
This is code in a view:
#{
var grid = new JqGridHelper<ViolationViewModel>("myGrid",
dataType: JqGridDataTypes.Json,
methodType: JqGridMethodTypes.Post,
pager: true,
sortingName: "ViolationType",
sortingOrder: JqGridSortingOrders.Asc,
url: Url.Action("Violation", "Cabinet"),
viewRecords: true,
rowsList: new List<int>() { 10, 20, 30, 50, 100 },
loadOnce: true,
multiSelect: true,
autoWidth: true,
groupingEnabled: true,
groupingView: new JqGridGroupingView { ColumnShow = new[] { false }, Fields = new[] { "ViolationType" }, DataSorted = true},
).FilterToolbar(new JqGridFilterToolbarOptions() { StringResult = true })
.Navigator(new JqGridNavigatorOptions() { Add = false, Delete = false, Edit = false, View = false, Refresh = false, Search = false });
}
I have 16 records, 15 records with the same ViolationType, 1 record have other value .
The problem with that jqGrid create three (must be two) groups, but there are two groups have the same caption. But when I click on any column (change sort) then all works fine and I have two groups.
Where is a problem?
One more question: in the rowList option I have the first value as 10. But when my grid is loaded default value is 20. How to setup it to first value?
You have set DataSorted to true. In this case the data from the initial request should be already properly sorted (by 'ViolationType') on the server side and returned in proper order.
For the second part of your question, just set rowsNumber to 10 for intial value:
#{
var grid = new JqGridHelper<ViolationViewModel>("myGrid",
dataType: JqGridDataTypes.Json,
methodType: JqGridMethodTypes.Post,
pager: true,
sortingName: "ViolationType",
sortingOrder: JqGridSortingOrders.Asc,
url: Url.Action("Violation", "Cabinet"),
viewRecords: true,
rowsList: new List<int>() { 10, 20, 30, 50, 100 },
rowsNumber: 10,
loadOnce: true,
multiSelect: true,
autoWidth: true,
groupingEnabled: true,
groupingView: new JqGridGroupingView { ColumnShow = new[] { false }, Fields = new[] { "ViolationType" }, DataSorted = true},
)
.FilterToolbar(new JqGridFilterToolbarOptions() { StringResult = true })
.Navigator(new JqGridNavigatorOptions() { Add = false, Delete = false, Edit = false, View = false, Refresh = false, Search = false });
}
Related
I am trying to implement server side filtering for a Kendo UI grid (client only). I am not sure how to pass the filter operator and value entered on the filter box. I was able to implement server paging and want the filtering to work alongside the server paging, i.e. show page 2 of 5 items of filtered rows. I saw some example of binding the request to "DataSourceRequest" object but we do not have licence for the server side Kendo UI and have to achieve it using the client side changes only.
Here is my jQuery code:
var page = 1;
var pageSize = 5;
var title = "test";
var selectWork = function (e) {
alert("selected");
};
$("#selectWorkGrid").empty();
$("#selectWorkGrid").kendoGrid({
dataSource:
{
transport: {
read: {
url: "http://example.com/" + "work/SearchWorkJ?worktitle=" + title,
dataType: "json",
contentType: "application/json",
data: {
page: page,
pageSize: pageSize
}
},
serverFiltering: true,
parameterMap: function (data, type) {
if (type == "read") {
return {
page: data.page,
pageSize: data.pageSize
}
}
}
},
schema: {
model: {
id: "workId",
fields: {
workId: { type: "number" },
workTitle: { type: "string" },
writers: { type: "string" },
durationInMmSs: { type: "string" }
}
},
data: "data",
total: "total"
},
pageSize: pageSize,
serverPaging: true,
serverFiltering: true
},
sortable: true,
resizable: true,
columnMenu: false,
filterable: {
mode: "row",
extra: false,
operators: {
string: {
startswith: "Starts with",
eq: "Is equal to",
neq: "Is not equal to"
}
}
},
noRecords: {
template: "No results available."
},
pageable: {
numeric: false,
refresh: true,
buttonCount: 15
},
scrollable: false,
columns: [
{
field: "workTitle",
title: "Title",
template: "#=workTitle#"
},
{
field: "writers",
title: "Writers",
filterable: false,
template: "${writers == null ? '':writers}",
width: 300
},
{
field: "durationInMmSs",
title: "Duration",
filterable: false,
headerAttributes: { style: "text-align:right;" },
attributes: { style: "text-align:right;" },
width: 80
},
{ command: { text: "Select", click: selectWork }, title: "", width: 60 }
]
});
Controller action returning json:
public ContentResult SearchWorkJ(string workTitle, int page = 0, int pageSize = 0)
{
var worksJson = "";
var works = WorkService.SearchWork(workTitle, page, pageSize);
if (works != null)
{
// Set total to upto current record + 1 so that next button works in kendo
int totalCount = page * pageSize + 1;
var sortedWorks = new List<WorkViewModel>();
sortedWorks.AddRange(works.Select(w => new WorkViewModel
{
WorkId = w.WorkId,
WorkTitle = w.WorkTitle,
Writers = w.Writers,
DurationInMmSs = w.Duration
}).OrderBy(w => w.WorkTitle));
worksJson = JsonConvert.SerializeObject(new { total = totalCount, data = sortedWorks });
}
return new ContentResult { Content = worksJson, ContentType = "application/json" };
}
If you look at this
https://dojo.telerik.com/EhUNUwOr
<div id="my-grid"></div>
<script>
$('#my-grid').kendoGrid({
dataSource: {
serverFiltering: true,
serverSorting: true,
serverPaging: true,
pageSize: 5,
transport: {
read: function(options) {
$.ajax({
url: '/yourapi',
contentType: 'application/json',
dataType: 'json',
type: 'POST',
data: JSON.stringify(options.data),
success: function(result) {
options.success(result);
}
})
}
},
schema: {
id: 'Id',
data: 'Data',
total: 'Total',
errors: 'Errors',
fields: [
{ field: 'Id', type: 'number' },
{ field: 'FirstName', type: 'string' },
{ field: 'LastName', type: 'string' }
]
},
filter: {
filters: [{ field: 'FirstName', operator: 'eq', value: 'David' }]
}
},
});
</script>
This will send
{"take":5,"skip":0,"page":1,"pageSize":5,"filter":{"filters":[{"field":"FirstName","operator":"eq","value":"David"}]}}
to your server / api
now if you have a model that shares this structure you can respond in the following format
{
"Data" : <your array of models>,
"Total" : the number of models that fits your filter regardless of the filter, this helps kendo grid knowing how many pages there is for the pager.,
"Errors" : is mostely used for create and update so just return null
}
From here its a bonus to the answer above.
I noticed you are using CSharp so you have two options to apply create dynamic queries from Queryable.
use a library I open sourced
https://github.com/PoweredSoft/DynamicLinq
which is available on Nuget https://www.nuget.org/packages/PoweredSoft.DynamicLinq/
There is an example you can look at on git hub.
You'll have to adapt the code around but it should get you started.
https://github.com/PoweredSoft/DynamicLinq#how-it-can-be-used-in-a-web-api
[HttpGet][Route("FindClients")]
public IHttpActionResult FindClients(string filterField = null, string filterValue = null,
string sortProperty = "Id", int? page = null, int pageSize = 50)
{
var ctx = new MyDbContext();
var query = ctx.Clients.AsQueryable();
if (!string.IsNullOrEmpty(filterField) && !string.IsNullOrEmpty(filterValue))
query = query.Query(t => t.Contains(filterField, filterValue)).OrderBy(sortProperty);
// count.
var clientCount = query.Count();
int? pages = null;
if (page.HasValue && pageSize > 0)
{
if (clientCount == 0)
pages = 0;
else
pages = clientCount / pageSize + (clientCount % pageSize != 0 ? 1 : 0);
}
if (page.HasValue)
query = query.Skip((page.Value-1) * pageSize).Take(pageSize);
var clients = query.ToList();
return Ok(new
{
total = clientCount,
pages = pages,
data = clients
});
}
An alternative is using
https://weblogs.asp.net/scottgu/dynamic-linq-part-1-using-the-linq-dynamic-query-library
I want to show Customer table's data of nopcommerce in admin page.
i did write a plugin for that and receive data in controller but in view i have a problem and show me error happened message.
here is my controller code:
public class UserDetailsController : BasePluginController
{
private ICustomerService _UserDetail;
public UserDetailsController(ICustomerService UserDetail)
{
_UserDetail = UserDetail;
}
public ActionResult Manage()
{
return View();
}
[HttpPost]
public ActionResult GetUsers(DataSourceRequest userDetail)
{
var details = _UserDetail.GetAllCustomers();
var gridModel = new DataSourceResult
{
Data = details,
Total = details.Count
};
return Json(gridModel);
}
}
And this is my view code:
#{
Layout = "~/Views/Shared/_AdminLayout.cshtml";
}
<script>
$(document).ready(function() {
$("#user-details").kendoGrid({
dataSource: {
type: "json",
transport: {
read: {
url: "#Html.Raw(Url.Action("GetUsers", "UserDetails"))",
type: "POST",
dataType: "json",
},
},
schema: {
data: "Data",
total: "Total",
errors: "Errors",
model: {
id: "Id",
}
},
requestEnd: function(e) {
if (e.type == "update") {
this.read();
}
},
error: function(e) {
display_kendoui_grid_error(e);
// Cancel the changes
this.cancelChanges();
},
serverPaging: true,
serverFiltering: true,
serverSorting: true
},
pageable: {
refresh: true,
numeric: false,
previousNext: false,
info:false
},
editable: {
confirmation: true,
mode: "inline"
},
scrollable: false,
columns: [
{
field: "Email",
title: "User Name",
width: 200
},
{
command: [
{
name: "edit",
text: "#T("Admin.Common.Edit")"
}, {
name: "destroy",
text: "#T("Admin.Common.Delete")"
}
],
width: 200
}
]
});
});
</script>
<div id="user-details"></div>
can anybody help me?
Change your GetUsers method on this way:
var details = _UserDetail.GetAllCustomers();
var gridModel = new DataSourceResult
{
Data=details.Select(x=>
{
return new UserDetail()
{
Email= x.Email
};
}),
Total = details.Count(),
};
return Json(gridModel);
I am using jqgrid to display,sort and filter records. At the moment, I have go the js code working, but I think there is something wrong with my controller code, that is not populating the grid. I can see only an empty blak jqgrid with the message "No records to display". Please let me know whats going wrong.
Here is my code:
Controller:
public JsonResult GetData(string sidx, string sord, int page, int rows)
{
int pageIndex = Convert.ToInt32(page) - 1;
int pagesize = rows;
var custList = db.Customers.Select(
c => new
{
c.ID,
c.Company,
c.FirstName,
c.EMail,
c.Status
});
int totalCustomers = custList.Count();
var totalPages = (int)Math.Ceiling((float)totalCustomers / (float)rows);
if(sord.ToUpper() == "DESC")
{
custList = custList.OrderByDescending(s => s.FirstName);
custList = custList.Skip(pageIndex * pagesize).Take(pagesize);
}
else
{
custList = custList.OrderBy(s => s.FirstName);
custList = custList.Skip(pageIndex * pagesize).Take(pagesize);
}
var jsonData = new
{
total = totalPages,
page,
customers = totalCustomers,
rows = custList
};
return Json(jsonData, JsonRequestBehavior.AllowGet);
}
Solved my problem. Dint know I would get the solution so quickly. I removed all the existing code from the controller and just added this:
public JsonResult GetData()
{
var customers = db.Customers.Select(m => new { ID = m.ID, Company = m.Company, FirstName = m.FirstName, Email = m.EMail, Status = m.Status }).ToList();
return Json(customers, JsonRequestBehavior.AllowGet);
}
This is all it needs,just two lines of code, rest of the functionalities, ie paging, sorting, filtering is already provided by jqwidgets:) Hope this helps someone who was facing a similar problem as mine.
The script is as follows:
var source =
{
//localdata: GetData(),
url: '/Client/GetData',
datatype: "json",
mtype: 'POST',
datafields: [
{ name: 'ID', type: 'int' },
{ name: 'Company' },
{ name: 'FirstName' },
{ name: 'EMail' },
{ name: 'Status' }
]
};
var dataAdapter = new $.jqx.dataAdapter(source);
// initialize jqxGrid
$("#jqxgrid").jqxGrid(
{
source: dataAdapter,
sortable: true,
filterable: true,
pageable: true,
columns: [
{ text: 'Client Id', datafield: 'ID', width: 200 },
{ text: 'Company', datafield: 'Company', width: 200 },
{ text: 'Username', datafield: 'FirstName', width: 180 },
{ text: 'Email', datafield: 'EMail', width: 100 },
{ text: 'Status', datafield: 'Status', width: 140 }
]
});
});
Hi im working on MVC project which uses jqgrid. I have an master grid . On click of the row and edit button im goin to CreateOrEdit view . In that view there is a one more grid -Detail grid.
In case of create: the fields for the master grid(labels and respective EditorFor) and the detail grid will be empty and once we populate everything(labels and respective EditorFor and the grid) and click on save .. it gets saved.. This much work is done. Now the problem..
While editing: I have to populate the detail grid depending on the Id selected in the master grid.
I've tried things like:
url:'#Url.Action("PDVs", "GetData", new { pdv = #Model.Details})'
data: JSON.stringify('#(Model.Details)')
and/or specifying the url as:
url:'/PDVs/GetData'
And in the Controller:
public JsonResult GetData(Details details)
So as to receive the model and query it and send the JsonResult back,
but the model details is getting null values for all the fields.
So can someone please give me any ideas of how to solve this problem?
Update: The Details Model is
using System;
using System.Collections.Generic;
using Repository.Pattern.Ef6;
namespace Abc.PROJECTS.Models
{
public partial class PDVDuration:Entity
{
public int PDVDurationId { get; set; }
public Nullable<int> PDVId { get; set; }
public Nullable<System.DateTime> DateFrom { get; set; }
public Nullable<System.DateTime> DateTo { get; set; }
public string Type { get; set; }
public string Remarks { get; set; }
public virtual PDV PDV { get; set; }
}
}
And this is my details grid:
jQuery("#DetailsGrid").jqGrid({
// url: '/PDVs/GetManintenance',
// datatype: 'json',
#*url:'#Url.Action("PDVs", "GetData", new { pdv = #Model.PDVDurations })',*#
mtype: 'GET',
//datatype: "local",
//data: mydata,
//data: JSON.pdv.PDVDuration,
// data:myGridComplete('#Model.PDVDurations'),
height: 100,
width: 900,
colNames: ['DateFrom', 'DateTo', 'Type', 'Remarks'],
colModel: [
{
name: 'DateFrom', index: 'DateFrom', width: 60, editable: true, sorttype: "date",
formatter: 'date',
formatoptions: {
srcformat: 'm/d/Y',
// newformat: 'd/m/Y '
//newformat: 'Y-m-d'
},
editoptions: { dataInit: initDateEdit, size: 14 },
},
{
name: 'DateTo', index: 'DateTo', width: 80, editable: true, sorttype: "date",
formatter: 'date',
formatoptions: {
srcformat: 'm/d/Y',
//newformat: 'd/m/Y'
},
editoptions: { dataInit: initDateEdit, size: 14 },
},
{
name: 'Type', width: 80, editable: true, formatter: "select",
edittype: "select", editoptions: { value: "Open:Open;Maintainance:Maintainance;Closed:Closed", defaultValue: "Open" },
},
{
name: 'Remarks', index: 'Remarks', width: 80, editable: true
}
,
],
#* data: JSON.stringify('#(Model.PDVDurations)'),*#
// data:JSON.stringify(viewModel),
//data:model,
//model:viewModel,
//data: JSON.parse(jsonData),
pager: "#PDVMPager",
loadonce: true,
sortname: 'Client',
ignoreCase: true,
sortorder: 'asc',
gridview: true,
autoencode: true,
rowNum: 10,
rowList: [5, 10, 20, 50],
caption: "Maintenance",
viewrecords: true,
editurl: "clientArray",
gridComplete:function myGridComplete(PDV)
{
return JSON.stringify('#(Model.PDVDurations)')
},
}).jqGrid("navGrid", "#PDVMPager", {}, editSettings, addSettings, {
multipleSearch: true,
overlay: false,
onClose: function () {
$("div#ui-datepicker-div.ui-datepicker").hide();
}
}).jqGrid("filterToolbar", { defaultSearch: "cn" });
});
I think you have problem with Url.Action method if you want url like you wrote you should flip params.
Anyway, i suppose you can try to write like this in your jqgrid init if you need whole model:
url: '#Url.Action("GetData", "PDVs")',
postData: '#Html.Raw(Json.Encode(Model))'
But if you need just some fields you can write like this:
url: '#Url.Action("GetData", "PDVs")',
postData:
{
PDVDurations: #Model.PDVDurations
}
But you should write different signature in controller method. Like this:
public JsonResult GetData(int PDVDurations)
I am facing this problem for quite a while now with the problem that I am unable to bind JSON data that my controller action is passing to the kendo UI Grid, there were few JavaScript issues before but now they are gone but still my grid is not showing any results:
In Model:
public object GetResult(string id)
{
var sqlCom = new SqlCommand("SELECT [No],[Desc],[Date],[Height],[Final] FROM [cr_form] WHERE [uId]=#id;", sqlConn);
sqlCom.Parameters.AddWithValue("#id", id);
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
JsonWriter jsonWriter = new JsonTextWriter(sw);
var rcrds = GETSQLRESULTS(sqlCom);
try
{
int i = 0;
if (rcrds != null || rcrds.HasRows)
{
//jsonWriter.WriteStartObject();
while (rcrds.Read())
{
jsonWriter.WriteStartObject(); //Changed
for (int j = 0; j < rcrds.FieldCount; j++)
{
jsonWriter.WritePropertyName(rcrds.GetName(j)); // column name
jsonWriter.WriteValue(rcrds.GetValue(j)); // value in column
}
i++;
jsonWriter.WriteEndObject(); //Changed
}
//jsonWriter.WriteEndObject();
}
}
catch (Exception ex) { }
return jsonWriter;
}
In Controller:
public ActionResult GetRecords()
{
var usrObj = new User();
var jsnRslt = usrObj.GetResult(Session["Id"].ToString());
//Till here jsnRslt contains this string: “{"No":null,"Desc":"asfasfasfasfasfasfasfasfasfasfasfasf","Date":"2013-03-27T00:00:00","Height":0,"Final":null,"No":null,"Desc":"etwetwetwetwet","Date":"2013-03-27T00:00:00","Height":0,"Final":0,"No":null,"Desc":"asfasfasfskfjklajsfkjasklfjklasjfklajsfkljaklsfjklasjfkljasfkljlasf","Date":"2013-03-27T00:00:00","Height":0,"Final":0,"No":null,"Desc":"askjfkajsfklaskjfkajsfklaskjfkajsfklaskjfkajsfklaskjfkajsfklaskjfkajsfklaskjfkajsfklaskjfkajsfklaskjfkajsfklaskjfkajsfklaskjfkajsfklaskjfkajsfkl","Date":"2013-03-27T00:00:00","Height":0,"Final":0,"No":null,"Desc":"safasfasfasfasfasf","Date":"2013-03-27T00:00:00","Height":0,"Final":0,"No":null,"Desc":"asfasf","Date":"2013-03-27T00:00:00","Height":0,"Final":0,"No":null,"Desc":"asfasfasf","Date":"2013-03-27T00:00:00","Height":2,"Final":0}”
//After Changes in the Model I am getting it in the required Array format:
//{"No":null,"Desc":"asfasfasfasfasfasfasfasfasfasfasfasf","Date":"2013-03-27T00:00:00","Height":0,"Final":null}
//{"No":null,"Desc":"etwetwetwetwet","Date":"2013-03-27T00:00:00","Height":0,"Final":0}
//{"No":null,"Des...
return Json(jsnRslt, JsonRequestBehavior.AllowGet);
}
In View:
<div>
<script type="text/javascript">
$(document).ready(function () {
$("#grid").kendoGrid({
dataSource: {
type: "json",
serverPaging: true,
pageSize: 5,
groupable: true,
selectable: "row",
transport: { read: { url: "Records", dataType: "json"} }
},
height: 400,
scrollable: true,
sortable: true,
filterable: true,
pageable: true,
columns: [
{ field: "No", title: " No" },
{ field: "Desc", title: "Description" },
{ field: "Date", title: "Date" },
{ field: "Height", title: "Height" },
{ field: "Final", title: "Final" }
],
dataBound: function () {
this.expandRow(this.tbody.find("tr.k-master-row").first());
}
});
});
</script>
</div>
But after all this all I can see is an empty grid. And no errors in JavaScript console.
Please help
The JSON that you return from the server should be array. You currently it seems that you are returning single objects with multiple fields that are the same.
Here is an example how the JSON should look like:
[{"No":null,"Desc":"asfasfasfasfasfasfasfasfasfasfasfasf","Date":"2013-03-27T00:00:00","Height":0,"Final":null},
{"No":null,"Desc":"etwetwetwetwet","Date":"2013-03-27T00:00:00","Height":0,"Final":0},
{"No":null,"Desc":"asfasfasfskfjklajsfkjasklfjklasjfklajsfkljaklsfjklasjfkljasfkljlasf","Date":"2013-03-27T00:00:00","Height":0,"Final":0}]
I think following code will be useful for you and let me know if you have any problem:
$('#gridName').kendoGrid({
dataSource: {
type: "odata",
transport: {
read: {
contentType: "application/json; charset=utf-8",
type: "POST",
url: 'YourURL'
}
},
pageSize: 10,
type: "json"
},
scrollable: true,
sortable: true,
resizable: true
});
Inside you dataSource set data.
data: #Html.Raw(Json.Encode(Model.RemoteObject)),
RemoteObject is you object containing all data.
First I check your tranport read URL. have you trace the controller if it fires the GetRecords command?
transport:
{
read: {
//if you don't use area then remove it
url: "#Url.Action("GetRecords", new { area = "YourAreaName", controller = "YourControllerName" })",
dataType: "json"
}
}
if it still doesn't fix your problem, then modify your Controller,
public ActionResult GetRecords([DataSourceRequest] DataSourceRequest request)
{
var usrObj = new User();
var jsnRslt = usrObj.GetResult(Session["Id"].ToString());
return Json(jsnRslt.ToDataSourceResult(request), JsonRequestBehavior.AllowGet);
}
here's the link to understand the Kendo's ToDataSourceResult