Using Count method on a for loop in Razor View - asp.net-mvc

The issue I am having is that I am trying to generate a series of text boxes using a for loop to prevent verbose code.
for (int i = 0; i < Model.frames(); i++)
{
<div class="form-group">
<div class="control-label col-sm-1 text-left ">
frame Number
</div>
<div>
<div class="col-sm-1">
#Model.frames
</div>
</div>
</div>
}
The "count" is not recognized for Integer. Any help is appreciated.

Related

how to add the placeholder value to ngmodel

I am following an example in primeng in which I can add a new row to a table. Everything "seems" to work as long as I fill out all the fields in the input option. However, I want to add the place holder value to the NGmodel if the user does not change the value of the input. I tried everything (ng-init, ngvalue, etc etc) but I can never get the ngmodel to carry the value in the place holder... and the table gets fill with the 3 filled fields but not the one where the user did not type anything.
extract of the HTML....
<div class="ui-g-12">
<div class="ui-g-4">
<label for="product_line_id">Product ID</label>
</div>
<div class="ui-g-8">
<input pInputText id="product_line_id" [ngModel]="myproduct.product_line_id" placeholder="{{ lastproductline + 1}}" />
</div>
</div>
<div class="ui-g-12">
<div class="ui-g-4">
<label for="product_line_1">Product</label>
</div>
<div class="ui-g-8">
<input pInputText id="product_line_1" [(ngModel)]="myproduct.product_line_1" autofocus />
</div>
</div>
<div class="ui-g-12">
<div class="ui-g-4">
<label for="product_line_2">Category</label>
</div>
<div class="ui-g-8">
<input pInputText id="product_line_2" [(ngModel)]="myproduct.product_line_2" />
</div>
</div>
<div class="ui-g-12">
<div class="ui-g-4">
<label for="product_line_3">Sub Category</label>
</div>
<div class="ui-g-8">
<input pInputText id="product_line_3" [(ngModel)]="myproduct.product_line_3" />
</div>
</div>
the ts file looks something like...
productlines = [];
myproduct: { [s: string]: ProductLines; } = {};
showDialogToAdd() {
this.newProductLine = true;
this.myproduct = {};
this.displayDialog = true;
}
save() {
let productlines = [...this.productlines];
productlines.push(this.myproduct);
this.finalproductchanges.push(this.myproduct)
this.productlinesClone = productlines;
this.myproduct = null;
this.displayDialog = false;
}
Any ideas will be greatly appreciated
I managed to change the code by adding the field directly in the controller.

display block not working Razor in asp.net mvc

I have 2 for loops in Razor syntax , I want to implement each one in a block , I added style block to second for loop but it appears inline with the first line of contents to the first loop
<div style="display:block;">
#foreach (var Item in Model)
{
<div class="col-sm-3">
<div class="content">
<p>#Item.Name</p>
</div>
</div>
}
<br>
</div>
// the page buttons appear next to #Item.Name (at the first line of the loop items) not after it
<div style="display:block;">
#for (int i = 1; i <= ViewBag.TotalPages; i++)
{
<button class="btn btn-info" type="button" id="addressSearch" onclick="location.href='#Url.Action("myaction","mycontroller", new { page = i } )'">#i</button>
}
</div>
this should work if it is not !important in external stylesheet

How to add div tag after fixed number of iteration in mvc

I am using Umbraco (mvc) with bootstrap.My template use partial view to load name and job title of staff in template. How I can add div (new row) after 4 iteration.
#inherits Umbraco.Web.Mvc.UmbracoTemplatePage
#{
var selection = Model.Content.Site().FirstChild("aboutUs").Children("staff")
.Where(x => x.IsVisible());
}
#foreach(var item in selection){
<div class="row team">
<div class="col-sm-3">
<div class="thumbnail-style">
<h3><a>#item.GetPropertyValue("fullName")</a> <small>#item.GetPropertyValue("jobTitle")</small></h3>
</div>
</div>
</div>
}
Difficulty:
I want to add
<div class="row team">
</div>
after every 4th
<div class="col-sm-3">
</div>
A more easier solution would be the use of the Umbraco helper method InGroupsOf(columns).
#foreach(var group in selection.InGroupsOf(4))
{
<div class="row team">
#foreach(var item in group)
{
<div class="col-sm-3">
<div class="thumbnail-style">
<h3><a>#item.GetPropertyValue("fullName")</a> <small>#item.GetPropertyValue("jobTitle")</small></h3>
</div>
</div>
}
</div>
}
Try:
#foreach(var obj in selection.Select((item, index) => new {item, index}))
{
if(obj.index==0||obj.index%4==0){
#Html.Raw("<div class='row team'>")
}
<div class="col-sm-3">
<div class="thumbnail-style">
<h3><a>#obj.item.GetPropertyValue("fullName")</a> <small>
#obj.item.GetPropertyValue("jobTitle")</small></h3>
</div>
</div>
#if((obj.index+1)%4==0||obj.index+1==selection.Count()){
#Html.Raw("</div>")
}
}
- It will works, Use for loop instead of foreach loop and then just add logic
#for (int i = 1; i < selection.Count; i++)
{
var item = selection[i];
<div class="row team">
<div class="col-sm-3">
<div class="thumbnail-style">
#if (i % 5 == 0)
{
<div class="col-sm-3">
<h4 >D #item</h4> <!--your actual html code-->
</div>
}
else
{
<h4 style="color:red">D #item</h4> <!--your actual html code-->
}
</div>
</div>
</div>
}

Grouping/GROUP BY With LINQ in MVC

I am new in MVC. In this page; I list the projects belonging to the "unit name" by loop. And what I want to do: I want to group projects belonging to the same "unit name". Each project has a "unit name" to which it belongs. There can be more than one project belonging to one unit. So I want to group it.
My cshtml code is as follows:
#if (Model.Projects.Any())
{
foreach (var item in Model.Projects.ToList())
{
<div class="ProjectPartialBody" data-id="#item.ID">
<div class="portlet box blue">
<div class="portlet-title">
<div class="caption">
<span><i class="glyphicon glyphicon-asterisk"></i> #item.tbl_Unit.Name</span>
</div>
<div class="tools">
</div>
<div class="actions">
Details
</div>
</div>
<div class="portlet-body">
<span><i class="fa fa-file"></i> #item.Name</span>
<span><i class="fa fa-calendar"> Contract Start and End Dates: #(item.ContractStartDate != null ? item.ContractStartDate.Value.ToString("dd.MM.yyyy") : "-") / #(item.ContractEndDate != null ? item.ContractEndDate.Value.ToString("dd.MM.yyyy") : "-")</i></span>
<div class="well">
<div class="form-group">
<label>Cash Completion Rate: %#item.CashCompletionRate</label>
<div class="progress progress-striped active">
<div class="progress-bar progress-bar-info" role="progressbar" style="width: #(item.CashCompletionRate)%;"></div>
</div>
</div>
</div>
<div class="well">
<div class="form-group">
<label>Physical Completion Rate: %#item.PhysicalCompletionRate</label>
<div class="progress progress-striped active">
<div class="progress-bar progress-bar-info" role="progressbar" style="width: #(item.PhysicalCompletionRate)%;"></div>
</div>
</div>
</div>
</div>
</div>
</div>
}
}
And the view of the page is as follows (my view is in Turkish language but you'll understand what I am talking about):
My Page View
Can you please help me? And if there is any other code block you want to insert, please tell me.
You first need to group by in your for statement:
foreach(var unitGroup in Model.Projects.GroupBy(g => g.tbl_Unit.Name))
{
//...your MVC markup here
}
Now you actualy need to change the markup as you would need to put in another foreach loop that would generate markup for projects.
So something simillar to this.
<div class="ProjectPartialBody" data-id="#item.ID">
<div class="portlet box blue">
<div class="portlet-title">
<div class="caption">
<span><i class="glyphicon glyphicon-asterisk"></i> #item.tbl_Unit.Name</span>
</div>
<div class="tools">
</div>
<div class="actions">
Details
</div>
</div>
#foreach(var project in unitGroup.ToList())
{
<div class="portlet-body">
<span><i class="fa fa-file"></i> #project.Name</span>
<span><i class="fa fa-calendar"> Contract Start and End Dates: #(project.ContractStartDate != null ? project.ContractStartDate.Value.ToString("dd.MM.yyyy") : "-") / #(project.ContractEndDate != null ? project.ContractEndDate.Value.ToString("dd.MM.yyyy") : "-")</i></span>
<div class="well">
<div class="form-group">
<label>Cash Completion Rate: %#project.CashCompletionRate</label>
<div class="progress progress-striped active">
<div class="progress-bar progress-bar-info" role="progressbar" style="width: #(project.CashCompletionRate)%;"></div>
</div>
</div>
</div>
<div class="well">
<div class="form-group">
<label>Physical Completion Rate: %#project.PhysicalCompletionRate</label>
<div class="progress progress-striped active">
<div class="progress-bar progress-bar-info" role="progressbar" style="width: #(project.PhysicalCompletionRate)%;"></div>
</div>
</div>
</div>
</div>
}
</div>
</div>
There should be some errors here as I am not very familliar with your model but this should be the general idea behind it.

in thymeleaf, how can write th:each to combine rows and columns?

I want to write 4 columns in a row like this
<div class="row">
<div class="span3">Something</div>
<div class="span3">Something</div>
<div class="span3">Something</div>
<div class="span3">Something</div>
</div>
<div class="row">
<div class="span3">Something</div>
<div class="span3">Something</div>
<div class="span3">Something</div>
<div class="span3">Something</div>
</div>
data sizes are dynamic, so it can be 4, 8 or more.
this is archived in other template engine
{{#each list}}
{{#if #index % 4 == 0}}
<div class="row">
{{/if}}
<div class="span3">{{this.name}}</div>
{{#if #index % 4 == 0}}
</div>
{{/if}}
{{/each}}
but how can I archive this in thymeleaf?
I can't find the way because th:each is in tag(<div class="row"> or <div class="span3">) as attribute.
Model code
List<String> data = new ArrayList<String>();
data.add("1");
data.add("2");
data.add("3");
data.add("4");
data.add("5");
data.add("6");
data.add("7");
data.add("8");
model.addAttribute("datas", data);
Thymeleaf view code
<div th:each="data, row: ${datas}" th:with="numList=${#strings.listSplit('3,2,1,0', ',')}" th:if="${row.current} % 4 == 0" class="span3">
<span th:each="num : ${numList}" th:with="dataIndex=(${row.index} - ${num})" th:text="${datas[dataIndex]}">data</span>
</div>
Result
<div class="span3">
<span>1</span><span>2</span><span>3</span><span>4</span>
</div>
<div class="span3">
<span>5</span><span>6</span><span>7</span><span>8</span>
</div>
I used an array to solve this problem.
I think you will find a better way.
This can be done using numbers.sequence too. Set colCount to whatever number of columns you'd like:
<th:block th:with="colCount=${4}">
<div th:each="r : ${#numbers.sequence(0, datas.size(), colCount)}" class="row">
<div th:each="c : ${#numbers.sequence(0, colCount - 1)}" th:if="${r + c < datas.size()}" th:text="${datas.get(r + c)}" class="span3"></div>
</div>
</th:block>
I just created an account here to correct the accepted answer. The accepted answer works great so long as the "datas" being passed in is an array of consecutive integers. However, to make it work with any kind of data structure, "row.current" needs to change to "row.count", as follows:
<div th:each="data, row: ${datas}" th:with="numList=${#strings.listSplit('3,2,1,0', ',')}" th:if="${row.count} % 4 == 0" class="span3">
<span th:each="num : ${numList}" th:with="dataIndex=(${row.index} - ${num})" th:text="${datas[dataIndex]}">data</span>
</div>
If you use row.current, then it uses the actual item in the list, which is great in the example shown, but not so great for any other kind of data structure. Hope this helps.
EDIT:
I have to further refine this because the accepted answer also does not work if the number of items in the list is not evenly divisible by 4. Here is a better (though probably not perfect) solution:
<div th:each="data, row: ${datas}" th:with="numList=${ {3,2,1,0} }" th:if="${row.count % 4 == 0 or row.last}" class="span3">
<!-- Show all rows except the leftovers -->
<span th:each="num : ${numList}" th:with="dataIndex=(${row.index} - ${num})" th:if="${row.count % 4 == 0}" th:text="${datas[dataIndex]}">data</span>
<!-- Show the remainders (eg, if there are 9 items, the last row will have one item in it) -->
<span th:each="num : ${numList}" th:with="dataIndex=(${row.index} - ${num})" th:if="${row.last} and ${row.count % 4 != 0} and ${num < row.count % 4}" th:text="${datas[dataIndex]}">data</span>
</div>
This may be able to be refactored to eliminate one of the spans, but I have to move on now.
th:each can be used on any element basically. So something like this:
<div class="row" th:each="row : ${rows}">
<div class="span3" th:each="name : ${row.names}" th:text="${name}">Something</div>
</div>
<div class="row" th:each="museum,step : ${museums}">
<span th:if="${step.index % 2 == 0}">
<div class="column" style="background-color:#aaa;" >
<h2 th:text="'Name: ' + ${museum.name}"></h2>
<p th:text="'Address: ' + ${museum.address}"></p>
<p th:text="'Capacity: ' + ${museum.capacity}"></p>
</div>
</span>
<span th:if="${step.index < 3 and step.index %2 == 0} ">
<div class="column" style="background-color:#bbb;">
<h2 th:text="'Name: ' + ${museums[step.index+1].name}"></h2>
<p th:text="'Address: ' + ${museums[step.index+1].address}"></p>
<p th:text="'Capacity: ' + ${museums[step.index+1].capacity}"></p>
</div>
</span>
</div>
This is how I would approach the problem. Using a simple odd or even trick
I had the same problem and I saw the accepted answer but it was not easy enough for me so I tried a new solution and it does the job with much less code and much easier to understand
this is what I came up with:
// rowNum your situation, but be aware that you have to change all its instances to
<div th:each="i: ${#numbers.sequence(1, rowNum)}" class="row">
<div th:each="j: ${#numbers.sequence(((i-1) * rowNum), ((i-1) * rowNum) + (rowNum - 1)) }"
th:if="${j < #lists.size(list)}"
class="col col-md-5">
<span th:text=${list.get(j)}>item</span>
</div>
</div>
These are all so complicated when the answer is so simple as answered here.
<div colCount=${4} class="row">
<div class="span3" th:each="data : ${data}">...</div>
</div>
It limits the for each to 4 element blocks. I'm guessing that's a relatively new feature. Pretty cool.

Resources