Increment ng-repeat index value in Html - html

I want to increment value of $index in ng-repeat. For example:
<div ng-repeat:x in ProductList">
<label>{{x}}</label> // if x = 1
x++; // this is the line i need
<label style="color:red">{{x}}</label> // x index should be equal to 2
x++; // this is the line i need
<label style="color:blue">{{x}}</label> // x index should be equal to 3
</div>
in the second time the loop runs, the x index needs to be '4'

You can simply do following:
<div ng-repeat="product in ProductList">
<label>{{$index}}</label>
<label style="color:red">{{$index + 1}}</label>
</div>

If I understand your question correctly (which is hard to understand), you want to perform different actions for even and odd indexes in your ng-repeat. You could use the special properties $even and $odd from ng-repeat.
<div ng-repeat="x in ProductList">
<label ng-if="$odd">{{x}}</label>
<label ng-if="$even" style="color:red">{{x}}</label>
</div>
If this does not help you, try to give an example of what output you are expecting.

You are trying to print index value in diff element for each item in your array,
what i will suggest is to create a custom directive and use it on different element here is "label", that we increment the count of index.

Related

How do I improve performance when constructing a grid in Angular?

Everytime the route changes (recordTab.Id changes) I have to construct a new grid with five columns and output it.
The following code generates the grid every route change
// used later in html code to generate five columns with *ngFor
this.columns = [0,1,2,3,4]
// the records are filtered based on the id
this.id = recordTab["id"];
//allRecords has 1300 elements in it
this.records= allRecords.filter(record => record.recordTabId == this.id); // filter by recordTabId
// construct grid with 5 columns
// the maximum number of cells per column are 300
for(let i=0; i<5; i++){
this.grid[i] = [];
this.grid[i] = new Array(recordTab["gridCells"]); // number of cells in a column
}
if(this.records){
for(let record of this.records){
// assigning record to its corresponding cell
this.grid[record.column - 1][record.row - 1] = record;
}
}
// has maximum 5*300 entries
// 600 entries filled
// rest is empty to simulate empty cells
console.log(this.grid)
Now I am displaying the grid in the following way:
<div class="grid-container">
<div class="column" *ngFor="let column of columns">
<div class="cell" *ngFor="let record of grid[column]">
<ng-container *ngIf="record">
<div class="record checkboxes" [ngStyle]="{'background-color': record.categorie==1 ? record.rgbFarbeHex : 'white'}" [ngClass]="{'heading-container': record.categorie==1}">
<label [ngClass]="{'heading': record.categorie==1}" [title]="record.name" (contextmenu)="showRecordInformation($event, record)"> <span *ngIf="record.categorie==0"> <input type="checkbox"> </span> {{record.name}}</label>
</div>
</ng-container>
</div>
</div>
</div>
The problem is that the grid takes some time to show up for the grid with 5*300 entries and 600 actually filled entries. How could I improve the performance?
I dont think the css is the problem, that is why I dont show it. If it is necessary, tell me.
You should take a look at trackBy. It will tell your ngFor to only rerender what changed based on what you are tracking. It's hard to tell if it can work in your case but there is no other solution since as soon as the array changes, angular loose track of what's going on and needs to render the *ngFor again.
It would look like that:
<div class="column" *ngFor="let column of columns; trackBy:trackByFn">
trackByFn(index, item) {
return item.id;
}

Skip array element in HTML

I have an array of length 5 on which I'm looping over to create the rating scale as shown in the image below. How can I skip iterating over the first element (1) of the array and only render the div for the last four elements of the array (2, 3, 4, 5). I tried slicing the array first and then render but it doesn't help. Is there any way that the element remains in the array and I can skip over it in the HTML.
<div class="rating-type__pipe" #messageEl [attr.data-option-id]="opt._id" id="rating_id_right{{opt?._id}}"
*ngFor="let opt of positiveArray; index as i">
<div class="rating-type__pipe-pillar">
<span [ngStyle]="{'height': (i+1)*(100/positiveArray.length)+'%','opacity': (i+1)*(1/positiveArray.length)}" class="rating-type__pipe-pillar-bg"></span>
</div>
<div class="rating-type__pipe-text">{{opt.text}}</div>
</div>
You can use slice method to skip first element.
<div class="rating-type__pipe" #messageEl [attr.data-option-id]="opt._id" id="rating_id_right{{opt?._id}}"
*ngFor="let opt of positiveArray.slice(1); index as i">
<div class="rating-type__pipe-pillar">
<span [ngStyle]="{'height': (i+1)*(100/positiveArray.length)+'%','opacity': (i+1)*(1/positiveArray.length)}" class="rating-type__pipe-pillar-bg"></span>
</div>
<div class="rating-type__pipe-text">{{opt.text}}</div>
</div>
I created a dummy div for the first element and now it works fine.

Layout: Need a cell that can be bigger than other cell in the same row

The best way to explain what I'm trying to do is with this image:
Desired Output
<\b>
What I'm currently getting is this:
current output
It almost works to think of this as 7 rows of data with two columns. The problem is that in row 1 cell 2, the control needs to be the same size as 5 rows, but currently its height is only 1 row. Its height should span from Field x all the way down to Label E.
Here is an example code of one of the rows, so you can see I'm just using two different div classes, one called "row-two", and another for columns, which in this case is "col-1-12". "row-two" and "col-1-12" are re-used frequently.
<div class="row-two" >
<label for="someLabel" class="col-1-12">TheLabel:</label>
<div class="col-2-12 left-align-button">
<p-dropdown [options]="optionNames" [(ngModel)]="selectedSomething" [filter]="true" filterBy="label" [style]="{width:'80%'}" (onChange) = "onSomeChange()"></p-dropdown>
</div>
<label for="somethingElse" class="col-1-12">AnotherLabel:</label>
<div class="col-3-12">
<select multiple="true" size="12" [(ngModel)]="selectedSomething" style="width: 100%;" (ngModelChange) = "getDatesFromServer()" >
<option title="{{something.label}}" *ngFor="let something of somethings" value= {{something.value.id}}>
{{something.label}}
</option>
</select>
</div>
Credit to Jensei: the answer is CSS Grid. This example here is basically going to be my solution: https://gridbyexample.com/examples/example20/

How to toggle index view with "where" in Rails

I have a table with multiple columns. One is boolean. I have this in my controller:
def index
#matchings = Matching.where(match: '1')
end
I only want to have lines with the corresponding value of 1 for the "match" column because usually lines with a value of "0" aren't important. However, I'm wondering whether there is a way to toggle the view without having to go into the controller and edit the def index every time.
Any ideas?
If you just would like to toggle it manually, you can just type
localhost:3000/controllername/index?match=0
or
localhost:3000/controllername/index?match=1
if you want to add it from your view you can make a form like this
<form class="smart-form">
<fieldset>
<section class="col col-3">
<label class="label font-sm">Toggle view</label>
<select class="form-control input-sm" name= "match">
<option value="0">View 1</option>
<option value="1">View 2</option>
</select><i></i>
</section>
</fieldset>
<footer>
<button type="submit" class="btn btn-primary">Submit</button>
</footer>
</form>
and in your controller type the following
def index
#matchings = Matching.where(:match => params[:match])
end
I assume that match is something defined at your model.
Thank you
Just use a query string. Whenever you want to load it with
match: '1'
add
?match=1
to the request and whenever you want it with
match: '0'
add
?match=0
to the request. For example:
/some/index/page?match=1
or
/some/index/page?match=0.
Then in the controller use:
def index
#matchings = Matching.where(match: match)
end
private
def match
params.require(:match) # reads the value of the `match` param in the query string
end
For what it's worth, you can write migrations to create boolean columns. (TINYINT in most SQL databases.) Using that, your queries can be changed to
Matching.where(match: true||false)
which makes a bit more sense for this purpose.
Also, I would avoid naming a column "match" altogether. match is a frequently used Ruby method, and it's best to avoid using common method names like that.

How to loop through array upto only some objects using ngFor in angular 2

I'm looping through an array which has 6 objects and using ngFor where I want to loop only up to 4 elements .. How Can I do that??
<div class="item active" *ngFor="#data of lengthArray">
content
</div>
In LengthArray I have 6 but how to loop up to 4 records only??
and also I want to loop from 4th record to 6th record in another div.. How can I start from 4th record??
You can use the slice pipe with a start and end parameter. The start parameter is required and the end parameter is optional.
<div class="item active" *ngFor="#data of lengthArray | slice:start[:end]">
content
</div>
You can capture the index and then make it less then 4
<div class="item active" *ngFor="#data of lengthArray;i=index">
<div *ngIf="i<=4">
content
</div>
</div>
I haven't really tested the code but you can find a lot of examples here on stackoverflow, do more researching...
Angular 2: how to apply limit to *ngFor?
More about filters...
How to apply filters to *ngFor
Simple solution:
<tr *ngFor=""let obj of ArrayogObjs; let i=index">
<td *ngIf="i<4">
{{obj.name}}
</td>
</tr>