Josh Bush
Josh Bush

Reputation: 2718

asp.net mvc radio button state

I'm trying out asp.net mvc for a new project, and I ran across something odd. When I use the MVC UI helpers for textboxes, the values get persisted between calls. But, when I use a series of radio buttons, the checked state doesn't get persisted.

Here's an example from my view.

<li>
        <%=Html.RadioButton("providerType","1")%><label>Hospital</label>
        <%=Html.RadioButton("providerType","2")%><label>Facility</label>
        <%=Html.RadioButton("providerType","3")%><label>Physician</label>
</li>

When the form gets posted back, I build up an object with "ProviderType" as one of it's properties. The value on the object is getting set, and then I RedirectToAction with the provider as a argument. All is well, and I end up at a URL like "http://localhost/Provider/List?ProviderType=1" with ProviderType showing. The value gets persisted to the URL, but the UI helper isn't picking up the checked state.

I'm having this problem with listbox, dropdownlist, and radiobutton. Textboxes pick up the values just fine. Do you see something I'm doing wrong? I'm assuming that the helpers will do this for me, but maybe I'll just have to take care of this on my own. I'm just feeling my way through this, so your input is appreciated.

Edit: I just found the override for the SelectList constructor that takes a selected value. That took care of my dropdown issue I mentioned above.

Edit #2: I found something that works, but it pains me to do it this way. I feel like this should be inferred.

<li>
  <%=Html.RadioButton("ProviderType","1",Request["ProviderType"]=="1")%><label>Hospital</label>
  <%=Html.RadioButton("ProviderType", "2", Request["ProviderType"] == "2")%><label>Facility</label>
  <%=Html.RadioButton("ProviderType", "3", Request["ProviderType"] == "3")%><label>Physician</label>
</li>

Hopefully someone will come up with another way.

Upvotes: 13

Views: 25837

Answers (7)

K.V. Sai Kishore
K.V. Sai Kishore

Reputation: 11

View:

<%=Html.RadioButton("providerType","1")%><label>Hospital</label>
<%=Html.RadioButton("providerType","2")%><label>Facility</label>
<%=Html.RadioButton("providerType","3")%><label>Physician</label>

Controller:

public ActionResult GetType(FormCollection collection)
{
 string type=collection.Get("providerType");

  if(type=="1")
   //code
  else if(type=="2")
   //code
  else
   //code

 return View();
}

Upvotes: -1

Eduardo Molteni
Eduardo Molteni

Reputation: 39413

I've made this HTML Helper extension:

    <Extension()> _
    Public Function RadioButtonList(ByVal helper As HtmlHelper, ByVal name As String, ByVal Items As IEnumerable(Of String)) As String
        Dim selectList = New SelectList(Items)
        Return helper.RadioButtonList(name, selectList)
    End Function

    <Extension()> _
    Public Function RadioButtonList(ByVal helper As HtmlHelper, ByVal Name As String, ByVal Items As IEnumerable(Of SelectListItem)) As String
        Dim sb As New StringBuilder
        sb.Append("<table class=""radiobuttonlist"">")
        For Each item In Items
            sb.AppendFormat("<tr><td><input id=""{0}_{1}"" name=""{0}"" type=""radio"" value=""{1}"" {2} /><label for=""{0}_{1}"" id=""{0}_{1}_Label"">{3}</label></td><tr>", Name, item.Value, If(item.Selected, "selected", ""), item.Text)
        Next
        sb.Append("</table>")
        Return sb.ToString()
    End Function

Then in the view:

<%= Html.RadioButtonList("ProviderType", Model.ProviderTypeSelectList) %>

In the controller the option is mapped automagically using the standard:

UpdateModel(Provider)

Works like a charm. If you are tablephobic, change the markup generated.

Upvotes: 1

Cheny
Cheny

Reputation: 21

I'm using vs2010 now, it works like:

<%=Html.RadioButton("ProviderType","1",Model.ProviderType==1)%><label>Hospital</label> 

looks better?

Upvotes: 2

David Gardiner
David Gardiner

Reputation: 17176

If you give the radio buttons the same name as the property on your model, then MVC will automatically set the checked attribute on the appropriate button.

I think this relies on having a strongly typed Model.

Upvotes: 7

Jonathan Parker
Jonathan Parker

Reputation: 6795

What you need is something like this in your view:

<% foreach(var provider in (IEnumerable<Provider>)ViewData["Providers"]) { %>
    <%=Html.RadioButton("ProviderType", provider.ID.ToString(), provider.IsSelected)%><label><%=provider.Name%></label>
<% } %>

And then in your controller have this:

var providers = GetProviders();
int selectedId = (int) Request["ProviderType"]; // TODO: Use Int32.TryParse() instead
foreach(var p in providers)
{
    if (p.ID == selectedId)
    {
        p.IsSelected = true;
        break;
    }
}
ViewData["Providers"] = providers;
return View();

The Provider class will be something like this:

public class Provider
{
    public int ID { get; set; }
    public string Name { get; set; }
    public bool IsSelected { get; set; }
}

Upvotes: 4

Al Katawazi
Al Katawazi

Reputation: 7242

Well logically it would not persist, there is no session state. Think of it as an entirely new page. In order to get your radio buttons to populate you need to persist back something like ViewData["ProviderType"] = 3 to have the radiobutton repopulate with its data.

Upvotes: 1

Haacked
Haacked

Reputation: 59011

The form shouldn't be posting to the querystring, unless you forgot to specify the form as method="POST". How are you specifying the form? Are you using ASP.NET MVC Beta?

Upvotes: 2

Related Questions