I'm new to asp.net mvc. I'm looking to create some control for reusing html. I have a complex HTML box for example:
<div class="Box">
<div class="Top"></div>
<div class="Content">
<div style="padding:10px;">
[CONTENT GOES HERE]
</div>
</div>
<div class="Bottom"></div>
</div>
Previously using webforms I've been able to reuse this by inheriting from WebControl and override Render. But how can I implement this in MVC?
The Content of the box could of course be what ever. Other boxes for example.
Easiest yet: using a UserControl
<%# Control Language="VB" Inherits="System.Web.Mvc.ViewUserControl" %>
<div class="Box">
<div class="Top"></div>
<div class="Content">
<div style="padding:10px;">
<%= Model.Content %>
</div>
</div>
<div class="Bottom"></div>
</div>
And then calling the user control with
<% Html.RenderPartial("NiceBox", New with {.Content = "The real content goes here"})%>
Here's an example of one way to build it as an HtmlHelper extension method:
public static string Box(this HtmlHelper helper, string content)
{
var builder = new StringBuilder();
builder.Append("<div class=\"Box\" .......... );
if (!String.IsNullOrEmpty(content))
{
builder.Append(content)
}
return builder.ToString();
}
In your view:
<%= Html.Box(contentString) %>
Your other options are to create it as a partial view (.ascx) and pass it a ViewModel class that contained the content that you wanted to render. Judging by the requirement of "the content could be anything", an HtmlHelper extension might be more flexible for you.
Related
This is my Manage page that was generated by the Scaffolded Identity.
Previously this weird Manage your account header with the subheading: Change your account settings and menu did not appear.
The only thing that showed was the form in the image and the Manage Account header located directly above the form but I'm not sure why suddenly this extra header and menu appears. I've tried searching on the page itself but it doesn't show up in the code. Is this a configuration somewhere?
EDIT:
Added structure of Manage
You can try to open the file _Layout.cshtml in the folder Manage, maybe there is something like this:
<h2>Manage your account</h2>
<div>
<h4>Change your account settings</h4>
<hr />
<div class="row">
<div class="col-md-3">
<partial name="_ManageNav" />
</div>
<div class="col-md-9">
#RenderBody()
</div>
</div>
</div>
#section Scripts {
#RenderSection("Scripts", required: false)
}
Based on your update, I think the problem comes from the way you add scaffolded item.
I suggest you to follow these steps to add all scaffolded items, then deleting which one you don't use.
Right-click on the solution -> Add -> New Scaffolded Item... -> Identity -> Identity -> Add
Check with the option: Override all files.
In the layout input, clicking on the ... button to select the default layout:
In the Data context class input, clicking on + button to create new context class:
After scaffolding, you will receive all the files:
Lastly, you can open the file _Layout.cshtml to check the title, the file content could be:
#{
Layout = "/Areas/Identity/Pages/_Layout.cshtml";
}
<h2>Manage your account</h2>
<div>
<h4>Change your account settings</h4>
<hr />
<div class="row">
<div class="col-md-3">
<partial name="_ManageNav" />
</div>
<div class="col-md-9">
#RenderBody()
</div>
</div>
</div>
#section Scripts {
#RenderSection("Scripts", required: false)
}
I have a controller, which is composed of many other partial views. I wanted to use a particular section of that controller in another controller. I am able to see the design but unable to load items in it.
Let say I have one controller named "Products" within Product view folder I have _items.cshtml. I wanted to use this _items.cshtml in another controller called "placeTheOrder".
In particular section of div in placeTheOrder view I referred to #Html.Partial("~/Views/Products/_items.cshtml"). Even after doing so it is unable to load the content from _items.cshtml into placeTheOrder.
What am I doing wrong.
_items.cshtml view
<div id="accordionProduct" class="span-6 last prod-acc">
#Html.Partial("~/Views/product/_ezCpSearchBar.cshtml")
<div id="filterPanel" class="span-6 last filter-panel">
<div class="span-6 last">
<div class="filter-panel-head">
<h1>Filter</h1>
</div>
</div>
<div class="span-6 last">
<div class="filter-panel-body">
<div class="filter-panel-prop"></div>
</div>
</div>
</div>
<div id="accordionProductInner" class="span-6 last prod-acc-body">
</div>
</div>
// this is the script are where the content gets loaded into the view
<div id="TemplateFilterItem" class="hidden"></div>
<div id="TemplateLastViewItem" class="hidden"></div>
This is the place where I have refered to it in another controller
<div class="span-6" style="background-color:#d4d4d4;padding:20px;">
#Html.Partial("~/Views/product/_items.cshtml")
</div>
You can use Html.Renderpartial in your view instead
Html.RenderPartial("~/Views/ControllerName/ViewName.cshtml", ModelData);
If you are using different model for both the views then you need to make ViewModel which will include required properties.
Hope this Helps
I have the following code in my View.
#model MovieApp.Models.HomeIndexViewModel
#foreach (var item in Model.Movies)
{
<div class="container">
<div class="row">
<div class="col-xs-4">
<img src=item.posterPath id="picture1" class="img-responsive" />
</div>
</div>
</div>
}
I retrieve the image Url's on item.Posterpath as a string.
When I try to add my Url's on item.PosterPath as <img src=item.posterPath id="picture1" class="img-responsive"/>I can see that the item is not in scope.
My question is how i should iterate over my Model to stay in the scope and retrieve my paths?
have you tried src="#item.posterPath" ?
I have a predicament that I am not quite sure how to overcome. I do not know what is the right way. I am building a website and I was given a template to integrate with my server code. The problem lies in how the template is outlined. Let me show you an example.
<body>
<div class="breakpoint active" id="bp_infinity" data-min-width="588">
<div id="header">full page header content</div>
<div id="body">some stuff</div>
<div id="footer">some stuff</div>
</div>
<div class="breakpoint" id="bp_587" data-min-width="493" data-max-width="587">
<div id="header">mobile header content</div>
<div id="body">some stuff</div>
<div id="footer">some stuff</div>
</div>
<div class="breakpoint" id="bp_492" data-max-width="492">
<div id="header">mobile header content</div>
<div id="body">some stuff</div>
<div id="footer">some stuff</div>
</div>
</body>
I am trying to setup my MVC5 Views in a way that does not repeats common code. The problem that I am facing is that the header and footer div are common code from page to page and the body changes. The second problem is that each page has different number of breakpoints. Here is a second page to show what I mean:
<body>
<div class="breakpoint active" id="bp_infinity" data-min-width="588">
<div id="header">full page header content</div>
<div id="body">some stuff</div>
<div id="footer">some stuff</div>
</div>
<div class="breakpoint" id="bp_587" data-max-width="587">
<div id="header">mobile header content</div>
<div id="body">some stuff</div>
<div id="footer">some stuff</div>
</div>
</body>
So the Layout page is now tricky to setup because I can't just say:
<body>
#RenderBody
</body>
One of the solutions I thought of was to use Sections, something like this:
<body>
#RenderBody
#RenderSection("Breakpoint-1", false)
#RenderSection("Breakpoint-2", false)
#RenderSection("Breakpoint-3", false)
</body>
Now each page would be along the lines of:
#section Breakpoint-1
{
<div class="breakpoint active" id="bp_infinity" data-min-width="588">
#{ Html.RenderPartial("full-page-header"); }
#{ Html.RenderPartial("full-page-body"); }
#{ Html.RenderPartial("full-page-footer"); }
</div>
}
#section Breakpoint-2
{
<div class="breakpoint" id="bp_587" data-max-width="587">
#{ Html.RenderPartial("mobile-page-header"); }
#{ Html.RenderPartial("mobile-page-body"); }
#{ Html.RenderPartial("mobile-page-footer"); }
</div>
}
A problem that I see with above code is that if the header now needs to have 5 breakpoints instead of 2, I need to go and modify it everywhere.
Is there a better way to do this? Is what I thought of the best solution for my scenario?
EDIT: To clarify. There are multiple brakpoints in the HTML because only one of them is active at a time. When page hits a certain width, 1 the currenct active breakpoint gets hidden and the new one becomes visible.
Assumptions
... are the mother of all....
"some stuff" that goes in the body tag is HTML being fed from some data source, or is hard-coded
"...the header and footer div are common code from page to page..." means that literally, you don't need to change the header/footer at all. (You still could, but I'm ignoring that for now)
The div id's "header", "body", "footer" should be handled as dom classes rather than dom ids. That is another discussion, but ids should always be unique.
Solution
This is a basic example, there are plenty of other approaches to try and plenty of other tweaks you can make
Controller
Let's call this BreakpointController
public ActionResult Index()
{
var model = new List<BreakpointViewModel>();
// populate model
return View(model);
}
ViewModel
public class BreakpointViewModel
{
public string BreakPointId { get; set; }
public int? MinWidth { get; set; }
public int? MaxWidth { get; set; }
public string Body { get; set; }
public bool IsActive { get; set; }
}
View
This should be your index.cshtml (or whatever you want to call it)
#model IEnumerable<WebApplication1.Models.BreakpointViewModel>
<div>
<h1>A header!</h1>
</div>
#Html.DisplayForModel()
<div>
<h4>A footer!</h4>
</div>
DisplayTemplate
* Thou shalt live in the folder containing views for the controller (or Shared)
* Thou shalt live in a subfolder named 'DisplayTemplates'
* Thou shalt be named {ModelName}.cshtml
in the end, the folder structure should look something like this:
Views
|-- Breakpoint
| |-- DisplayTemplates
| | +-- BreakpointViewModel.cshtml
| +-- Index.cshtml
And BreakpointViewModel.cshtml should look like this:
#model WebApplication1.Models.BreakpointViewModel
<div class="breakpoint #(Model.IsActive ? "active" : null)"
id="#Model.BreakPointId"
#(Model.MinWidth.HasValue ? "data-min-width='" + Model.MinWidth + "'" : null)
#(Model.MaxWidth.HasValue ? "data-max-width='" + Model.MaxWidth + "'" : null)>
#Html.Raw(Model.Body)
</div>
Note the minwidth/maxwidth lines in the div. Not required, just how I would personally deal with the widths.
Resulting HTML
<div>
<h1>A header!</h1>
</div>
<div class="breakpoint active"
id="bp_1"
data-max-width='720'>
<div>Hello World!</div>
</div>
<div class="breakpoint"
id="bp_2"
data-max-width='720'>
<div>Another Breakpoint</div>
</div>
<div class="breakpoint"
id="bp_3"
data-max-width='720'>
<div>Third Breakpoint</div>
</div>
<div class="breakpoint"
id="bp_4"
data-max-width='720'>
<div>Fourth Breakpoint</div>
</div>
<div>
<h4>A footer!</h4>
</div>
Original Answer
DisplayTemplates are your friend. If your sections are going to be the same, you can put the relevant information into a ViewModel, then pass the List<ViewModel> to the DisplayTemplate. The MVC engine will then use the DisplayTemplate for your ViewModel to fill out the needed code for each section.
You only need code your DisplayTemplate for your ViewModel once.
I don't have any sample code up at the moment, but if you need further help, comment on this and I'll break some out over the weekend.
Say, I'm using often the following HTML in ASP.NET MVC application:
<div class="a">
<div class="b">
(varying content)
</div>
</div>
I'd like to put the repeating div part to a separate file and reuse it (notice, that the content may, and will change). How can I do that?
Keep it in a partialView, eg: _CommonDiv
call Partial view from your view
#Html.Partial("_CommonDiv", null, new ViewDataDictionary {{ "yourvaringcontentKey", yourcontent}})
get content in partialView
string yourcontent= (string)this.ViewData["yourvaringcontentKey"];
And use the same where you want.
In your web application add App_Code\Helpers.cshtml
Paste the code below inside Helpers.cshtml
Helper code:
#helper DivHelper(string text)
{
<div class="a">
<div class="b">
#text
</div>
</div>
}
Now you can call this helper in any of your views using #Helpers.DivHelper("Some text...") and because the logic is inside App_Code no using statements are required!