MVC Ajax not posting a dropdownlist value - asp.net

Using the following form in a view
<% using (Ajax.BeginForm("PatientSearch", new {}, new AjaxOptions()
{
HttpMethod = "POST",
UpdateTargetId = "searchResults",
OnBegin = "BeginRequest",
OnSuccess = "SuccessRequest",
OnFailure = "FailRequest"
}))
{ %>
<%=Html.DropDownList("patientType",(SelectList)ViewData["PatientTypeList"]) %>
<%=Html.DropDownList("edCenterID",(SelectList)ViewData["EdCenterList"]) %><br />
<input type="submit">
<%} %>
Results in the following HTML
<select id="patientType" name="patientType">
<option selected="selected">Referral</option>
<option>Patient</option>
</select>
<select id="edCenterID" name="edCenterID">
<option value="2">Barren River District Health Department</option>
<option value="3">Madison County Health Department</option>
</select>
and I attempt to catch the values with the code in the my controller
public ActionResult PatientSearch(string patientType, int edCenterID) {
//do something with values
}
patientType is always passed as ""; however, edCenterID is posted and received just fine.
If I change this from an Ajax.BeginForm to an HTML.BeginForm, everything works perfectly.
Is the problem in my DropDownList, my controller, both?
ADDED FROM COMMENTS
#Eoin pointed out to me that my select is rendering without a value and that is probably the problem. That brings up two questions:
1. Why does it work with the a standard post, but not an Ajax post.
2. How do I get my dropdownlist to contain a value with the list is a simple string only list (no key). I am posting the code used to generate my SelectList below
ViewData["PatientTypeList"]=new SelectList(new List<string>()
{ "Referral", "Patient"});

Does the patientType List have a .Value
By the looks of things, theres no value being rendered for the PatientType DDL <option>'s so essentially every option has a value="" so it is actually post back the correct value.
The problem is with what's being rendered in the first place.
edit
Try
Dictionary<string, string> d = new Dictionary<string, string>();
d.Add("referral", "referral");
d.Add("patient", "patient");
ViewData["PatientTypeList"]=new SelectList(d, "Key", "Value");

Is there no solution to this? Seems like something is broken in the Ajax form submission.
Here is a good fix, write your methods as normal, then run:
function addDropDownValues() {
$("select option").each(function(i) {
if ($(this).text() == "Red") { $(this).attr('value', "Red"); }
else if ($(this).text() == "Amber") { $(this).attr('value', "Amber"); }
else if ($(this).text() == "Green") { $(this).attr('value', "Green"); }
else if ($(this).text() == "Complete") { $(this).attr('value', "Complete"); }
});
}
Where "red", "amber", etc... are the values you want to be passed through
This will append a value to each dropdown, producing:
<select name="status1" id="status1"><option value="Red">Red</option>
<option value="Amber">Amber</option>
<option selected="selected" value="Green">Green</option>
<option value="Complete">Complete</option>
</select>
This will work with both Firefox AND Internet Explorer. Internet Explorer requires the value item, firefox does not.

Related

Getting html select value on postback

I'm having a bit of trouble here, hoping someone can help:
I am dynamically populating an html select element in a razor script and onChange I am hoping to get this posted value.
It is posting back as the page is refreshing but I don't seem to be getting the value of the select; The reason I know is that I am passing a category and filtering on it. This filtering works when I change the querystring in the URL manually and post it.
Razor Script:
#using umbraco.MacroEngines
#inherits DynamicNodeContext
#{
dynamic rootNode = #Model.NodeById(1066);
DynamicNodeList list = rootNode.Descendants();
List<dynamic> categories = new List<dynamic>(list.Cast<dynamic>());
List<string> alias = new List<string> { "GeneralPage" };
var filtered = categories.Where(n => alias.Contains(n.NodeTypeAlias));
}
<form method="post" action="">
<select id="selectCategory" name="selectCategory" onchange="this.form.submit(); alertMe(selectCategory)">
#foreach (var node in filtered)
{
<option value="#node.Name">#node.Name</option>
}
</select>
</form>
<script type="text/javascript">
function alertMe(selectCategory) {
alert(selectCategory)
}
</script>
You'll notice I have a function to alert the selected value but this is coming back as [object HTMLSelectElement]
I can post more code if needed to show what's happening on the server, but as I said the filtering DOES work, however I am trying capture the value in the following way:
string category = Request["selectCategory"];
if (category != null)
{
Any help much appreciated.
Thanks
Try:
ViewContext.RouteData.Values["selectCategory"]
As for the javascript, you are passing in the dom reference to the select list, not the selected item. If you want to see the value of it, you need to use
alert(selectCategory.value)

How to add a title attribute to every option of an ASP.NET DropDownList

I'm working on an older ASP.NET project (not MVC I don't think) and one of the features they require is to view a description of an item when they hover over that item in a dropdown list. This can be simply done with HTML using the following code and making use of title text:
<select>
<option value="1" title="Option 1 Desc">Option 1</option>
<option value="2" title="Option 2 Desc">Option 2</option>
<option value="3" title="Option 3 Desc">Option 3</option>
</select>
Ok so how do I do this using ASP.NET DropDownList control? I have the following code:
<asp:DropDownList ID="DropDownListLocation" runat="server" AutoPostBack="true" OnSelectedIndexChanged="DropDownListLocation_OnSelectedIndexChanged" CssClass="editorFieldServerControl" ClientIDMode="Static"></asp:DropDownList>
And in the 'code behind' page:
private void PopulateFacilityDropdown(List<FacilityAvailableByLocation> facilities, int? selectedID)
{
DropDownListFacility.DataSource = facilities;
DropDownListFacility.DataTextField = "FacilityName";
DropDownListFacility.DataValueField = "FacilityID";
DropDownListFacility.DataBind();
DropDownListFacility.Items.Insert(0, new System.Web.UI.WebControls.ListItem("", ""));
if (selectedID.HasValue && selectedID.Value > 0)
DropDownListFacility.SelectedIndex = facilities.FindIndex(b => b.FacilityID == selectedID.Value);
else DropDownListFacility.SelectedIndex = 0;
}
}
Basically each facility in the list of facilities there has properties for an ID, Name, Description that I can get out. I just want to be able to put a title attribute on each <option> that gets rendered and put the description into it. Either that or be able to add a custom attribute like 'data-description' to each <option> tag then I can add the title into each option tag myself using a bit of jQuery which is easy enough.
I miss the days where you could just loop through a list and output the custom dropdown code manually.
Any ideas? Many thanks
You can manually add a title attribute to each list item like this. Give it a shot:
private void PopulateFacilityDropdown(List<FacilityAvailableByLocation> facilities, int? selectedID)
{
DropDownListFacility.DataSource = facilities;
DropDownListFacility.DataTextField = "FacilityName";
DropDownListFacility.DataValueField = "FacilityID";
DropDownListFacility.DataBind();
DropDownListFacility.Items.Insert(0, new System.Web.UI.WebControls.ListItem(String.Empty, String.Empty);
foreach (FacilityAvailableByLocation f in facilities)
{
DropDownListFacility.Items.FindByValue(f.FacilityID).Attributes.Add("title", f.TitleDescription);
}
if (selectedID.HasValue && selectedID.Value > 0)
DropDownListFacility.SelectedIndex = facilities.FindIndex(b => b.FacilityID == selectedID.Value);
else DropDownListFacility.SelectedIndex = 0;
}
}
f.TitleDescription would be the property you want the title to be.

ASP.NET MVC 2 - Select List Item without Database

I am still struggling with this--
All I am after is an order form, initially it will be a laptop order form but it might be a computer, printer etc in the future. So I have an Order Controller with a Laptop Action which makes a new laptop model. In the model I want to collect various information such as Customer Name, Customer Details etc. In my MODEL I also want to keep a Select List but I've been trying for ages and just cant seem to get it running. My laptop model has this:
--Laptop Model Select List
public SelectList screenSize = new SelectList(new[]
{
new SelectListItem { Text = "11.6", Value = "11.6" },
new SelectListItem { Text = "15.6", Value = "15.6" },
new SelectListItem { Text = "17", Value = "17" }
}, "Value", "Text");
In the controller I accept the laptop on the post
[HttpPost]
public ActionResult Index(Laptop laptopToEmail)
{
if (ModelState.IsValid)
{
...send an email
}
else return View(laptopToEmail)
}
In the view i am able to render out the list of items and I have a select list but I dont get a value passed to the email when i use
laptopToEmail.screenSize.SelectedValue
The view has this helper.
<%: Html.DropDownList("screenSize",Model.screenSize) %>
Am i missing something here? Surely it cant be this difficult to get a select list to work without a database in MVC.
You know, all these neato MVC Html helpers do have HTML equivalents. For a 2-item drop down, why not just write a bit of html:
<select>
<option value="a">Option A</option>
<option value="b">Option b</option>
</select>

When I use a form to call a method on the controller, I want the page to refresh, and the url to show the passed variable ASP MVC

Using ASP MVC, I have set up a webpage for localhost/Dinner/100 to show the dinner details for dinner with ID = 100.
On the page, there is a dropdown that shows Dinner 1, Dinner 2, etc. The user should select the dinner of interest (Dinner 2, ID = 102) off the form and press submit. The page should refresh and show the url: localhost/Dinner/102, and show the details of dinner 2.
My code is working except for the url. During this, my url shows localhost/Dinner/100 even though it is correctly displaying the details of Dinner 2 (ID = 102).
My controller method is pretty simple:
public ActionResult Index(string id)
{
int Id = 0;
if (!IsValidFacilityId(id) || !int.TryParse(id, out Id))
{
return Redirect("/");
}
return View(CreateViewModel(Id));
}
can you help me figure out how to get this all working?
p.s. I did create a custom route for the method:
routes.MapRoute(
"DinnerDefault", // Route name
"Dinner/{id}", // URL with parameters
new { controller = "Dinner", action = "Index", id = "" } // Parameter defaults
);
If you are using ASP.NET MVC HtmlHelper BeginForm() method, keep in mind that by dafult it uses the POST method.
I Think the easiest way is to do this via RedirectToAction result.
View:
<body>
<% Html.BeginForm("Select", "Home"); %>
<select id="dinners" name="dinners">
<option value="100">dinner 1</option>
<option value="101">dinner 2</option>
<option value="102">dinner 3</option>
</select>
<button type="submit"></button>
<% Html.EndForm(); %>
</body>
Controller:
public ActionResult Index(string id)
{
int Id = 0;
if (!IsValidFacilityId(id) || !int.TryParse(id, out Id))
{
return Redirect("/");
}
return View(CreateViewModel(Id));
}
public ActionResult Select(string dinners)
{
return RedirectToAction("Index", "Home", new {id = dinners});
}
Input fields in forms can only change the querystring portion of a URL and only if you use 'get' as the method.
The dinner id is probably being passed as a 'post' value. This will be hidden in the page's http headers, but will over right the values in the visible url.
You can change the url a form posts to in Html.BeginForm, but not dynamically based on form input, unless you use javascript to change the form's action.
An easier thing to do might be to return a RedirectToAction result from your controller:
return RedirectToAction("Index", new { id = 102 ]);
But you'd need to make sure you only did this on post requests.

equivalent of OnSelect javascript hook in multi-select asp listbox

I have a multi-select <asp:listbox> and a button. I want to disable the button unless >= 1 item in the listbox is selected. How can I do this client-side? I can't find some sort of OnSelect callback, only OnSelectedIndexChanged which from googling seems complicated to use for this behavior, possibly impossible.
Use OnChange event, and count the selected items :
<script>function enableButton(opt) {
var selected = new Array();
var count = 0;
for (var intLoop=0; intLoop < opt.length; intLoop++) {
if (opt[intLoop].selected) {
count++;
}
}
if (count >= 1)
{
// disable button
}
}
</script>
<select id="list" style="font-size: 11px;"
onChange="enableButton(this.options);" MULTIPLE SIZE="5">
<option value="0">Select...</option>
<option value="1">1</option>
<option value="2">2</option>
</select>
EDIT : ASP:ListBox rendered to HTML as select as the code above. So all you need to do is to add the script at the onchange attribute :
myListBox.Attributes.Add("onchange", "enableButton(this.options);");
This wouldn't be so hard to do using jQuery. Something along the lines of -
$("select#myListBox").change(function() {
if ($("select#myListBox option:selected").length >= 1)
$("input#myButton").attr("disabled", "true");
}
All hail the mighty jQuery.
OnClick or OnChange for a selectbox is the same thing as a "OnSelect".

Resources