created nested list in MVC3 - asp.net-mvc-3

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

Related

Asp.net core RazorComponent working with dynamic <li></li>

I am creating a RazorComponent in my asp.net core mvc application.
The component has a html list in it which is dynamically generated according to the number of item fetched from the model.
<ul>
#{
foreach (var prod in newProductList)
{
if (prod.Brand.Equals("1") && prod.Class.Equals("2"))
{
<li #onclick="(() => AddToSaleList(prod.Product, prod.ProductId, prod.SellRate))">
<div class="posSelected-item">
<span class="posFoodname inline-block"> #prod.Product </span>
<span class="inline-block posSeletedPrice">#prod.SellRate</span>
<span class="posFoodtotal-item inline-block">
<i class="inline-block fas fa-minus" #onclick="() => Quantity(2)"></i>
<span class="posincrementItem">#changeQuaitity</span>
<i class="inline-block fas fa-plus" #onclick="() => Quantity(1)"></i>
</span>
</div>
</li>
}
}
}
</ul>
The UI looks like this (as expected)
The Problem
The Plus and Minus buttons on the UI are supposed to increment or decrement the quantity of each item on the list.
The function I have written is
int changeQuaitity = 0;
public void Quantity(int e)
{
if (e == 1)
{
changeQuaitity++;
}
else if (e == 2)
{
changeQuaitity--;
}
}
However, as you can see since the increment is bound with the parameter changeQuantity so clicking on any of the Plus or Minus button changes the quantity of each list item simultaneously.
How do I modify the code to identify one list item and change quantity of only that item when the button on the list is clicked.
You need a separate counter for each entry, so I recommend making what I call a "carrier class" to carry quantity info along with each item:
class countableProducts {
Product prod {get; set;}
int quantity;
}
In your initialization:
foreach (var item in newProductList)
countableProductsList.Add( new countableProduct() { prod = item });
Then in your loop
foreach (var item in countableProductsList){
// everything looks like item.prod.(property)
<i class="inline-block fas fa-minus" #onclick="() => item.quantity--;"></i>
<span class="posincrementItem">#item.quantity</span>
<i class="inline-block fas fa-plus" #onclick="() => item.quantity++;"></i>
}
I don't have enough of your code to make a working example without basically writing the whole program, but hopefully you can see my idea.

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.

How to use inline template with multiple inputs in MVC Razor view

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>
}

Problem to pass data model to view

I have this in view "Index":
<ul>
#foreach (var r in Model.Where(c => c.id_parent == null)) {
<li>
#Html.DisplayFor(i => r.node.name)
#if (r.node.children.Count > 0) {
<ul>
#{Html.RenderPartial("aView", r.node);}
</ul>
}
</li>
}
</ul>
But getting this error on the RenderPartial line:
The model item passed into the dictionary is of type 'System.Data.Entity.DynamicProxies.arrangement_86479E2FE1ED6F9584881D169E310F3C37120A10A806A6CF640967CBCB017966',
but this dictionary requires a model item of type
'System.Collections.Generic.IEnumerable`1[PlanovaniZdroju.Models.arrangement]'.
How can I retype the r.node to IEnumerable? OR how else can I solve it?
Are you sure you didn't mean:
<ul>
#{Html.RenderPartial("aView", r.node.children);}
</ul>

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