kendo radio button value - asp.net-mvc

I've following code in razor view. How do I use Kendo Radio button to render the same? Mainly, I'm struggling to assign enum value to radio button value.
#if (Model == declaredEnum.​Val1)
{
#Html.RadioButtonFor(l => l, (int)declaredEnum.​Val1, new { #checked = "checked" });
}
else
{
#Html.RadioButtonFor(l => l, (int)declaredEnum.​Val1);
}
#Html.LabelFor(l => l, "Label")​
Edit
Definition of Enum
Public Enum declaredEnum
{
Val1,
Val2
}
There is another radio button with the same code, but it checks for val2. Current logic is working fine. I just need to convert to Kendo control instead of razor.

I realize that this post is very old, but I am working with Kendo UI for the first time and needed to figure this out for myself. The following code snippet creates a radio button group called "name-of-radio-group" from an enum with two values. It defaults the first radio button to checked:
<div class="form-group row">
#Html.Label(Enum.GetNames(typeof(declaredEnum)).ToList()[0], new { #class = "col-sm-2" })
#(Html.Kendo().RadioButtonFor(m => m.declaredEnum).Checked(true).Name(Enum.GetNames(typeof(declaredEnum)).ToList()[0])
.HtmlAttributes(new { #class = "col-sm-1", name = "name-of-radio-group"}))
#Html.Label(Enum.GetNames(typeof(declaredEnum)).ToList()[1], new { #class = "col-sm-2"})
#(Html.Kendo().RadioButtonFor(m => m.declaredEnum).Name(Enum.GetNames(typeof(declaredEnum)).ToList()[1])
.HtmlAttributes(new {#class = "col-sm-1", name = "name-of-radio-group"})
)
</div>
In my example I only had two enum values so I did not feel the need to use a loop, instead I just indexed the enums directly. In case it is not clear to someone the m.declaredEnum represents a property on a strongly typed model where the property name is the same as the name of the enum.

Related

ASP.Net MVC Dynamic input bound to same controller property

I have 2 controller fields say Type and Data.
Depending on value selected for Type (Date or Text), I want to display Data field dynamically as either a text input or a custom timepicker input.
Since only one will be rendered at any time, I need to bind with the same property name (Data).
This is what I am trying:
#if (Model.Type == "Date")
{
// custom timepicker control goes here
<input asp-for="Data" class="form-control timepicker"/>
}
else
{
<input asp-for="Data" class="form-control text-input" type="text"/>
}
On page load only text input is rendered, and it shows/hides based on Type selected. The timepicker input is never displayed (the html is not generated at all).
Is there a way to achieve this in MVC?
You can not have two <input> elements with the same name. If a <form> containing multiple inputs with the same name is posted, the MVC model binder will only bind one value from the last input.
To achieve what you want, you have two options:
Either have only one input with name="Data" of type="text" in the View, and let the timepicker write the time as a string to this input. Then in the controller, parse this input value depending on the selected Type.
Or have two inputs with name="TextData" and name="TimeData", and disable and hide one of these inputs using JS depending on the selected Type. In the controller, read the value from the right input depending on the selected Type. This is arguably the cleaner solution.
In MVC5 the second solution would look like this (I am not familiar with MVC-Core):
#model MyViewModel
#using (Html.BeginForm("Submit", "MyController", FormMethod.Post)) {
#Html.EditorFor(m => m.Type)
#Html.EditorFor(m => m.TextData, new { #class = "text-input"})
#Html.EditorFor(m => m.TimeData, new { #class = "timepicker"})
}
<script type="text/javascript">
function toggleInput_() {
if ($('##Html.IdFor(m => m.Type)').val() === 'Text') {
$('##Html.IdFor(m => m.TextData)').prop('disabled', false).show();
$('##Html.IdFor(m => m.TimeData)').prop('disabled', true).hide();
}
else {
$('##Html.IdFor(m => m.TextData)').prop('disabled', true).hide();
$('##Html.IdFor(m => m.TimeData)').prop('disabled', false).show();
}
}
$(document).ready(function() {
$('##Html.IdFor(m => m.Type)').on('change', function() {
toggleInput_(); // toggle when drop down changes
});
toggleInput_(); // toggle initially on page load
});
</script>
Controller:
[HttPost]
public ActionResult Submit(MyViewModel postData) {
string textValue = null;
DateTime? timeValue = null;
if (postData.Type == "Text") {
textValue = postData.TextData;
}
else {
timeValue = postData.TimeData;
}
// ...
}
ASP MVC already has this functionality built in with Editor Templates. By following the convention, you can specify a template to be used for any type (including user-defined complex types) which will be rendered with #Html.EditorFor().
In a nutshell, just place two partial views in your ~/Views/Shared/EditorTemplatesfolder, one with model type DateTime and the other string. The correct partial view will be rendered when using #Html.EditorFor(m => m.Property) based on the type of Property.
Note: the default editor for a string property will already be an input with type="text", so you don't necessarily need to specify that template.
See this link for a tutorial on Editor templates (and Display templates):
https://exceptionnotfound.net/asp-net-mvc-demystified-display-and-editor-templates/

Razor EditorFor with Onclick Event

I have nullable Boolean value that is being presented as a checkbox using the following code:
#Html.EditorFor(m => m.IsInitialStatus, new { htmlAttributes = new { #onclick = "InitialOrStarting()" } })
however the #onclick attribute is not being added to the HTML when the page is loaded. Am I missing something here? I had taken the example from an answer on this page.
I have also looked at changing this to a CheckBoxFor but keep getting an issue with the nullable Bool datatypes.
Any help on this would be appreciated! I just want a nullable bool checkbox with an onClick event firing to a Javascript function... I am not the most advanced user but this seems to be more difficult for me to do than maybe it should!?
EDIT
There appears to be an EditorTemplate for Boolean which contains:
#model bool?
#Html.CheckBox("", Model.GetValueOrDefault())
You are using the overload of EditorFor() where the 2nd parameter is additionalViewData. If you did not have a specific EditorTemplate for bool?, the method would generate the default template, which is a <select> with 3 values for null, true and false, and include the attributes.
But because you have an EditorTemplate, you need to add the attributes yourself by reading the value from the ViewDataDictionary (typically, an EditorTemplate includes multiple html elements, so the method cannot know which element you want to apply the attributes to).
Your template would need to be
#model bool?
#{ var attributes = ViewData["htmlAttributes"]; }
#Html.CheckBox("", Model.GetValueOrDefault(), attributes)
Having said that, your should not be doing this. A bool? has 3 states (null, true or false) but a checkbox has only 2 states - on or off (translates to true or false) so your EditorTemplate does not represent the possible values of your property.
If you only want to allow true or false, then your property should not be nullable. Alternatively, use the default template that does allow a null selection (or if you want an alternative UI, create a template that renders 3 radio buttons for example)
In addition, I recommend you stop polluting you markup with behavior and use Unobtrusive JavaScript - i.e. your script will be
$(yourCheckBox).click(function() {
... // do something
});
Onclick Event does not working for #HtmlEditorFor. But you can use class attribute.
<script>
$(".single-checkbox").on("change", function () {
if ($(".single-checkbox:checked").length > 2) {
this.checked = false;
alert ("Only 2 choice")
}
});
</script>
#Html.EditorFor(model => model.YourProperty, new { htmlAttributes = new { #class = "single-checkbox" } })
#Html.EditorFor(model => model.YourProperty, new { htmlAttributes = new { #class = "single-checkbox" } })
#Html.EditorFor(model => model.YourProperty, new { htmlAttributes = new { #class = "single-checkbox" } })
#Html.EditorFor(model => model.YourProperty, new { htmlAttributes = new { #class = "single-checkbox" } })

In Asp.net MVC Razor Radiobutton, how to assign variable to name?

I have multiple radio button groups on my razor cshtml page. I need to specify the name as a variable because each group needs to have it's own unique radio button choice. Basically I have what is below that does not work. that is, workshopDay does not appear to be being interpreted as a variable.
#foreach (var workshopDay in new List<string> {"Wednesday", "Thursday"})
...
#Html.RadioButtonFor(a => a.AngularUsignup.AttendeeParty,
new { #class = "radio",#name="#(workshopDay)" })
try following.
#foreach (var workshopDay in new List<string> {"Wednesday", "Thursday"})
...
#Html.RadioButtonFor(a => a.AngularUsignup.AttendeeParty,
new { #class = "radio",#name=workshopDay.ToString() })
Note: As Stephen mentioned in comment to question it will allow all radio button to be selected. Instead you should use checkbox in such a scenarios.
This is one of those gotcha's:
To override the name attribute (or one of the other attributes that the HtmlHelper adds for you) you need to use the attribute name with the first letter upper-cased (so: "Name" rather than "name"):
#Html.RadioButtonFor(a => a.SomeProperty, new { Name="yourValuehere" })
So, I think your example goes to:
#Html.RadioButtonFor(a => a.AngularUsignup.AttendeeParty,
new { #class = "radio",#Name="#(workshopDay)" })
HTH

DropDownListFor HTML helper not selecting option for Enum model property

I have an ASP.NET MVC 4 site and a domain model that uses an Enum. I'm able to generate a list of SelectListItem objects, but the proper item is not selected.
Domain Model
public enum ApplicationStatus
{
Unknown = 0,
Incomplete = 1,
Submitted = 2,
Error = 4
}
public class Application
{
public ApplicationStatus Status { get; set; }
// ...
}
The "Edit" View
#model Application
#using (Html.BeginForm("Edit", "Applications", new { ... }, FormMethod.Post, new { role = "form", #class = "form-horizontal" }))
{
#Html.Partial("_Form", Model)
<p>
#Html.ActionLink("Cancel", "Details", new { ... }, new { #class = "btn btn-default" })
<button type="submit" class="btn btn-primary">Save</button>
</p>
}
The "_Form" Partial
#model BWE.Models.Entity.BitWeb.Application
#Html.ValidationSummary(true)
<div class="form-group">
#Html.LabelFor(model => model.Status, new { #class = "col-sm-2" })
<div class="col-sm-10">
#Html.DropDownListFor(model => model.Status, SelectHelper.GetApplicationStatusOptions(Model.Status))
#Html.ValidationMessageFor(model => model.Status)
</div>
</div>
SelectHelper
public static class SelectHelper
{
public static IEnumerable<SelectListItem> GetApplicationStatusOptions(ApplicationStatus currentStatus)
{
var items = new List<SelectListItem>()
{
new SelectListItem()
{
Text = "Select",
Value = string.Empty
}
};
IEnumerable<ApplicationStatus> statuses = Enum.GetValues(typeof(ApplicationStatus)).Cast<ApplicationStatus>();
foreach (var status in statuses)
{
if (status == ApplicationStatus.Unknown)
continue;
items.Add(new SelectListItem()
{
Text = status.ToString(),
Value = ((int)status).ToString(),
Selected = status == currentStatus
});
}
return items;
}
}
The "Select" option is always selected in the dropdown even though I can step through the code and see one of the SelectListItem objects get their Selected property set to true.
I've tried the solution recommended in My templated helper using a DropDownListFor does NOT reflect the model of enum. Why?, but this solution was geared towards MVC 3. I tried the solution (passing a SelectList object as the second argument to Html.DropDownListFor) and all I got was a dropdown list with 4 options whose display text was "System.Web.Mvc.SelectListItem" and no values for the <option> tags.
Furthermore, I tried other solutions that created an #Html.EnumDropDownListFor(...) helper function, which behaved the same way. It seems that all though the proper SelectListItem is getting selected, maybe the current Model.Status value is overriding it?
Update #1
I added an integer property called StatusId which gets and sets the Status property as an integer, and this works when calling Html.DropDownListFor(model => model.StatusId, ...) however I was hoping for a solution that allows me to use the enum value directly, not as a proxy through another property.
For some crazy reason, enum values are rendered as their string-based names by Razor, rather than their integer value counterparts. Regardless, my guess is that your SelectHelper is returning options with values as integers, which is why converting your enum value to an int allowed the selection to work. Since this is a custom component you have anyways, I would suggest simply modifying your helper to return the enum string names as the option values instead of ints. Then the property value and the option values will line up properly.

Selected property is ignored in MVC using DropList or DropListFor

I have an enum, which is a mapping for a description of a property against an index in the database. I have a property on my ViewModel that represents an instance of that enum. I've tried both returning a list of enum instances, which means I do this:
#Html.DropDownListFor(m => m.CurrentFilter,
Model.FilterTypes.Select(entry =>
new SelectListItem{ Text = entry.ToString(), Value = ((int)entry).ToString()}),
new { #class = "normalcell", style = "WIDTH: 132px;" })
and returning a list of SelectListItems, which means I do this:
#Html.DropDownListFor(m => m.CurrentFilter,
Model.FilterTypes.Select(entry =>
new SelectListItem{ Text = entry.Text, Value = entry.Value, Selected = entry.Selected}),
new { #class = "normalcell", style = "WIDTH: 132px;" })
In the second case, when I debug, I am certain that the Selected property on the entry object is true for the correct item. In both cases, there is no 'selected' attribute written in to my HTML and so the correct item is not selected. I've also set a breakpoint, and CurrentFilter DOES have the correct value and the rest of my page renders appropriately, so it's finding the value.
I've written plenty of drop lists that work, using similar code, I can't for the life of me see why this does not work, no matter how I try to do it ?
I have also tried:
#Html.DropDownListFor(m => m.CurrentFilter,
Model.FilterTypes,
new { #class = "normalcell", style = "WIDTH: 132px;" })
which seems to me to be the logical way to do it ( return a list of SelectListItems and just do no processing in the page ), but the Selected property is still ignored.
Update:
I tried to do it this way:
#Html.DropDownList("CurrentFilter", Model.FilterTypes, new { #class = "normalcell", style = "WIDTH: 132px;" })
and just read the value out of the request. It's still the case that I am returning a list with only one item that has Selected == true, and it's still the case that MVC is ignoring it.
This works, not surprisingly, but I'd love to know why all the other things don't.
<select class="normalcell" id="CurrentFilter" name="CurrentFilter" style="WIDTH: 132px;">
#foreach (SelectListItem item in Model.FilterTypes)
{
if (item.Selected)
{
<option value="#item.Value" selected="selected">#item.Text</option>
}
else
{
<option value="#item.Value">#item.Text</option>
}
}
I believe the reason is that the MVC binding engine doesn't know how to deal with Enum values. I think you need to create a "proxy" property for your view model. Something like this...
public enum MyEnum { a, b, c, d };
public MyEnum EnumVal { get; private set; }
public string EnumProxy
{
get { return EnumVal.ToString(); }
set { EnumVal = (MyEnum)Enum.Parse(typeof(MyEnum), value); }
}
Then construct the drop-down list using the Enum names:
Type t = typeof(MyEnum);
var ddList = Enum.GetNames(t).Select(
item => new SelectListItem() { Text = item, Value = item }
).ToArray();
Now you should be able to use DropDownListFor normally:
#Html.DropDownListFor(model => model.EnumProxy, ddList)
I'm not sure if there's a neater solution. This one should work though.
My DDL tutorial shows how to use enums. See See my tutorial Working with the DropDownList Box and jQuery and My blog Cascading DropDownList in ASP.Net MVC Part 2 of the tutorial explains: When the string argument (the property to bind) and the SelectList object have the same name, the selected value is not used.
Darin has a SO post on another common reason the selected value is not display. See MVC DropDownList SelectedValue not displaying correctly

Resources