ASP.NET MVC Get Id (value) from DropDownListFor - asp.net-mvc

I have a series of DropDowns that I want the user to add to and edit. I found a helper extension from StackOverflow to build an action image link.
#Html.DropDownListFor(model => model.Entry.ParadigmId, ((IEnumerable<Pylon.Models.Paradigm>)ViewBag.PossibleParadigms).Select(option => new SelectListItem {
Text = (option == null ? "None" : option.Name),
Value = option.ParadigmId.ToString(),
Selected = (Model != null) && (option.ParadigmId == Model.Entry.ParadigmId)
}), "Select")
#Html.ActionImage("ParadigmEdit", new { id = ? }, "~/Content/Images/Edit_Icon.gif", "ParadigmEdit")
I am not sure how to reference the selected id value in the DropDownList where the question mark is in the above code.

You can't reference the selected value from the dropdown using server side code (which what HTML helpers represent) because the selection is done by the user on the client side. Your problem stems from the fact that you are trying to generate an anchor which should send a value which is known only by the client. You can do this only using javascript. Or another possibility is to simply use a form with an image submit button:
#using (Html.BeginForm("ParadigmEdit", "ControllerName"))
{
#Html.DropDownListFor(
model => model.Entry.ParadigmId,
// WARNING: this code definetely does not belong to a view
((IEnumerable<Pylon.Models.Paradigm>)ViewBag.PossibleParadigms).Select(option => new SelectListItem {
Text = (option == null ? "None" : option.Name),
Value = option.ParadigmId.ToString(),
Selected = (Model != null) && (option.ParadigmId == Model.Entry.ParadigmId)
}),
"Select"
)
<input type="image" alt="ParadigmEdit" src="#Url.Content("~/Content/Images/Edit_Icon.gif")" />
}
and of course after you move the ugly code where it belongs (the mapping layer or the view model) your code would become:
#using (Html.BeginForm("ParadigmEdit", "ControllerName"))
{
#Html.DropDownListFor(
model => model.Entry.ParadigmId,
Model.ParadigmValues,
"Select"
)
<input type="image" alt="ParadigmEdit" src="#Url.Content("~/Content/Images/Edit_Icon.gif")" />
}

Related

MVC default to checked based on value in item

I have an MVC 5 project and we are creating radio buttons from database records.
It works fine below but there has to be a way to NOT have the if check in there and either append the checked after the fact or even before.
As shown below, the only difference between the 2 radio button creations is: new { #checked = "checked" }
#{
foreach (var item in Model.PaintColor)
{
if (item.DefaultChoice == true)
{
#Html.RadioButtonFor(m => m.pledge.PaintColorId,
item.ColorId.ToString(),
new { #checked = "checked" }
)
}
else
{
#Html.RadioButtonFor(m => m.pledge.PaintColorId,
item.ColorId.ToString()
)
}
#Html.Label("Color" + item.ColorId, item.ColorDesc)
}
<br />
}
See comments from Stephen regarding fixing this. Basically setting it as checked as not required as since it checks the value that it is being bound to.
When the view model is initially created I set the field value to the Default value and the radio button is set as checked.
foreach (var item in Model.PaintColor)
{
var idVal = string.Format("PaintColor_{0}", item.ColorId);
<div>
<label>
#Html.RadioButtonFor(m => m.pledge.PaintColorId,
item.ColorId,
new { id = string.Format("Rb{0}", idVal) }
)
<span>#item.Description</span>
</label>

Include 'ALL' option in dropdownlist bind using ViewBag

I have bind the dropdownlist in view by Viewbag from controller as following :
ViewBag.test = from p in _userRegisterViewModel.GetEmpPrimary().ToList().Where(a => a.UserType_id != Convert.ToInt32(Session["loginUserType"].ToString()))
select new
{
Id = p.EmpId,
Name = p.First_Name.Trim() + " " + p.Last_Name.Trim()
};
In view I have bind as following :
#Html.DropDownListFor(model => model.EmpId, new SelectList(#ViewBag.test, "Id", "Name"),
new { #class = "form-control", id="ddlEmp" })
Now i want to Insert "ALL" and "--Select--" in this dropdownlist.. How can i do this..
Can anyone help me to do this..
Thanks in advance..
You can add a null option to the dropdownlist by using one of the overloads of DropDownlistFor() that accepts a optionLabel, for example
#Html.DropDownListFor(m => m.EmpId, new SelectList(#ViewBag.test, "Id", "Name"), "--select--", new { #class = "form-control", id="ddlEmp" })
which will generate the first option as <option value="">--select--</option>
However, if you want to include options with both "--select--" and "ALL" you will need to generate you own IEnumerable<SelectListItem> in the controller and pass it to the view. I would recommend using view model with a IEnumerable<SelectListItem> property for the options, but using ViewBag, the code in the controller would be
List<SelectListItem> options = _userRegisterViewModel.GetEmpPrimary()
.Where(a => a.UserType_id != Convert.ToInt32(Session["loginUserType"].ToString()))
.Select(a => new SelectListItem
{
Value = a.EmpId.ToString(),
Text = a.First_Name.Trim() + " " + a.Last_Name.Trim()
}).ToList();
// add the 'ALL' option
options.Add(new SelectListItem(){ Value = "-1", Text = "ALL" });
ViewBag.test = options;
Note that I have given the ALL option a value of -1 assuming that none of your EmpId values will be -1
Then in the view, your code to generate the dropdownlist will be
#Html.DropDownListFor(m => m.EmpId, (Ienumerable<SelectListItem>)ViewBag.test, "--select--", new { #class = "form-control" })
Not sure why your wanting to change the id attribute from id="EmpId" to id="ddlEmp"?
Then in the POST method, first check if ModelState is invalid (if the user selected the "--select--" option, a value of null will be posted and the model will be invalid), so return the view (don't forget to reassign the ViewBag.test property).
If ModelState is valid, then check the value of model.EmpId. If its -1, then the user selected "ALL", otherwise they selected a specific option.

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.

ng-model on hidden razor input not working

In my MVC 5 Razor view, I created a hidden field, like this:
#Html.HiddenFor(x => x.FormData.UserId,
new { ng_model = "selectedEmployee.userId" })
When I perform the necessary angular action to fill the selectedEmployee.userId property, the hidden input's value is not filled.
But, when I change it to
#Html.TextBoxFor(x => x.FormData.UserId,
new { ng_model = "selectedEmployee.userId" })
It's working and the data is posted to the server.
And
<input type="hidden" name="FormData.UserId" value="{{selectedEmployee.userId}}">
is working, but
#Html.HiddenFor(x => x.FormData.UserId,
new { value = "{{selectedEmployee.userId}}" })
is not. (which probably has to do with Razor overwriting the HTML value)
What's the reason that in Razor a hidden input with an ng-model is not working?
Please change value into ng_value
#Html.HiddenFor(x => x.FormData.UserId,
new { ng_value = "{{selectedEmployee.userId}}" })
Here is how to assign a value to Hidden field. 'V' character of value attribute must be Capital letter.
<div data-ng-controller="MyFunction">
#{Html.BeginForm("SchoolMedium", "BasicSetup", FormMethod.Post, new { });
#Html.HiddenFor(s => s.SchoolMediumId, new { Value = "{{mascotmedium.SchoolMediumId}}" });
Html.EndForm();
}
and in controller
$scope.EditWhenAdded= function(row){
$scope.mascotmedium = row.entity;
};

Ext.Net MVC - Render partial view with parameter

I have a partial view on my mvc page. The view is rendered by default with no data, but will be updated based on a value selection from a combobox in another section of the page. The partial view takes an id as a parameter which it will use to get the data needed to return the model.
The problem that I am having is that on the initial load, the parameter is null since nothing has been selected and I am getting a null value exception.
Is there a way that I can use an if statement in a direct events call to check the selected item and return 0 is that is null?
See me sample code below for clarification.
Thanks
Here are the relevant parts of my main page (index.cshtml) -
x.ComboBox()
.ID("MyCombo")
.DisplayField("Title")
.ValueField("Number")
.TypeAhead(false)
.Width(500)
.PageSize(10)
.HideBaseTrigger(true)
.MinChars(0)
.TriggerAction(TriggerAction.Query)
.DirectEvents(de =>
{
de.Select.Url = Url.Action("MyPartial");
#* Can I use an if statment here to check the selected item's value? *#
de.Select.ExtraParams.Add(new { id = App.MyCombo.getValue() });
})
.ListConfig(Html.X().BoundList()
.LoadingText("Searching...")
.ItemTpl(Html.X().XTemplate()
.Html(#<text>
<div class="search-item">
<h3><span>{Number}</span>{Title}</h3>
{Description}
</div>
</text>)
)
)
........
#Html.Partial("MyPartial", Model.MyPartialVM)
and here is my controller code -
public ActionResult MyPartial(string id)
{
var vm = new MyPartialViewModel
{
Number = id,
Title = "New Title"
};
ViewData.Model = vm;
var pvr = new Ext.Net.MVC.PartialViewResult
{
ViewData = this.ViewData
};
return pvr;
}
This works if I hardcode a parameter value, but not if I try it as it is now. Here is the error I get -
Message=Cannot perform runtime binding on a null reference
So I was thinking that I can do an if in teh DirectEvents piece to check for a null on the combobox selection, I can inject a 0 when necessary and handle that in the controller. Can this be done?
Try if this works:
x.ComboBox()
.ID("MyCombo")
.DisplayField("Title")
.ValueField("Number")
.TypeAhead(false)
.Width(500)
.PageSize(10)
.HideBaseTrigger(true)
.MinChars(0)
.TriggerAction(TriggerAction.Query)
.DirectEvents(de =>
{
de.Select.Url = Url.Action("MyPartial");
de.Select.ExtraParams.Add(new {
Name = "id",
Value ="App.MyCombo.getValue() == null ? '0' : App.MyCombo.getValue()",
Mode = ParameterMode.Raw
});
})
.ListConfig(Html.X().BoundList()
.LoadingText("Searching...")
.ItemTpl(Html.X().XTemplate()
.Html(#<text>
<div class="search-item">
<h3><span>{Number}</span>{Title}</h3>
{Description}
</div>
</text>)
)
)

Resources