Dropdown list in ASP MVC Kendo grid will not open - asp.net-mvc

I am trying to replicate exactly what is on this Kendo demo page with the Categories column. Simply a drop down list inside the grid. I copied all their source code exactly, but when I click the column with a drop down, the grid simply flashes. I can edit the FullName value fine. I tried to get an animation of the effect with a screen recorder, but for some reason it is not showing everything I see. In this image I am clicking the "Rol" drop down column multiple times.
What the gif does not show is that when I click the column, it briefly changes to a drop down control for a split second. I was able to capture this by adding a "debugger" line to the onDataBound event for the dropdown and taking a screenshot:
What is going on? Why doesn't it just pop open?
Here is some of the relevant code:
The EditorTemplates/RolList.cshtml file. Note that NONE of these events fire except the onDataBound event. That is probably a clue.
#model MyCompany.Web.CaseLink.Mvc.Admin.Models.RolDropDown
#(Html.Kendo().DropDownListFor(m => m)
.BindTo((System.Collections.IEnumerable)ViewData["roles"])
.DataValueField("RolId")
.DataTextField("RolDescription")
.Events(events => events
.Select("onSelect")
.Change("ddlChange")
.Open("onOpen")
.DataBound("onDatabound")
)
)
<script type="text/javascript">
function onSelect(e) {
console.log("ddl select" + e);
}
function ddlChange(e) {
console.log("ddl change" + e);
}
function onOpen(e) {
console.log("ddl open" + e);
}
function onDatabound(e) {
debugger;
console.log("ddl databound" + e);
}
</script>
Here is the partial view containing the MVC Grid itself. Note that the gridChange event was added just for debugging, and it does not fire when clicking in the drop down column.
#(Html.Kendo().Grid<CaseMemberGridRow>()
.Name("grid")
.Columns(columns =>
{
columns.Bound(c => c.FullName)
.Title("Name")
;
columns.Bound(p => p.Rol).ClientTemplate("#=Rol.RolDescription#").Width(180);
columns.Bound(c => c.Email)
.Title("Email")
;
columns.Bound(c => c.Telephone)
.Title("Phone")
;
columns.Command(command => command.Destroy()).Width(150);
})
.ToolBar(toolBar =>
{
toolBar.Create();
toolBar.Save();
})
.HtmlAttributes(new { style = "height: 550px;" })
.Scrollable()
.Sortable()
.Editable(editable => editable.Mode(GridEditMode.InCell))
.DataSource(dataSource => dataSource
.Ajax()
.Batch(true)
.ServerOperation(false)
.Events(events => events.Error("error_handler").Change("gridChange"))
.Model(m =>
{
m.Field(p => p.FullName).Editable(true);
m.Field(p => p.Rol).Editable(true);
m.Field(p => p.Rol).DefaultValue(
ViewData["defaultRol"] as MyCompany.Web.CaseLink.Mvc.Admin.Models.RolDropDown);
})
.Create(create => create.Action("AddCaseMemberNoCustomerRecord_Create", "AddMember"))
.Update(update => update.Action("AddCaseMemberNoCustomerRecord_Update", "AddMember"))
)
)
Controller is nothing special, as I said, I am doing exactly when Telerik did in their demo. A sample:
var roles = _rolService.GetAllRolesDTO()
.OrderBy(o => o.Description)
.Select(r => new RolDropDown
{
RolDescription = r.Description,
RolId = r.RolId
});
ViewData["roles"] = roles;
ViewData["defaultRol"] = roles.First();
If there is something to look for in the debugger on the "onDataBound" event, let me know. As you can see here, the datasource is definitely populated.
EDIT: I am aware that you can attempt to do the same thing using the ForeignKey type of column. When I try that, I can get a drop down to work once. After selecting a value, the column starts acting like before where you cannot change the value.
columns.ForeignKey(p => p.RolId, (System.Collections.IEnumerable)ViewData["roles"], "RolId", "Description")
.Title("Role")
.Width(150);

Related

How can i delete multi selected records using checkbox in Kendo Grid?

I want to allow the user to select one or more rows using checkbox in kendo grid and to delete the selected rows, my project is asp.net MVC
How can i add the checkbox in order to allow the user to select it?
How to delete all selected rows? i.e rows with selected checkbox
anyone can suggest me how can i do this?
#(Html.Kendo().Grid<TelerikMvcAppCombo.Models.ImageModel>()
.Name("grdImageModel")
.Columns(columns =>
{
columns.Bound(c => c.IMAGESIZE_NAME).Width(140);
columns.Bound(c => c.IMAGESIZE_DESC).Width(140);
columns.Bound(c => c.created_by);
columns.Bound(c => c.created_date);
columns.Bound(c => c.modified_by);
columns.Bound(c => c.modified_date);
})
.HtmlAttributes(new { style = "height: 580px;" })
.Scrollable()
.Groupable()
.Sortable()
.Pageable(pageable => pageable
.Refresh(true)
.PageSizes(true)
.ButtonCount(10)
)
.DataSource(datasource => datasource
.Ajax()
.Read(read => read
.Action("GetData", "Image")
))
)
In kendo grid add this column
columns.Template(x => { }).ClientTemplate("<input type='checkbox' id='chkSelect_#= yourid#' userId='#= yourid#' />").Width(20);
and lets say you have a button to delete records and when we click that button you can loop the data source and delete records. See the JavaScript example. You have to use jquery to do that
var grid, dataSource, data = null;
grid = $("#grdImageModel").data("kendoGrid"), dataSource = grid.dataSource, data = dataSource.data();
$.each(data, function (i, tmpObject) {
$('tr[data-uid="' + tmpObject.uid + '"] td input[id^="chkSelect_"]:checked').each(function (k, input) {
// here you are access the checked row object
});
});

How to pass the model of a row from Kendo Grid to an editable template

I have a Kendo Grid which has a popup editable template,
If possible i would like to pass the model (the model of the row, or at least its Id) to the editable template
Grid
#(Html.Kendo().Grid<Client>()
.Name("grid")
.Columns(columns =>
{
columns.Bound(c => c.Name).Width(140);
columns.Bound(c => c.Status);
columns.Bound(c => c.ProcesingStyle);
columns.Bound(c => c.ArchiveDays);
columns.Command(command =>
{
command.Edit().Text(" ");
command.Destroy().Text(" "); ;
}).Width(90);
})
.ToolBar(toolbar => toolbar.Create().Text("New"))
.Editable(editable => editable
.Mode(GridEditMode.PopUp)
.TemplateName("Client").AdditionalViewData(new { Client = Model })
.Window(w => w.Title("Site")))
.HtmlAttributes(new { style = "height: 380px;" })
.Scrollable()
.Sortable()
.Selectable()
.Resizable(resize => resize.Columns(true))
.Reorderable(reorder => reorder.Columns(true))
.Events(events => events.Change("onChange"))
.Pageable(pageable => pageable
.Refresh(true)
.PageSizes(true)
.ButtonCount(5))
.DataSource(dataSource => dataSource
.Ajax()
.Read(read => read.Action("Get", "Clients"))
.Model(model => model.Id(p => p.Id))
.Create(update => update.Action("Create", "Clients"))
.Update(update => update.Action("Update", "Clients"))
.Destroy(update => update.Action("Destroy", "Clients"))
)
)
Template
#model Client
#(Html.Kendo().ComboBoxFor(m => m.Plan)
.DataTextField("Name")
.DataValueField("Id")
.Placeholder("Select Plan...")
.HtmlAttributes(new { style = "width:300px" })
.Filter(FilterType.Contains)
.MinLength(3)
.DataSource(source =>
source.Read(read =>
read.Action("GetPlans", "Plans",new {ClientId = Model.Id}))))
Everything works fine except i need to use the Id of the row/model inside the template, in particular , i need the to pass the model.Id (which is the id of the model of the row), to the action on the Combobox in the template, so i can filter the data correctly
This is the offending line in the grid,
.TemplateName("Client").AdditionalViewData(new { Client = Model })
The result is the Model inside the template is always null, im not sure how to pass the data i need to the template
Is there anyway i can do this, or should i be looking at a different approach?
The way I got around this was to put a JavaScript function in the original view as seen below:
function getClientId() {
var row = $(event.srcElement).closest("tr");
var grid = $(event.srcElement).closest("[data-role=grid]").data("kendoGrid");
var dataItem = grid.dataItem(row);
if (dataItem)
return { clientId: dataItem.Id }
else
return { clientId: null }
}
And reference it from my editor template:
.DataSource(source => source.Read(read => read.Action("GetPlans", "Plans").Data("getClientId"))))
Note : I'm pretty sure you cant run JavaScript from a EditorTemplate so it needed to be housed in the original view.
I know this is a really old question, but for those who are wondering why this doesn't work:
.TemplateName("Client").AdditionalViewData(new { Client = Model })
This code doesn't work because the only data you can pass through this method is static data. You can pass specific strings or numbers, like "Hello World", and that would work fine. For dynamic data with kendo, I've learned that it really depends on the situation, and your solution here works well.

Changing row color in Kendo MVC grid, using RowAction

I'm hoping to use RowAction with a lambda to set the background color of a few rows of data in a Grid.
<%: Html.Kendo().Grid<HomeController.SuccessfulBuildsByDevice>()
.Name("Grid")
.Columns(columns =>
{
columns.Bound(p => p.A);
columns.Bound(p => p.B);
})
.Scrollable()
.Sortable()
.Filterable()
.RowAction(row =>
{
if(row.DataItem.A > row.DataItem.B)
row.HtmlAttributes["style"] = "background:red";
})
.HtmlAttributes(new { style = "height:500" })
.DataSource(dataSource => dataSource
.Ajax()
.Read(read => read.Action("_GetData", "Home"))
.ServerOperation(false)
)
%>
However, when I use the above the RowAction() doesnt seem to be called. I tried setting a breakpoint, etc. Am I missing something in the intended use of RowAction(), does anyone see an obvious problem?
the problem is .Ajax() and .RowAction() are mutually exclusive
http://www.kendoui.com/forums/kendo-ui-web/grid/ajax-binding-and-rowaction-conflict-.aspx
Just because I came accorss this issue today and to save time here the short answer that worked for me based on the explanation from stuck
add this to the grid
.Events(e => e.DataBound("onDataBound"))
add this javascript above the grid
function onDataBound() {
// get the grid
var grid = this;
// iterate through each row
grid.tbody.find('>tr').each(function () {
// get the row item
var dataItem = grid.dataItem(this);
// check for the condition
if (dataItem.IsArchived) {
// add the formatting if condition is met
$(this).addClass('bgRed');
}
})
}

Grid into Grid Popup Editor - Passing ID parameter in sub grid

I have a Grid with Employes. There is a Edit button and the edit mode is set to Popup. In the EditorTemplate of the entity I want to edit, there is another grid that has a history of Salary with a incell or inline edit mode.
Both grids uses Ajax datasources. The problem is with the inner grid binding. The controller action feeding a Json result to the ajax call requires the ID of the employe we are editing to return the appropriate Salary history. However, Kendo UI ASP.NET MVC wrapper will render some sort of template of the editor before knowing which employee we want to edit, then it will edit it when we are requesting the popup.
How can I feed the Employe ID in the Read Ajax call?
Main Grid
#(Html.Kendo().Grid<MyProject.Business.Models.EmployeDTO>().Name("EmployeGrid")
.ToolBar(toolbar => toolbar.Create())
.Columns(cols =>
{
cols.Bound(o => o.someData).Title("Some Data");
cols.Bound(o => o.moreData).Title("More Data");
cols.Command(o =>
{
o.Edit();
o.Destroy();
}).Title(" ");
})
.Editable(editor => editor
.Mode(GridEditMode.PopUp)
.Window(window => window.Draggable().Resizable().HtmlAttributes(new { #style = "width:700px;" })))
.Sortable()
.Filterable()
.Groupable()
.DataSource(datasource => datasource
.Ajax()
.Model(model => model.Id(o => o.id))
.Read(read => read.Action("GetAll", "EmployesAjax"))
.Update(update => update.Action("Update", "EmployesAjax"))
.Create(create => create.Action("Create", "EmployesAjax"))
.Destroy(destroy => destroy.Action("Destroy", "EmployesAjax"))
)
)
Inner Grid (In Views/Shared/EditorTemplates/EmployeDTO.cshtml)
#Html.Kendo().Grid<MyProject.Business.Models.SalairyDTO>().Name("SalaryGrid")
.Columns(cols =>
{
cols.Bound(o => o.someInfo).Title("Some Info");
})
.DataSource(datasource => datasource
.Ajax()
.Model(model =>
{
model.Id(o => o.id);
model.Field(o => o.employe_id).DefaultValue(Model.id);
})
// NEED THE ID HERE
.Read(read => read.Action("GetByEmployeId", "SalairyAjax", new { id = "" }))
.Update(update => update.Action("Update", "SalairyAjax"))
.Create(create => create.Action("Create", "SalairyAjax"))
.Destroy(destroy => destroy.Action("Destroy", "SalairyAjax"))));
Basically I would suggest you to Set the AutoBind option to false of the inner Grid and use the edit event of the outer Grid to perform a read request and pass the value as additional parameter.
Here is an example:
function onEditOfEmployeGrid(e){
$('#SalaryGrid').data().kendoGrid.dataSource.read({id:e.model.EmployeeID})
}
You could simply pass the value from the grid using addtionaldata parameter within the grid. the RouteID on the (left side) can then be referenced within the Grid Popup Editor using ViewData["RouteID"]. I hope that helps
.Editable(editable => editable.Mode(GridEditMode.PopUp)
.TemplateName("busStop")
.DisplayDeleteConfirmation(true)
.Window(window => window.Modal(true).Resizable().Draggable())
.AdditionalViewData(new { RouteID = Model.RouteID }))

Telerik Grid MVC Razor : auto select a row and fire select event

Using a Telerik Grid with ASP.NET MVC 3 Razor engine.
When a user selects a row, we un-hide some part of the page. This is working fine when I click on a row.
However, I need to automatically select the first row when the page is loaded
I can change the row display color so it appears selected, but I can't figure out how to have the select event called!
Here is the grid code :
#(Html.Telerik().Grid<SomethingViewModel>()
.Name("SomethingGroupGrid")
.ClientEvents(events =>
{
events.OnDataBinding("SomethingGroupGrid_onDataBinding");
})
.DataBinding(dataBingding => dataBingding.Ajax().Select("SomethingGroupGrid", "Something"))
.Columns(columns =>
{
columns.Bound(c => c.Id).Hidden();
columns.Bound(c => c.Name)
.Title("Groups");
})
.Selectable()
.Pageable(x => x.PageSize(10))
.ClientEvents(events => events.OnRowSelect("SomethingGroupGrid_RowSelect"))
)
Can someone help?
Ok I found a freakishly ugly solution :
I added a OnRowDataBound event on the grid. This OnRowDatabound Functions fires the OnRowSelect events.
Then I added page global javascript variable to hold a bool value that checks if the first row has been selected, so the OnRowDatabound does not call OnRowSelect for each row.
#(Html.Telerik().Grid<SomethingViewModel>()
.Name("SomethingGroupGrid")
.ClientEvents(events =>
{
events.OnDataBinding("SomethingGroupGrid_onDataBinding");
})
.DataBinding(dataBingding => dataBingding.Ajax().Select("SomethingGroupGrid", "Something"))
.Columns(columns =>
{
columns.Bound(c => c.Id).Hidden();
columns.Bound(c => c.Name)
.Title("Groups");
})
.Selectable()
.Pageable(x => x.PageSize(10))
.ClientEvents(events => events.OnRowSelect("SomethingGroupGrid_RowSelect"))
.ClientEvents(events => events.OnRowDataBound("SomethingGroupGrid_OnRowDataBound"))
)
<script type="text/javascript">
var firstRowSelected = false;
function PreviewAccountGrid_DataBound(e) {
if (firstRowSelected == false) {
SomethingGroupGrid_RowSelect(e);
firstRowSelected = true;
}
}
</script>
Plese tell me that there is a better way to do that, or it will severely degrade my opinion of Telerik controls (which is already damn low).

Resources