How to make dynamically Tree in asp.net mvc - asp.net-mvc

I have a table called "Tabel_Items" in database with these fields: id, parent, and child:
I want to generate html tags such as these:
<ul>
<li>parent1
<ul>
<li>child1</li>
<li>child2
<ul>
<li>child21</li>
<li>child22</li>
</ul>
</li>
</ul>
</li>
<li>parent2
<ul>
<li>child3</li>
</ul>
</li>
</ul>
I get my items with a LINQ query and pass them to view:
public ActionResult Index()
{
DataClasses1DataContext db = new DataClasses1DataContext();
var items = from i in db.Table_Items
select i;
return View(items);
}
How can I loop through the "items" in view and make a Tree list out of them?
I want a lambda expression to select those rows that have "parentId==null" at first. I test a code like this, but has an error:
#foreach (var i in Model)
{
#Html.DisplayFor(x => i.ItemName.Where(i.ParentId==null));
}

I solved my problem.Thank for me:
<ul>
#foreach (var x in Model.Where(f => f.ParentId == null))
{
<li>
#Html.DisplayFor(f => x.ItemName)
<ul>
#foreach (var y in Model.Where(c => c.ParentId == x.Id))
{
<li>
#Html.DisplayFor(c => y.ItemName)
<ul>
#foreach (var z in Model.Where(c => c.ParentId == y.Id))
{
<li>#Html.DisplayFor(c => z.ItemName)</li>
}
</ul>
</li>
}
</ul>
</li>
}
</ul>

Related

Encountered end tag "li" with no matching start tag error when putting li inside if statement

i am using asp.net MVC 5 and Visual studio 2013
and working on Razor view
the view is working fine without if statement around the < li > start
if i enclosed any < li > start, with an if condition statement i get this error
Parser Error Message: Encountered end tag "li" with no matching start tag. Are your start/end tags properly balanced?
#using TheodorHR_App.Models
<div id="tree_CadreGroupLevel" class="tree-demo">
<ul>
#{
TheodorHrEntities db = new TheodorHrEntities();
var nodes = db.Cadres.ToList();
foreach (var node in nodes)
{
Cadre root = new Cadre();
root.Id = node.Id;
if (#Model.RuleElementCadres.Select(e => e).Where(e => e.Cadre == node.Id).Count() > 0)
{
<text>
<li id="Cnode_#node.Id" data-jstree='{ "selected" : true }'>
</text>
}
else
{
<text>
<li id="Cnode_#node.Id">
</text>
}
#node.Name
<ul>
#{
var nodes1 = db.JobGroups.Where(jg => jg.CadreId == #node.Id).ToList();
foreach (var node1 in nodes1)
{
Cadre root1 = new Cadre();
root1.Id = node1.Id;
<li id="Gnode_#node1.Id">
#node1.Name
<ul>
#{
var nodes2 = db.JobGroupJobLevels.Where(jl => jl.JobGroup == #node1.Id).ToList();
foreach (var node2 in nodes2)
{
Cadre root2 = new Cadre();
root2.Id = node2.Id;
<li id="Lnode_#node2.Id">
#node2.JobLevel1.Name
<ul></ul>
</li>
}
}
</ul>
</li>
}
}
</ul>
</li>
}
}
</ul>
</div>
Update after first answer
doesn't work
Razor understand it as c# and tried to enclose it with double quotes doesn't work because the literal contains already doubles quotes then tried to replace " with \" this doesnt work because it doesn't give a meaning to the js Tree i am building
i found the solution elsewhere
i think there is an issue on adding server side code inside html tags like this
< li /* adding server code here leads in many inconvenient issues */ >
i found the solution by adding #:< / li > at the end of the li instead of just < / li >
Oh I Forgot to put the quotes around the attribute.
I think using a conditional operator might solve the issue.
#using TheodorHR_App.Models
<div id="tree_CadreGroupLevel" class="tree-demo">
<ul>
#{
TheodorHrEntities db = new TheodorHrEntities();
var nodes = db.Cadres.ToList();
foreach (var node in nodes)
{
Cadre root = new Cadre();
root.Id = node.Id;
<li id="Cnode_#node.Id" #(Model.RuleElementCadres.Select(e => e).Where(e => e.Cadre == node.Id).Count() > 0 ? "data-jstree='{ 'selected' : true }'" : "") >
#node.Name
<ul>
#{
var nodes1 = db.JobGroups.Where(jg => jg.CadreId == #node.Id).ToList();
foreach (var node1 in nodes1)
{
Cadre root1 = new Cadre();
root1.Id = node1.Id;
<li id="Gnode_#node1.Id">
#node1.Name
<ul>
#{
var nodes2 = db.JobGroupJobLevels.Where(jl => jl.JobGroup == #node1.Id).ToList();
foreach (var node2 in nodes2)
{
Cadre root2 = new Cadre();
root2.Id = node2.Id;
<li id="Lnode_#node2.Id">
#node2.JobLevel1.Name
<ul></ul>
</li>
}
}
</ul>
</li>
}
}
</ul>
</li>
}
}
</ul>

Reading collection of user input from the view?

I have created a page to display list of questions to user & read user input for each question.
Issue: When user submits the Form, Model Parameter is null.
Post Action of the View is defined as below -
[HttpPost]
public ActionResult Index(IEnumerable<Question> model)
{
return View(model);
}
Code to display options to user is as below -
#foreach (var quest in Model)
{
<li>
#Html.LabelFor(x => quest.Title, quest.Title)
<ol class="Opt">
#foreach (var opt in quest.Options)
{
<li>#Html.RadioButtonFor(o => opt, opt.Title)
#Html.LabelFor(o => opt.Title, opt.Title)
</li>
}
</ol>
</li>
}
Here model is #model List<LakshyaMvc.Models.Question> and of course I have wrapped the code inside #using (Html.BeginForm())
Change your View Model.
#using (Html.BeginForm("Index", "Queries", FormMethod.Post))
{
for (int i = 0; i < Model.Count; i++)
{
<li>
#Html.LabelFor(x => Model[i].Question, Model[i].Question)
<ol class="Opt">
#for (int j = 0; j < Model[i].Options.Count; j++)
{
<li>#Html.RadioButtonFor(o => Model[i].Options[j].Option, false)
#Html.LabelFor(o => Model[i].Options[j].Option,
Model[i].Options[j].Option)
</li>
}
</ol>
</li>
<input type="submit" name="Submit" value="Submit" />
}
}

MVC 3/4 Razor Help needed

I need to create Menu for the master page. I've faced with following problem
<ul class="main_menu">
#foreach (var node in Model.Nodes)
{
int i = 1;
<li class="**HOW TO ADD HERE A CLASS like level+i.ToString()?????**">#Html.DisplayFor(m => node) |
#if (node.Children.Any()) {
<ul class="menuchild" style="display: none;">
<li>
#Html.DisplayFor(m => node.Children)
</li>
</ul>
}
</li>
}
</ul>
I need to create levels for the menu for Javascript , say level1 , level2 , level3 , how to combine strings inside Razor.
Thanks.
Enclose with #()
<li class="#("level" + i.ToString() )">
or
<li class="#string.Format("level{0}", i)">

MVC - Displaying Content

How to Display the following
public ActionResult Index()
{
IEnumerable<int> items = Enumerable.Range(1000, 5);
ViewData["Collection"] = items;
return View();
}
in "View"
<ul>
<% foreach(int i in (IEnumerable)ViewData["Collection"]){ %>
<li>
<% =i.ToString(); }%>
</li>
</ul>
the foreach throws System.Web.HttpCompileException.
You had the closing brace of the foreach's loop in the wrong place. This is what you need:
<ul>
<% foreach (int i in (IEnumerable)ViewData["Collection"]) { %>
<li>
<%= i.ToString() %>
</li>
<% } %>
</ul>
And you also had some other extra punctuation in there as well (such as an extra semicolon).

How to add an attribute to an HTML tag depending on the URL in a MVC app

I render a list of items like:
<ul>
<li>Something 1</li>
<li>Something 2</li>
<li>Something 3</li>
<li>Something 4</li>
<li>Something 5</li>
</ul>
Depending on the route I want to add a class to one of the <li> tags so that I can highlight.
Maybe something like:
<ul>
<% if (this.Context.Request.RawUrl.Contains(something1Var)) { %>
<li class="highlight">
<% } else { <%>
<li>
<% } %>
Something 1</li>
<% if (this.Context.Request.RawUrl.Contains(something2Var)) { %>
<li class="highlight">
<% } else { <%>
<li>
<% } %>
Something 2</li>
<% if (this.Context.Request.RawUrl.Contains(something3Var)) { %>
<li class="highlight">
<% } else { <%>
<li>
<% } %>
Something 3</li>
<% if (this.Context.Request.RawUrl.Contains(something3Var)) { %>
<li class="highlight">
<% } else { <%>
<li>
<% } %>
Something 4</li>
<% if (this.Context.Request.RawUrl.Contains(something5Var)) { %>
<li class="highlight">
<% } else { <%>
<li>
<% } %>
Something 5</li>
</ul>
It does work but it seems a bit verbose. Can anyone suggest a better method of doing this sort of thing?
I'd argue that this kind of logic is better isolated in the controller. Consider making a lightweight class to represent your menu items, like this:
public class MenuLinkItem {
public string Text { get; set; }
public bool Highlight { get; set; }
}
Then in your controller method, build a list of these, set the CSS class on the highlighted element, and pass the result to the view via the ViewData:
public class MyController : Controller {
private MenuLinkItem MakeMenuLinkItem(string text, string urlFragment) {
return (new MenuLinkItem() {
Text = text,
Highlight = (this.Context.Request.RawUrl.Contains(urlFragment))
}
}
private IList<MenuLinkItem> GetMenuLinkItems() {
var items = new List<MenuLinkItem>();
items.Add(MakeMenuLinkItem("Something 1", something1var));
items.Add(MakeMenuLinkItem("Something 2", something2var));
items.Add(MakeMenuLinkItem("Something 3", something3var));
items.Add(MakeMenuLinkItem("Something 4", something4var));
items.Add(MakeMenuLinkItem("Something 5", something5var));
return(items);
}
public ActionResult Index() {
ViewData["menuLinkItems"] = GetMenuLinkItems();
/* other controller logic here */
return(View());
}
}
Then, in your actual view code, you render your menu like this:
<ul>
<% foreach(var item in (IList<LinkMenuItem>)ViewData["menuLinkItems"])) { %>
<li <%= item.Highlight ? "class=\"highlight\"" : ""%>><%=item.Text%></li>
<% } %>
</ul>
The controller's making the decisions about which links are highlighted, and the view is converting those decisions into an HTML/CSS representation that makes sense to your users.

Resources