0

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);
}

  • 1
    The same approach should work, just with whatever view syntax you're using. (Razor?) Basically you need to set the values. You could do this with JavaScript as in the linked question, you could conditionally output a `selected` attribute to a given ` – David Nov 23 '22 at 18:45

1 Answers1

1

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.

Albert D. Kallal
  • 42,205
  • 3
  • 34
  • 51
  • Hey Albert, thanks for the time to answer. I didn't think about the fact that WebForms and MVC are so different. Yes, this is MVC with Razor injected. Your answer caused me to go back and edit my question. The original is still up top, but I added the code from my project below the link to the example that I found. –  Nov 23 '22 at 21:05