Is there anyway to show serial number in a table? [duplicate] - javascript

This question already has an answer here:
How to display the index data in a *ngFor?
(1 answer)
Closed 1 year ago.
I'm currently new angular, so if there is any mistake in my implementation then please let me know,
This my HTML code from component.html file
<table id="table">
<tr>
<th>Sl.No.</th>
<th>Name</th>
<th>Email</th>
<th>Phone Number</th>
<th>Skill</th>
<th>Gender</th>
</tr>
<tr *ngFor = " let i of counter()">
<td></td> <!-- To print the serial number here -->
<td>{{nameFromLocalStorage}}</td>
<td>{{emailFromLocalStorage}}</td>
<td>{{phoneFromLocalStorage}}</td>
<td>{{skillFromLocalStorage}}</td>
<td>{{genderFromLocalStorage}}</td>
<td>
<button (click)="delete()" ><img src="./assets/icon/trash.png"></button>
</td>
</tr>
</table>
Here is code for counter() from component.ts file
counter() {
//TO DO
//Implementation is remaining,
return new Array(20);
}
The counter is supposed to return a value, the value is to be captured by the html file in the *ngFor directive and based on that it should create the required number of rows. Then I wanted to display the serial number in the first column of the table.
According to the code above I'm able to get 20 rows.
Note:- I have seen the solution in CSS and doesn't wish to implement until its the only option left.
My question is that how do I get the serial number there.
From my understanding i in the *ngFor directive should starts from zero so, is there anyway to directly display the value of i it self.
I'll be very glad if you can help me learn and correct my mistake.
Thank you in advance.

Yes you can loop it as simple dont know what your serial no is, if its from array then just use CounterArr.Serial_No.
<tr *ngFor = " let CounterArr of counter();let i = index;">
<td>{{i+1}}</td>
<td>{{CounterArr.nameFromLocalStorage}}</td>
<td>{{CounterArr.emailFromLocalStorage}}</td>
<td>{{CounterArr.phoneFromLocalStorage}}</td>
<td>{{CounterArr.skillFromLocalStorage}}</td>
<td>
<button (click)="delete()" ><img src="./assets/icon/trash.png"></button>
</td>
</tr>

Related

hide an item in the parent based on the data in the child loop in Angular

I have the following HTML code snippet where i am looping through my json response to display the data. It is a nested loop with *ngIf as in the HMTL below. What i need is based on the value of one of the items in the child loop i want to hide/show an item in the parent loop.
Basically i have mtr.eu inside the child loop which is an input type.Initially it will be empty and when the user enter any value in it, i want to show the item in the parent shown below. What would be the best suitable way to achieve this.
<div class="row accordian-head" accordion-heading>
<span class="w20">MPRN: {{header.gpr}}</span>
<span class="w20">Meter ID: {{header.num}}</span>
<span class="w20" *ngIf="mtr.eu">New data added</span>
</div>
<div class="accordian-inner-content">
<table class="table table-borderless">
<thead>
<tr class="meter-reading-header">
<th scope="col">Last read date</th>
<th scope="col">Last meter read</th>
<th scope="col">New reading (kWh)</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let mtr of header.mtrs" class="meter-reading-content">
<td>{{mtr.lrd}}</td>
<td>{{mtr.lrv}}</td>
<td>
<input type="number" name="newReading" class="form-control new-reading-input"
placeholder="eg. 12345" [(ngModel)]="mtr.eu">
</td>
</tr>
</tbody>
</table>
</div>
</accordion-group>
You can not use the child variables in the parent node. Instead, you can make a getter where you can check the records which has mu value. based on that getter value you can show the record on the parent element.
The only thing you need to do is write a function and pass your list of items into it. inside that use filter to check for required data(in your case its mt.mu). then return the data. Based on returned data you can show the element.
But when you call any function from the template it calls the function recursively.
So as a best practice I would prefer using pipes to do the same logic. Which makes my code much better.
I hope this helps you to achieve your need.

Search JSON between two dates [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
I have a JSON object which needs to be searched if I input a angular form with two dates
I tried searching using a single date angular form control.
template code:
<div>
<div class="card w-75">
<div class="card-body">
<h5 class="card-title">Invoice summary</h5>
<hr>
<p class="card-text">Total revenue made by this venue: <strong>
{{totalRevenue}}</strong></p>
<p *ngIf="invoicesFiltered === true" class="card-text">Revenue
made on <strong>{{inputInvoiceDate}}</strong> is <strong>
{{filteredTotalRevenue}}</strong></p>
</div>
</div>
<div>
<div style="float:left;">
<label for="queryInvoiceDate">Start Date:</label>
<input
#queryInvoiceDate
(change)="filterInvoice(queryInvoiceDate.valueAsDate)"
type="date"
class="form-control"
style="width:100%">
</div>
<table class="table table-striped" [mfData]="filteredInvoices" #mf="mfDataTable" [mfRowsOnPage]="10">
<thead>
<tr>
<th>Advertiser Acct Balance</th>
<th>Service Fee Amt</th>
<th>Target Amt for Venue</th>
<th>Venue Acct Balance</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let invoice of mf.data">
<td>{{invoice.acntbalances}}</td>
<td>{{invoice.servicefeeamount}}</td>
<td>{{invoice.targetamount}}</td>
<td>{{invoice.targetbalance}}</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="4">
<mfBootstrapPaginator [rowsOnPageSet]="[10,15,20]"></mfBootstrapPaginator>
</td>
</tr>
</tfoot>
</table>
</div>
component code:
filterInvoice(queryInvoiceDate: any) {
this.inputInvoiceDate = queryInvoiceDate.toISOString().split('T')[0];
this.filteredInvoices = (queryInvoiceDate) ?
this.invoices.filter(i =>
i.timestamp.includes(queryInvoiceDate.toISOString().split('T')[0])) : this.invoices;
console.log(queryInvoiceDate.toISOString());
this.filteredTotalRevenue = this.filteredInvoices.reduce((sum, invoice) => {
return sum + invoice.targetamount; }, 0);
}
What would i need to do if I want to pass two dates and search for all JSON values falling between the passed dates and specific timestamps?
I would strongly recommend using momentjs if you need to do anything with dates in javascript that isn't trivial. That is likely to be the case if you are writing a real-world application as opposed to a theoretical exercise. Javascript dates are messy and nasty, and you can see that you are already doing ugly things like .toISOString().split('T')[0] in order to extract the date. In momentjs, you can do something like moment(queryInvoiceDate1).isBefore(moment(i.timestamp)) && moment(queryInvoiceDate2).isAfter(moment(i.timestamp)) to filter the invoices by the date range. This will let you write much more readable and maintainable code.
On the other hand, the nice thing about ISO strings is that they can be compared vie lexicographical (alphabetical) sort, so '2018-09-01' is > '2018-08-01' and < '2018-09-03' for instance. So you could use your current method of extracting the date from the ISO string and simply use >= and <= operators in the filter.

.each() function on affect current object

having some issues with my code below, first here is the HTML:
<table class="finance-table">
<tbody><tr>
<th></th>
<th>Deposit</th>
<th>Balance</th>
<th>Fees</th>
<th>Total Payable</th>
<th>Term</th>
<th>Fixed Rate</th>
<th>Representative APR</th>
<th>Monthly Pmt</th>
</tr>
<tr class="hp">
<td><strong>HP</strong></td>
<td id="td_finance_deposit">£11700.00</td>
<td id="td_finance_balance">£105300.00</td>
<td id="td_finance_fees">£298.00</td>
<td id="td_finance_total_inc_deposit">£146255.50</td>
<td id="td_finance_term">60 mths</td>
<td id="td_finance_rate">5.50%</td>
<td id="td_finance_apr">10.1%</td>
<td id="td_finance_monthly_payments">£2242.59 p/m* x 60 mths</td>
</tr>
</tbody></table>
There is about 10 of these tables [within the same document], all with the same id's and class's. I'm using an each loop to execute some code against each table found, however it only seems to be working on the first table and disregards the others.
Below is the jQuery, like I said works find on the first table, but ignores the rest!
<!-- Remove First and Final Payment from Showroom Finance Examples -->
<script>
$(".finance-table").each(function(key, value) {
// Display loading
var html = $(this);
// Remove the First Payment and Final Payment Column
$(this).find("#td_finance_first_payment, #td_finance_final_payment").remove();
$(this).find("th:contains('1st Pmt')").remove(); $(this).find("th:contains('Final Pmt')").remove();
// Get the Term and update the monthly payment
var term = $(this).find("#td_finance_term").html(); // .replace(/\D/g,'')
var payments = ($(this).find("#td_finance_monthly_payments").html()).split('x')[0];
($(this).find("#td_finance_monthly_payments")).html(payments + " x " + term);
})
</script>
Edit:
Please note, I can't change the HTML at all
You should first give a unique ID to each <td>, perhaps with your DB identifier for that record. You don't need it now but this will allow you to do other thing later if you need it.
Then change all the <td> ids to classes:
<td class="td_finance_fees">£298.00</td>
Finally change all your javascript accordingly to use class instead of IDs:
$(this).find(".td_finance_first_payment, .td_finance_final_payment").remove();
Using Attribute Equals Selector
Change your code from:
$(this).find("#td_finance_first_payment, #td_finance_final_payment").remove();
to:
$(this).find('td[id="td_finance_first_payment"], td[id="td_finance_final_payment"]').remove();
Do this type of change for all areas of #xxx to id="xxx"
What this does is find all tds with attribute id="xxx", rather than using #id identifier, this is forces jQuery to do a tree search.
Also your HTML does not match your code, (theres no td_finance_first_payment in your html, I assume you removed it?)
Edit: This solution is useful if you 100% cannot edit the html (comes from a source you have no control over, such as an API or internal software). Best solution would be to fix the ids!

Update model based on ng-repeat of array

Sorry if you find this question's solution is simple or silly.
Need suggestions or solution on this angular part.
I have an object containing array("value"), as shown below.
scope.resp.DefaultData.graphRowData = [
{YName:"Mary", value:[1,4], points:1},
{YName:"Tom", value:[2,5], points:1}
];
My Code viewer uses this style to render the array.
<table>
<tbody>
<tr ng-repeat="rowLabels in resp.DefaultData.graphRowData track by $index">
<th>
<input type="text" value="{{rowLabels.YName}}" ng-model="rowLabels.YName"/>
</th>
<td ng-repeat="value in rowLabels.value track by $index">
<input type="text" ng-model="value"/>
</td>
</tr>
</tbody>
</table>
The html viewer would render like below way:
<table>
<tbody>
<th>Mary</th><td>1</td><td>4</td>
<th>Tom</th><td>2</td><td>5</td>
</tbody>
</table>
Now to my question:
The table displays the data as per the model but if i try to update the table with custom or edit the values, doesn't update the model and the value remains same
For example: Mary has two tags of 1 and 4 values, if I try to change the 1 to 2 and 4 to 5, the data inside the model remains same without update.
Is there any way to fix in my code or should I change the array into array of objects like below
value:[{val:1},{val:4}]
and so ... for other objects under resp.DefaultData.graphRowData? Then it would work fine. Just confused why for array not working in angular js in my code! :(
You need to pass a reference of array instead of value in ng-model
<tr ng-repeat="rowLabels in resp.DefaultData.graphRowData track by $index">
<th>
<input type="text" value="{{rowLabels.YName}}" ng-model="rowLabels.YName"/>
</th>
<td ng-repeat="value in rowLabels.value track by $index">
<input type="text" ng-model="rowLabels.value[$index]"/>
</td>
</tr>
check this working plunker

Loop through multiple TD, grab multiple values, fill array

I have two tables on the page.
Inside of my second table I am dynamically adding html from JS.
I am checking to see if the <tr> inside of the tbody are empty using:
var rowCount = $('#dynatable >tbody >tr').length;
If the row count is 0 I continue on with my javascript, if 1 or more <tr> exists I need to go through each <tr> and grab the two input values inside the <td>; for every <tr> available. Then need to collect the data into an array for server-side processing.
<table id="dynatable">
<thead>
<tr>
<th>Time</th>
<th>Description</th>
</tr>
</thead>
<tbody id="p_scents">
<tr><td class="ts_td"><input type="text" name="ts_value[]" class="timestamp_input"/></td><td><TEXTAREA NAME="ts_description[]" class="ts_desc" rows="3" cols="30" style="resize:none;" ></TEXTAREA></td></tr>
<tr><td class="ts_td"><input type="text" name="ts_value[]" class="timestamp_input"/></td><td><TEXTAREA NAME="ts_description[]" class="ts_desc" rows="3" cols="30" style="resize:none;" ></TEXTAREA></td></tr>
</tbody>
I have browsed similar questions but I cannot figure out a solution for my situation. I had a previous solution using simpleHTMLDOM + PHP but it's way too slow performance wise.
I was told to use JS or jquery and I am quite unfamiliar with both, any help is greatly appreciated.
How do I grab the values of multiple inputs from multiple <tr>'s inside a specific table and store the values in an array?
If your classes will be the same, you could do something like this with jQuery.
It put the values into arrays.
var values = $("input[class='timestamp_input']").map(function(){return $(this).val();}).get();
var textAreaValues = $("textarea[class='ts_desc']").map(function(){return $(this).val();}).get();
console.log(values);
console.log(textAreaValues);
JSFiddle demo here.

Categories