ng class is not applied in this condition - html

I have 3 loops
1-getting the name of the week day
2-getting the number of the day
1 and 2 came from js function.
JavaScript
var DAYS = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
$scope.rangetxt = [];
var d1 = new Date(fromdate);
while (d1 <= new Date(todate)) {
//alert(DAYS[d.getDay()]);
$scope.rangetxt.push({ Day: DAYS[d1.getDay()] });
//console.log($scope.rangetxt);
d1 = new Date(d1.getTime() + (24 * 60 * 60 * 1000));
}
$scope.dateArray = [];
var currentDate = moment(fromdate);
var stopDate = moment(todate);
while (currentDate <= stopDate) {
$scope.dateArray.push({ Day: moment(currentDate).format('DD') })
currentDate = moment(currentDate).add(1, 'days');
}
HTML
<td class="employeedata">
<table class="table table-bordered table-hover myTable" style="font-size: 10px;" id="table2">
<thead>
<tr>
<th rowspan="3">Type</th>
</tr>
<tr>
<!--<th rowspan="2">Type</th>-->
<th ng-repeat="r in rangetxt">{{r.Day}}</th>
<!--<th rowspan="3"></th>-->
</tr>
<tr>
<th ng-repeat="dt in dateArray">{{dt.Day}}</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="df in duration | filter : du.StaffKey | limitTo:3 ">
<td>{{df.TypeTransDesc}}</td>
<td ng-repeat="x in dateArray " >
<span ng-repeat="(key,value) in df" ng-if="key=='D'+x.Day" **ng-class="{{df.['C'+x.Day]}}">**
{{value}}
</span>
</td>
</tr>
</tbody>
</table>
</td>
I am successfully show the data inside its cell but i cant apply the class,
i have 6 classes , i want to apply them based on a condition
don't know why and how
any idea, Thanks in advance

You can get the class name from the controller, create a function on the controller and call it from the html:
html:
ng-class="getDfClass(df, x.day)"
and in the controller:
getDfClass(df, day) {
return df['C'+day];
}
this assumes that the result of df['C'+x.Day] is a string with the name of the class you want to apply to the span

Related

Format value as currency in HTML table

I have the HTML table shown below that displays a variable which is set by an array.
How can set the values as a currency to display correctly in the relevant table cell?
Here is my code:
var x = document.getElementById("exvat");x.innerHTML=data[14][1];
var y = document.getElementById("incvat");y.innerHTML=data[15][1];
<div class="card bg-light mb-3">
<div class="card-header">Pricing Data</div>
<div class="card-body">
<table class="table table-hover">
<tr>
<th></th>
<th></th>
</tr>
<tr>
<td>Price Ex Vat</td>
<td id="exvat"></td>
</tr>
<tr>
<td>Price Inc Vat</td>
<td id="incvat"></td>
</tr>
</table>
If you're working with a fixed currency, then you could simply do something like:
var x = document.getElementById("exvat");x.innerHTML= "USD$" + data[14][1];
var y = document.getElementById("incvat");y.innerHTML= "USD$" + data[15][1];
Of course, change "USD$" to the currency you would like. It's a String concatenation.
After searching and trial and error, the following worked
Rik
var x = document.getElementById("exvat");x.innerHTML=data[14][1].toLocaleString('en-US', { style: 'currency', currency: 'GBP' });

Create sparse Html table

I want to create HTML table like following
# Class Method A b c d
1 User get 10 20 30 40
set 40 30 20 10
find 40 30 20 10
2 Profile get 10 20 30 40
set 40 30 20 10
find 40 30 20 10
I have the following structure
export class Profiler {
constructor(
public classz: string,
public methodProfilers: {[key: string]: MethodProfiler;}
) {}
}
export class MethodProfiler {
constructor(
public count: number,
public totalTime: number,
public lastTotalTime: number,
public maxTime: number,
public avgTime: number,
public avgMemory: number
) {}
}
Is it possible to create such Html table using angular 4 *ngfor ? I am getting list of Profiler from back end.
getProfilerKeys(methodProfilers: Map<string, MethodProfiler>) {
return Object.keys(methodProfilers);
}
<div class="table-responsive">
<table class="table table-sm table-bordered">
<thead class="thead-default">
<tr>
<th class="text-center">Classz</th>
<th class="text-center">Method</th>
<th class="text-center">Count</th>
<th class="text-center">TotalTime</th>
<th class="text-center">LastTotalTime</th>
<th class="text-center">MaxTime</th>
<th class="text-center">AvgTime</th>
<th class="text-center">AvgMemory</th>
</tr>
</thead>
<tbody>
<tr class="text-center" *ngFor="let profiler of page.content;">
<td>{{profiler.classz}}</td>
<td>
<table>
<tr *ngFor="let key of getProfilerKeys(profiler.methodProfilers);">
<td>{{key}}</td>
</tr>
</table>
</td>
<td>
<table>
<tr *ngFor="let key of getProfilerKeys(profiler.methodProfilers);">
<td *ngFor="let subkey of getProfilerKeys(profiler.methodProfilers[key]);">{{profiler.methodProfilers[key][subkey]}}</td>
</tr>
</table>
</td>
</tr>
</tbody>
</table>
</div>
It is more easy to achieve IMHO if you expand out the *ngFor into its <ng-template> equivalent.
Then create one td for each Profile and set the rowspan attribute on the td to be the number of "ProfilerKeys" in the array.
I use the function isNewIndex() to detect when the outer loop (Profiler objects) changes its index to draw another row-spanned td.
import { Component } from '#angular/core';
import { Profiler, MethodProfiler } from './profile';
#Component({
selector: 'my-app',
template: `
<table class="table table-sm table-bordered" width="100%">
<thead class="thead-default">
<tr>
<th class="text-center">#</th>
<th class="text-center">Class</th>
<th class="text-center">Method</th>
<th class="text-center">Count</th>
<th class="text-center">TotalTime</th>
<th class="text-center">LastTotalTime</th>
<th class="text-center">MaxTime</th>
<th class="text-center">AvgTime</th>
<th class="text-center">AvgMemory</th>
</tr>
</thead>
<tbody>
<ng-template ngFor let-profiler [ngForOf]="profilers" let-i="index">
<ng-template ngFor let-method [ngForOf]="getProfilerKeys(profiler.methodProfilers)">
<tr class="text-center">
<td *ngIf="isNewIndex(i)" [attr.rowspan]="getProfilerKeys(profiler.methodProfilers).length">{{i + 1}}</td>
<td *ngIf="isNewIndex(i, true)" [attr.rowspan]="getProfilerKeys(profiler.methodProfilers).length">{{profiler.classz}}</td>
<td>{{method}}</td>
<td>{{profiler.methodProfilers[method].count}}</td>
<td>{{profiler.methodProfilers[method].totalTime}}</td>
<td>{{profiler.methodProfilers[method].lastTotalTime}}</td>
<td>{{profiler.methodProfilers[method].maxTime}}</td>
<td>{{profiler.methodProfilers[method].avgTime}}</td>
<td>{{profiler.methodProfilers[method].avgMemory}}</td>
</tr>
</ng-template>
</ng-template>
</tbody>
</table>
`
})
export class AppComponent {
lastIndex = -1;
getProfilerKeys(methodProfilers: Map<string, MethodProfiler>) {
return Object.keys(methodProfilers);
}
// on last call to this function per row pass true for the updateIndex param
isNewIndex(thisIndex: number, updateIndex : boolean) {
if (thisIndex === this.lastIndex) return false;
if (updateIndex === true) this.lastIndex = thisIndex;
return true;
}
profilers = [
new Profiler('User',
{
'get' : new MethodProfiler(10,20,30,40,50,60),
'set' : new MethodProfiler(1,2,3,4,5,6)
}
),
new Profiler('Profile',
{
'get' : new MethodProfiler(60,50,40,30,20,10),
'set' : new MethodProfiler(6,5,4,3,2,1)
}
)
];
}
Demo: https://plnkr.co/edit/B5YYn9Jxx9nQCzxlr2VS?p=preview

Table displaying count of data with conditions AngluarJS

I am trying to create a table like below:
Number of days Count
Over 3 days 3
Over 20 days 4
Over 30 days 5
So I get back a total count of things open over 3 days etc.
Problem 1: If i use Ng-repeat i cannot specify my row titles (i.e column 1)
Problem 2: My data is not pulling through
Please find a snippet of my code below:
My Controller :
$scope.requests = requests;
function daysBetween(modifiedDate) {
var currentDate = new Date();
modifiedDate = new Date(modifiedDate);
return UtilityFactory.getNumberOfDaysBetween(currentDate, modifiedDate);
}
$scope.numberOfDaysSince = function(modifiedDate) {
var days = daysBetween(modifiedDate);
if(days === 1) {
return '(1 day)';
} else {
return '(' + days + ' days)';
}
};
My index.html
<table class="table table-condensed" st-safe-src="requests" st-table="requestsCollection">
<thead>
<tr>
<th>Number Of days</th>
<th>Total Count</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="request in requestsCollection ">
<td>Over 3 days</td>
<td>column 2
<span ng-repeat="requestCollection in requestsColl| filter: numberOfDaysSince(ticket.Modified) > 3">
{{requestsColl.length}}
</span>
{{requestsColl.length}}
</span>
</td>
<td>Over 20 days</td>
<td>
<span ng-repeat="requestCollection in requestsColl| filter: numberOfDaysSince(ticket.Modified) > 20">
{{requestsColl.length}}
</span>
</td>
<td>Over 30 days</td>
<td>
<span ng-repeat="requestCollection in requestsColl| filter: numberOfDaysSince(ticket.Modified) > 30">
{{requestsColl.length}}
</span>
</td>
<td>Total</td>
<td>
{{requestsCollection.length}}
</td>
<td></td>
</tr>
</tbody>
</table>

Selecting a date from the calendar using selenium

I want to select any date from the calendar to test some application .
I cant find the table or tr or td elements here .
I think i can get the table divison but not able to go ahead of this .
This is my solution
public String findElementInTable(WebDriver driver,String elementXpath) {
WebElement select2Element = driver.findElement(By.xpath(elementXpath));
select2Element.click();
WebElement datepicker = driver.findElement(By.xpath("//div[#class='period_picker_days']/table"));
List<WebElement> rows_table = datepicker.findElements(By.tagName("tr"));
int rows_count = rows_table.size();
// Loop will execute till the last row of table.
for (int row = 0; row < rows_count; row++) {
// To locate columns(cells) of that specific row.
List<WebElement> Columns_row = rows_table.get(row).findElements(By.tagName("td"));
// To calculate no of columns(cells) In that specific row.
int columns_count = Columns_row.size();
// Loop will execute till the last cell of that specific row.
for (int column = 0; column < columns_count; column++) {
// To retrieve text from that specific cell.
if (Columns_row.get(column).getText().equals(name)) {
String celtext = Columns_row.get(column + 2).getText();
System.out.println("Cell Value Of row number " + row + " and column number " + (column) + " Is "
+ celtext);
return Columns_row.get((column + 2)).getText();
}
}
}
return null;
}
Here is a detailed html snippet of the calendar
<div class="ParkingWidgetParkingLanding period_picker_box xdsoft_noselect animation xdsoft_norange visible active periodpickerstart" style="left: 487.467px; top: 857px; width: 511px; height: 294px;" unselectable="on">
<div class="period_picker_head">
<div class="period_picker_work">
<div class="period_picker_days">
<a class="periodpicker_btn_prev" href="#">Prev</a>
<table>
<tbody>
<tr>
<td class="period_picker_month5 periodpicker_table_container">
<table>
<tbody>
<tr>
<th class="period_picker_month" title="May 2016" colspan="7" data-dateend="2016/05/31" data-datestart="2016/05/1">May 2016</th>
</tr>
<tr class="period_picker_first_letters_tr">
<th class="period_picker_holiday">Sun</th>
<th class="">Mon</th>
<th class="">Tue</th>
<th class="">Wed</th>
<th class="">Thu</th>
<th class="">Fri</th>
<th class="period_picker_holiday">Sat</th>
</tr>
<tr>
<td class="period_picker_gray_period">1</td>
<td class="period_picker_gray_period">2</td>
<td class="period_picker_gray_period">3</td>
<td class="period_picker_gray_period">4</td>
<td class="period_picker_cell period_picker_weekday" data-date="2016/05/5">5</td>
<td class="period_picker_cell period_picker_weekday" data-date="2016/05/6">6</td>
<td class="period_picker_cell period_picker_holiday period_picker_last_cell" data-date="2016/05/7">7</td>
</tr>
<tr>
<tr>
<tr>
<tr>
</tbody>
</table>
</td>
<td class="period_picker_month6 periodpicker_table_container">
<table>
Hi please do it like below (answer is as per the html source provided)
List<WebElement> dates = driver.findElements(By.xpath("//*[#class='period_picker_month5 periodpicker_table_container']/table/tbody/tr[3]/td"));
// for printing every date
// and selecting a date form the calender
String MyDate = "6";
for (int j = 0; j < dates.size(); j++) {
String date = dates.get(j).getText();
System.out.println(date);
if(dates.get(j).getText().equals(MyDate)){
dates.get(j).click();
break;
}
}
Try this for first date //html/body/div/div/div/div/table/tbody/tr/td/table/tbody/tr[3]/td[1]
Also you can download xpath finder, it's mozzila add-on i think it helps a lot.
When you install it just right click on element, choose Xiew xpath-> and it will show xpath for element.

How to bind Knockout model data to Multiple tables

I am using knockout binding to bind some data into html tables. My knockout view Model had multiple products and each product will have multiple chars. I want to display the products in one table and when i select the link "show chars" it should display the corresponding chars in below table.
This is my View Model
var ProductViewModel = function(items) {
this.items = ko.observableArray(items);
this.itemToAdd = ko.observable("");
this.addItem = function() {
if (this.itemToAdd() != "") {
this.items.push(this.itemToAdd());
this.itemToAdd("");
}
}.bind(this);
};
And this is my html tables
<div id="productTable">
<table class="ui-responsive table">
<thead>
<tr>
<th >Product Name</th>
<th >Description</th>
<th >Parent?</th>
</tr>
</thead>
<tbody id="pBody" data-bind="foreach: items">
<tr class="success" >
<td><span data-bind="text: name"></span>
</td>
<td><span data-bind="text: desc"></span>
</td>
<td>show chars</td>
</tr>
</tbody>
</table>
</div>
</div>
<div id="productChars">
<div id="productCharTable">
<table class="ui-responsive table">
<thead>
<tr>
<th >Char Name</th>
<th >Description</th>
<th >Length</th>
<th >Type</th>
</tr>
</thead>
<tbody id="pBody" data-bind="foreach: $data['chars']">
<tr class="success">
<td><span data-bind="text: name"></span>
</td>
<td>asdf asdfasdf</td>
<td>10</td>
<td>String</td>
</tr>
</tbody>
</table>
</div>
I am able to bind the products into first table. But for characteristics i am not sure how to achieve the same.
Could someone please help me in figuring out how to achieve the same.
Here is the jsfiddle
https://jsfiddle.net/sirisha_k/0Ln7h2bo/7/
As #supercool pointed out you can use "data-bind='with selectedItem'" to populate the second table with chars data. For that you need to add one more item into your model called selectedItem and every time you select or add a row, you point the selectedItem to that elementdata. And use "data-bind='with selecteItem'" for second table.
var ProductViewModel = function(items) {
this.items = ko.observableArray(items);
this.selectedItem = ko.observableArray();
this.itemToAdd = ko.observable("");
this.addItem = function() {
if (this.itemToAdd() != "") {
this.items.push(this.itemToAdd());
this.itemToAdd("");
}
}.bind(this);
};
and on row select call some function selectedItem($data) where $data refers to the current item.
then set that data to selectedItem in model.
function selectedItem(prod){
ProductViewModel.selectedItem(prod);
}