Model binding fails with Kendo MultiSelect - kendo-ui

In the model I have long? field that I like to use Kendo MultiSelect for it. The main reason for this choice is server-side filtering. It doesn't reflect current Model's value, nor it sends any value to the server. By inspected traffic, I'm sure that it doesn't update the model's value.
#(Html.Kendo().MultiSelectFor(x => x.theField)
.Name("msname")
.MaxSelectedItems(1)
.Placeholder("")
.HighlightFirst(true)
.DataValueField("Id")
.DataTextField("Text")
.AutoBind(true)
.DataSource(ds =>
ds.Read(" ", "API").ServerFiltering(true))
.Value(new long?[] { Model.theField})
)
I can put a hidden field and update its value or multiselect's change, but there should be a better solution.
I should note that this multi select is in an editor template and is used by Kendo Grid in popup editor.
UPDATE
When using nullable types, you need to use ValuePrimitive(true)! So the end code is:
#(Html.Kendo().MultiSelectFor(x => x.theField)
.MaxSelectedItems(1)
.Placeholder("")
.HighlightFirst(true)
.DataValueField("Id")
.DataTextField("Text")
.AutoBind(true)
.DataSource(ds =>
ds.Read(" ", "API").ServerFiltering(true))
.ValuePrimitive(true)
)

The main reason for this choice is server-side filtering
You can find on their demo site that DropDownList and ComboBox also support that feature. But if you insist to use MultiSelect then lets dig some of your code.
Look Name() method will give a name for your input element e.g (input, select). When form serialized it will use our input name as form's field property. If you are using HtmlHelper that ends with "For" e.g (LabelFor, MultiSelectFor) input attribute name will be named by its binded property.
Html.Kendo().MultiSelectFor(x => x.theField)
You will have
<select name="theField"> ....
You don't have to use Name() method anymore, therefore MultiSelect value will be binded as theField property as per form serialized to server.
Now if you look to Request.Form["theField"] when you debug inside your controller, you will see what value being sent. It usually a content of joined string array if multiple items selected, so you need to change theField type to handle array of string or int instead of nullable long type.
EDIT
At last you find the way to solve your problem, this solution credit to Akbari
When using nullable types, you need to use .ValuePrimitive(true)

Related

how to get selected value for Kendo DropDownList

I can't figure out how to determine which item is selected in the my kendo dropdownlist. My view defines it's model as:
#model KendoApp.Models.SelectorViewModel
The ViewModel is defined as:
public class SelectorViewModel
{
//I want to set this to the selected item in the view
//And use it to set the initial item in the DropDownList
public int EncSelected { get; set; }
//contains the list if items for the DropDownList
//SelectionTypes contains an ID and Description
public IEnumerable<SelectionTypes> ENCTypes
}
and in My view I have:
#(Html.Kendo().DropDownList()
.Name("EncounterTypes")
.DataTextField("Description")
.DataValueField("ID")
.BindTo(Model.ENCTypes)
.SelectedIndex(Model.EncSelected)
)
This DropDownList contains the values I expect but I need to pass the selected value back to my controller when the user clicks the submit button. Everything works fine except I don't have access to which item was selected from the controller's [HttpPost] action. So, how do i assign the DropDownList's value to a hidden form field so it will be available to the controller?
For anyone who found this wondering how to get the selected value in JavaScript, this is the correct answer:
$("#EncounterTypes").data("kendoDropDownList").value();
From the documentation: http://docs.telerik.com/kendo-ui/api/javascript/ui/dropdownlist#methods-value
when select a value from a dropdown list, and in the selec event , we can get the selected value as following ,
#(Html.Kendo().DropDownList()
.Name("booksDropDown")
.HtmlAttributes(new { style = "width:37%" })
.DataTextField("BookName")
.DataValueField("BookId")
.Events(x => x.Select("onSelectBookValue"))
.DataSource(datasource => datasource.Read(action => action.Action("ReadBookDropDow", "PlanningBook").Type(HttpVerbs.Get)))
.OptionLabel("Select"))
javascript function like following ,
function onSelectBookValue(e) {
var dataItem = this.dataItem(e.item.index());
var bookId = dataItem.BookId;
//other user code
}
I believe this will help someone
Thanks
Hello I was just going through this problem,kept on searching for 2 hours and came up with a solution of my own.
So here is the line to fetch any data bidden to the kendo drop down.
$("#customers").data("kendoDropDownList").dataSource._data[$("#customers").data("kendoDropDownList").selectedIndex].colour;
Just change the id customers to the id you have given tot he kendo drop down.
Maybe you should be using the DropDownListFor construct of the Kendo DropDownList like so in your view:
#(Html.Kendo().DropDownListFor(m => m.EncSelected)
.Name("EncounterTypes")
.DataTextField("Description")
.DataValueField("ID")
.BindTo(Model.ENCTypes)
.SelectedIndex(Model.EncSelected)
)
This way, when you submit, it will be availble on the POST request and you won't need to put an hidden field anywhere.
BUT should you need to use the hidden field for some reason, put it there, subscribe the the select event of the dropdown list and put using JQuery (for instance) put the selected item on the hidden field.
It's your choice :)
If you want to read also out the text of the dropdown, you can get or set the value by using the following kendo function:
$('#EncounterTypes').data("kendoDropDownList").text();
REFERENCE TO THE DOCUMENTATION
Using this .val() as #Vivek Parekh mentions will not work - there is no function .val() in the kendo framework.
If you want you could use jQuery and get the value back: $('#EncounterTypes').val()
Updated DEMO
$("#EncounterTypes").kendoDropDownList().val();
You can get the selected item like following code and then use item.property to get further information
var selectedFooType = $("#fooType").data("kendoDropDownList").dataItem();
selectedFooType.name
//OR
selectedFooType.id

Binding current value to SelectList's display

I've been able to correctly display a dictionary as a dropdownlist as well as pull it's value on a page submit. But on the GET (initial display) the selected item does not reflect the object's value. My controller is passing state:
ViewData["Status"] = new SelectList(AppHelper.WebinarStatuses, "Key", "Value", selectedStatus);
the View:
<%: Html.DropDownListFor(m => m.Status, (ViewData["Status"] as SelectList), Model.Status )%>
I understand that I need to find the right overload of the DropDownListFor helper - I don't understand how I go about doing that. Small picture, what syntax forces the select list to display what the controller's sending - bigger picture, how do I discover/interpret which overload does what?
profuse thanks

MVC Html.DropDownList selected value being overriden by QueryString value

I am using a dropdownlist in my view like so:
#Html.DropDownList("ClientId", Model.AvailableClients, "-- None --")
Model.AvailableClients is an IEnumerable one of the item's Selected property is set to true. If in the query string for the page request includes "ClientId=" (as in its not set) MVC ignores my selected item. I assume this is because MVC is trying to be helpful and set the selected item automatically using the querystring, but I dont want this.
How can I prevent the querystring value from overriding my item's selected value?
If the name you give your DropDownList is already the name of an element in your model then DropDownList will automatically override the selected value with the model value. If letting ClientId determine the selected value isn't an option then the only solution I know is to rename the DropDownList with a name not included in the model.
#Html.HiddenFor(m => m.ClientId)
#Html.DropDownList("ClientIdNewName", Model.AvailableClients, "-- None --", new { onchange = "ClientId.value = this.value"})
This will keep the value in ClientId without making it the default selection value.

DropDownList MVC3

I am doing a edit operation on a record in Grid . One of the column is DropDownValue.
When I go to Edit View , depending upon this dropdownvalue , I make few fields editable and readable. And , One more point is here, I didnt select the dropdown Yet, But whatever its value selected before is the one which I should retrieve. I know I have to use jQuery .But I didnt exact Syntax to do tht.
Here is my dropdown
<div id="dvstatus">
#Html.DropDownListFor(model => model.Study.StudyStatusId, Model.StatusSelectList, new { id = "ddlStatus" })
</div>
NOT SELECTED VALUE, BUT THE VALUE WITH WHICH IT IS LOADED
My requirement is how to get the dropdown value item , when it is loaded onto .cshtml
If you're not referring to the selected value of the dropdown then just pass the value from the controller to your view using your model if you're using a strongly-typed view or pass it some other way like using ViewBag and just set the value when it's passed on view.
You can add a hidden field to save the initially loaded value. Eg
<div id="dvstatus">
#Html.HiddenFor(model => model.Study.StudyStatusId)
#Html.DropDownListFor(model => model.Study.StudyStatusId, Model.StatusSelectList, new { id = "ddlStatus" })
</div>
Then you can use java script to compare current value of the drop down and the value of the hidden field(which has the initial value).

mvc 3 html attributes

i have been playing around with MVC. I am currently stumped on with html helper methods. One thing i have noticed is that I cant really cant apply the ASP.NET Web Form logic into MVC. To explain further, in ASP.NET I could create a Label control and assign it some text data and then read the text data.
However, in MVC, I cant seem to do the same with #Html.LabelFor/#Html.Label, I have realised that once you do a POST from your form, the value from the Label is not bound back into my view model. However, if I use an EditorFor or TextBoxFor, I can get values bound to my viewmodel upon POST.
My question what html hlper method should I use to display text as readonly but yet be able to bind back to my viewmodel upon post ? I have tried TextBoxFor with its html attributes set to disabled and readonly but no luck.
Appreciate any pointers.
thanks
You should be able to bind the readonly attribute to the TextBox by passing in htmlAttributes as the 2nd parameter of the TextBoxFor method:
<%=Html.TextBoxFor(m => m.SomeProperty, new { #readonly = "readonly" }) %>
On MSDN: InputExtensions.TextBoxFor Method (HtmlHelper, Expression>, Object)
If you're trying to maintain the Label value you can use a combination of the LabelFor and HiddenFor methods.
I don't know why you would need to do this though, since you should be able to get the DisplayText attribute or the Property Name from the property.
<%=Html.LabelFor(m => m.SomeProperty) %>
<%=Html.HiddenFor(m => m.SomeProperty) %>
but this doesn't make a lot of sense since the usual syntax would be:
<%=Html.LabelFor(m => m.SomeProperty) %>
<%=Html.TextBoxFor(m => m.SomeProperty) %>
Note that if you use the disabled attribute the input will not be posted when the form is submitted
This is expected behaviour, only values form elements are added to your Model on POST so your label will be ignored. To get around this duplicate your label value in a hidden field
Html.HiddenFor(model => model.FieldName)
or
Html.Hidden("FieldName", model.FieldName)

Resources