Suppress read action in kendo grid mvc - asp.net-mvc

How I can suppres read action in kendo grid mvc which depends on field in model which send to this grid?
For example I send false value and I dont call read action

As JamieD77 mentioned one of the ways to do this is to use the AutoBind option of the Grid (not the DataSource):
#(Html.Kendo().Grid<OrderViewModel>()
.Name("grid")
.AutoBind(Model.ShouldLoad)
Using the above approach however have some drawbacks - for example if the "Sortable" option of the Grid is enabled and the user try to sort the empty Grid, it will result in "Read" request (the Grid will try to fetch data from the server). That why I would suggest ot instead conditionally hide the whole Grid or conditionally remove the "Read" option of the DataSource and bind the Grid to empty array using it's "BindTo" option.

I also need to conditionally suppress the grid's read action, based on a value in the model (there was no reason in this case to make a call to the server). Thanks to the answer by #Vladimir lliev, where he mentioned NOT using AutoBind, but instead removing the "Read" action from the DataSource and binding to an empty array.
This pointed me in the right direction, but I didn't know how to do that with the razor syntax. I figured it out, so I'm sharing for anyone else who needs this.
#(Html.Kendo().Grid<SomeNamespace.Model>(
// If you need to optionally bind to an empty datasource in certain scenarios,
// use the grid's constructor. Also, conditionally enable the DataSource's "Read"
// action. Note: it's not enough to just conditionally enable the "Read" action,
// since the grid still makes a request for some reason, but when you use an empty
// array AND disable the "Read" action, no call is made to the server.
Model.ShouldGridRead ? null : new SomeNamespace.Model[] { }
)
.Name("MyGrid")
.Columns(cols =>
{
})
.DataSource(ds => ds
.Ajax()
.Batch(true)
.Model(model =>
{
})
.Read(a =>
{
if (Model.ShouldGridRead)
{
a.Action("Some_Action", "Some_Controller");
}
})
)

Related

RowAction styles lost while sorting Telerik extension grid

I am using Grid control from Telerik Extensions for ASP.NET MVC. I have loaded the grid in the partial view using Ajax binding. When I sort the grid columns, the styles specified in RowAction are lost.
#(Html.Telerik().Grid<MySite.DTO.CaseDto>(Model.Cases)
.Name("CasesGrid")
.HtmlAttributes(new { style = "width: 1000px;" })
.DataBinding(dataBinding => dataBinding.Ajax()
.OperationMode(GridOperationMode.Client)
.Select("DI_UrgentCases_AjaxRead", "Dashboard")
)
I am using RowAction to highlight certain rows based on the values of the particular cell.
.RowAction(row =>
{
if (row.DataItem.IsUrgent)
{
row.HtmlAttributes["style"] = "background:#FFBABA";
}
})
I tried the suggestion given in http://www.telerik.com/forums/ajax-binding-and-rowaction-conflict- but it did not work. I tried rebinding the grid on client side, but when I do that, the sorted grid appears in the new page instead of within the partial view.
Please help!
Finally, I found a solution to my issue. My problem was that every time I sorted the grid, all the rendering and events bindings were lost. Every time the grid was rebind using ajax binding, it only returned the data and loaded in the grid.
To retain any css styles and event binding, I had to apply the css again and rebind the events after the data was bound to the grid.
Telerik extension provides a client event called "OnDataBound" which is called when the grid is data bound via ajax or web-service. (Reference: Client Events for Telerik Extensions Grid
#(Html.Telerik().Grid<MySite.DAL.DTO.UserDto>(Model.Users)
.Name("MyUsersGrid")
.ClientEvents( events => events.OnDataBound("grid_OnDataBound"))
function grid_OnDataBound(e) { code for rebind, apply css...}
Then in function grid_OnDataBound(), we can define the code to rebind events and apply css when this event is raised on data bound.

Why is CascadeFrom() not doing anything?

I'm really new to Kendo UI, and I'm having problems with CascadeFrom() not calling an action on my controller. Here's the bare bones of my problem:
// The parent dropdown
<select id="Testing">
<option value="0">Vehicle</option>
<option value="1">Driver</option>
<option value="2">Trailer</option>
</select>
// The dynamic dropdown
#(Html.Kendo().DropDownListFor(m => m.VDTId)
.DataValueField("Id")
.DataTextField("Item")
.DataSource(ds =>
{
ds.Read(c => c.Action("GetVDT", "CompanyVDTUnavailability")
.Data("getVDTSelection"))
.ServerFiltering(true);
})
.CascadeFrom("Testing"))
// Function to allow Kendo to pass a value to
// the type parameter of my GetVDT action.
function getVDTSelection() {
return {
type: parseInt($("#Testing").val())
};
}
The action is being called when the page first loads, and returns the correct data. The problem is, if I then make a selection from the Testing dropdown, the action is never invoked on the controller (I've verified this using a breakpoint on the action), meaning the dynamic dropdown never gets updated.
Looking through the official example, and other questions around SO, I can't see what I'm doing wrong. Could someone point me in the right direction, please?
Edit: I've tried Petur's solution below by changing the parent dropdown to the following:
#(Html.Kendo().DropDownListFor(m => m.Type)
.Name("Testing")
.DataValueField("Id")
.DataTextField("Text")
.BindTo(Model.UnavailabilityTypes))
This binds the parent dropdown correctly, but no longer invokes the controller action for the cascading dropdown even when the page first loads. Any suggestions?
Controller action signature as requested:
public JsonResult GetVDT(CompanyUnavailabilityType type)
Where CompanyUnavailabilityType is an enum.
Kendo DropDownList can cascade only from another Kendo DropDownList/ComboBox. Turn the first widget into kendo DropDownList and it should start working properly.
I think the problem is that getVDTSelection() is returning an int or string value not an Enum value. Change your method sig to an int if not, try a string and the method described in my comment
public JsonResult GetVDT(int type)
{
//AllowGet might be needed as well
return Json(jsonObjx,JsonRequestBehavior.AllowGet);
}
Edit:
You can also try to Manually force the ddl to cascade. Ditch CascadeFrom and do it manually.
function OnChangeOfParentDDL(e){
var parentValue = $("#ParentDDL").val();
$("#ChildDDL").val("").data("kendoDropDownList").text("");//clear it out
var child = $("#ChildDDL").data("kendoDropDownList");
child.dataSource.read({ type : parentValue });
}
Both Petur and C Sharper were on the right track with the problem.
I did need to build the dropdown using Html.Kendo.DropDownList() (I've just verified this after getting the solution to work.)
The method signature on the controller was a problem, but only because I'd had old testing methods left on there, leading to an ambiguous call.
The major difficulty for me was that nothing was being reported in the debugger, so diagnosing the problem was a pain. In the end, I used the Network tab of the Firefox web developer tools to ensure the Ajax request was indeed being sent, and it was. Inspecting that request showed it was leading to an ambiguous call on the controller.
Also, to clear up comments from C Sharper's answer:
The parseInt() call is not required.
The call will correctly map to an enum on the server-side, meaning the method signature I posted in my question is correct.

How to bind Kendo ListView to Model and make it pageable

I have a Kendo ListView on my view like this:
#(Html.Kendo().ListView<SearchResultViewModel>(Model)
.Name("searchResults")
.TagName("div")
.DataSource(dataSource => {
dataSource.Model(model => model.Id("ID"));
dataSource.PageSize(100);
})
.Pageable()
.Selectable()
)
Controller:
[HttpPost]
public ActionResult AdvancedSearch(AdvancedSearchViewModel criteria)
{
// Get the search results (IEnumerable<SearchResultViewModel>)...
var results = GetSearchResults(criteria);
return View(results );
}
This ListView is inside a partial view on an Advanced Search page which sends the search criteria to the Controller via POST.
The Controller then returns the search results to the view using SearchResultsViewModel as the model.
The problem is the pagination does not work, and I know that that's because the pagination only works when there's an ajax call to the server to read the data. But, the problem is I can't using dataSource.Read to get the data via an ajax call, because as I said, the search criteria is inside a form and is sent to the controller via POST.
Now, the questions is how can I either make the pagination work without changing the data source, or read the data source using a POST method?
In the DataSource you should be able to add
Datasource.ServerOperation(false) // this should enable paging on the client.

Detect if you are adding or updating within an EditorTemplate View

I have a View that I am using as an EditorTemplate. I want to limit what the user can edit vs. what they can insert. My EditorTemplate View is typed as SomeModel and I know that if SomeModel.Id is not 0, that means we are doing an edit, otherwise we are doing an insert. I thought I'd be able to do something like:
#if (Model.Id == 0)
{
//show "insert-specific" UI
}
but for some reason, I always get 0's, nulls, default, etc. when I check via Model. whereas the Html helper methods pick up the true value just fine, such as:
#Html.TextBoxFor(model => model.Id)
Again, the value of Model.Id is always 0, even when #Html.TextBoxFor(model => model.Id) shows another value.
Is there a better way to achieve what I am trying to do?
Note: Not sure that it matters, but I'm using the Telerik MVC Grid control. It doesn't seem to allow for a different View for inserting vs. editing.
Yo,
If you are using Ajax binding then the EditorTemplate is serialized and send to the client where it is re-populated with different values each time you edit a record or add new record.
If you are using ajax binding then you can use the OnEdit client event and check whether or not the e.mode is edit or insert. Then you can manipulate that editor with JavaScript.

how to Rebind Telerik grid

Consider I have below mentioned Telrik Grid and first time it is loaded by employee details(name, Description). I want to add a row in telrik grid when i click add button which is out side of grid. My problem is how to add new record with existing record. I mean how to rebind the grid.
#(Html.Telerik().Grid<Project.Models.Employee>()
.Name("myName")
.DataKeys(keys => keys.Add(c => c.EmpId))
.Columns(columns => {
columns.Bound(o => o.Name).Width(200);
columns.Bound(o => o.Description).Width(400);
})
)
Please, provide me better solution. Remember my button out side the grid.
Take a look at the following example. This demo explains how to do the editing with the grid using AJAX.
http://demos.telerik.com/aspnet-mvc/grid/editingajax
Go through the demo - things are pretty clear what to do.
Lohith (Tech Evangelist, Telerik India)
If you in client side, then you can use javascript function rebind():
var grid = $("#Grid").data("tGrid");
//send additional arguments by passing them as a literal JavaScript object
grid.rebind({customerID : "ALFKI"});
But for more custom answer i need more information about your scenario. Is it ajax binding, server binding, or else. How do you add row (is it editing in cell or else) etc.
'It could be helpfull'
var grid = $("#Grid").data("tGrid");
//send additional arguments by passing them as a literal JavaScript object
grid.rebind({customerID : "SAJJAD"});

Resources