MVC Layout Navbar Active Hide/Show DIV - asp.net-mvc

So i am going off of this example:
better way to get active pages
What I'm trying to accomplish in my _Layout.cshtml is this:
<div id="navbar">
<div><img src="~/Images/home_on.png" /></div>
<div><img src="~/Images/home_off.png" /></div>
<div><img src="~/Images/contact_on.png" /></div>
<div><img src="~/Images/contact_off.png" /></div>
</div>
The navbar div changes depending on the active page. If its home, then show "home_on.png" div. If its not display "home_off.png" and so forth.

I've used this in the past.
Declare at the top of the layout:
#{
var currentController = ViewContext.RouteData.Values["controller"] as string ?? string.Empty;
var currentAction = ViewContext.RouteData.Values["action"] as string ?? string.Empty;
string getImageSource(string basePath, string controller, string action)
{
var onOrOff = currentController.Equals(controller, StringComparison.OrdinalIgnoreCase) && currentAction.Equals(action, StringComparison.OrdinalIgnoreCase) ? "on.png" : "off.png";
return string.Format("{0}_{1}", basePath, onOrOff);
}
}
Then you can render the appropriate image based off the expected controller and action:
<div id="navbar">
<div><img src="#(getImageSource("~/Images/home", "Home", "Index"))" /></div>
<div><img src="#(getImageSource("~/Images/contact", "Home", "Contact"))" /></div>
</div>
I assume that the base ~/Home URL is going to the Index action on the HomeController, and that ~/Home/Contact is going to the Contact action on the HomeController.

Related

MVC foreach set item.ID to model.ID

I have a form that shows all the available hotel rooms, each room has a button that does a HttpPost if clicked, I have made a property in the BookingViewModel called 'RoomID'. I would like to assign the item.RoomID to Model.RoomID so I can use it in my controller to get the id from the selected room but i'm not sure how to achieve this.
ChooseRoom View
#foreach (var item in Model.AvailableRooms)
{
<li class="room-item clearfix">
<h5>#item.Name</h5>
<div class="room-list-left">
<img src="#item.Image" alt="" />
</div>
<div class="room-list-right">
<div class="room-meta">
<ul>
<li><span>Occupancy:</span> #item.Adults Adults #item.Childs Children</li>
#if (item.SmokingRoom)
{
<li><span>Smoking Allowed:</span> Yes</li>
}
else
{
<li><span>Smoking Allowed:</span> No</li>
}
</ul>
</div>
<div class="room-price">
<p class="price">From: <span>$#item.Price</span> / Night</p>
</div>
<div class="clearboth"></div>
#using (Html.BeginForm("chooseroom", "booking", FormMethod.Post))
{
<input class="button2" type="submit" value="Select Room" />
}
BookingController
[HttpPost]
public ActionResult ChooseRoom(BookingViewModel vm)
{
BookingViewModel bookingObj = GetBooking();
bookingObj.SelectedRoom = Repository.GetRoomByID(vm.RoomID);
return View("reservation", bookingObj);
}
Thank you for your time!
update your begin form as below
#using (Html.BeginForm("chooseroom", "booking", FormMethod.Post))
{
<input type="hidden" name="RoomId" value="#item.RoomID" />
<input class="button2" type="submit" value="Select Room" />
}
Just need to provide input tags having the same name as your ViewModel property.
You could add inputs in foreach loop , it should be inside form. Something like this <input name="Model.AvailableRooms[index].RoomID" value="Id Here"/>
Or if you want to select one Room you should use ajax and post id.
If I'm not wrong you form is in loop,so you could add hidden input with id
#Html.HiddenFor(c => c.AvailableRooms[index].RoomID)

Form action not hitting MVC controller method

I want to do a simple file upload using Html forms. I have the following in my view:
<form action='#Url.Action("Save", "Order")' method="post" enctype="multipart/form-data" id="attachmentForm">
<div >
<label style="text-align: left;">Delivery note:</label>
</div>
<div style="float:left; ">
<input type="file" name="DeliveryNoteFile" id="DeliveryNote" style="width: 400px;" />
</div>
<div style="float:right; margin-top:10px; margin-left:5px; margin-bottom:0px;">
#(Html.Kendo().Button()
.Name("btnAddAttachment")
.HtmlAttributes( new {type = "submit"} )
.Content("Submit"))
</div>
</form>
Now here is my controller method. Controller name: Order , Method name: Save.
Why is it not hitting my controller method?
[HttpPost]
public ActionResult Save(HttpPostedFileBase file)
{
if (file != null)
{
var fileName = Path.GetFileName(file.FileName);
var physicalPath = Path.Combine(Server.MapPath("C:\\Attachments"), fileName);
file.SaveAs(physicalPath);
}
return Content("");
}
Note that this is only a first draft. Any suggestions to improve this are also welcome.
I think in your case your button is not of type submit that is why it is not hitting controller action just try making submit button this way:
#(Html.Kendo().Button()
.Name("btnAddAttachment")
.HtmlAttributes( new {type = "submit"} )
.Content("Submit"))
as # AbbasGaliyakot comment worked for the user in comment section so i m also including it here.
Change controller action parameter name from file to DeliveryNoteFile.
Please try this out. This would help.
#using (Html.BeginForm("Save", "Order", FormMethod.Post, new { enctype = "multipart/form-data", id = "attachmentForm" }))
{
<div >
<label style="text-align: left;">Delivery note:</label>
</div>
<div style="float:left; ">
<input type="file" name="DeliveryNoteFile" id="DeliveryNote" style="width: 400px;" />
</div>
<div style="float:right; margin-top:10px; margin-left:5px; margin-bottom:0px;">
#(Html.Kendo().Button()
.Name("btnAddAttachment")
.HtmlAttributes( new {type = "submit"} )
.Content("Submit"))
</div>
}
And in JS you need to bind the click function of your submit button like shown below:
$('#btnAddAttachment').bind('click', function () {
$('#attachmentForm').submit();
});
Thanks!

The model item passed into the dictionary is of type 'BlogHomePageModel', but this dictionary requires a model item of type 'BlogHomePageModel'

I'm using Umbraco 7.04. I would post code but I can't determine what is causing the problem. I did make some edits to a class in my App_Code folder and my website started displaying this error. I reverted those edits but still get the error.
A coworker mentioned that .net can cache files so I tried recycling app pool and editing web.config to no avail.
EDIT: here is the code I believe was causing the problem, although it seemed to have gone away randomly.
BlogHomePage View
#inherits Umbraco.Web.Mvc.UmbracoViewPage<BlogHomePageModel>
#{
Layout = "BlogLayout.cshtml";
var BlogBackgroundImageCss = Html.Raw(HttpUtility.HtmlDecode(Model.BannerImageBackgroundImageCss));
var BlogHomeContent = Html.Raw(HttpUtility.HtmlDecode(Model.BlogHomeContent));
var AllTags = Html.Raw(HttpUtility.HtmlDecode(thunder.TagHelper.GetAllTags(Model.Content)));
var PagingHtml = Html.Raw(HttpUtility.HtmlDecode(Model.PagingHtml));
}
<div class="blog-area">
<div class="blog-banner-area" style="#BlogBackgroundImageCss" >
<span>#Model.BannerImageTitle</span>
</div>
<div class="blog-nav-area">
<button class="blog-nav-collapse-button"><span>Search</span></button>
<div class="blog-nav-inner-area">
#{ Html.RenderPartial("BlogHomeSearchInformation", Model); }
#{ Html.RenderPartial("BlogPostSearch"); }
#AllTags
#{ Html.RenderPartial("BlogHomeAside", Model); /*use partial to render blog post aside*/ }
</div>
</div>
<div class="blog-main-area">
<div class="blog-heading-area">
<div class="blog-heading-text-container">
#BlogHomeContent
<button class="blog-about-this-blog-expand-button">Read More</button>
</div>
</div>
#if (Model.Posts.Count() > 0) {
foreach (var Post in Model.Posts) {
Html.RenderPartial("BlogHomePostPartial", Post); /*use partial to render blog post content*/
}
#PagingHtml
} else {
<p>Sorry, but no posts matched your query.</p>
}
</div>
</div>
BlogHomeSearchInformationPartial
#inherits Umbraco.Web.Mvc.UmbracoViewPage<BlogHomePageModel>
#{
string SearchTerm = (!string.IsNullOrEmpty(Request.QueryString["s"])) ? Request.QueryString["s"] : "";
string TagTerm = (!string.IsNullOrEmpty(Request.QueryString["t"])) ? Request.QueryString["t"] : "";
}
<div id="blog-search-results-information">
#if (!string.IsNullOrEmpty(SearchTerm)) {
if (Model.TotalResults == 1) {
<p>Your search for "#SearchTerm" returned #Model.TotalResults result. Click here to return to home page.</p>
} else {
<p>Your search for "#SearchTerm" returned #Model.TotalResults results. Click here to return to home page.</p>
}
}
#if (!string.IsNullOrEmpty(TagTerm)) {
if (Model.TotalResults == 1) {
<p>There is #Model.TotalResults post tagged "#TagTerm". Click here to return to home page.</p>
} else {
<p>There are #Model.TotalResults posts tagged "#TagTerm". Click here to return to home page.</p>
}
}
</div>
BlogPostSearch
#inherits UmbracoTemplatePage
#{
string SearchTerm = "";
SearchTerm = Request.QueryString["s"];
}
<form role="search" method="get" id="searchform" action="/">
<div class="blog-search-area">
<input type="search" name="s" value="#SearchTerm">
<button type="submit">Search</button>
</div>
</form>
BlogPostAside
#inherits Umbraco.Web.Mvc.UmbracoViewPage<BlogHomePageModel>
#{
var AsideLinks = Html.Raw(HttpUtility.HtmlDecode(Model.AsideLinks));
}
#if (!string.IsNullOrEmpty(Model.AsideHeading) || !string.IsNullOrEmpty(Model.AsideSubheading) || !string.IsNullOrEmpty(Model.AsideContent) || !string.IsNullOrEmpty(Model.AsideLinks)) {
<div class="blog-contact-area">
<span class="blog-contact-heading">#Model.AsideHeading</span>
<span class="blog-contact-subheading">#Model.AsideSubheading</span>
<p>#Model.AsideContent</p>
#AsideLinks
</div>
}
Seems to me you have defined a special model on your view (or you did inherit form something).
Try to remove the #model and the #inherits from your view.
problem solved itself mysteriously :( After a little more research I believe it may be related to this question: The model item passed into the dictionary is of type ‘mvc.Models.ModelA’ but this dictionary requires a model item of type ‘mvc.Models.ModelB‘

PagedListPager page always null

This used to work... but now the >> anchor tag of the PagedListPager always passes null to the controller for the page value required...
VS 2013 Web Express & MVC 4 with latest package updates for all.
Just like in Scot Allen's MVC 4 intro, I have a partial view with a PagedListPager
The Controller:
public ActionResult Catalog(string Id= "0", int page=1)
{
var CurrentItemsPage = (get-data-blaw-blaw-blaw).ToPagedList(page,18);
var model = new ShowRoomCatalogPackage(){ CurrentItems = CurrentItemsPage};
return View(model);
}
The catalog page
#model craftstore.Models.ShowRoomCatalogPackage
#{
ViewBag.Title = "Catalog";
Layout = "~/Views/Shared/_Details.cshtml";
}
#using (Ajax.BeginForm("Catalog", "Home", new { category = #Model.SelectedCategoryId, page = 1 },
new AjaxOptions
{
UpdateTargetId = "products",
InsertionMode = InsertionMode.Replace,
HttpMethod = "post"
}
)
)
{
<div class="container" >
<div class="row">
<div class="col-lg-10 col-md-5 col-sm-4 dropdown-menu">
#Html.LabelFor(m => m.SelectedCategoryId)
#Html.DropDownList("id", Model.CategoryItems, new { #id = "ddlCategories", onchange = "this.form.submit();" })
</div>
<div class="col-lg-2 col-md-2 col-sm-1">
#Html.ActionLink("Your Cart", "Index", "ShoppingCart", "", new { #class = "btn btn-green btn-lg" })
</div>
</div>
<div class="row">
#Html.Partial("_CatalogPartial", Model.CurrentItems)
</div><!-- row -->
</div><!-- container -->
}
<br />
<br />
#section Scripts
{
<script type="text/javascript">
new AnimOnScroll(document.getElementById('grid'), {
minDuration: 0.4,
maxDuration: 0.7,
viewportFactor: 0.2
});
</script>
}
The partial view:
#model IPagedList<ShowroomCatalog>
<div id="productList">
<div class="col-lg-12 col-md-12 col-sm-12">
<div class="pagedList" data-cs-target="#productList">
#Html.PagedListPager(Model, page => Url.Action("Index", new { category = ViewBag.SelectedCategoryId, page }), PagedListRenderOptions.MinimalWithItemCountText)
</div>
<ul class="grid effect-2" id="grid">
#foreach(var item in Model)
{
var path = String.Format("~/Content/Images/catalog/{0}/{1}", item.OfferType, item.ImagePath);
<li>
<div class="itembox">
<div class="imagebox">
<a href="#Url.Action("Detail", "Home", new { id = item.Id })" title="Detail for #item.CatalogName">
<img class="catalogimg" src="#Url.Content(path)" />
</a>
</div>
<p>#item.CatalogName</p>
</div>
</li>
}
</ul>
</div>
</div><!-- productlist -->
Now the rendered partialview in the browser doesn't have anything in the anchors which may or may not be normal...
<div class="pagedList" data-cs-target="#productList">
<div class="pagination-container"><ul class="pagination"><li class="disabled PagedList-skipToPrevious"><a rel="prev">«</a></li><li class="disabled PagedList-pageCountAndLocation"><a>Showing items 1 through 18 of 65.</a></li><li class="PagedList-skipToNext">»</li></ul></div>
</div>
And when you hover on the >> it doesn't show the page parameter in the URL:
Again, back in the Controller - I get the category (15) but no page parameter or Request.URL parameter is passed to the controller - it's not hiding because of some routing mistake...I think...
How do I get the paging control to work again...???
[EDIT: one more note - the url path on the pager is /controller/action/category/page rather than what shows up on Scot Allen's OdeToFood example where it's equivalent would be /controller/action/category?page=n (like /Home/Catalog/15?page=1 ]
I was missing the JS for the PagedList class anchor element.
var getPage = function () {
var $a = $(this);
var options = {
url: $a.attr("href"),
data: $("form").serialize(),
type: "get"
};
$.ajax(options).done(function (data) {
var target = $a.parents("div.pagedList").attr("data-otf-target");
$(target).replaceWith(data);
});
return false;
};
And this is fired off by :
$(".main-content").on("click", ".pagedList a", getPage);
BUT, this means you need to have your #RenderBody() call in your _Layout.cshtml file wrapped in something with a class of main-content. An example:
<section class="content-wrapper main-content clear-fix">
#RenderBody()
</section>

Pass constant value and variable (input) text from View to Controller

I'm fairly new to ASP.NET MVC and still getting used to some of the concepts.
I understand that to pass the value of a text box in the View back to the Controller, I can use Html.BeginForm and give the text box the same name as the corresponding parameter in the Controller Action.
Here's my situation: I have 2 buttons. I want them to call the same Action in the Controller. I want them to both pass the value for the text box (i.e. the "searchText").
However, I want one of the buttons to pass "false" for the parameter isQuickJump and I want the other button to pass "true" for the parameter isQuickJump.
Here is my View:
#using (Html.BeginForm("SearchResults", "Search", FormMethod.Get)) {
<div id="logo" class="centered">
<a href="SearchResults">
<img alt="Search" src="../../Content/themes/base/images/Search.jpg" />
</a>
</div>
<div id="searchBox" class="centered">
#Html.TextBox("searchText", null, new { #class = "searchTextBox" })
</div>
<div id="buttons" class="centered">
<input type="submit" id="searchButton" value="Search" class="inputBtn" />
#Html.ActionLink("Quick Jump", "SearchResults", "Search", new { isQuickJump = true }, new { #class = "btn" })
</div>
}
Controller:
public ActionResult SearchResults(string searchText, int? page, int? size, bool? isQuickJump, GridSortOptions sort)
{
var items = GetSearchGrid(searchText, page, size, sort);
if (Request.IsAjaxRequest())
return PartialView("_SearchResultsGrid", items);
return View(items);
}
Any suggestions on how to do this?
I appreciate your help!
Just use 2 submit buttons with the same name and different value:
<div id="buttons" class="centered">
<button type="submit" name="isQuickJump" value="false">Search</button>
<button type="submit" name="isQuickJump" value="true">Quick Jump</button>
</div>
Depending on which button is clicked the corresponding value will be sent to the server for the isQuickJump parameter. And since both are submit buttons, they will also submit all other input fields data to the server (which was not the case with the anchor that you used as the second button).

Resources