Hierarchical Data In ASP.NET MVC - asp.net

I am trying to come up with the best way to render some hierarchical data in to a nested unordered list using ASP.NET MVC. Does anyone have any tips on how to do this?

I suggest jquery tree view plugins for making it function like a tree, but as for render, just put it in a recursive lambda helper to do the nesting.

You mean... you want some sort of tree view?
You can actually get the treeview control to work... but you have to wrap it in server side form tag to function. You'll get the usual nastiness that that brings (like generated ids and viewstate) but it will work from a rendering perspective.
If you want to just create tags and nest them, it would be pretty easy to do with foreach() loops.

I believe currently there is no such control.... TreeViews are complex by nature. You can of course "draw" a hierarchy as much as you like using all sorts of repeaters and loops, but to achieve functionality of a tree view like the one in the Web forms toolbox... you have to wait !

Why don't you pass your model in the form of a tree to the view?
/// This is the model class
public class MyTreeNode<T>
{
public ICollection<MyTreeNode> ChildNodes {get;}
public T MyValue { get; set; }
bool HasChildren { get { return ChildNodes.Any(); } }
}
///This is the html helper:
public static string RenderTree<T>(this HtmlHelper html, MyTreeNode<T> root, Func<T, string> renderNode)
{
var sb = new StringBuilder();
sb.Append(renderNode(root.MyValue));
if (root.HasChildren)
{
foreach(var child in root.ChildNodes)
{
sb.Append(RenderTree<T>(html, child, renderNode));
}
}
return sb.ToString();
}
I didn't actually test this code, but it's about the idea. You can imagine creating your own recursive html helper to render a tree.

For that (rendering hierarchical menu, treeview, etc) i use recursive calls of custom component (ascx, or aspx in new preview5).
I give component first level of items (List of items), and component then check for each item in list if there's any child items and call itself with list of that child items.
You can build hierarchical graph of objects in controller, or just 1 dimensional list with ParentID property.

Related

Is there a way to filter out hidden elements with css?

as an example some html has several elements which have the css path table.class1.class2[role="menu"] but only one of these elements will be visible at any given time, so I want to get only the one that is visible.
can I adjust my css path to narrow it down?
Possibly use Linq to get the list. I am not sure which language you are using. But, similar concept can be applied using any of them. Using Linq
to accomplish this kind of scenario is very simple in C#
public IWebElement Test()
{
//selector
By bycss = By.CssSelector("table.class1.class2[role='menu']");
return Driver.FindElements(bycss).ToList().FirstOrDefault(d => d.Displayed);
}
And, make sure to import
using System.Linq; if you are using C#
In Java you can do something like this[not using lambdas]
List<WebElement> visibleList = null;
//selector
By byCss = By.cssSelector("table.class1.class2[role='menu']");
//list of visible and hidden elements
Iterator<WebElement> iterator = driver.findElements(byCss).iterator();
while (iterator.hasNext()){
WebElement element = iterator.next();
if (element.isDisplayed()){
//building the list of visible elements
visibleList.add(element);
}
}
//get the first item of the list
//you can return all if needed
return visibleList.get(0);
In Java, you can use WebElement.isDisplayed().

Is it possible to pass a radiobuttonList to a method in a custom class as a parameter in asp.net

I have a few different pages with a radiobutton list that I populate using a collection of answers in the page load event of each page. I was wondering rather than repeating the same code on 4 different pages, is it possible to pass in the radio button list as a parameter to my own class that I made and populate it in there? I can't seem to see A ListItem parameter to pass in.
My code is
foreach (var item in collection)
{
RadioButtonList.Items.Add(item);
}
Instead of having to repeat that, I'm trying to pass the list and the collection to my Person Class, and create a method in there that does the same.Any help is appreciated!
Unless I'm missing something obvious, can you not have something like a static function that has the RadioButtonList and collection as parameters?
public static void PopulateMyRadios(RadioButtonList rdoButtons, MyCollection collection)
{
foreach (var item in collection)
{
rdoButtons.Items.Add(item);
}
}
Yes.. We can create a method of parameter string array which are hold the text of radio button required. Then create html radio button list by using string array and input this radio button list to any of div of corresponding page as inner HTML.

Partial Views with view models different to the main view

My home-screen has a view model of DashboardViewModel. It has PartialViews with their own ViewModels such as CustomerSearchViewModel and SelectProductViewModel.
All three ViewModels are separate.
When I run the application I get this error:
The model item passed into the dictionary is of type
'Invoice.Web.ViewModels.DashboardViewModel', but this dictionary
requires a model item of type
'Invoice.Web.ViewModels.SearchCustomerWindowVM'.
I wonder what should I do to resolve this issue.
As planned, the Home screen will eventually integrate a lot of PartialViews with their own view models. Do I declare the Partial-view-models inside the DashboardViewModel? or do I simply have a single big DashboardViewModel for all partialViews to come?
You can have your partial view viewmodels as properties of your main viewmodel and call Html.Partial and pass these properties.
public class DashBoardVM
{
public string Name { set;get;}
public CustomerSearchVM CustomerSearch { set; get;}
public DashBoardVM()
{
CustomerSearch =new CustomerSerachVM();
}
}
In your dashboard view,
#model DashBoardVM
<h2>#Model.Name</h2>
#Html.Partial("CustomerSearch",Model.CustomerSearch)
Assuming CustomerSearch partial view is strongly typed o CustomerSearchVM class.
Another option is to use Html.Action() or Html.RenderAction(). This allows you to call a completely separate controller from your parent view, and return a completely different, non associated model. Here is a pretty good explanation on both rendering Partial Views and Actions. http://www.midnight-coding.com/2013/01/partial-vs-action-vs-renderpartial-vs-renderaction.html

How can I run code from my layout file?

I used the following tutorial to help me build an RSS Reader in my ASP.NET MVC3 Razor application:
http://weblogs.asp.net/jalpeshpvadgama/archive/2011/08/17/creating-basic-rss-reader-in-asp-net-mvc-3.aspx
However, unlike the tutorial example, I want the RSS feed to be displayed on every page, and have therefore added it to my layout file, /Views/Shared/_Layout.cshtml
I currently only have 2 views on my site, and to get the RSS Reader to work on both views I've got the following code in my HomeController:
public class HomeController : Controller
{
//
// GET: /Index/
public ActionResult Index()
{
return View(CT.Models.RssReader.GetRssFeed());
}
public ActionResult About()
{
return View(CT.Models.RssReader.GetRssFeed());
}
}
From my WebForms experience, I would simply add the RSS Reader code in my master page code behind, and it would automatically work on every page.
Is there a Controller for layout pages which allows me to do the same?
How can I get this to work on every call of the layout page, without having to return anything?
EDIT: Following #Sebastian's advice, I've now added this code to a Partial View, removed CT.Models.RssReader.GetRssFeed() from return View() and included this in my layout file:
#Html.Partial("_MyPartialView")
The code in this partial view is:
<ul>
#foreach (var item in Model)
{
<li>
#item.Title
</li>
}
</ul>
However, I'm not getting a runtime error:
Object reference not set to an instance of an object.
It's erroring on the line #foreach (var item in Model)
You have to create a partial view and add functionality there.
Then in your layout, render this partial.
EDIT
Is your partial view really a partial view? The reason I said that is because you have "_" in front of the name which suggests that it might be a layout (might just be a naming convention).
To fix object reference error, you have to add the #Model declaration on top of your partial view.
Hope it helps.
UPDATE
In order to use different model in partial view, you need to explicitly declare which model you are going to use on render partialmethod.
#{Html.RenderPartial("../YourFeed", Model.YourFeedModel);}
Let me know if that resolved your issue.
The new error you are having is due to you not passing a Model to the partial view. You can do this with the second argument of the Html.Partial function...
Html.Partial("ViewName", MyModel);
As I think you are trying to do this in a Layout page you could also consider using a static reference to get your RSS feed. So forget about needing to pass in a Model and in your partial have:
#foreach (var item in RssRepository.GetFeed())
{
<li>
#item.Title
</li>
}
this like to a class something like...
public static RssRepository
{
public static MyModel GetFeed()
{
return new MyModel();//<- return what you would normally pass as a Model for RSS feeds
}
}
Hope that all makes sense

How to create custom filter toolbar html helper in mvc3

I'm strugling on this for quite a while now. I need to create a custom mvc3 html helper for easy filter and toolbar management.
All that helper should look something like this below or something similar. What i want to do is to have a helper where i could give toolbar buttons and filter fields and it generate a toolbar and filter form for me.
I just can't figure it out, because i'm quite new in asp.net mvc
#Html.Toolbar(x => {
x.AddFilterButton();
x.AddButton("Naujas");
x.AddDropDownList();
},
#<text>
#Html.EditorFor(Model.ListFilter.Name)
Filter
ResetFilter
</text>,
filterVisible: false)
How i could achieve this? Any help would be highly apreciated. Thanks indeed.
Something like this:
public static class ToolbarExtensions {
public static Toolbar Toolbar<T>(this HtmlHelper<T> html) {
return new Toolbar();
}
}
public class Toolbar : IHtmlString {
public string ToHtmlString() { /* build your HTML off the state here */ }
public Toolbar AddButton(string label) {
/* build up state here */
return this;
}
}
The syntax on this would be a little different, instead of a lambda, would look like this:
#Html.Toolbar().AddButton("Button 1").AddButton("Button 2")
But you could easily change it to use a chaining object in the lambda instead of on the Toolbar method call.
The IHtmlString interface tells the ViewEngine to output the object as raw HTML when its encountered. The chaining is just achieved by returning the current instance in your methods after modifying the object state.

Resources