Multiselect list in Kendo Grid inline editing - asp.net-mvc

I need to use multiselect list in kendo grid (inline editing) so that user can select multiple values from the list per row.
Following are my requirements:
At the time of display, kendo grid should show comma separated list of all the selected values.
At the time of Add, kendo grid should show multiselect list and allow to select multiple values.
At the time of Edit, kendo grid should show multiselect list with already selected values. User should be able to modify the select and add/remove items from the list.
When user clicks on update/save button, selected values from multiselect list should be available in code behind (in update ajax action) along with id of row.
Following what I do as of now:
I am taking an approach similar to using a drop down list in kendo inline grid.
I have created an Editor Template for displaying multiselect at the time of add/edit.
Following is the code:
#model List<Namespace.CompanyConnector>
#using Kendo.Mvc.UI
#(Html.Kendo().MultiSelectFor(c=>c)
.Name("company_connector_id")
.DataTextField("connector_name")
.DataValueField("company_connector_id")
.Placeholder("Select connector...")
.AutoBind(false)
.Value((List<int>)ViewData["SelectedValues"])
.DataSource(source =>
{
source.Read(read =>
{
read.Action("GetCompanyConnectors", "BrandConnector");
})
.ServerFiltering(true);
})
)
#Html.ValidationMessageFor(m => m)
Explanation: I bind a list of model class to the multiselect and set data source in the read action. For selecting the selected values at the time of edit, I have created a function that returns the ids of selected values and put that in View Data in the read action.
I've used this Editor template in my Index page as following code:
#{Html.Kendo().Grid<Cee.DomainObjects.DomainObjects.BrandConnector>()
.Name("BrandConnectorGrid")
.Filterable()
.Events(e => e.Edit("onEdit"))
.DataSource(dataSource => dataSource
.Ajax()
.Events(e => e.Error("error_handler").RequestEnd("onRequestEnd"))
.ServerOperation(false)
.Model(model =>
{
model.Id(p => p.brand_id);
model.Field(e => e.CompanyConnectorList).DefaultValue(new
List<Cee.DomainObjects.DomainObjects.CompanyConnector>());
})
.Read(read => read.Action("_AjaxBinding", "BrandConnector",new{companyID = 0 }).Type(HttpVerbs.Post))
.Update(update => update.Action("_UpdateBinding", "BrandConnector").Type(HttpVerbs.Post)))
.Columns(columns =>
{
columns.Bound(c => c.brand_connector_id).Width(0).Hidden(true);
columns.Bound(c => c.company_id).Width(0).Hidden(true);
columns.Bound(c => c.brand_id).Width(0).Hidden(true);
columns.Bound(u => u.brand_name).Title("Brand").Width("18%").HtmlAttributes(new { #class = "brkWord", #readonly = "readonly" });
columns.ForeignKey(u => u.connector_name, Model.CompanyConnectorList, "company_connector_id", "connector_name").Title("Connector").Width
("16%").HtmlAttributes(new { #class = "brkWord" }).EditorTemplateName("company_connector_id");
columns.Command(p => p.Edit().Text("Edit").HtmlAttributes(new { #title = "Edit" })).Width("16%").Title("Edit");
})
.Editable(editable => editable.Mode(GridEditMode.InLine).CreateAt(GridInsertRowPosition.Top))
.Pageable(pageable => pageable.Refresh(true).PageSizes(GlobalCode.recordPerPageList).ButtonCount(GlobalCode.PageSize).Input(true).Numeric(true))
.HtmlAttributes(new { #class = "dynamicWidth" })
.Sortable(sorting => sorting.Enabled(true))
.Render();
}
Explanation: I've used ForeignKey. Bound it to the string column "connector_name". Connector_name is a comma separated list of IDs that I send from controller. Editor template is used here.
Issue: It works fine at the time of View/Display in Index but Edit does not show selected value. Also we do not get updated value in code behind on update click.
Is this correct way of implementing multiselect list or do I need to bind a collection property as a column in grid?
If I bind a collection property as a column then how would I be able to show comma separated string at the time of display?

Try below code:
function onEdit(e) {
var multiselect = $("#YourMutliselectDropdown").data("kendoMultiSelect");
var IDArray = [];
$(e.model.propertyName).each(function (index) {
var ID = e.model.propertyName[index].id;
IDArray.push(ID);
});
multiselect.value(IDArray);
}
I assume that propertyName is List of your collection and it contains id as property.

try it:
c.Bound(p => p.CompanyConnectorList).ClientTemplate("#= connectorsToString(data)#").EditorTemplateName("company_connector_id");
and js:
function connectorsToString(data) {
var list = data.company_connector_id;
var result = "";
for (var i = 0; i < list.length; i++) {
result += list[i].Name + ';';
}
return result;
}

Related

Telerik MVC Grid Popup Default Values

I have a Telerik MVC Grid with a custom editable popup template
.Editable(editable => editable
.Mode(GridEditMode.PopUp)
.Window(w => w.Width(600))
.TemplateName("Inspection")
)
The template is based on a model, and contains two drop down lists
#(Html.Kendo().DropDownListFor(model => model.InspectionStatus)
.BindTo(new List<SelectListItem>()
{
new SelectListItem() { Text = "Fail", Value = "0" },
new SelectListItem() { Text = "Pass", Value = "1" }
})
)
and
#(Html.Kendo().DropDownListFor(model => model.CloseoutStatusID)
.DataValueField("LookUpID")
.DataTextField("LookUpText")
.DataSource(source => {
source.Read(read => { read.Action("Get", "LookUp", new { LookUp = "CloseOutStatus" }); });
})
)
I need to set the default values for both fields... Currently they both come back as 0 regardless of what I have done.
So far I've:
Tried setting the default value attribute
Set the values in the model's constructor
Set the .Value() to what the default should be.
Everything else is working correctly... I can select a bound item and it returns the correct value. I can edit an existing item and it shows the proper data in the template. I can saved edited data and it returns the correct value.
Any reliable documentation would be greatly appreciated.
Received the answer on the telerik forums.
The telerik grid create action in the toolbar uses the model information in the data source.
by adding the fields to the model and setting the default value there I was able to get the desired behavior.
.Model(model => {
model.Id(Inspection => Inspection.DEPInspectionsID);
model.Field(Inspection => Inspection.CloseoutStatusID).DefaultValue(2);
model.Field(Inspection => Inspection.InspectionStatus).DefaultValue(1);
})

Dropdown list in ASP MVC Kendo grid will not open

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);

multiple data sources in kendo ui dropdownlistfor?

I using the following:
#(Html.Kendo().DropDownListFor(m => m.AbcID)
.OptionLabel("Select Abc")
.DataTextField("AbcName")
.DataValueField("AbcID")
.AutoBind(true)
.HtmlAttributes(new { style = "width: 300px" })
.Filter(FilterType.Contains)
.DataSource(source =>
{
source.Read(read =>
{
read.Action("AutoCompleteAbcList", "Common").Data("GetSelectedXyz");
});
})
So basically what's happening is that the dropdownlist is being populated by the Json returned by the AutoCompleteAbcList ActionMethod.
What I'd like to know is that I have another ActionMethod ddlPQRList that returns a Json and I'd like to populate my dropdownlist using both the Jsons.
I have tried the following:
#(Html.Kendo().DropDownListFor(m => m.AbcID)
.OptionLabel("Select Abc")
.DataTextField("AbcName")
.DataValueField("AbcID")
.AutoBind(true)
.HtmlAttributes(new { style = "width: 300px" })
.Filter(FilterType.Contains)
.DataSource(source =>
{
source.Read(read =>
{
read.Action("AutoCompleteAbcList", "Common").Data("GetSelectedXyz");
read.Action("ddlPQRList", "Common").Data("GetSelectedXyz");
});
})
but do not get the desired output. I get the list from the 2nd ActionMethod only.
Any help is appreciated. Thanks.
No, this is not possible the way you are trying to do it. A widget can only have one dataSource.
The second read Action is overwriting the first. It is the same thing as setting a variable value twice...only the second one counts.
If you want the dataSource of the DropDownList to be the concatenation of list, then you need to create a single controller action that returns that list, i.e.:
read.Action("AutoCompleteAbcListANDddlPQRList", "Common").Data("GetSelectedXyz");
where the implementation of AutoCompleteAbcListANDddlPQRList() returns a single list of BOTH AutoCompleteAbcList and ddlPQRList lists.

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 format the row based on condition in kendo ui mvc grid

I am working on asp.net mvc. I am trying to display list of messages in a Kendo mvc ui grid.
I have written the code like,
Html.Kendo().Grid((List<messages>)ViewBag.Messages))
.Name("grdIndox")
.Sortable(m => m.Enabled(true).SortMode(GridSortMode.MultipleColumn))
.HtmlAttributes(new { style = "" })
.Columns(
col =>
{
col.Bound(o => o.RecNo).HtmlAttributes(new { style = "display:none" }).Title("").HeaderHtmlAttributes(new { style = "display:none" });
col.Bound(o => o.NoteDate).Title("Date").Format("{0:MMM d, yyyy}");
col.Bound(o => o.PatName).Title("Patient");
col.Bound(o => o.NoteType).Title("Type");
col.Bound(o => o.Subject);
}
)
.Pageable()
.Selectable(sel => sel.Mode(GridSelectionMode.Single).Type(GridSelectionType.Row))
.DataSource(
ds => ds.Ajax().ServerOperation(false).Model(m => m.Id(modelid => modelid.RecNo))
.PageSize(10)
//.Read(read => read.Action("Messages_Read", "Msg"))
)
.Events(ev => ev.Change("onSelectingGirdRow"))
)
and i have the field in the table like IsRead-boolean type. so if the message is unread message then i need to format that record with bold font. I have used clientTemplates but with that i am able to format only particular cells i want format entire row. Please guide me.
as Sanja suggested you can use the dataBound event but it will be better to cycle through the tr elements (the rows). Also I assume that you will need the related dataItem to check if the property that indicates if the message is read.
e.g.
dataBound: function ()
{
var grid = this;
grid.tbody.find('>tr').each(function(){
var dataItem = grid.dataItem(this);
if(!dataItem.IsMessageRead)
{
$(this).addClass('someBoldClass');
}
})
}
You can use dataBound event to change your rows.
dataBound: function ()
{
$('td').each(function(){
if(some condition...)
{
$(this).addClass('someBoldClass')}
}
})
}
There is another way to do that.It's called RowAction.
.RowAction(row =>
{
if (condition)
{
row.HtmlAttributes["class"] = "someBoldClass";
}
})
Please note that the RowAction is available only for rows that are rendered on server side. So in your case, you can use RowAction as an alternative to DataBound.

Resources