Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Drop down list at layout page - MVC

My problem: drop down list at layout page.

I've read this post: ASP.NET MVC Razor pass model to layout it's more or less similar to my problem. In one of comments Mattias Jakobsson wrote that: "But a common solution is to use RenderAction to render parts that need their own data in the layout page". So ok I've created layout page with @Html.Action() that render my drop dwon list with a date from the db. Everything's perfect. But...

  1. I have two pages, for example: 'Home', 'About' and my drop down list (ddl) at layout page
  2. How to achive that when I'm at 'Home' and I changed selection in ddl it refresh 'Home' page and when I'm at 'About' it refresh 'About' page.
  3. How to store selected ddl value through pages?

Part of Layout.cshtml code:

    .
    .
    <body>
    <header id="top" class="grid-full-margin">

        <strong id="logo" class="grid-304"><a href="/"><img src="/images/logo.png" ></a></strong>
        @Html.ActionLink(@Resources.Resource.BackToIntranet, "Index", "Home", null, new {@class = "link link-home grid-position-left"})

        <h1>@Resources.Resource.SiteTitle</h1>

        <a href="#" class="link link-help">@Resources.Resource.LayoutHelp</a>

        <nav clss="grid-896">

            <ul>
                <li>@Html.ActionLink(Resources.Resource.LayoutMenuItem1, "Index", "Home")</li>
                <li>@Html.ActionLink(Resources.Resource.LayoutMenuItem2, "Index", "ClimaticStation")</li>
                <li>@Html.ActionLink(Resources.Resource.LayoutMenuItem3, "Index", "ClimaticPoint")</li>
                <li>@Html.ActionLink(Resources.Resource.LayoutMenuItem4, "Index", "IcewaterExchanger")</li>
                <li>@Html.ActionLink(Resources.Resource.LayoutMenuItem5, "Index", "Pipeline")
                    <ul>
                        <li>@Html.ActionLink("Zestawienie", "YearsLength", "Pipeline")</li>
                    </ul>
                </li>
            </ul>

            <div class="mod-select-list tbl-actions">
                @Html.Partial("~/Views/Shared/Partials/LoginPartial.cshtml")
            </div>
        </nav>



    </header>
    <form action="#">
        @Html.Action("VariantsDdl", "MyBase")
    </form> 

    @RenderBody()
    .
    .

Part of MyBaseController.cs

   public class MyBaseController : Controller
{
   [ChildActionOnly]
    public ActionResult VariantsDdl()
    {
        var dataFromDb = GetDataFromDB(); // it's not importstn right now
        return this.PartialView("~/Views/Shared/Partials/VariantsDdlPartial.cshtml", dataFromDb);
    }
   .
   .
   }

Regards, Marcin

like image 208
Marcin Avatar asked Oct 19 '25 02:10

Marcin


1 Answers

ok I've managed to solve this problem and I want to know your opinion abut my solution.

_Layout.cshtml looks the same way like at first post, so belowe is only most important part for this question (drop down list at layout)

    <div style="float: right;">
            @Html.Action("VariantsDdl", "MyBase")
    </div>

Action: VariantsDdl is implemented at MyBaseController. This action loads selected variant id from session or if it's null then from web.config (in this situation it's project requirement that at least one variant must be present at db and its id must be specified in config):

    [ChildActionOnly]
    public ActionResult VariantsDdl()
    {
        long defaultVariantID;
        long.TryParse(System.Configuration.ConfigurationManager.AppSettings["DefaultVariantId"], out defaultVariantID);

        if (System.Web.HttpContext.Current.Session["mySelectedVariant"] != null)
        {
            long.TryParse(System.Web.HttpContext.Current.Session["mySelectedVariant"].ToString(), out defaultVariantID);
        }

        var variants = this.db.warianties.ToList();
        var items = new List<SelectListItem>();
        foreach (var variant in variants)
        {
            var selectedItem = false;
            if(variant.id == defaultVariantID)
            {
                selectedItem = true;
            }

            items.Add(new SelectListItem { Selected = selectedItem, Text = variant.nazwa, Value = variant.id.ToString() });
        }

        return this.PartialView("~/Views/Shared/Partials/VariantsDdlPartial.cshtml", items);
    }

Partial view and post action that stores selected variant id to session:

    @model IEnumerable<SelectListItem>

    <label for="field">Current variant</label>
    @Html.DropDownList("Varaints", Model, new { id = "variantsDdl" })

   <script type="text/javascript">
$(function () {
    $('#variantsDdl').change(function () {
        var val = $('#variantsDdl').val()
        $.ajax({
            type: "POST",
            url: '@Url.Action("ChangeVariant", "MyBase")' + '/' + val,
            success: function (result) {
                location.reload();
            },
            error: function (data) { alert('Error'); }
        });

    });
});

Partial View post action 'ChangeVariant', saves selected variant id to session:

   [HttpPost]
    public ActionResult ChangeVariant(long id = 0)
    {
        System.Web.HttpContext.Current.Session["mySelectedVariant"] = id;

        return null;
    }

This is solution for my requirements: 1. DDL at layout 2. Refresh current page at DDL 'onchange' 3. Keep selected DDL value through pages

Please comment if it's appropriate solution or maybe should I go different way?

Regards, Marcin

like image 71
Marcin Avatar answered Oct 21 '25 16:10

Marcin



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!