Telerik MVC Grid in Razor view, GridCommand not populating - asp.net-mvc-3

I have a telerik mvc grid in a Razor view. I am using custom server binding. My issue is that on paging and sorting the GridCommand object properties "Page", "PageSize" & "SortDescriptors" are not getting the correct value. The funny thing is that the exact same code works for an aspx view. Since this is a new view, I have started using "Razor".
My view is -
#(Html.Telerik().Grid((IEnumerable<Mitek.MobileImaging.AdminSite.Models.ImagingTransactionModel>)ViewData["DeficientGridView"])
.Name("DeficientImagesGrid")
.DataBinding(databinding => databinding.Server()
.Select("ViewDeficientImages", "SuperAdmin", new { orgId = ViewData["OrgId"], beginDate = ViewData["BeginDate"], endDate = ViewData["EndDate"], searchString = ViewData["SearchString"] }))
.DataKeys(keys => keys.Add(o => o.TranId))
.EnableCustomBinding(true)
.BindTo((IEnumerable<Mitek.MobileImaging.AdminSite.Models.ImagingTransactionModel>)ViewData["DeficientGridView"])
.Columns(
columns =>
{
columns.Template(
#<text>
<a href="#Url.Action("DeficientImageDetails", "SuperAdmin", new { id = item.TranId }) ">
<img alt="Deficient Image Details" src= "#Url.Content("~/Content/ImagesUI/detail_icon.gif")" style="border:0px" /></a>
</text>
).Title("Actions").Width(75);
columns.Bound(o => o.TranId).Hidden(true);
columns.Bound(o => o.user_email).Title("User Email").Width(250);
columns.Bound(o => o.xml_config_name).Title("Job File").Width(200);
columns.Bound(o => o.datetime_created).Title("Date Created").Format("{0:MM/dd/yyyy}").Width(200);
columns.Bound(o => o.short_note).Title("Note").Width(200);
columns.Bound(o => o.iqa_code).Title("IQA Code").Width(200);
}).HtmlAttributes(new { style = " font-family:arial; font-size: .9em; " })
.Sortable()
.Pageable(paging => paging.Position(GridPagerPosition.Bottom)
.Style(GridPagerStyles.NextPreviousAndNumeric)
.Total((int)ViewData["DeficientImagesCount"])
.PageSize(25))
)
The controller looks like
[GridAction(GridName = "DeficientGridView")]
public ActionResult ViewDeficientImages(DeficientImagesViewModel model, GridCommand command, string button)
{
//Some Code......;
GridCommand myCommand = new GridCommand() { PageSize = 25 };
}
The command object never has any values for command.Page, command.SortDescriptors at the time of paging or sorting. Please note that the exact same code works in a asps page.
Please help.
Thanks,
SDD

Can you check if it has to do with [GridAction(GridName = "DeficientGridView"] attribute and your grid name being different.Name("DeficientImagesGrid") ?

You have to change [GridAction(EnableCustomBinding = true, GridName = "DeficientImagesGrid")] to this. I have the same problem today and i found this is working. If you don't specify the GridName then you will not get GridCommand.
gridCommand is NOT populated when the query string parameters are QueueGrid-size=2&QueueGrid-page=3
gridCommand is populated when the query string parameters are size=2&page=3

Related

Kendo Grid: Toolbar template issue

I have a grid that lists Road information and want a Toolbar Template that will allow me to filter the roads by choosing a Concession from a DropDownList. Something like this
My code:
CSHTML
<div id="datagrid">
#(Html.Kendo().Grid<SustIMS.Models.RoadModel>()
.Name("datagrid_Roads")
.Columns(columns =>
{
columns.Bound(r => r.RoadCode).Title(ViewBag.lblCode).Width(140);
columns.Bound(r => r.RoadType).Title(ViewBag.RoadType).Width(140);
columns.Bound(r => r.RoadMediumDescription).Title(ViewBag.lblDescription);
columns.Bound(r => r.ConcessionCode).Title("CCode").Hidden();
columns.Bound(r => r.ConcessionMediumDescription).Hidden().Title(ViewBag.Concession);
})
.ToolBar(toolbar =>
{
toolbar.Template(#<text>
<div class="toolbar">
<label class="category-label" for="category">Concessão:</label>
#(Html.Kendo().DropDownList()
.Name("concessions")
.OptionLabel("All")
.DataTextField("ConcessionMediumDescription")
.DataValueField("CCode")
.AutoBind(false)
.Events(e => e.Change("concessionChange"))
.DataSource(ds =>
{
ds.Read("ConcessionFiltering", "MasterData");
})
)
</div>
</text>);
})
.HtmlAttributes(new { style = "height: 534px;" })
...
)
)
</div>
<script type="text/javascript">
function concessionChange() {
var value = this.value(),
grid = $("#datagrid_Roads").data("kendoGrid");
if (value) {
grid.dataSource.filter({ field: "ConcessionMediumDescription", operator: "eq", value: value });
} else {
grid.dataSource.filter({});
}
}
Controller
public ActionResult ConcessionFiltering()
{
ConcessionModel cm = new ConcessionModel();
var aux = cm.getConcessions();
return Json(aux.concessions.Select(c => c.concession.mediumDescription).Distinct(), JsonRequestBehavior.AllowGet);
}
This is the current result:
The list is filled with the word "undefined" 16 times, which is the number of concessions I currently have. When I select one of the undefined options, it shows the actual name of the concession, refreshes the grid but doesn't filter it.
I want the list to show the concession names and to filter the grid by concession as I select one of them. What am I missing?
change this
return Json(aux.concessions.Select(c => c.concession.mediumDescription).Distinct(), hJsonRequestBehavior.AllowGet);
to
return Json(aux.concessions.Select(c => new ConcessionModel { Description = c.concession.mediumDescription }).Distinct(), JsonRequestBehavior.AllowGet);
First, double check what Json you are returning from the controller method. It looks like your ConcessionMediumDescriptions may have no data in them.
Second, it looks like, in your controller, that you are returning a list of "ConcessionMediumDescription" data objects.
I am guessing it looks like this...
{ConcessionMediumDescription: {
CCode: 'mycode',
...
}
}
You may consider returning a title field as a part of this Json and to use that for the text field of your dropdown. This is just me guessing from what you are returning in that controller.
Ideal Json would be somting like this...
[{
{{id: 'id1'},{text: 'text1'}},
{{id: 'id2'},{text: 'text2'}}
}]
And you defind your dropdown as such.
.DataTextField("text")
.DataValueField("id")
You have to do json return line like this.
return Json(aux.concessions.Select(c => new { Value = c.concession.DATAVALUE, Text = c.concession.DATATEXT }), JsonRequestBehavior.AllowGet);
Just change DATAVALUE and DATATEXT

pass view data to custom editor in kendo grid

I'm looking at an example form the demo website of kendo
http://demos.kendoui.com/web/grid/editing-custom.html
In the asp mvc code sample there is absolutely no reference to ViewData["categories"] from the controller.
Which black magic is it using to get this data in a dropdownlist in the editor?
here as shown in below section they are providing datasource path direct to database and it fetches the value from the database so no magic there everything is using basic code laungage
dataSource: {
type: "odata",
transport: {
read: "http://demos.kendoui.com/service/Northwind.svc/Categories"
}
}
and for MVC
var categories = dataContext.Categories
.Select(c => new ClientCategoryViewModel {
CategoryID = c.CategoryID,
CategoryName = c.CategoryName
})
.OrderBy(e => e.CategoryName);
ViewData["categories"] = categories;
ViewData["defaultCategory"] = categories.First();
and for MVC view :-
.Model(model =>
{
model.Id(p => p.ProductID);
model.Field(p => p.ProductID).Editable(false);
model.Field(p => p.Category).DefaultValue(
ViewData["defaultCategory"] as Kendo.Mvc.Examples.Models.ClientCategoryViewModel);
})

select Kendo ui grid row from controller

My first problem is : I use kendo grid with Single Select mode and I need when view loaded for the first time, the first row is selected, in other words, i want to select the first kendo grid row programatically.
moreover other problem is i insert radiobutton column in that grid , and i want synchronize
radiobutton select with row select , in other words, i want that when user select row,it causes it's radiobutton Selected
Please help me
tnx
this is the code:
#(Html.Kendo().Grid<CommonData.Domain.LegalEntityPhone>()
.Name("SMSGrid")
.HtmlAttributes(new { style = "width:800px;" })
.Selectable(selectable =>
selectable.Mode(GridSelectionMode.Single).Type(GridSelectionType.Row))
.Columns(columns =>
{
columns.Bound(c => c.Id)
.Title(" ")
.ClientTemplate(" <input type='radio' id='Approve' name='chkApprove' />");
columns.Bound(c => c.Number)
.Title("Destination")
.HeaderHtmlAttributes(new { style = "text-align: center;" })
.HtmlAttributes(new { style = "text-align: center; });
columns.Bound(c => c.CityCode)
.Title("City Code")
.Width(30)
.HeaderHtmlAttributes(new { style = "text-align: center" })
.HtmlAttributes(new { style = "text-align:center;width:30px" });
columns.Command(command => { command.Edit(); }).Width(150);
})
.Editable(editable => editable.Mode(GridEditMode.InLine))
.Events(events => events.Change("OnChange"))
.DataSource(dataSource => dataSource
.Ajax()
.Model(model =>
{
model.Id(p => p.Id);
model.Field(p => p.Id).Editable(false);
})
.Read(read => read.Action("LegalEntityPhoneInfo_Read", "Message"))
.Update(update => update.Action("LegalEntityPhoneInfo_Update", "Message"))
)
)
There is no such thing as making the row selected in the controller because the Grid is all created on the client. You can use the dataBound event to make the first row selected.
e.g.
$(function(){
$('#GridName').data().kendoGrid.bind('dataBound',function(e){
this.select(this.tbody.find('>tr:first'));
})
})
Or use one instead of bind to make the row selected only when the page is loaded, not each time when the Grid is rebound - sort,filter, etc. Check documentation for more info.
If you are unfamiliar with jQuery, I highly recommend you take an online free tutorial from http://jqueryair.com/.
Assuming your project is referencing the jQuery script in your _Layout page, all you should have to do is add an Event handler for Databound to the grid:
.Events(events => events.DataBound("Grid_Databound"))
Then just paste this script onto the page:
<script>
function Grid_Databound() {
var grid = $("#MyGridName").data("kendoGrid");
row = grid.tbody.find(">tr:not(.k-grouping-row)").eq(0);
grid.select(row);
}
</script>
I'm sure the same script that zeinad added would work as well, always more than one way to skin a cat. As far as making the radio button show selected if the row is selected, I think if you watched the tutorial I mentioned, you should be able to figure it out. Post back if you need more help.

Binding a grid to a drop down list

I have a grid that I want to show depending on the result of the drop down list. I can't seem to be able to send the values to the select("controller", "action", data) method. How can I do that? I can't get my javascript to handle it.
This is the drop down list
<select id="workoutType" onchange="changed(value)">
#{ foreach (var type in Model.WorkoutTypes)
{
<option value="#type"> #type </option>
}
}
</select>
and here is the grid
#(Html.Telerik().Grid(Model.Approvers)
.Name("Orders")
.DataBinding(dataBinding => dataBinding
//Ajax binding
.Ajax()
//The action method which will return JSON
.Select("__AjaxBinding", "AssetResearch", new { workoutType = ViewData["dropDownValue"] })
)
.Columns(columns =>
{
columns.Bound(o => o.InvestorName).Width(125);
columns.Bound(o => o.ApproverType).Title("Type").Width(100);
columns.Bound(o => o.Email).Title("E-mail Address");
})
.ClientEvents(events => events
.OnDataBinding("onDataBinding")
)
.Pageable()
.Sortable()
)
I tried using Viewbag and sadly I can't seem to pull it off.
$(document).ready(function() {
$('#workoutType').change(function(){
//bind your data here
var data = $(this).value;
// pass into your C# stuff here
});
});
Would something like this work?
this is not the right way to achieve it because the RouteValue cannot be set on the server (when you are rendering the Grid)
One way to achieve it is to use the change event of the DropDOwnList which Phonixblade9 mentioned to make the Grid perform request and fetch its data from the server. This could be achieved through the ajaxRequest method of the Grid.
Here is what I mean:
$(document).ready(function() {
$('#workoutType').change(function(){
var data = $(this).value;
var gridClientObject = $('#Orders').data().tGrid;
gridClientObject.ajaxRequest({workoutType :data});// do not forget to name the parameter in the action again method again 'workoutType'
});
});

Bound column to a list and loop...Is it possible at all?

I'm a novice Telerik Grid user and was wondering if it is a possibility to use Telerik Grid such that I bound one column to a string array and then somehow loop through it to show the array items as list.
StoreViewModel:(One store can have multiple displays)
public string Name { get; set; }
public string[] StoreDisplays { get; set; }
Controller:
private IQueryable<StoreViewModel> GetRetailers()
{
var stores = from sg in db.Store
select new RetailerViewModel
{
Name = sg.sg_Name,
Name = sg.sg_Name,
StoreDisplays = ( from ca in db.Categories.Where(item => item.c_ParentId == null)
join sd in db.StoreDisplays.Where(item => item.sd_StoreGroupId == sg.sg_Id)
on ca.c_Id equals sd.sd_CategoryId into gj
from subpet in gj.DefaultIfEmpty()
select (ca.c_Name)).ToArray<string>()
};
return stores;
}
Index.aspx
<%= Html.Telerik().Grid<StoreLocatorBackOffice.Models.RetailerViewModel>(Model) <br/>
.Name("Grid")
.Columns(columns =>
{
columns.Bound(sg => sg.Name)
columns.Bound(sg => sg.StoreDisplays);
})
.DataBinding(dataBinding => dataBinding
.Ajax()
.Select("_Index", "Retailer", true)
)
.Scrollable(scrolling => scrolling.Enabled(false))
.Sortable(sorting => sorting
.OrderBy(sortOrder => sortOrder.Add(p => p.Name).Ascending()))
.Pageable(settings => settings.PageSize((int)ViewData["pageSize"]))
.Filterable(filtering => filtering.Enabled(true))
.Footer(true)
%>
Currently it Displays like this.
Name Store Display
Store#1 Display#1Display#2Display#6
Store#2 Display#3Display#9
And want to some how show it as follows.
Name Store Display
Store#1 Display#1
Display#2
Display#6
Store#2 Display#3
Display#9
Instead of:
columns.Bound(sg => sg.StoreDisplays);
You should bind using a template. That template can be whatever you want, (even another grid).
Here's a template that will put an image in:
columns.Template(c => {
%>
<img
alt="<%= c.CustomerID %>"
src="<%= Url.Content("~/Content/Grid/Customers/" + c.CustomerID + ".jpg") %>"
/>
<%
});
Changing that template to display a list should be simple.
Look here for more info.
I would use HTML tags in to make data to spread vertically
For example
StoreDisplays = "
<ul>
<li>Display#1</li>
<li>Display#2</li>
<li>Display#3</li>
</ul>";
.Columns(columns =>
{
columns.Bound(o => o.StoreDisplays).ClientTemplate("<#= StoreDisplays #>");
}

Resources