getting all values in list without iterating through them - asp.net-mvc-3

In my controller, I'm returning returning View with a list of products.
return View(ProductList)
In my view I want to get all the values of the product list WITHOUT iterating through them either with a for each loop or any other way.
I need to do this as I'm going to design each Product differently in the view and I can't use a for each loop
The first productId is available using Model.Firstordefault().ProductId. Similarly I can get productName, productDescription and so on.
But how can I get the second productId to nth productId in the list?
Thanks
Arnab
.

That's a great candidate for a display template. In your strongly typed view simply:
#model IEnumerable<ProductViewModel>
<table>
<thead>
<tr>
<th>Id</th>
<th>Name</th>
<th>Description</th>
</tr>
</thead>
<tbody>
#Html.DisplayForModel()
</tbody>
</table>
and then define a display template which will automatically be rendered for each element of the collection (~/Views/Shared/DisplayTemplates/ProductViewModel.cshtml):
#model ProductViewModel
<tr>
<td>#Html.DisplayFor(x => x.Id)</td>
<td>#Html.DisplayFor(x => x.Name)</td>
<td>#Html.DisplayFor(x => x.Description)</td>
</tr>
Templated helpers work by conventions and you never have to write any loops in your views.

Related

: EL1008E: Property or field 'LEVEL' cannot be found on object of type 'java.util.ArrayList' - maybe not public or not valid?

please assist with the below. I am trying to display an arraylist returned from the controller and display it to an Html table but I get the above error.
here is my controller code:
#GetMapping(value="/chart" )
public List<List<CanvasjsChartData.DataPointModel>> chart(Model modelMap) {
List<List<CanvasjsChartData.DataPointModel>> dataPointsList = canvasjsChartService.getCanvasjsChartData();
modelMap.addAttribute("dataPointsList", dataPointsList);
System.out.println("dataPointsList");
return dataPointsList;
}
and this is the table I want to display my list in
<table class="table" id="dataTable" style="width:100%">
<thead>
<th>Level</th>
<th>Occurences</th>
</thead>
<tbody>
<tr th:each="item :${dataPointsList}">
<td th:text="${item.LEVEL}"> </td>
<td th:text="${item.OCCURENCES}"> </td>
</tr>
</tr>
</tbody>
I know for sure the ArrayList has the data I require as shown below I dont know why its giving me the error
Your debug shows you have an List<List<CanvasjsChartData.DataPointModel>> (two Lists inside of each other) -- when your HTML is expecting List<CanvasjsChartData.DataPointModel>. You should fix that in your controller/model by only returning a single list.
You could also display your HTML like this (where you loop over the 0th element of the outer array):
<tr th:each="item :${dataPointsList[0]}">
<td th:text="${item.LEVEL}" />
<td th:text="${item.OCCURENCES}" />
</tr>

How to get rows from table with specific header using Xpath

I need to get all rows in an HTML table:
<table>
<thead>
<tr>
<th>Name</th>
<th>Location</th>
</tr>
</thead>
<tbody>
<tr>
<td>Dunkin Donuts</td><td>2 York Ave</td>
</tr>
</tbody>
</table>
Since there are many tables in the page I want to get the rows from this specific table.
Here is my Xpath:
table[tr/th/text()="Location"]//tr
I also tried:
table[tr/th[2]/text()="Location"]//tr
No elements are returned. Ideas on how I might get this to work?
Maybe your context node has no table children. You can fix this by globally selecting all table elements with //table. You also did not take the thead and tbody elements into account. Doing so results in the following XPath expression:
//table[thead/tr/th/text()="Location"]/tbody/tr

Scraping page with correct xpath using Mechanize and nokogiri

I am trying to access data contained in a table that is itself contained in a table with class ='L1'.
So basically my html structure is like this:
<table class="L1">
<table>
<tr></tr>
<tr>
<td></td>
<td>data</td>
</tr>
<tr>
<td></td>
<td>data</td>
</tr>
...ect...ect
</table>
</table>
I need to catch the data contained in a all <a> </a> that are in the second contained in <tr> </tr> but only starting with the second <tr> of the table.
So far I came up with that:
html_body = Nokogiri::HTML(body)
links = html_body.css('.L1').xpath("//table/tbody/tr/td[2]/a[1]")
But seems to me that this doesn't express the fact that I want to start only after the second <tr> (second <tr> included?
What would be the right code to do this ?
You can use position() to select the later elements that you want.
html_body = Nokogiri::HTML(body)
links = html_body.css('.L1').xpath("//table/tbody/tr[position()>1]/td[2]/a[1]")
As the comments on that SO answer say, remember XPath counts from 1, so >1 skips the first tr.

AngularJS: How to use ng-repeat on a data collection that is hierarchical

I am receiving a collection from server that is hierarchical. ie., I've a list of Study that contains Series. For example I get below object from server.
var studies = [ {studyDescription: 'Study1', series:[
{seriesDescription:'Series1'},
{seriesDescription:'Series2'}
]
}];
'series' is nested within a study.
I am using a HTML table to display this data. And I wanted to flatten the hierarchy while displaying. ie the table should look like:
Study Series
--------------------
Study1 Series1
Study1 Series2 ---> Study1 repeats for each series it contains
I use ng-repeat to iterate the the rows:
<tr ng-repeat="study in studies">
<td>{{studyDescription}}</td>
// HOW to repeat for each series ????
</tr>
How to display such hierarchical data using AngularJS ng-repeat directive? I tried using before , but that did not work. Basically I need multiple for loops to repeat the rows that many time. How to achieve this.
Thanks.
You can use multiple tbody to iterate on the series :
HTML :
<table border=1>
<thead>
<th>Studies</th>
<th>Series</th>
</thead>
<tbody ng-repeat="study in studies">
<tr ng-repeat="series in study.series">
<td>{{study.studyDescription}}</td>
<td>{{series.seriesDescription}}</td>
</tr>
</tbody>
</table>
Here's the JSFiddle :
http://jsfiddle.net/L3MWJ/1/
Tell me if it works for you, still I'm not sure if it will work on all browsers.
Did you try nested ng-repeat ? Try this :
<tr ng-repeat="study in studies">
<td>{{study.studyDescription}}</td>
<td>
<span ng-repeat="serie in study.series"></span>
<p> {{serie.seriesDescription}}</p>
</td>
</tr>

ASP.NET MVC 3: Using Enumerable extension methods in the view

Given the following Razor Partial View and understanding that Product is an NHibernate mapped object so the calls to IEnumerable here will fire database queries (when not cached).
Is this bad practice? Should I be providing a flatter view of my data for this view so that I can make these calls in my controller/business logic?
#model IEnumerable<MyProject.Data.Models.Product>
<table>
<tr>
<th></th>
<th>Total Orders</th>
<th>Fulfilled</th>
<th>Returned</th>
<th>In stock</th>
</tr>
#foreach (var product in Model) {
<tr>
<td>
#Html.ActionLink(product .Name, "Detail", "Product", new { id = product.Id }, null)
</td>
<td>
#product.Orders.Count
</td>
<td>
#product.Orders.Where(x=>x.Fulfilled).Count()
</td>
<td>
#product.Orders.Where(x=>x.Returned).Count()
</td>
<td>
#(product.Stock.Count - product.Orders.Count)
</td>
</tr>
}
</table>
Is this bad practice?
Yes.. In fact it's breaking the MVC pattern - the View's should not call back through the model, only receive in order to do it's sole job: rendering HTML.
If you need additional information than just the one entity, populate a ViewModel with all the information you need, then pass that to your View.
Also, don't loop through the IEnumerable in the model, use a Display Template:
#Html.DisplayForModel()
The advantage of this is no explicit loop, taking advantage of MVC conventions, and adhering to model hierachy when model binding.

Resources