简体   繁体   中英

How to display a specific MVC Partial View when clicking a corresponding link?

I'm using MVC 5 and Visual Studio 2015. I have a very simple thing I want to do...

I have a page with a controller and NO MODEL. I don't believe I need a model, I'm not accessing or capturing any data; I simply want to display different information (views) based on what a user clicks.

I have an icon bar on the top of the page (which is its own partial) and when you click on an icon, it corresponds to a specific partial view. Click another icon, the previous info disappears and the new info displays. Easy peasy right? I'm not having any luck.

I've found at least a gazillion articles explaining how to do it for ONE partial. but what if I want to conditionally display info that isn't in a list and isn't in a database, but is simply a partial view connected to a link?

Here's some of the code...

My Controller

public class MyController : Controller {

    public ActionResult Index() {
        return View();
    }

    public ActionResult _about() {
        return View();
    }

    public ActionResult _business() {
        return View();
    }
    public ActionResult _finance() {
        return View();
    }
    public ActionResult _jobs() {
        return View();
    }
    public ActionResult _locations() {
        return View();
    }
    public ActionResult _marketing() {
        return View();
    }
    public ActionResult _programming() {
        return View();
    }
}

}

My Markup for the Index View (the main view for this page):

 @using System.Configuration @{ViewBag.Title = "Index";} @Html.Partial("_cteIconBar") <!-- This is the row of icons --> <div class="padding-top-50" id="partial"> @Html.Partial("_about") <!-- I do want to display the "about" partial when a user first lands on the page.--> </div> <div class="padding-top-50" id="partial" style="display: none"> <!-- this is not working... *sigh* --> @{Html.RenderAction("_business"); } @{Html.RenderAction("_programming"); } @{Html.RenderAction("_finance"); } @{Html.RenderAction("_marketing"); } </div>

My Markup for the icon bar:

 <div class="row"> <div class="col-lg-12 col-xs-12"> <div class="text-center margin-bottom icon-container"> <ul> <li class="icon-bar-cte" id="about"> <a role="button" href="@Url.Action("_about", "CTE")"> <i class="icon-aboutInfo cte-icon"></i> </a> </li> <li class="icon-bar-cte" id="business"> <a role="button" class="cte-icon" href="@Url.Action("_business", "CTE")"> <i class="icon-business cte-icon"></i> </a> </li> <li class="icon-bar-cte"> <a role="button" href="@Url.Action("_finance", "CTE")"> <i class="icon-finance cte-icon"></i> </a> </li> <li class="icon-bar-cte"> <a role="button" href="@Url.Action("_marketing", "CTE")"> <i class="icon-marketing cte-icon"></i> </a> </li> <li class="icon-bar-cte"> <a role="button" href="@Url.Action("_programming", "CTE")"> <i class="icon-programming cte-icon"></i> </a> </li> <li class="icon-bar-cte"> <a role="button" href="@Url.Action("_jobs", "CTE")"> <i class="icon-jobs cte-icon"></i> </a> </li> <li class="icon-bar-cte"> <a role="button" href="@Url.Action("_locations", "CTE")"> <i class="icon-location-marker cte-icon"></i> </a> </li> </ul> </div> </div> </div>

My markup for one of the partials (they're all the same with different words). I substituted a little "Hippie Ipsum" for your pleasure.

 <div class="container collapse in" id="about" aria-expanded="true"> <div class="row padding-bottom-50"> <div class="col-lg-8 col-lg-offset-2 col-md-8 col-md-offset-2 col-sm-12"> <h2 class="green">Some Hippie Ipsum for You!</h2> <p><strong>What is Career Technical Education?</strong></p> <p>Equinox plant consciousness midwifery embracing and moving towards djembe craniosacral, dolphin Hafiz ecstatic dance higher cosmic force spoken word. Prayer flags fair trade what quantum theory says, healing tonic non-profit co-create impermanent hemp seed.</p> <br /> <p><strong>Why is Hippie Ipsum important?</strong></p> <p>Closing circle himalayan sea salt multi-dimensional honoring your truth, forest birth name. Tofurkey native american ancestry diva cup human potential yoni, bioneers the buddha sunset. Animal totem deep cleansing emotional release one taste life coach compostable toilet, be the change astrological mercury retrograde holistic.</p> </div> </div> </div>

 .padding-top-50{ padding-top:50px; }

The easiest solution for what you'd like to achieve is to use AJAX so you can inject the views into the container.

So let's start from the beginning:

1) You have to return PartialView() instead of regular View()

public ActionResult _about() {
    return PartialView();
}

2) Not needed, but I'd change some things in your menu markup. Note the data-url instead of href .

<li class="icon-bar-cte" id="business">
    <a href="#" role="button" class="cte-icon" data-url="@Url.Action("_business", "CTE")">
        <i class="icon-business cte-icon"></i>
    </a>
</li>

3) Most important part is the following jQuery. Depending of what you need you can use append instead of html when injecting the view.

$(document).on('click','.cte-icon',function(e){
    e.preventDefault();

    var url = $(this).data('url');
    $.ajax({
       url: url,
       type: 'GET'
    }).done(function(response){
       $('#partial').html(response);
    });
});

Yet another way, if you wanna go more "vanilla" .NET MVC is to use actionlinks and return partial views from your controller actions. Something like this:

public ActionResult _programming() 
{
        PartialView("~/Views/YourPartialsPath/_programming.cshtml");
}

And in your views put this:

    @Html.ActionLink("Html element text", 
                     "_programming", 
                     "MyController", 
                      new { controller = "MyController" }, 
                      new { @class = "MaybeYouWantAClassOnTheHtmlElement" })

And if you want you could structure your site to be a single page app by initially loading a single view to be your "base structure" container. This page would then load a set of partials consisting of maybe side/top menu bars and maybe a "main page" container. This main page could also be in charge of loading of some javascripts you want to run across all of your later loaded partials (maybe a function showing/hiding an ajax.gif image)

Lets say you put this in your initial page load. Maybe you put this in your: \\Views\\Home\\index.cshtml Or even your: \\Views_Layout.cshtml

        <div id="navbar" class="navbar-collapse collapse">
            <ul class="nav navbar-nav navbar-left">
                @{ Html.RenderAction("TopMenuRenderer", "Menu");}
            </ul>
            <ul class="nav navbar-nav navbar-right">
                @{ Html.RenderAction("UserMenuRenderer", "Menu");}
            </ul>
        </div>

Then you create a controller called Menu

namespace WebPortal.Web.Controllers
{
    public class MenuController : Controller
    {
        [ChildActionOnly] //for ajax call to controller remove this annotation
        public ActionResult TopMenuRenderer()
        {
            //return PartialView();
            if (User.IsInRole(Role.Admin.ToString()) ||
                User.IsInRole(Role.SuperAdmin.ToString()))
            {
                return PartialView("~/Views/Menu/_TopMenu.cshtml");
            }
            return null;
        }

        [ChildActionOnly]
        public ActionResult UserMenuRenderer()
        {
            if (User.Identity.IsAuthenticated)
                return PartialView("~/Views/Menu/_UserMenuAuthenticated.cshtml");
            else
                return PartialView("~/Views/Menu/_UserMenuNotAuthenticated.cshtml");
        }
        [ChildActionOnly] 
        public ActionResult SideMenuRenderer()
        {
            //you could put some user checks here if you want to limit some of the loaded meny options depending on the user type.
            if (User.IsInRole(Role.Admin.ToString()) ||
                User.IsInRole(Role.SuperAdmin.ToString()))
            {
                return PartialView("~/Views/Menu/_SideMenu.cshtml");
            }
            return null;
        }
}     

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM