user153923
user153923

Reputation:

How do I Keep dropdown values selected after ASP.NET form submission?

Consider this HTML inside my ASP.NET page:

<form method="get" action="">
   <select name="name">
      <option value="a">a</option>
      <option value="b">b</option>
   </select>
   <select name="location">
      <option value="x">x</option>
      <option value="y">y</option>
   </select>
   <input type="submit" value="Submit" />
</form>

On submitting the form, how do I make sure that the selected values remain selected in the dropdowns?

NOTE: Similar to this question for PHP, but my question is for ASP.NET MVC application using the .NET Framework 4.5.2:

Keep values selected after form submission

In the HTML of my .cshtml page, I have this:

<table border="0" width="100%">
    <tr>
        <th width="20%"></th>
        <th width="20%">Selection</th>
        <th></th>
    </tr>
    <tr>
        <td align="right">By Model/By Month:</td>
        <td>
            @Html.DropDownListFor(m => m.ByModel,
            new List<SelectListItem>() {
                new SelectListItem() { Text = "", Value = "" },
                new SelectListItem() { Text = "By Model", Value = "Model" },
                new SelectListItem() { Text = "By Month", Value = "Month" }
            }, new { @onchange = "updateForm('1')" })
        </td>
        <td>@Model.ByModel</td>
    </tr>
    <tr>
        <td align="right">By Region/By Dealer/ All Regions:</td>
        <td>
            @Html.DropDownListFor(m => m.ByRegion,
            new List<SelectListItem>() {
                new SelectListItem() { Text = "", Value = "" },
                new SelectListItem() { Text = "By Region", Value = "Region" },
                new SelectListItem() { Text = "By Dealer", Value = "Dealer" },
                new SelectListItem() { Text = "All Regions", Value = "All" }
            },
            new { @id = "ByRegion", @onchange = "updateForm('2')" })
        </td>
        <td>@Model.ByRegion</td>
    </tr>
    <tr>
        <td align="right">Region:</td>
        <td>
            @Html.DropDownListFor(m => m.Region,
                Model.Regions,
                new { @onchange = "updateForm('3')" })
        </td>
        <td>@Model.Region</td>
    </tr>
    <tr>
        <td align="right">Dealership:</td>
        <td>
            @Html.DropDownListFor(m => m.DealerID, new List<SelectListItem>())
        </td>
        <td>@Model.Dealership</td>
    </tr>
    <tr>
        <td></td>
        <td><input type="submit" value="Submit" class="submit" onclick="history.go(-1);" /></td>
        <td></td>
    </tr>
</table>

I have been successful in displaying information from the @Model object, but it does not show the Dealer Name that I need.

At the bottom of that page, there are a few lines of added Javascript:

<script>

    const updateForm = (changeElement) => {
        let byModel = document.getElementById("ByModel");
        let byRegion = document.getElementById("ByRegion");
        let region = document.getElementById("Region");
        let dealership = document.getElementById("DealerID");
        window.byModel = byModel;
        window.byRegion = byRegion;
        window.region = region;
        window.dealership = dealership;

        //Removes dealership value when region is changed, used in logic below
        if (changeElement === '3') {
            dealership.value = "";
        }
        //Removes dealer list if ByRegion is anything other than By Dealer and dealership is not blank
        //This is used for when the form submits to refresh the list without needing to interact with the dropdowns
        if (byRegion.value !== "Dealer" && dealership.value.length > 0) {
            dealership.innerHTML = "";
        }
        //if All Regions is selected submit the form - previous functionality
        if (changeElement === '2' && byRegion.value === "All" && byModel.value.length > 0) {
            region.innerHTML = "";
            document.forms[0].submit();
        }
        //Checks that region has a value and dealership does not (because this function is run on page load/refresh)
        //Pulls in dealer values
        if (0 < region.value.length && byRegion.value === "Dealer" && dealership.value.length < 1) {
            getDealers(region);
        } else {
            $('#DealerID').prop('disabled', true);
            $("#DealerID").html("").show();
        }
        if (window.selectedDealerName != null) {
            setTimeout(() => {
                dealership.value = window.selectedDealerName;
            }, 5000);
        }
    }

    function getDealers(e) {
        let value = $(e).val();
        $.get("@Url.Action("GetDealers", "Admin")?region=" + value, function (res) {
            var markup = "";
            for (var i = 0; (res != null) && (i < res.length); i++) {
                markup += '<option value='+res[i].Value+'>'+res[i].Text+"</option>"
            }
            $('#DealerID').prop('disabled', false);
            $("#DealerID").html(markup).show();
        });
    }

    window.onload = function refreshForm() {
        updateForm();
    }

</script>

I never knew Javascript could call Code Behind like that in the $.get statement.

But, calling that is what causes me to lose the value of my dropdown for DealerID.

In the Code Behind, the C# is a simple database pull:

private static RetailActivityDealers m_dealerships;

[HttpGet]
public ActionResult GetDealers(string region)
{
    if (m_dealerships == null)
    {
        m_dealerships = RetailActivityModelData.GetDealers();
    }
    var dealerships = new List<SelectListItem>
    {
        new SelectListItem() { Text = "", Value = "" }
    };
    if (string.IsNullOrWhiteSpace(region))
    {
        foreach (var dealer in m_dealerships)
        {
            dealerships.Add(new SelectListItem() { Text = dealer.Name, Value = dealer.Number });
        }
    }
    else
    {
        foreach (var dealer in m_dealerships.Where(x => x.Region == region))
        {
            dealerships.Add(new SelectListItem() { Text = dealer.Name, Value = dealer.Number });
        }
    }
    return Json(dealerships, JsonRequestBehavior.AllowGet);
}

Upvotes: 0

Views: 198

Answers (1)

Albert D. Kallal
Albert D. Kallal

Reputation: 49039

Is this web forms, or MVC?

For web forms, then viewstate is automatic if you use asp.net controls.

so, say this markup:

<asp:DropDownList ID="DropName" runat="server">
    <asp:ListItem>a</asp:ListItem>
    <asp:ListItem>b</asp:ListItem>
</asp:DropDownList>

<asp:DropDownList ID="DropLocation" runat="server" style="margin-left:25px">
    <asp:ListItem>x</asp:ListItem>
    <asp:ListItem>y</asp:ListItem>
</asp:DropDownList>

<asp:Button ID="cmdMyChoice" runat="server" Text="Submit" style="margin-left:25px"
    CssClass="btn"
    OnClick="cmdMyChoice_Click" />

<br />
<br />
Result
<asp:TextBox ID="TextBox1" runat="server" style="border-radius:1em">
</asp:TextBox>

and code behnd for button click is

Protected Sub cmdMyChoice_Click(sender As Object, e As EventArgs)

    TextBox1.Text =
        $"{DropName.SelectedItem.Text} - {DropLocation.SelectedItem.Text}"

End Sub

and result is this:

enter image description here

So it depends on what type of project you are creating.

So "state" of controls is often managed automatic for you.

Upvotes: 1

Related Questions