The layout page that calls the #Renderbody() method has a navigation bar, and I want to add an orange border to the button that represents the page the user is currently on. The only way I can think to do this is to add a class (.current or something) to the button on each individual page, but since the elements live in the _layout page, I can't change them per-page. This is easy to do with JavaScript, but is there a way to do it using strictly HTML and CSS?
Just because they creating the menu happens in _Layout doesn't mean that it cannot change on a page by page basis. You still have access to all the usual pipeline components whilst rendering _Layout. I can think of two methods that you could use, not sure which I prefer or if I even really like either of them, but they should show you that things are possible and perhaps you can think of a cleaner way to achieve it or someone else can think of a better way of doing it.
You could load something into the ViewData object in you action (or as part of a base controller or some generic code that is run for every action) that can then be fished out in the _Layout and used to add the class to the relevant button.
You could interrogate the Route object from within _Layout to figure out what page you where currently looking at and use that to add the class to the relevant button.
Hope this helps.
Cheers Mike
Related
I have a menu and I used a cookie in order to set the menu as selected by refreshing. The menu is common to all classes, so I put it in the _layout.cshtml, but the same time I want a controller for this layout because there some function to set the menu as highlight. Can I create a controller for this?
Yes, you can call #Html.Action or #Hmtl.RenderAction to invoke a controller from the view. But this borders on mixing of concerns, as now your view is actively calling your controller.
The better approach is often to pass the appropriate data to the view as part of your view model.
Somewhat related answer of mine
RenderAction method documentation
But the same time I want a controller for this layout because there
some function to set the menu as highlight.
If you are doing something basic like highlighting the current page, there may be a simpler solution. You could put the current page ID into the ViewBag and retrieve that value in your main _Layout file and use it to select the appropriate item.
Partial actions may be what you looking for here - this article may be some help. It relates to MVC2 but the principles remain the same.
create an action for menu, and put menu ui in the view, and then call Html.Action("menu action name","controllern name") on layout page.
In my layout file, I am displaying some text, and I want to hide this text only in one view. How do I tell what view is currently loaded from inside the view?
An easy way is to add some conditional logic to render in your _Layout as long as a viewbag bit is not set. If you don't want to render simply say so by defining the viewbag variable in the controller action and the layout won't render it.
There are more elegant solution involving attributes but this should get you going.
Don't forget the layout shouldn't know about specifically what view you're rendering thats a bleeding concerns. Viewbag helps by providing a communication and allowing decoupling of these two pieces.
You can set Id to that text container and in that specific view you can hide that Id by jquery
write this code in that view where you can to hide the text
$(function() { $("#id").hide(); }
I'm having trouble figuring out how to do the following:
On every page (or every page I so desire), I'd like to put a common control widget (e.g. think - Search functionality that contains a textbox+button). What's the best way to do this, and who handles the submit button (assuming it is a submit button)?
i.e. what does my ViewUserControl look like? Does it have a form? does it use jQuery onclick""? Does it post to the main View's action method, or can I redirect it to another Controller/Action?
I have tried using RenderAction of a "Search.ascx" which contains a Form, and is handled by my SearchController... but in the SearchController, it then tries to call RedirectToAction... and I get a complaint about RedirectActions not allowed on Child Actions.
I'm a bit lost on what to do next, so suggestions greatly welcome!
Ray
You seem to be on the right track (using ViewUserControl and RenderPartial). But with the information you have provided, it is not easy to see what you other problems are (RenderAction , ...)
It is easy:
Create a UserControl (.ascx) and get a form in there with URL being /search/..., something that you can get back.
In your views, call RenderPartial and provided the view name
Create your controller to receive the post from your search. This is not the same controller as your parent view controller.
The best way to have the HTML elements show up is to put them in a master page, or in a partial that is referenced by your master page. I would have it be it's own form and submit to your SearchController.
Let me know if you want more particulars.
RenderPartial is the way to go here. Your control.ascx will consist of it's form and submit button.
What's the best way to do this
Probably a partial view. An .ascx file.
and who handles the submit button
(assuming it is a submit button)?
The partial view
what does my ViewUserControl look
like? Does it have a form?
Yes, it has a form. It should be as self contained as possible.
does it use jQuery onclick""? Does it
post to the main View's action method,
or can I redirect it to another
Controller/Action?
Well, whatever fits your exact scenario best. It should probably post to whichever action is most appropriate. That is not likely to be the main view's action, since the partial is reused in different parent views.
I have tried using RenderAction of a
"Search.ascx" which contains a Form,
and is handled by my
SearchController... but in the
SearchController, it then tries to
call RedirectToAction... and I get a
complaint about RedirectActions not
allowed on Child Actions.
You'll probably want to render it using RenderPartial in the parent view:
<%: Html.RenderPartial("MyPartialView.ascx") %>
Ok, I figured out what my problem was. The replies above are correct. I have my own Search.ascx user control and SearchController, I also used RenderPartial, but what stumped me was that I forgot to explicitly specify the controller/action... so then I was fiddling around with onclick events and Url.Action on my button instead.
<% using (Html.BeginForm("MySearchAction", "MySearchController")) { %>
Thanks to all who replied.
In a recent post, I expressed a need to access the properties for the body using declarative syntax, see
Contentplaceholder for replacing attributes?
I thought the first suggestion solved my problem. But, the syntax confuses the editor which is not acceptable.
My hypothesis for a workable solution is to make the change in code. To derive a class from System.Web.UI.Page with extended functionality. However, I want for the designer to be able to still use declarative syntax to set the body tag.
In other words,
I do not want to have to change any code in my aspx web pages except that they derive from base
I want to be able to set these properties using declarative syntax, merely by adding a tag in the derived page
I'm not immediately sure how to go about doing this because it doesn't exactly fit the OOP paradigm and I'm not sure where the changes need to be made.
Initial hypothesis,
I can use a findcontrol in the base to see if the placeholder has been added. But, not sure exactly at what point in the page processing lifecycle that I can use this findcontrol. I need to set the body before it renders but also be able to grab something from the declarative code.
I hope what I'm trying to accomplish is clear(?) Basically, I want to be able to edit a user defined tag in my aspx page that will change the class for the body in a master page.
Why not create a custom server control (called something like BodyAttributeManager) that does not render anything, but just looks at its attributes and programatically adds them to the body element on PreRender?
Nested tags as mentioned in that example isn't going to work. ASP.NET does not support that. #jball's suggestion is a good idea; having a class outside of the body that can programmably affect the body's settings from code (which is the only real solution here) would give you what you are looking for.
HTH.
In ASP.NET (not MVC), what is the best approach to programmatically setting styles on an unordered list used for navigation so the appropriate menu item is styled as the active item if that page is being viewed?
This would most likely be used in conjunction with a MasterPage.
The answer to your question depends a lot on how you have your list implemented {User control or not, etc}. How I would do it, is implement the list to be generated by a user control.
I'd have the UserControl tag each element with something like:
<{...} class="GeneratedMenuItem"> {...}
And I'd have the appropriate styles in the Style Sheet; of course if it was in a user control then you might be able to use Themes (but that depends on which version of ASP.net you are using.
Good question, I have played around with various methods of doing this since the bad old days of asp, and am yet to find the perfect hammer.
Generally I have used the Request.Url.AbsoluteUri (or similar) as an argument to whatever the rendering function was, and most often set a css class of "current" or similar on the appropriate node, as well as rendering child nodes as needed.
I have most often used an xml/xsl combination, which can usually be worked against most cms platforms, although I have never been that happy with the overhead of firing up an xsl transform just to output a nav list, but if you know xsl, is a very nice tool for generating html, and you can always cache the output - for little static html sites which come up occasionally, I often use this approach in a build process to render static menu markup.
Have also used the aspnet sitemap functionality a few times, which is pretty good if you use the css friendly adapters with it - the default rendering makes very ugly markup.
I found this article earlier this weeek: http://blog.devarchive.net/2008/01/auto-generate-strong-typed-navigation.html which uses t4 templates to make a strongly typed navigation class, and I will definately be investigating that further.
The way I took this approach was to create ASP.NET Hyperlink Controls for each of my navigation items in my master page.
Within the master page, I then created a public method that would assign the appropriate "selected" CSS style to the control I specify:
Public Sub SetNavigationPage(ByVal MenuName As String)
DirectCast(Me.FindControl(MenuName), HyperLink).CssClass = "MenuCurrent"
End Sub
Then in my content pages, I simply had to reference the master page accordingly.
Dim myMaster As EAF = DirectCast(Me.Master, EAF)
myMaster.SetNavigationPage("hypSearchRequest")
This gave me the flexibility to add/remove navigation items on various pages and also be able to assign multiple pages to the administrator navigation option when necessary.
It is also interesting to note that referencing the hyperlink control and setting the Visibility attribute (for hiding administrative pages) didn't work. This is due to the order in which the master and the content pages load. Instead, I created another CSS class that simply set the visibility property and used the same approach as above.