How to use inline template with multiple inputs in MVC Razor view - asp.net-mvc-3

Inside my view I currently have
#{
Func<Website.Security.User[], object> renderUserList = #<text>
<div class="span4">
#*<h2>#title</h2>*#
<ul>
#foreach (var user in item)
{
<li>#user.UserName - Edit</li>
}
</ul>
</div>
</text>;
}
#renderUserList(Model.AdminUsers)
How can I rework this so that the renderUserList expression can take in a second input for the section title?

As I understand, you trying to create helper: ASP.NET MVC 3 and the #helper syntax within Razor
#helper renderUserList(Website.Security.User[] users, string title)
{
<div class="span4">
<h2>#title</h2>
<ul>
#foreach (var user in users)
{
<li>#user.UserName - Edit</li>
}
</ul>
</div>
}

Related

View data from another controller in ASP.NET Core MVC

I'm trying to build an ASP.NET Core 6 MVC app.
I have two controllers 'home' and 'work'. How can I display data from 'work' model in the home/index view?
Unfortunately, I don't know the terminology to better formulate the question, but actually I want to achieve that on the home page I can display the last few works.
The part where I enter/edit data works fine. When I go to the /Works/Index page, I see all the entered data. How to display, for example, the last 4 on the home page of the application
In index.cshtml I have
#model IEnumerable<Website.Models.Work>
#foreach (var item in Model)
{
<div class="col-lg-3 col-sm-6">
<div class="gallery-item wow fadeInUp delay-0-2s">
<img src="~/assets/images/gallery/gallery-1.jpg" alt="Gallery">
<div class="gallery-content">
<span class="category">#Html.DisplayFor(modelItem => item.Tag)</span>
<h5>#Html.DisplayFor(modelItem => item.Headline)</h5>
</div>
</div>
</div>
}
But I get an error:
System.NullReferenceException: Object reference not set to an instance of an object.
If you just want to know how to display the data on page, here is a working demo below:
HomeController
public class HomeController: Controller
{
private readonly YourDbContext _context;
public HomeController(YourDbContext context)
{
_context = context;
}
public IActionResult Index()
{
//get the last 4 records...
var model = _context.Work.AsEnumerable().Reverse().Take(4).ToList();
return View(model);
}
}
Home/Index.cshtml
#model IEnumerable<Website.Models.Work>
#foreach (var item in Model)
{
<div class="col-lg-3 col-sm-6">
<div class="gallery-item wow fadeInUp delay-0-2s">
<img src="~/assets/images/gallery/gallery-1.jpg" alt="Gallery">
<div class="gallery-content">
<span class="category">#Html.DisplayFor(modelItem => item.Tag)</span>
<h5>#Html.DisplayFor(modelItem => item.Headline)</h5>
</div>
</div>
</div>
}

ASP.NET MVC4 PartialView Not Being Rendered Inside Parent View

I'm trying to filter a list of entities and update the partial view on the page with the filtered data. The partial view is returning the correct model with the filtered data, but is not being rendered inside the parent page. Instead it is being rendered in "body" element of an empty HTML page. I've found many topics on this but even though I appear to be following their directions, I'm still having no luck. A fresh set of eyes from the community here may be a huge help.
#model PennLighting.ViewModels.LinecardViewModel
#{
ViewBag.Title = "Linecard";
}
<div class="linecard-head">
#using (Ajax.BeginForm("Index",
new AjaxOptions
{
UpdateTargetId = "linecard"
}))
{
#Html.EditorFor(model => model.Categories)
<div class="buttons">
<input type="submit" name="btnFilter" value="Filter" />
<input type="submit" name="btnShowAll" value="Show All" />
</div>
}
</div>
<div id="linecard">
#Html.Partial("Linecard")
</div>
#section Scripts
{
#Scripts.Render("~/bundles/jqueryval")
}
public ActionResult Index()
{
var viewModel = new LinecardViewModel();
viewModel.Categories = db.Categories
.OrderBy(c => c.Name).ToList();
viewModel.Manufacturers = db.Manufacturers
.OrderBy(m => m.Name).ToList();
return View(viewModel);
}
public ActionResult Index(string btnFilter, string[] selectedCategories)
{
var viewModel = new LinecardViewModel();
var selectedMfrs = new List<Manufacturer>();
if (btnFilter != null && selectedCategories != null)
{
var categoryIds = selectedCategories.Select(c => int.Parse(c)).ToArray();
if (categoryIds != null)
{
selectedMfrs = db.Manufacturers
.Where(m => m.Categories.Any(c => categoryIds.Contains(c.ID)))
.OrderBy(m => m.Name).ToList();
}
}
else
selectedMfrs = db.Manufacturers.OrderBy(m => m.Name).ToList();
viewModel.Manufacturers = selectedMfrs;
return PartialView("Linecard", viewModel);
}
<!DOCTYPE html>
<html>
<head>
<title>#ViewBag.Title</title>
#Styles.Render("~/Content/themes/base/css", "~/Content/css")
</head>
<body>
<div id="container" class="round-bottom">
<div id="header">
<div id="header-left">
<div id="logo">
<a href="#Url.Content("~/")">
<img src="#Url.Content("~/Content/Images/logo.png")" alt="Penn Lighting Associates" /></a>
</div>
</div>
<div id="header-right">
<ul class="nav">
<li>#Html.ActionLink("Home", "Index", "Home")</li>
<li>#Html.ActionLink("About", "Index", "About")</li>
<li>#Html.ActionLink("Linecard", "Index", "Linecard")</li>
<li>#Html.ActionLink("Events", "Index", "Events")</li>
<li>#Html.ActionLink("Gallery", "Index", "Gallery")</li>
<li>#Html.ActionLink("Contact", "Index", "Contact")</li>
<li><a href="http://oasis.pennlighting.com:81/OASIS/desk/index.jsp" target="_blank">
Customer Login</a></li>
</ul>
</div>
</div>
<div id="main">
#RenderBody()
</div>
</div>
<div id="footer">
<p>
Copyright © 2008 Penn Lighting Associates</p>
</div>
#Scripts.Render("~/bundles/jquery")
#RenderSection("scripts",false)
</body>
</html>
So what am I missing? Thanks!
You cannot have 2 actions on the same controller with the same name accessible on the same HTTP verb. You might want to decorate your Index contorller action that is invoked with an AJAX call and returns a partial with the [HttpPost] attribute:
[HttpPost]
public ActionResult Index(string btnFilter, string[] selectedCategories)
{
...
}
Without seeing more of your solution, it's a bit fuzzy, but I believe you want to still return the Index and pass the model data into the Partial in your view. The way you are doing it would return only the partial view, which is why you're getting those results.
So in the filtered index:
return View(viewModel)
And in the index view, pass the data to the partial, which I assume without seeing has the right model association to display.
UPDATE
If you're looking to dynamically pull a subset of data and leave the rest untouched, then do an AJAX POST with the filter information to the action specified for the partial view. Take the data results and place them in the Linecard div.
There are many ways to send the data (bundle by JSON, serialize form, individual data points). Here are some examples:
http://brandonatkinson.blogspot.com/2011/01/using-jquery-and-aspnet-mvc-to-submit.html
MVC ajax json post to controller action method
The problem was that my jqueryval bundle was missing the jquery.unobtrusive-ajax.js file. My code works as is once that was included.

Is't possible to get access to <ul> and <li> during submiting form

I have view with controller. I would like to know if it is possible to get access to ul and li? I don't want to do ajax call and pass these elements as parameters. Li elements are added on client side dynamically. this.Request.Form show me only 'name' variable without 'list'. Any advices?
<form action="#Url.Action("Filter")" method="POST">
<ul data-role="listview" data-inset="true" data-filter="false" name="list">
#foreach (var item in #Model.Items)
{
<li value="#item">#item</li>
}
</ul>
<input type="text" name="name"/>
<inpu type="submit" value="Filter"/>
</form>
and controller:
[HttpPost]
public ActionResult Filter(string name, List<string> list)
{
// working with list
return RedirectToAction("Index");
}
thanks
No,
It is not possible to access <ul> and <li> on post back.
BTW, the following code is generates <li> on server not on client
#foreach (var item in #Model.Items)
{
<li value="#item">#item</li>
}
If you wish to access Items (#item) on server, there are other ways to get those that do not require access to <ul> or <li>
For instance, you can emit a hidden (#Html.HiddenFor) element in each <li> in your loop.
You can try the following.
I'm not sure what your view model looks like, but it seems like a list of string values? So then it will look like this in your view model:
public class YourViewModel
{
public List<string> Items { get; set; }
}
In your view try the following:
<ul>
#for (int i = 0; i < Model.Items.Count(); i++)
{
<li>
#Html.DisplayFor(x => x.Items[i])
#Html.HiddenFor(x => x.Items[i])
</li>
}
</ul>
When you post then these items should still be in the list.
It might not be a perfect solution but it can guide you on the right track.
I hope this helps.

created nested list in MVC3

I want to create menu using <ul> and <li> tags. Im working in MVC3 + Razor. And I stored menu in database like this
MenuId Name ParentMenuId OrderBy
1 Item1 Null 1
2 Item2 Null 2
3 Item2.1 2 1
4 Item2.1.1 3 1
5 Item2.1.2 3 2
The HTML output should be
<ul>
<li>Item1</li>`
<li>Item2</li>`
<ul>
<li>Item2.1</li>
<ul>
<li>Item2.1.1</li>
<li>Item2.1.2</li>
</ul>
</ul>
</ul>
Can anyone please help me how can I generated menu from this. I tried searching on internet, but not able to find something which I can use.
I see this article (Recursion in an ASP.NET MVC view) where one reply is to create HTMLHelperExtension.
But not able to find out in my case how to use.
you can try something like this :
#helper CreateCategory(int? nid)
{
var childs = context.Categories.Where(c=>c.parentid == nid).OrderBy(C => C.order);
int childsCount = childs.Count();
if (childsCount == 0)
return;
<ul>
#foreach (Category child in childs)
{
<li>
#child.Title
CreateCategory(child.Id);
</li>
}
</ul>
}
you most call this helper so :
CreateCategory(null);
hope this could help.
You should use DisplayTemplate
Here is an example:
<!-- Your view -->
#if (Model.Items != null)
{
<ul>
foreach (var item in Model.Items)
{
#Html.DisplayFor(m => item)
}
</ul>
}
<!-- Your DisplayTemplate control -->
<li>
#Model.Name
</li>
#if (Model.Items != null) {
<ul>
foreach (var item in Model.Items)
{
#Html.DisplayFor(m => item)
}
</ul>
}
So you will recurcively call DisplayTemplate from DisplayTemplate to render nested Items

Razor Syntax Not working the way I expected

having some trouble with my razor syntax
gives a Parsor error saying that
The foreach block is missing a closing "}" character
<ul>
#{var client = "null";}
#foreach (var instance in Model)
{
if (instance.tbl_Policy.tbl_Client.txt_clientName != client)
{
client = instance.tbl_Policy.tbl_Client.txt_clientName;
</ul><h1>#client</h1>
<ul>
}
<li>
#instance.tbl_Policy.txt_policyNumber -
Assigned to : #instance.aspnet_Membership.aspnet_User.UserName
#instance.ATLCheckType.Question
<button type="button" rel="<%:instance.ATLCheckInstanceId.ToString()%>">DelFiled</button>
<button type="button" rel="<%:instance.ATLCheckInstanceId.ToString()%>">DelLineItem</button>
</li>
}
</ul>
Razor cannot handle imbalanced HTML tags in code blocks.
Change your if block to treat the imbalanced tags as plain text:
if (instance.tbl_Policy.tbl_Client.txt_clientName != client)
{
client = instance.tbl_Policy.tbl_Client.txt_clientName;
#:</ul><h1>#client</h1>
#:<ul>
}
The code should be refactored to correctly support balanced tags
#foreach (var groupedClient in Model.GroupBy(i => i.tbl_Policy.tbl_Client.txt_clientName))
{
<ul>
<h1>#groupedClient.Key</h1>
foreach(var instance in groupedClient)
{
<li>
#instance.tbl_Policy.txt_policyNumber -
Assigned to : #instance.aspnet_Membership.aspnet_User.UserName
#instance.ATLCheckType.Question
<button type="button" rel="#instance.ATLCheckInstanceId.ToString()">DelFiled</button>
<button type="button" rel="#instance.ATLCheckInstanceId.ToString()">DelLineItem</button>
</li>
}
</ul>
}
What's with all of the <%: %> stuff in there? You need to use the # syntax.
<ul>
#{var client = "null";}
#foreach (var instance in Model)
{
if (instance.tbl_Policy.tbl_Client.txt_clientName != client)
{
client = instance.tbl_Policy.tbl_Client.txt_clientName;
</ul><h1>#client</h1>
<ul>
}
<li>
#instance.tbl_Policy.txt_policyNumber -
Assigned to : #instance.aspnet_Membership.aspnet_User.UserName
#instance.ATLCheckType.Question
<button type="button" rel="#instance.ATLCheckInstanceId.ToString()">DelFiled</button>
<button type="button" rel="#instance.ATLCheckInstanceId.ToString()">DelLineItem</button>
</li>
}
</ul>

Resources