Conditionally displaying parts of my view - asp.net-mvc

Say I have an asp.net mvc website with a page that lists products. ON that page I have a "delete" button that should only show up for the user that inserted the product. What's the best way to do this?
One way I thought of doing it was setting a boolean in the controller to let the view know if the button should be displayed. Something like:
if(IsProductOwner(UserId))
ViewData["CanDelete"] = true;
Then in the view I can just do
<% if((boolean)ViewData["CanDelete"] == true) { %>
// show delete button
<% } %>
But is there a better way to do this?

My initial thought is that you should at least make that a function of the Product class so you can go:
<% if (product.IsOwnedBy(UserId)) { %>
// show delete button
<% } %>
This removes some of the floaty ViewData and builds the business logic into your classes rather than floating out on the edges.
However, I haven't found a decent way to do this sort of conditional display in views unless the view is significantly different then I get the action to display a different view depending on the context.

Related

Include variable definitions in multiple views

In a number of views I have the following kind of code:
<% compute a number of variables %>
Do something with those variables to layout and configure HTML elements.
I'm drying to dry up my views. That first part where I compute the values for the variables is used in a number of different views. I would like to be able to pull it out into another file and use it in each view that needs it so that I only have to change it in one place. If I pull it into its own partial and then render that partial in another view, the variables are not defined in the view. To be more specific:
<%
top = 0
link.siblings_before.each do |sibling|
top = top + compute_top(sibling)
end
%>
<div style="position:absolute;top:<%= top %>px"><%= link.name %></div>
I want to be able to use the computation of top in more than one view without having to cut and paste the ruby code into each view.
Try avoiding logic in your views.
You can define a before_filter in your controller and enabled it for multiple actions that you need them for.
Those variables defined in your before filter will be available in those views and you keep your views clear at the same time.

building custom navigation in razor view

I hope to get some useful input on how to implement my desired functionality:
I've got a razor partial view without a model that contains the navigation for my webapp. As some functions are only ment to be available for specific users, I want to customize the view.
In particular I want to show/not show specific li elements in the ul.
I already have a query which determines whether the element needs to be shown or not.
The element itself has to be like this:
<li>#Resources.Label1</li>
How would I achieve this?
You should be able to use the ViewBag.
Main view or controller:
ViewBag.LoggedIn = true;
Partial view:
<ul>
<li>Visible to everyone</li>
#if (ViewBag.LoggedIn == true) {
<li>Visibility based on some data</li>
}
</ul>

Can I conditionally render partial views in _Layout.cshtml?

Suppose I have a _Layout.cshtml where I render a left sidebar, which is common to every page of my website.
Something along these lines - a menu, for example
<div id="left-sidebar">
#Html.Action("_MenuView", "LeftSideMenu")
</div>
A feature I would like to have would be to add another partial view, but only display it in certain sections of the website.
For example, in the blog section I may want to display a list of post categories or a treeview of the posts.
<div id="left-sidebar">
#Html.Action("_MenuView", "LeftSideMenu")
#if ("???")
{
#Html.Action("_BlogTreeView", "BlogEntries")
}
</div>
How could I do that? I know that I want to display "_BlogTreeView" if the view I'm rendering is returned by BlogController ... where do I go from there?
In your layout, add this section
#RenderSection("blogEntries", false)
Then in every view where you want to show the partial view add this:
#section blogEntries {
#Html.Action("_BlogTreeView", "BlogEntries")
}

ASP MVC ViewData from one view to another (Html.Encode())

I have a page with a bunch of labels and checkboxes on it. On this page, the labels need to be easily customizable after the project is deployed.
So I made all of the labels in this style:
Html.Encode(ViewData["lblText"])
And I added a button on the page called "Edit Button Labels" that will only be seen by admins.
When that button is clicked, I would like to load another view that simply contains a table of two columns. One column needs to contain the current labels and the other should have text boxes for the user to enter new labels.
Then, once any changes have been made, I need to permanently change the "lblText" for each label on the original page.
I have tried passing viewdata and tempdata to the "Edit Button Labels" view using both return view() and return RedirectToAction() with no success. Am I missing something minor or is there a better way to do this?
Don't use ViewData is the first thing I'd say. Return a model to your view which contains the labels. Create a composite model if required.
Then, to edit your labels, go to a view that takes the same model, allows you to enter the new text and saves the results to the xml, db, text file, whatever.
So you might have a model like this;
public class Labels
{
public List<string> text{ get; set; }
}
So in your db layer, wherever that is, fill the object with the label text items.
On your EDIT view you should then do the following imho;
<% Html.PartialView("EditLabels", Model); %>
Then you have a partial view called EditLabels and it would have something like the following psuedo;
foreach(string item in Model)
{
<% Html.PartialView("labelEdit", item); %>
}
Then finally you have a partial view that takes a single item and allows you to edit it called labelEdit.
This, in my opinion, is the correct way to do it in MVC as to breaks the entire view into chunks of functionality and seperates the concerns nicely.
Obviously you still need an ActionResult to take a post and affect the changes.

ViewData not inheriting in partials

I was trying to use a shared partial view to render when a particular listing page has no data. I wanted to use ViewData to pass information from the page into my listing control, which would then conditionally render the NoData partial view using the ViewData values.
I would like to be able to specify them in the view markup, not in the controller action, but when I add them in the view the don't seem to inherit down into child partial views (like the Nodata partial view). However, specifying them in the ViewData values in the controller actions works fine, the data is available all the way down...
Does anyone know why it behaves this way?
When rendering a partial you can also pass the ViewData.
<% Html.RenderPartial("NoData", ViewData); %>
<%Html.RenderPartial("partialViewName", "viewData", "model"); %>
it is a best practice to do the decision inside the controller, if you have a scenario to make a decision inside the view, separate them and call them inside the controller conditionally

Resources