I have a Kendo ComboBox as an EditorTemplate for nullable IDs (people). I bind the model normally with a UIHint
#Html.Kendo().ComboBoxFor(x=>x.Person.MotherID)
The combo works great, I can type and it filters on the server.
The problem is that when the form first loads, the ID of the person appears as the visible text, not the name.
There are 1 million records, so I can't send them all to the combobox initially.
How do I get the combobox, when it first renders, to go get the name of the person via Ajax and not show the ID?
#(Html.Kendo()
.ComboBoxFor(m => m)
.DataTextField("Name")
.DataValueField("Value")
.AutoBind(true)
.ValuePrimitive(true)
.Filter(FilterType.Contains)
.Placeholder(Words.Type_Name)
.MinLength(2)
.DataSource(source =>
source.Read(read =>
read.Action("ReadComboBoxPerson", "Picker", new { area = "" }))
.ServerFiltering(true))
)
MVC:
public ActionResult ReadComboBoxPerson(string text)
{
return Json(_personManager.PersonGetter(text), JsonRequestBehavior.AllowGet);
}
Related
I have a kendo mvc grid set for inline editing. I have a dropdown that I would like to populate when the user selects edit, and the list needs to be populated based upon a value in the row (which is in a hidden field)
c.Bound(a => a.MyId)
.Hidden(true);
I have the dropdown that I wish to populate in an editor template (which I need as this dropdown is shared by several grids).
#model int?
#(Html.Kendo().ComboBoxFor(m => m)
.AutoBind(true)
.Filter("contains")
.Placeholder("Select...")
.DataTextField("MyOtherName")
.DataValueField("MyOtherId")
.DataSource(source =>
{
source.Read(read =>
{
read.Action("Data_Read", "MyController").Data("OnAdditionalData");
});
})
.Suggest(true)
.HtmlAttributes(new { data_value_primitive = "true" })
)
#Html.ValidationMessageFor(m => m)
With an additional data method in a script file ...
function OnAdditionalData()
{
var myId = $("#MyId").val();
return { myId : myId };
}
I would like for the dropdown to populate when the user clicks on the row edit button. With the autobind property set to true, it does just that. But the value in the additional datat function is always an empty string. This value does not populate correctly until after the additional data method (verified using the JS console.) If I set autobind to false, the user has to click on the drop down in the editable row, but then the value of myId is correct.
I see what is going on, with autobind true the values from the row object is not being populated until after the read method of the ComboBox is called.
Does anyone know of a work around for this?
I can't use edit and create command of a Kendo Grid, because binding always fails and controller always receives a null object, even though DataSourceRequest is fine.
I used a #html.EditorForModel() and it worked fine and controller received the data. So MVC Model binding and my class aren't the problem.
Also, using F12, I can see the data being posted and it's fine too.
Any Idea about possible problem and debugging? There is an issue with all of my Kendo Grids, sometimes they post a model twice and I receive double Create on the server, which one of them always fails because of repetitive Keys. Or sometimes create will be triggered by edit command too.
I have no idea where I'm going wrong, in most scenarios the user will choose the primary key as well, so my returned model doesn't need an update.
With this particular class, server always receives two create and none of them binds correctly. The first create, posts all of the fields, and the second posts all of the navigation properties' fields too!
This is the action method:
[HttpPost]
public ActionResult Create([DataSourceRequest] DataSourceRequest request, Stock stock){
if (stock != null && ModelState.IsValid)
{
repo.Insert(stock);
return Json(new[] { stock }.ToDataSourceResult(request, ModelState));
}
else
return Json(null);
}
And the Grid:
#(Html.Kendo().Grid<Stock>()
.Name("stock")
.Columns(columns =>
{
columns.ForeignKey(x => x.CGoodCode, (IEnumerable)ViewData["Goods"], "Id", "Text");
///
columns.Command(command => { command.Edit(); command.Destroy(); });
})
.ToolBar(toolbar => {
toolbar.Create();
toolbar.Excel();
toolbar.Pdf();
})
.Editable(edit => edit.Mode(GridEditMode.PopUp))
.Sortable()
.Pageable(p => p.PageSizes(true))
.DataSource(ds =>
ds.Ajax()
.Model(model => {
model.Id(x => x.CGoodCode);
model.Id(x => x.SWhCode);
model.Id(x => x.LiIdPeriod);
model.Field(x => x.CGoodCode).DefaultValue(ViewData["GoodsDefault"]);
////
})
.Read("Read", "Stock")
.Update("Edit", "Stock")
.Create("Create", "Stock")
.Destroy("Delete", "Stock")
)
)
UPDATE
It seems Kendo Grid doesn't support composite primary keys yet!
This question helped me out! I just need to rename the parameter like:
public ActionResult Create([DataSourceRequest] DataSourceRequest request, Stock somethingElse){
Because my class contains some fields with that name, Stock!
I am not able to get Kendo UI Multiselect's value in controller. it gives me length of list as 0. MultiSelect is as:
#(Html.Kendo().MultiSelectFor(model => model.Technicians)
.Name("Technicians")
.Placeholder("Select Technician(s)")
.DataTextField("Name")
.DataValueField("ID")
.Filter(FilterType.Contains)
.AutoBind(true)
.DataSource(source =>
{
source.Read(read =>
{
read.Action("GetTechnicians", "Project");
})
.ServerFiltering(false);
})
.BindTo(Model.Technicians)
)
Technicians is : public List Technicians{get; set;} in model
I ran into this problem as well.
We ended up creating an IEnumerable<int> of Ids in the viewmodel to store that value.
So, in our instance
public IEnumerable<PersonLookupViewModel> TaggedPersons { get; set; } (this is the list of people with IDs that I really want - contains first/last/id)
public IEnumerable<int> PeopleToTag { get; set; } (this is the IEnumerable Int of the view model solely for posting the ints to the controller)
My view looked like this:
<div class="editor-field">
#Html.LabelFor(model => model.taggedPersons)
#Html.ListBoxFor(model => model.PeopleToTag,
new SelectList(Model.CommitteeMembers, "PersonId", "FullName"))
</div>
and the JS wire up
$("#PeopleToTag").kendoMultiSelect({ "dataTextField": "FullName", "dataValueField": "PersonId", "placeholder": "Tag or Untag Persons to Action Item" });
So switching it to a ListBoxFor(model = > model.PeopleToTag) which was my Ienumerable field in my viewmodel solely to be able to get the data in the controller. I then used automapper to create the Person model I actually needed.
I'm not sure if this is the best way, but it worked for us.
I have a Kendo grid set up like so:
#(Html.Kendo().Grid<ParticipatingDentalEE>()
.Name("DentalEE")
.Columns(columns =>
{
columns.Bound(p => p.State).Title("State").Width(150).EditorTemplateName("State");
columns.Bound(p => p.Count).Title("Count").Width(150);
columns.Command(c => { c.Edit(); c.Destroy(); });
})
.DataSource(dataSource => dataSource
.Ajax()
.Model(m => {
m.Id(p => p.State);
m.Field(p => p.State).Editable(true);
m.Field(p => p.Count).Editable(true).DefaultValue("");
})
.Create(update => update.Action("EditingInline_Create", "Dental"))
.Read(read => read.Action("EditingInline_Read", "Dental"))
.Update(update => update.Action("EditingInline_Update", "Dental"))
.Destroy(update => update.Action("EditingInline_Destroy", "Dental"))
)
//.Scrollable()
//.Sortable()
.Editable(e => e.Mode(GridEditMode.InLine))
)
The "State" column consists of a dropdown template that looks like this:
#(Html.Kendo().DropDownList()
.Name("States") // Name of the widget should be the same as the name of the property
.DataValueField("CODE") // The value of the dropdown is taken from the EmployeeID property
.DataTextField("NAME") // The text of the items is taken from the EmployeeName property
.BindTo((System.Collections.IEnumerable)ViewData["States"]) // A list of all employees which is populated in the controller
)
My dropdown shows up properly when I edit or create an item, but when I save the item the dropdown value does not stay in the grid. Is there something else I need to set up in order to do this?
as you say in your own comment,
.Name("States") // Name of the widget should be the same as the name of the property
which is to say, it must match the name of the column, and the column name is "State" not "States".
Obviously this is an old thread, however the fix is to use the DropDownListFor method (as opposed to the DropDownList) and not to specify a name. I suspect Kendo does some internal name matching to apply the edited value back to the model.
#model int // ...or whatever type works for your model
#(Html.Kendo().DropDownListFor(i => i)
.DataValueField("CODE")
.DataTextField("NAME")
.BindTo((System.Collections.IEnumerable)ViewData["States"]))
I'm not sure if this will fix your problem, but the editor templates for my grid didn't work correctly until I had set the UIHint decorator in the model, and the EditorTemplateName in the view.
E.g.
public class ParticipatingDentalEE {
...
[UIHint("State")] // this should be the name of your EditorTemplate
public State State { get; set; }
}
I speculate that UIHint is used for the grid in 'view' mode, while the EditorTemplateName is used while in 'edit' mode, and both are required to link the two together.
I am using KendoUI on MVC4.
I have a DropDownList bound to a model property that is a empty string:
#(Html.Kendo().DropDownListFor(model => model.AppUserStatus)
.Name("userStatusDropDownList")
.DataTextField("Text")
.HtmlAttributes(new {style = "width:100%;"})
.DataValueField("Value")
.BindTo(#ViewBag.StatusList))
model.AppUserStatus is a string that is empty by default.
After the user selects a new item , or leaves the selected item as the default item (index 0) and posts the form back, the model.AppUserStatus is empty still, even though all the other fields are correctly bound:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Update(EditUserViewModel model)
{
model.AppUserStatus ***** IS Null always, all other fields are good
return View("EditUser", model);
}
You don't need to set Name("userStatusDropDownList") property for control.
Remove it and the name will be auto generated properly - i.e. #AppUserStatus.
This Name method also controls the name by the value that is posted to the server - the name attribute of the input element which is posted.