create a html helper for mvc - asp.net-mvc-3

I am new to mvc so not sure if this is possible.
I have some html that basically uses some images to create a nice looking rounded corners box.
Is it possible in mvc3 to create a helper function that will allow me to call the helper and insert any content I want into the main area of the div tags.
this is my html
<div class="rounded">
<div class="top">
<div class="right">
</div>
</div>
<div class="middle">
<div class="right">
<div class="content">
Some how allow me to insert data into here
<div class="Clear">
</div>
</div>
</div>
<div class="bottom">
<div class="right">
</div>
</div>
</div>
</div>
I dont want to have to copy this everywhere I want to use this styling so I am hoping I can create some type of helper and call it whenever I need to use this box and allow me to insert html into
<div class="content">
Some how allow me to insert data into here
<div class="Clear">
</div>
Does anyone have any suggestions?
Thank you

Seems like an excellent scenario for a custom html helper:
public class RoundedCorner : IDisposable
{
private readonly ViewContext _viewContext;
private bool _disposed = false;
public RoundedCorner(ViewContext viewContext)
{
_viewContext = viewContext;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!_disposed)
{
_disposed = true;
_viewContext.Writer.Write(
#"<div class=""Clear"">
</div>
</div>
</div>
<div class=""bottom"">
<div class=""right"">
</div>
</div>
</div>
</div>"
);
}
}
}
public static class HtmlExtensions
{
public static RoundedCorner RoundedCorner(this HtmlHelper htmlHelper)
{
htmlHelper.ViewContext.Writer.Write(
#"<div class=""rounded"">
<div class=""top"">
<div class=""right"">
</div>
</div>
<div class=""middle"">
<div class=""right"">
<div class=""content"">"
);
return new RoundedCorner(htmlHelper.ViewContext);
}
}
and in your view simply:
#using (Html.RoundedCorner())
{
<div>Some how allow me to insert data into here</div>
}
which would generate (I know, what an ugly formatting but perfectly valid HTML, I am too lazy to fix it at the moment):
<div class="rounded">
<div class="top">
<div class="right">
</div>
</div>
<div class="middle">
<div class="right">
<div class="content"> <div>Some how allow me to insert data into here</div>
<div class="Clear">
</div>
</div>
</div>
<div class="bottom">
<div class="right">
</div>
</div>
</div>
</div>

I like the solution above provided by Darin. The only changes I would make is to have two private methods in the RoundedCorner class that write the opening and closing tags to the view context, rather than having part of it in the class and the other part in the helper. Then the helper just returns a new instance of RoundedCorner.

Related

01/01/0001 when passing birth date to control

I want to save a register form and must save birth date in another format.
In model I have:
public DateTime BirthDate { get; set; }
In the view:
#model Univer.Model.KarApplicant
#{
ViewData["Title"] = "";
}
<div class="container MainMiddle" style="padding-top:50px;">
<hr />
<div class="row container-fluid">
<div class="col-md-10">
<form asp-action="Register">
<div asp-validation-summary="ModelOnly" class="text-danger">
</div>
<div class="form-row">
....
<div class="form-group col-md-4">
<label asp-for="BirthDate" class="control-label"></label>
<div class="input-group mb-2 mr-sm-2">
<div class="input-group-prepend">
<div class="input-group-text"><i class="fas fa-calendar-alt"></i></div>
</div>
<input asp-for="BirthDate" class="form-control example1" data-val="false" />
<span asp-validation-for="BirthDate" class="text-danger"></span>
</div>
</div>
</div>
....
<div class="form-row">
</div>
<div class="form-group float-left">
<input type="submit" value="next" class="btn btn-lg btn-primary btn-block" />
</div>
</div>
</form>
</div>
</div>
</div>
#section Scripts {
#{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
<script src="~/lib/persian-date/persian-date.js"></script>
<script src="~/lib/persian-datepicker/js/persian-datepicker.js"></script>
<script type="text/javascript">
$(document).ready(function () {
$(".example1").pDatepicker();
});
</script>
}
When I click on Submit button and send data to action of controller, with breakpoint check form value that pass to controller, birth dates value that are passed to controller is 01/01/0001 but I have value in persian mode in input in view.
My question is: why when set value with javascript in input and send to controller the value doesn't get sent?
UPDATE: after the comment i Added this code
public void ConfigureServices(IServiceCollection services)
{
services.Configure<RequestLocalizationOptions>(options =>
{
options.DefaultRequestCulture = new RequestCulture("fa-IR");
}); .....
}
and
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{....
app.UseRequestLocalization();
app.UseMvc()....
}

Submitting a POST object

I spent the whole weekend searching the net on my problem. It seems like I am missing something really silly, but I failed to pick it up.
Here's the problem. I sent an object to a JSP and on the JSP I could see its content. I them I submitted the form. Back in the controller, it shows the object is overwritten/recreated. I can't seem to understand. I checked the logs on my Tomcat but I do not see any error...
On my Controller:
#RequestMapping(value = {"/", "/home"}, method = RequestMethod.GET)
public String homePage(ModelMap model) {
model.addAttribute("user", getPrincipal());
Catalog catalog = catalogService.getCatalogByCategory(Catalog.CatalogCategory.ALL);
model.addAttribute("catalog", catalog);
model.addAttribute("numberOfItemsAdded", "500");
return "welcome";
}`
and in my JSP I have the following:
<form:form method="POST" modelAttribute="catalog">
<form:hidden path="id"/>
<div id="products" class="row list-group">
<c:forEach var="orderItem" items="${catalog.orderItems}">
<div class="item col-xs-4 col-lg-4">
<div class="thumbnail">
<img class="group list-group-image" src="http://placehold.it/400x250/000/fff" alt=""/>
<div class="caption">
<h4 class="group inner list-group-item-heading">
${orderItem.name}</h4>
<p class="group inner list-group-item-text">
${orderItem.description}
</p>
<div class="row">
<div class="col-xs-12 col-md-6">
<p class="lead">
R ${orderItem.price}</p>
</div>
<div class="col-xs-12 col-md-6">
<label for="${orderItem.id}" class="btn btn-primary">Add to Cart <input
type="checkbox" id="${orderItem.id}" name="orderItem.addedToCart"
class="badgebox"><span class="badge">&check;</span></label>
</div>
</div>
</div>
</div>
</div>
</c:forEach>
</div>
<div class="row">
<div class="form-group">
<div class="col-sm-12 pull-right">
</div>
<div class="col-sm-2 pull-right">
<input type="submit"
class="btn btn-default btn-block btn-primary"
value="Next" name="action" formmethod="POST"
formaction="confirmList"/>
</div>
</div>
</div>
</form:form>`
After pressing "Next", which submits the form data to a controller:
#RequestMapping(value = "/confirmList", method = RequestMethod.POST)
public String confirmList(#ModelAttribute Catalog catalog, #ModelAttribute String numberOfItemsAdded) {
System.out.println("\n\n------>catalog = " + catalog);
System.out.println("\n\n------>numberOfItemsAdded = " + numberOfItemsAdded);
List<OrderItem> selectedItems = new ArrayList<OrderItem>();
for (OrderItem orderItem : catalog.getOrderItems()) {
if (orderItem.isAddedToCart()) {
selectedItems.add(orderItem);
}
}
//model.addAttribute("numberOfItemsAdded", selectedItems.size());
return "welcome";
}
`
The System.out.println(...) output the following:
------>catalog = Catalog{id=1, name='null', category='null', orderItems=null}
------>numberOfItemsAdded =
Those are empty outputs.... :'(
I have no idea what I am doing wrong here.....
This was answered in a comment line by George. All I had to do is hide/bind those null fields.
It is very concerning that we use the term 'hidden' to also mean 'ignore' or 'leave as is'. But anyway, the solution above did exactly what I was looking for.
Thanks to the Community

Sending data from function to view template?

I have a blade template that looks something like this:
<div class="comment">
<div class="username"></div>
<div class="message"></div>
<div class="children">
</div>
</div>
I need to be able to call this view from a function and insert data into it.
I have a class, Helpers.php, with a recursive function that looks like this:
function getComments(array $comments)
{
foreach ($comments as $comment)
{
echo $comment;
if (!empty($comment->children))
{
getComments($comment->children);
}
}
}
What this is meant to do is print out a comment, and then check if that comment has any children comments and recurse if it does.
How can I modify my view/function so that I can send data to the view, such that I end up with something like this:
<div class="comment">
<div class="username">Username1</div>
<div class="message">Hello, world!</div>
<div class="children">
<div class="comment">
<div class="username">Username1</div>
<div class="message">Hello, world!</div>
<div class="children">
<div class="comment">
<div class="username">Username1</div>
<div class="message">Hello, world!</div>
<div class="children">
</div>
</div>
</div>
</div>
</div>
</div>
<div class="comment">
<div class="username">Username1</div>
<div class="message">Hello, world!</div>
<div class="children">
</div>
</div>
Thanks!
You don't have to use a function in this particular case.
To achieve your goal, create a view comments.blade.php. Depending on your Laravel version and setup you can put it into app/views or resources/views directory.
The content of this file has to be like follows:
#foreach ($comments as $comment)
<div class="comment">
<div class="username">{{ $comment->username }}</div>
<div class="message">{{ $comment->message }}</div>
<div class="children">
#include('comments', ['comments' => $comment->children])
</div>
</div>
#endforeach
Then render this view and pass the same argument you were passing to your getComments() function.
This will hopefully give the desired result.
Good luck!
you can send the data to view from function you can use by three method compact,with and session. compact of with method while your are redirecting of loading any view you can use compact or ->with(array());

How to modify HTTP Response Using Filters in MVC 3 Razor?

HtML section in _Layout.cshtml
<div id="header">
<div class="logo"><img src="#Url.Content("~/!(IMAGEPATH)!/logo.png")" alt="" /></div>
<div class="fb_like"><img src="#Url.Content("~/!(IMAGEPATH)!/fb_like_btn.png")" alt="" /></div>
<div class="google_plus"><img src="#Url.Content("~/!(IMAGEPATH)!/google_plus.png")" alt="" /></div>
<div class="header_rt">
<ul>
<li>Call us: 1500 258 789</li>
<li>Live chat</li>
<li>My Account</li>
<li>Sign in</li>
</ul>
<div class="search">
<input type="text" value="Type your keyword..." class="srh_txt" />
<input name="Submit" type="submit" value="Submit" class="srh_btn" />
</div>
</div>
</div>
<div id="main">
#RenderBody()
</div>
Html section in Index.cshtml
#{
ViewBag.Title = "Home Page";
}
<div class="clr"></div>
<div id="banner">
<div id="slider"><img src="#Url.Content("~/!(IMAGEPATH)!/banner.jpg")" alt="" /></div>
<div class="banner_rt">
<div class="adv1"><img src="#Url.Content("~/!(IMAGEPATH)!/adv1.jpg")" alt="" /></div>
<div class="adv2"><img src="#Url.Content("~/!(IMAGEPATH)!/adv2.jpg")" alt="" /></div>
</div>
Using bellow code I able to Replace !(IMAGEPATH)! only in _Layout.cshtml
void Application_PostReleaseRequestState(object sender,EventArgs e)
{
if(string.CompareOrdinal(Response.ContentType,"text/html") == 0)
{
Response.Filter = new ResponseFilter(Response.Filter);
}
}
But above described code not affecting child pages like Index.cshtml. Please tell me any event in ASP.NET MVC3 like old protected override void OnPreInit(EventArgs e) of Classic ASP.NET !!!!
I want to know which event effecting all the child pages before rendering in MVC3 ?
Within Base Controller, write the bellow code
protected override void OnResultExecuting(ResultExecutingContext filterContext)
{
var response = filterContext.HttpContext.Response;
if (string.CompareOrdinal(response.ContentType, "text/html") == 0)
{
response.Filter = new ResponseFilter(response.Filter);
}
base.OnResultExecuting(filterContext);
}

layout difficulty in MVC3

I am having a login page. In the login Page I don`t have any menu and based upon the user login a menu appear on the Home page.
My problem is how not to display the menu only in my login page?
I am having a page MenuControlPartial.cshtml as follows for the menu:
<li>Admin
<ul>
<li>TimeKeeper</li>
<li>AAA</li>
<li>BBB</li>
<li>CCC</li>
</ul>
</li>
<li>Settings
<ul>
<li>VV</li>
<li>XX</li>
</ul>
</li>
</ul>
My _layout.cshtml is as as follows:
<div id="page">
<div id="header">
<div id="title">
<br />
</div>
#if (Request.IsAuthenticated)
{
<div id="loginInfo">
#Html.Partial("_LogOnPartial")
</div>
<div class="clear">
</div>
<div id="menucontainer">
#Html.Partial("MenuControlPartial")
</div>
<div class="clear"></div>
}
</div>
<div id="content">
#RenderBody()
</div>
</div>
}
</body>
You could test the current controller and action
#if (!(Html.ViewContext.RouteData.GetRequiredString("controller") == "Login" && Html.ViewContext.RouteData.GetRequiredString("action") == "Index")) {
<div id="menucontainer">
#Html.Partial("MenuControlPartial")
</div>
}
And to avoid this ugliness write a helper:
public static bool ShouldDisplayMenu(this HtmlHelper htmlHelper)
{
var routeData = htmlHelper.ViewContext.RouteData;
var controller = routeData.GetRequiredString("controller");
var action = routeData.GetRequiredString("action");
return !(controller == "Login" && action == "Index");
}
and then:
#if (Html.ShouldDisplayMenu()) {
<div id="menucontainer">
#Html.Partial("MenuControlPartial")
</div>
}

Resources