How to set the outer div values in html page - html

I have an html page in Angularjs. In the page there are two divs one contains the data regarding total no of users and other div contains the table in which the data are populated from the service a list of user.
The code is.
app_user.html
// IN this div i am getting the total no of users by users.length
<div id ="total_user"> no of users {{users.length}} </div>
<div id ="user_table">
// In this the no of users keeps changing as soon filter is applied
<tr ng-repeat="row in users | filter : {status: search['_status']} | filter : {payment_type:search['pay_type']}| orderBy : orderBy:reverse ">
<td >
<div ng-if="row.status !== 'Failure'"><!--{{$index}} -->
<input type="checkbox" checklist-model="user.roles" checklist-value="row.id">
</div>
</td>
<td>
<a ng-href="https://userapp.com/{{row.id}}" target="_blank">{{row.username}}</a>
</td>
<td>
<div>
<div>{{row.location}}</div>
</div>
</td>
</div>
In the first div i am finding the total no of users and in the second div i am showing the list of user with details.
I have applied the filters which are working fine. Now what i want is when i apply the filter the No of user should also change for a particular filter applied. I am not getting the way of how to pass the row.length to the outer div.
For ex : before applying filters i have total no of user say 100, When i applied the filters the total no of users are now 40. Now in the first div i want to show the total no of user as 40 instead of 100.

Please use the below way to get the count.
ng-repeat="row in filteredusers = (users | filter:{status: search['_status']} | filter : {payment_type:search['pay_type']} | orderBy:reverse)"
Would create the filtered list on the fly, you can use filteredusers.length anywhere else in the current scope to show the count.
Filtered Count
{{filteredusers.length}}

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;
}

I used bootstrap-Vue and this issue is related to rendering the data based on #click event in for loop

I have used bootstrap-vue to create buttons inside a table. Requirement was to get the data of the button that was clicked. But since I used a for loop, even though i click on any of the 3 buttons (number is based on for loop), the data is getting rendered for all the 3 buttons on clickon any of the 3 buttons. I tried using "collapse-{{index}}" so that the index value might change. But if use this I am getting module error.
<b-tbody>
<b-tr v-for="(_,index) in gradableItems" :key="index">
<b-td>
<div>
<b-button
:class="visible ? null : 'collapsed'"
:aria-expanded="visible ? 'true' : 'false'"
aria-controls="collapse-4"
#click="fetchGIChildren({gradableItemId:gradableItems[index].id+'',userID:'701709', giIndex: index}), visible = !visible"
></b-button>
</div>
{{gradableItems[index].id+" "+gradableItems[index].name}}
<table>
<b-collapse id="collapse-4" v-model="visible" class="mt-2">
<tr v-for="(_,childIndex) in gradableItems[index].children" :key="childIndex">
<td>{{gradableItems[index].children[childIndex].status +' '+ gradableItems[index].children[childIndex].name}}</td>
</tr>
</b-collapse>
</table>

Update table cell value dynamically using angular6

I am working with an angular 6 application, in the HTML template I have some code as per below, just showing the table cell part of the array, also the table is built using divs.
<div class='table_small'>
<div class='table_cell'>Status</div>
<div class='table_cell'>
<p class="status" >{{incomingData.status}}</p>
</div>
</div>
Please note here that "data" is an array (*ngFor) and is being used in row data and there are multiple data in the table.
Now I have a situation wherein there is a button inside the table rows to cancel the particular order, when the user clicks in, a pop up/modal asks for user confirmation, if the user opts for 'Yes' it would change the status field value to "cancellation is in process" temporarily before it hits the service, once there is a successful response from the customer it would change the station to "cancelled".
I am really not sure how to do the cancellation within the table cell here, if anyone can give insight on this please do.
Thanks
You could pass the element to the function and edit its status:
<div class='table_small'>
<div class='table_cell'>Status</div>
<div class='table_cell'>
<p class="status" >{{incomingData.status}}</p>
</div>
<div class='table_cell'>
<button (click)="showCancelModal(incomingData)"> Cancel</p>
</div>
</div>
And then in the component something like this:
showCancelModal(incomingData) {
// logic for showing modal and retrieving user response
if( response === 'yes') {
incomingData.status = 'Cancel in progress';
yourService.cancel(incomingData)
.pipe( finally(() => incomingData.status = 'Cancelled') )
.subscribe();
}
}

(Reverse) Traverse XPath Query for Accessing a DIV with a particular Text Value

Working with a DOM that has the same HTML loop 100+ times that looks like this
<div class="intro">
<div class="header">
<h1 class="product-code"> <span class="code">ZY001</span> <span class="intro">ZY001 Title/Intro</span> </h1>
</div>
<div>
<table>
<tbody>
<tr>
<td>Available</td>
<td> S </td>
<td> M </td>
<td> XL </td>
</tr>
I was previously using this XPath Query to get ALL the node values back (all 100+ instances of the DOM Query in connection with the variable nodes that may contain in Available
//div[#class='intro']/div/table/tbody/tr/td[contains(text(),'Available')]/following-sibling::td
object(DOMNodeList)[595]
public 'length' => int 591
Now I am needing to target the product-code / code specifically to retrieve all the td attributes for a particular code
Because the div that contains the unique identifier (in the example above, ZY001) is not a direct ancestor, my thinking is I have to do a Reverse XPath Query
Here's one of my attempts:
//h1[#class='product-code']/span[contains(#class, 'code') and text() = 'ZY001']/../../div[#class='intro']/div/table/tbody/tr/td[contains(text(),'Available')]/following-sibling::td
As I am defining /span[contains(#class, 'code') and text() = 'ZY001'] and then attempting to traverse the dom backwards twice using /../../ I was hoping/expecting to get back the div[#class='intro'] with the text ZY001 immediately above it, or rather a public 'length' => int 1
But all my attempts thus far have resulted in 0 results. Not false, indicating an improper XPath, but 0.
How can I modify my XPath Query to get back the single instance in the one-of-many <div class="intro">'s that contain the <h1 class="product-code">/<span class="code"> text value ZY001?
Use
//h1[#class='product-code']/span[contains(#class, 'code') and text() = 'ZY001']/../../../div/table/tbody
instead of
//h1[#class='product-code']/span[contains(#class, 'code') and text() = 'ZY001']/../../div[#class='intro']/div/table/tbody
You can use any of the below xpath's for that:
//div[#class='intro' and //h1[#class='product-code']/span[#class='code' and text()='ZY001']]//tbody/tr[td[text()='Available']]/td[2]
//div[#class='intro' and //span[#class='code' and text()='ZY001']]//tbody/tr[td[text()='Available']]/td[2]
//div[#class='intro' and //span[#class='code' and text()='ZY001']]//tr[td[text()='Available']]/td[2]
Change td[2] to td[3] and td[4] to get the 3rd and 4th td respectively

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/