In an ASP.NET MVC application using for the first time jqGrid.
I have a menu, I call "employee" from the menu in the master page like this :
<script language="javascript" type="text/javascript">
$(document).ready(function() {
$(".mnuEmployee").click(function() {
$.post("/Employee/Index", null, function(data) {
$("#text").html(data);
});
});
});
</script>
In the controller, I have this :
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Index()
{
EmployeeModel model = new EmployeeModel();
model.List = _employeeService.List();
model.Languages = _languageService.List();
return View("Index", model);
}
In the View (Index.ascx), I have this :
<script type="text/javascript">
jQuery(document).ready(function() {
jQuery("#sandgrid").jqGrid({
url: '/Employee/MyGridData/',
datatype: 'json',
mtype: 'GET',
height: 255,
width: 600,
colNames: ['Index', 'Name', 'Code'],
colModel: [
{ name: 'item_id', index: 'item_id', width: 65 },
{ name: 'item', index: 'item', width: 150 },
{ name: 'item_cd', index: 'item_cd', width: 100}],
pager: jQuery('#sandgridp'),
rowNum: 10,
rowList: [5, 10, 20, 50],
sortname: 'item_id',
sortorder: "desc",
viewrecords: true,
caption: 'Liste des employés'
});
});
</script>
<table id="sandgrid" cellpadding="0" cellspacing="0"></table>
<div id="sandgridp" style="text-align:center;"></div>
The problem is in this last part (I think), I have all datas in my model, I'd like display employee list in a jqGrid and languages (and more are coming) in classic textbox, textarea, ... How can I use the "model.List" (IList) to show in the grid ?
Thanks,
What is the reason to show languages in textbox/textarea? Did you mean select? If so then look at http://www.trirand.com/jqgridwiki/doku.php?id=wiki:common_rules, for the "select" edit type. Note that you can have multiselect list.
If you just want to display languages, then do this in your model:
model.Languages = string.Join(_languageService.List().Select(x => x.Name).ToArray(), ",");
And then jqGrid will display your languages as a string, comma-separated.
But I'd suggest you to decide (since it's not clear from the Q):
how you want to display languages/list
do you want to edit them and how
Also take a look at custom formatters http://www.trirand.com/jqgridwiki/doku.php?id=wiki:custom_formatter, you can write a function to convert your languages list into anything you want, on input you get data, on output you return string with any HTML. Don't forget "unformatter" if you need to edit the cell value. For example, I use custom formatter to display checkbox images instead of true/false text.
I'm a little confused. You have your jqGrid set up to do an AJAX query for it's data as JSON so there's no need to include in in the Index view's model.
url: '/Employee/MyGridData/',
datatype: 'json',
To use the AJAX method your controller needs a MyGridData action.
[AcceptVerbs(HttpVerbs.Get)]
public JsonResult MyGridData ()
{
var list = _employeeService.List();
return Json(list);
}
Also, the name and index properties in the colModel must match the property names in your model.
Related
How to set columns dynamically in Kendo template for kendo grid.In my kendo grid,columns are subject to change dynamically based on user preference.How to dynamically create Kendo Template?I am using Kendo JavaScript,I can switch to Kendo MVC if same thing i can achieve there.Is there any other approach to achieve this?
<script id="rowTemplate" type="text/x-kendo-template">
<tr class="k-master-row">
<td>
<div>#=column1#</div>
</td>
<td><span class="mydesign" title="column2#"</span></td>
<td>#column3#</td>
<td>#=column4#</td>
</tr>
</script>
Edit : In Kendo grid, we are dynamically setting the columns. Now issue is how do we set the dynamic width for content table and the header table. If it exceeds the max width how do we enable the horizontal scroll bar. Is there any approach to achieve this?
I'm not using kendo for MVC but I can still explain how to do this using regular kendo functions.
Basically, you can create a new kendo template instance by passing an html string to kendo.template. Then you can assign the new template instance to the grid's rowTemplate (or altRowTemplate) then call dataSource.read() to force a grid refresh.
You can generate your own html string or update an existing template in your page then use the jquery's html() to convert it into a string.
Ex:
var htmlTemplate = '';
if (userPreferences.likeRed) {
htmlTemplate ='<tr class="k-master-row"><td style="background-color:red">#column1#</td></tr>'
} else {
htmlTemplate ='<tr class="k-master-row"><td style="background-color:green">#column1#</td></tr>'
}
$("#grid").data("kendoGrid").rowTemplate = kendo.template(htmlTemplate);
$("#grid").data("kendoGrid").dataSource.read();
In order to format Kendo Grid column value with conditionally chosen action you can use one of the suitable examples below. For more information: How Do I Have Conditional Logic in a Column Client Template?
Here are some of the usage samples below. You can easily generate different templates with the help of this approach.
UI for Javascript:
{
field: "EmployeeName", type: "string", width: "55px", title: "Employee Name",
template: "#= GetEditTemplate(data) #"
}
UI for MVC:
...
columns.Bound(t => t.EmployeeName)
.Title("Status Name")
.Template(#<text></text>)
.ClientTemplate("#= GetEditTemplate(data)#")
.Width("55px");
...
Example I: In this example, Model is passed to the Javascript method by using "data" property and the model property is used in the "if" condition.
<script>
//Change the color of the cell value according to the given condition
function GetEditTemplate(data) {
var html;
if (data.StatusID == 1) {
html = kendo.format(
//"<a class=\"k-button\" href='" + '#Url.Action("Edit1", "Controller")' + "/{0}" + " '>Edit</a> ",
"<span class='text-success'>" +
data.EmployeeName
+ "</span>"
);
}
else {
html = kendo.format(
//"<a class=\"k-button\" href='" + '#Url.Action("Edit2", "Controller")' + "/{0}" + " '>Edit</a> ",
"<span class='text-danger'>Cancel</span>"
);
}
return html;
}
</script>
Example II:
<script>
function Getvalue(value) {
// console.log(value);
if (value && value != null && value.indexOf("A") == 0)
return "<b style='color:red'>" + value + "</b>";
else
return "";
}
$(document).ready(function () {
$("#grid").kendoGrid({
dataSource: localDataSource,
columns: [
{
field: "FirstName",
title: "First Name", template: '#=Getvalue(FirstName)#'
}
],
});
});
</script>
Hope this helps...
This will work in ASP.NET MVC/Razor, if you prepare a collection of the dynamic columns definitions in advance, then put them in the view model for the cshtml. Then loop through the collection and insert the field name that will match the datasource, header title, desired width, etc...
$("#grid-quick").kendoGrid({
pageable: {
pageSizes: [10, 20, 50, 100]
},
sortable: { mode: "multiple" },
columns: [
#{
foreach (var col in Model.Columns)
{
#:{ field: "#col.Name.Replace(".","_")", width: "#col.Width" + "px" },
}
}
],
filterable: false,
dataSource: {
serverPaging: true,
serverSorting: true,
pageSize: 20,
type: 'aspnetmvc-ajax',
schema: {
data: "Data",
total: "Total",
model: {
fields: {
#{
foreach (var col in Model.Columns)
{
#: "#col.Name.Replace(".","_")" : { type: "string" },
}
}
}
}
},
transport: {
read: {
url: oVariables.baseURL + "Query/DynamicResults",
dataType: "json",
type: "post"
}
}
}
});
I'm attempting to filter my results based on a drop down selected value. All the filtering and everything is working, I'm just struggling to get my view to update with the results. I'm leaving out some brackets and other irrelevant code Here is what I have:
public ViewResult Index()
{
-- this effectively returns all Invoices no matter what date --
var data = new UserBAL().GetInvoice(date);
return View(data);
}
My Jquery and Ajax is :
$(document).ready(function () {
$("[name='DDLItems']").change(function () {
var selection = $("[name='DDLItems']").val();
var dataToSend = {
//variable to hold selection?
idDate: selection
};
$.ajax({
type: "POST",
url: "Invoice/FilterInvoice",
data: dataToSend,
success: function (data) {
$("#Index").html(data);
}
[HttpPost] // Selected DDL value
public ActionResult FilterInvoice(int idDate)
{
switch (idDate)
{
case 0:
date = DateTime.Parse("01-01-1754");
break;
case 3:
date = DateTime.Now.AddMonths(-12);
break;
}
//var data is returning my expected results
var data = new UserBAL().GetInvoice(date);
// I know this isn't right and needs to be changed
return View(data);
My ajax success function isn't doing anything either So it i'm guessing this needs some tweaking. Also Here's how I am displaying the table using table tags. Keep in mind I left some code out but everything important is here, and the only issue is rendering my filtered results back to the view,
#foreach (var item in Model) {
<tr><td>
#Html.DisplayFor(modelItem => item.Invoice_Number)
#Html.DisplayFor(modelItem => item.Amt_Total)
</td>
Instead of passing view you can return the partial view as string then in ajax success using jquery you can update the result :
Controller Logic:
[HttpPost]
public JsonResult FilterInvoice(int idDate)
{
.....
return Json((RenderRazorViewToString("YourViewName", data)), JsonRequestBehavior.AllowGet);
}
[NonAction]
public string RenderRazorViewToString(string viewName, object model)
{
ViewData.Model = model;
using (var sw = new StringWriter())
{
var viewResult = ViewEngines.Engines.FindPartialView(ControllerContext, viewName);
var viewContext = new ViewContext(ControllerContext, viewResult.View, ViewData, TempData, sw);
viewResult.View.Render(viewContext, sw);
viewResult.ViewEngine.ReleaseView(ControllerContext, viewResult.View);
return sw.GetStringBuilder().ToString();
}
}
Ajax call :
$.ajax({
//........
success: function (result) {
$("#Index").replaceWith(result);
}
});
Here's the answer if anyone else comes across this. This is what I ended up doing, the rows are getting filtered passed on the date parameter I'm passing to the URL of the function. Having the Grid populate inside the Ajax call also seemed like it was a problem so I had to take it out.
public JsonResult JqGrid(int idDate)
{
switch (idDate)
#region switch date
--Switch Statement--
#endregion
var invoices = new UserBAL().GetInvoice(date);
return Json(invoices, JsonRequestBehavior.AllowGet);
}
[HttpPost] // pretty much does nothing, used as a middle man for ajax call
public JsonResult JqGridz(int idDate)
{
switch (idDate)
#region switch date
--Switch Statement--
#endregion
var invoices = new UserBAL().GetInvoice(date);
return Json(invoices, JsonRequestBehavior.AllowGet);
}
Yes these two functions seem very redundant and they are. I don't know why my post wouldn't update data, but I needed to reload the grid each time and when I did that it would call the first function. So yea the post jqGridz is kinda of just a middle man.
Here's the jquery code I used
var dropdown
var Url = '/Invoice/JqGrid/?idDate=0'
$(document).ready(function () {
$("#jqgrid").jqGrid({
url: Url,
datatype: 'json',
mtype: 'GET', //insert data from the data object we created above
width: 500,
colNames: ['ID','Invoice #', 'Total Amount', 'Amount Due', 'Amount Paid', 'Due Date'], //define column names
colModel: [
{ name: 'InvoiceID', index: 'Invoice_Number', key: true, hidden: true, width: 50, align: 'left' },
{ name: 'Invoice_Number', index: 'Invoice_Number', width: 50, align: 'left'},
{ name: 'Amt_Total', index: 'Amt_Total', width: 50, align: 'left' },
{ name: 'Amt_Due', index: 'Amt_Due', width: 50, align: 'left' },
{ name: 'Amt_Paid', index: 'Amt_Paid', width: 50, align: 'left' },
{ name: 'Due_Date', index: 'Due_Date', formatter: "date", formatoptions: { "srcformat": "Y-m-d", newformat: "m/d/Y" }, width: 50, align: 'left' },
],
pager: jQuery('#pager'),
sortname: 'Invoice_Number',
viewrecords: false,
editable: true,
sortorder: "asc",
caption: "Invoices",
});
$("[name='DDLItems']").change(function () {
var selection = $(this).val();
dropdown = {
//holds selected value
idDate: selection
};
$.ajax({
type: "POST",
url: "Invoice/JqGridz",
data: dropdown,
async: false,
cache: false,
success: function (data) {
$("#jqgrid").setGridParam({ url: Url + selection})
$("#jqgrid").trigger('reloadGrid');
}
})
})
});
I would like to use JQ grid in my current MVC project but I'm running into quite a few problems trying to figure it out. I find the available documentation lacking if not missing and all the problems seem to focus on a single aspect such as getting data into the grid. Well I'm way beyond that point and I would love to see a fully functional example that does fetching data, sorting, paging, add, edit, delete and search all in one with MVC. Is there such an example anywhere on the web?
Furthermore I would like to know if I can use data annotations in conjunction with JQ grid add/edit? From what I read so far it seems that I have to define new validation rules within JQ Grid declaration and that rules that I established on the model are being ignored. Is there a way to use model rules during JQ Grid CRUD operations? I was thinking along the way of making my own jquery dialog popup with appropriate partial view loaded once a row is selected and add/edit button is clicked. however I cannot find JQ grid event which is raised when Add button is clicked. It seems to force you into using their auto generated modal popup form...
I'm not sure if all this makes any sense to any of you but any help would be appreciated. If anyone has a link to all JQ Grid events even that would be a big help... Thanks!
I just tested JQGrid and DataAnnotations on my underlying datasource and there does not appear to be any support (yet hopefully) for them.
As for the for the MVC part, are you looking to use the ASP.NET MVC Helpers provided by trirand.net? if so you can find a working example here:
http://www.trirand.net/aspnetmvc/grid/editrowinlineactionicons
-Brandon
you can try my Jq.Grid
already support for data annotation and simple searching
Razor View: Total CRUD Operation
#{
ViewBag.Title = "Home Page";
}
<table id="tbl"></table>
<div id="pager"></div>
#section scripts{
<link href="~/Content/Theme/ui.jqgrid.css" rel="stylesheet" />
<link href="~/Content/Theme/jquery-ui.min.css" rel="stylesheet" />
<script src="~/Scripts/jqGrid/jquery.jqGrid.js"></script>
<script src="~/Scripts/jqGrid/grid.inlinedit.js"></script>
<script src="~/Scripts/jqGrid/grid.locale-en.js"></script>
<script src="~/Scripts/jqGrid/jquery.sortable.js"></script>
<script>
$(function () {
var lastsel;
$("#tbl").jqGrid({
url: "/Home/GetData",
mtype: "Get",
datatype: "Json",
colNames: ["ID", "Name", "Address", "Mobile", "Salary"],
colModel: [
{ name: 'id', index: 'id', editable: false, align: 'center' },
{ name: 'name', index: 'name', editable: true },
{ name: 'address', index: 'address', editable: true },
{ name: 'mobile', index: 'mobile', editable: true },
{ name: 'salary', index: 'salary', editable: true }
],
loadonce: true,
pager: "#pager",
rowNum: 20,
height:"100%",
onSelectRow: function (id) {
if (id && id !== lastsel) {
$("#tbl").restoreRow(lastsel);
$("#tbl").editRow(id, true);
lastsel = id;
}
},
caption: "jqGrid",
editurl: "/Home/EditData",
viewrecords: true,
sortorder: "desc",
sortname: "id",
}).navGrid("#pager", { edit: false, add: false, del: true, refresh: false, search: false },
{},
{},
{
url: "/Home/DelData",
mtype: "Post",
delData: "row_id_s",
}).inlineNav("#pager", {
add: true,
addParams: {
addRowParams: {
url: "/Home/AddData",
mtype: "Post"
}
}
});
});
</script>
}
MVC Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using jqGrid_Exam2.Models;
using System.Data.Entity;
namespace jqGrid_Exam2.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
[HttpGet]
public ActionResult GetData()
{
DBcontext db = new DBcontext();
var data = db.EmployeeTbls.ToList<EmployeeTbl>();
return Json(data,JsonRequestBehavior.AllowGet);
}
[HttpPost]
public void EditData(EmployeeTbl emp)
{
DBcontext db = new DBcontext();
db.Entry(emp).State = EntityState.Modified;
db.SaveChanges();
}
[HttpPost]
public void AddData(EmployeeTbl emp)
{
DBcontext db = new DBcontext();
db.EmployeeTbls.Add(emp);
db.SaveChanges();
}
[HttpPost]
public void DelData(string id)
{
DBcontext db = new DBcontext();
EmployeeTbl emp = db.EmployeeTbls.Find(int.Parse(id));
db.EmployeeTbls.Remove(emp);
db.SaveChanges();
}
}
}
I am able to display my records on jqGrid however the paging is not working. I have 90 records in total and its always showing the first 10 records even though the page number did increase. I had checked the return values to jqGrid from my method and it did show a different set of records being sent to jqGrid but jqGrid is not able to display that new set of records.
Below is my code.
public JsonResult CheckReading(int page, int rows, string sidx, string sord)
{
IList<SamplerReading> Model =
(IList<SamplerReading>)Session["samplerReadingArray"];
int totalRecords = Model.Count + 1;
int pageSize = rows;
int pageIndex = Convert.ToInt32(page) - 1;
int totalPages = (int)Math.Ceiling((float)totalRecords / (float)pageSize);
string orderBy = string.Format("{0} {1}", sidx, sord);
var sales = Model.AsQueryable()
.OrderBy(orderBy) // Uses System.Linq.Dynamic library for sorting
.Skip(pageIndex * pageSize)
.Take(pageSize);
var jsonData = new
{
total = totalPages,
page = page,
records = totalRecords,
rows = (
from s in Model
select new
{
i = s.ReadingId,
cell = new string[] {
s.SamplingDate.ToShortDateString(),
s.Ph.ToString(),
s.Ec.ToString(),
s.Arsenic.ToString(),
s.Temperature.ToString(),
s.OilAndGrease.ToString(),
s.DepthToCollar.ToString()
}
}).ToArray()
};
return Json(jsonData);
}
where
<table id="list" cellpadding="0" cellspacing="0">
</table>
<div id="pager" style="text-align: center;">
</div>
and
<script type="text/javascript">
var gridimgpath = '/Scripts/jqgrid/themes/redmond/images';
var gridDataUrl = '/Shared/CheckReading';
jQuery("#list").jqGrid({
url: gridDataUrl,
datatype: "json",
mtype: 'GET',
colNames: ['Sampling Date', 'pH', 'EC', 'Arsenic', 'Temperature',
'Oil and Grease', 'Depth to Collar'],
colModel: [
{ name: 'SamplingDate', index: 'SamplingDate', width: 100, align: 'left'},
{ name: 'Ph', index: 'Ph', width: 30, align: 'left' },
{ name: 'Ec', index: 'EC', width: 30, align: 'left' },
{ name: 'Arsenic', index: 'Arsenic', width: 30, align: 'left' },
{ name: 'Temperature', index: 'Temperature', width: 30, align: 'left' },
{ name: 'Oil And Grease', index: 'OilAndGrease', width: 30, align:'left'},
{ name: 'Depth To Collar', index: 'DepthToCollar', width:30,align:'right'}
],
rowNum: 10,
rowList: [10, 20, 30],
imgpath: gridimgpath,
height: 'auto',
width: '900',
pager: jQuery('#pager'),
sortname: 'ReadingId',
viewrecords: true,
sortorder: "desc",
caption: "Sampler Readings",
edit: true
}).navGrid("#pager", { edit: true, add: false, del: false });
</script>
You code seems to me your code has some small errors. The most important which I see is that you should place all JavaScript code inside of jQuery(document).ready(function() {/* your code */}); handle.
The total or totalRecords should be equal to Model.Count and not Model.Count + 1.
The usage of Convert.ToInt32(page) is not needed. You can just use page direct.
You can calculate total or totalPages without usage of some float arithmetic: totalPages = (totalRecords + rows - 1) / rows. This will make the same rounding.
You should returns rows having id and not i. So you should replace i = s.ReadingId to id = s.ReadingId
The usage of sidx and sord directly without any checking I find dangerous. In the way you can allow SQL Injection. It is very easy to replace sord with for example
String.Compare (sord, "desc", StringComparison.Ordinal) == 0 ? "desc": "asc"
then you can be sure that you will use no hacks inside of sord. In the same way you can verify sidx as a property of SamplerReading. It seems to me that you can use .NET Reflection: typeof(SamplerReading).GetProperties(). Instead of this you can also verify that sidx is in the list (array) of following strings 'SamplingDate','Ph','EC','Arsenic','Temperature','OilAndGrease','DepthToCollar' and use no other value of sidx.
You should place all JavaScript code inside of jQuery(document).ready(function() {/* your code */}); handle.
From the jqGrid definition you could remove deprecated imgpath parameter and default property align: 'left' from the every column definition. There are also no parameter edit: true in jqGrid.
The HTML markup
can be reduce to
<table id="list"></table>
<div id="pager"></div>
You don't wrote which version of ASP.NET MVC you use. Probably 1.0 version. For MVC 2.0 you should use Json(jsonData, JsonRequestBehavior.AllowGet).
I recommend you verify in Fiddler of Firebug what will be send in the requests to the server and what will be send back. Moreover ids of all <tr> elements of the table must be the values of ReadingId which you send back. Verify also by setting breakpoints in the CheckReading function that the client get the response every time from the server and not from the local cache.
I have to get value from Jqgrid Selected row and populate one more grid with datas based on the selected value from the master grid. I dont want to use master detail or subgrdi in Jqgrid. Since I am using MVC, is there any way to populate the second jqgrid in one more view?
I am not able to get the column value on selected row to post it to the second grid.
here is my code
$(document).ready(function() {
$("#UBSImageList").jqGrid({
url: '<%= Url.Content("~/UpdateBatchStatus/UBSDataJson/") %>',
datatype: "json",
mtype: 'POST',
colNames: ['BatchImageName'],
colModel: [
{name:'BatchImageName', index:'BatchImageName', align: 'left', width: 40, editable: false ,sortable: true}
],
rowNum: 20,
rowList: [10, 20, 30, 50],
pager: jQuery('#UBSImagePager'),
viewrecords: true,
imgpath: '<%= Url.Content("~/Content/Scripts/themes/basic/images")%>',
sortname: 'BatchImageName',
sortorder: "asc",
autowidth: true,
caption: 'Client Payor Group',
height: 350
});
$('#UBSImageList').setGridParam({
onSelectRow: function(id) {
window.location = '/UpdateBatchStatus/Details?id=' + id;
}
});
}
You can get rows on server with the following code. From here you can check how to populate the second jqgrid.
<script type="text/javascript">
$(document).ready(function(){
var grid = jQuery("#Jqgrid1");
jQuery("#m1").click( function() {
var s;
var rowcells=new Array();
s = grid.getGridParam('selarrrow');
//alert(s);
if(s.length)
{
for(var i=0;i<s.length;i++)
{
var entirerow = jQuery("#Jqgrid1").jqGrid('getRowData',s[i]);
rowcells.push($.param(entirerow));
}
}
$.ajax({
url: "/jqSubGrid.aspx",
type: "POST",
data: rowcells.join('||'),
success: function(html) {
alert(html);
}
});
});
});
</script>
Get Selected rows