Implementing the GitHub tree slider on MVC3

I am trying to implement the same tree slide in my MVC3 application, and I'm not quite sure if I am doing this correctly:

Index Page:

<script type="text/javascript"> $(document).ready(function () { $('#slider a').click(function () { history.pushState({ path: this.path }, '', this.href); $.get(this.href, function (data) { $('#slider').slideTo(data); }); return false; }); }); </script> @{Html.RenderAction("MainTableTracker", "Release", new { releaseId = Model });} 

Partial view of MainTableTracker:

 <script type="text/javascript"> $(document).ready(function () { $('#slider a').click(function () { history.pushState({ path: this.path }, '', this.href); $.get(this.href, function (data) { $('#slider').slideTo(data); }); return false; }); }); </script> <div id="slider"> @Html.RouteLink(Model.Brand.Name, "Brand", new { BrandId = Model.Brand.Id }) / <ul> <li><a href="#">Overview</a></li> @foreach(var model in Model.ModelExts) { <li>@Html.RouteLink(model.Model.Name, new { modelId = model.Model.Id })</li> } </ul> </div> 

Partial view of VersionTable version:

 <script type="text/javascript"> $(document).ready(function () { $('#slider a').click(function () { history.pushState({ path: this.path }, '', this.href); $.get(this.href, function (data) { $('#slider').slideTo(data); }); return false; }); }); </script> <div id="slider"> @Html.RouteLink(Model.Brand.Name, "Brand", new { BrandId = Model.Brand.Id }) / @Html.RouteLink(Model.Name, "Model", new { modelId = Model.Id }) / <ul> <li><a href="#">Overview</a></li> @foreach(var model in Model.Brand.Model) { <li>@Html.RouteLink(model.Name, new { modelId = model.Id })</li> } </ul> <div class="versionWraper"> @foreach(var version in Model.Version) { <div> @version.Name </div> } </div> </div> 

This works, however I'm sure that I am doing it wrong, I assume that I should not have 3 different views, each time copying the code of the parent view.

I am wondering if I should have only one view model and one action, and let the view decide what to show each time? But I don’t really like to use only one action to display different types of data (Release, Brand and Feature).

In addition, the layout has:

  $(window).bind('popstate', function (e) { $.get(e.originalEvent.state.path, function (data) { $('#slider').slideTo(data); }); }); 

This works, but when I get back to the Brand level, it will reload all my scripts (being that this View is not partial for the standard).

Is there a better way to implement this?

thanks

+4
source share
1 answer

When creating something like this, I would advise you not to target objects by ID. This puts you in odd situations, like the one you encountered, where you want to ensure that the element is on the page before the script fires and things that can be inherently problematic when working with partial downloads and such.

Instead, consider this approach:

 <style> .slider { /* Styles here */ } .slider > ul { /* Styles here */ } .slider > ul > li { /* Styles here */ } .slider > .versionWrapper { /* Styles here */ } .slider > .versionWrapper > .versionName { /* Styles here */ } </style> <div class="slider"> @Html.RouteLink(Model.Brand.Name, "Brand", new { BrandId = Model.Brand.Id }) / @Html.RouteLink(Model.Name, "Model", new { modelId = Model.Id }) / <ul> <li><a href="#">Overview</a></li> @foreach(var model in Model.Brand.Model) { <li>@Html.RouteLink(model.Name, new { modelId = model.Id })</li> } </ul> <div class="versionWrapper"> @foreach(var version in Model.Version) { <div class="versionName">@version.Name</div> } </div> </div> <script type="text/javascript" language="javascript"> $(document).ready(function () { $('.slider > ul > li > a').live('click', function (ev) { ev.preventDefault(); ev.stopPropagation(); var $a = $(ev.target); var $slider = $a.closest('.slider'); history.pushState({ path: $a.path }, '', $a.href); $.get($a.href, function (data) { $slider.slideTo(data); }); }); }); </script> 

At this point, you are actually aiming ANY slider that you place on the page, no matter what part it is wrapped in - and a small amount of jQuery logic at the end can easily be placed on the site or on the page, a wide JS file, separated from the specific implementation, which outputs your HTML.

Then just create the switch for which you are. I like to do this with ViewData["SettingName"] , but it's just me.

If you want your "MainTable" style to display, set something like:

 ViewData["Mode"] = "Default"; 

If you want your version view to display, set:

 ViewData["Mode"] = "Version"; 

Then change the partial render as:

 <div class="slider"> @{ bool versionMode = (ViewData["Mode"] as String == "Version"); string breadCrumb = Html.RouteLink( Model.Brand.Name, "Brand", new { BrandId = Model.Brand.Id } ).ToString(); if (versionMode) { breadCrumb = String.Format("{0} / {1}", breadCrumb, Html.RouteLink( Model.Name, "Model", new { modelId = Model.Id } ).ToString() ); } } @breadCrumb / <ul> <li><a href="#">Overview</a></li> @{ if (versionMode) foreach(var model in Model.ModelExts) { <li>@Html.RouteLink(model.Model.Name, new { modelId = model.Model.Id })</li> } } else { @foreach(var model in Model.Brand.Model) { <li>@Html.RouteLink(model.Name, new { modelId = model.Id })</li> } } } </ul> @{ if (versionMode) { <div class="versionWrapper"> @foreach(var version in Model.Version) { <div>@version.Name</div> } </div> } } </div> 
+2
source

All Articles