nested ng-repeat with open particular index with respect to repeated data - javascript

Every time the toggle is clicked, all payments are getting replaced with new payments. My problem is how to maintain the payments of a particular index of every click and show at respective index. please help me out
here is my html
<tbody data-ng-repeat="invoice in relatedInvoices>
<tr>
<td class="td-bottom-border">
{{invoice.PayableCurrencyCode}} {{invoice.PayablePaidAmount | number: 2}}<br />
<small>
<a data-ng-click="isOpenPayablePayments[$index] = !isOpenPayablePayments[$index]; togglePayablePayments(invoice.PayableInvoiceId)">Paid</a>
</small>
</td>
</tr>
<tr data-ng-show="isOpenPayablePayments[$index]">
<td>
<table>
<thead>
<tr>
<th>Transaction Id</th>
</tr>
</thead>
<tbody>
<tr data-ng-repeat="payment in payablePayments">
<td>{{payment.TransactionId}}</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
Here is my javascript
var getPayments = function (invoiceId) {
paymentService.getPayments(invoiceId).then(function (paymentsResponse) {
return paymentsResponse.data;
});
};
$scope.togglePayablePayments = function(invoiceId) {
$scope.payablePayments = getPayments(invoiceId);
};

If I understood correctly, you want to have "payablePayments" for every invoice.
This is working: http://plnkr.co/edit/cj3jxZ?p=info
Try something like
// init at beginning
$scope.payablePayments = [];
$scope.togglePayablePayments = function(invoiceId) {
$scope.payablePayments[invoiceId] = getPayments(invoiceId);
};
and then
<tr data-ng-repeat="payment in payablePayments[invoice.PayableInvoiceId]">
Otherwise you overwrite the object for the preceding invoice.

Related

Why is a value gotten from a table cell not working when passed as a condition in an IF/ELSE statement embedded in an array of objects loop?

I have the following code samples.
The table rows are generated automatically and appended to the tbody. When I perform the click function on the Delete/Trash Icon, I get the value of the cell which is that currentRow, but then when I try to use it inside the for-loop and if-else condition, it doesn't work. I am trying to do so so I can delete the user from both the table and the storage as well (using LocalStorage for storage)-array of objects.
let sampleArray =
[
{
attendanceCount: 0
fullName: "Ezeugo Obieze"
password: "qtvpr3h933i"
userPhoneNumber: "07060858438"
},
{
attendanceCount: 0
fullName: Felistus Ezekiel"
password: "tcph4aym3mb"
userPhoneNumber: "07087032997"
}
]
let listAllEmployees = () => {
return userDetails.forEach( (element) => {
$("#employees-table").append(`
<tr>
<td> ${element.fullName} </td>
<td class="userMobile">${element.userPhoneNumber </td>
<td> ${element.password}</td>
<td class="centerText">${element.attendanceCount} </td>
<td class="centerText"><i class="fa fa-trash icon" aria-hidden="true"></i></td>
</tr`);
});
};
$("#employees-table").on("click", ".icon", function() {
let currentRow = $(this).closest("tr").children("td.userMobile").text();
console.log(currentRow) //test if the value was gotten
for(let index = 0; index < userDetails.length; index++) {
if ( currentRow === userDetails[index].userPhoneNumber) console.log(useDetails)
}
});
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.10.2/css/all.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<thead>
<tr>
<th>Name</th>
<th>Phone Number</th>
<th>Password</th>
<th>Count</th>
<th>Delete</th>
</tr>
</thead>
<tbody id="employees-table">
<tr>
<td>Alfreds Futterkiste</td>
<td class="userMobile">09060858438</td>
<td>Germany</td>
<td class="centerText"> 0</td>
<td class="centerText"> <i class="fa fa-trash icon" aria-hidden="true"></i> </td>
</tr>
</tbody>
</table>
I finally was able to debug the code and found the error.
Chrome DevTool was not displaying any errors, so I had to track each value gotten from the table and array, consoled to the browser, and found out that they weren't equal:
sample code
// data from the table
targetUserMobile = currentRow.children("td.userMobile").text() returned " 09060858438 ";
// data from the array
userDetails[index].userPhoneNumber returned "09060858438"
// when compared
userDetails[index].userPhoneNumber !== targetUserMobile
so I had to use the trim() method to clear the whitespaces before and after the number and it worked like so:
userDetails[index].userPhoneNumber === targetUserMobile.trim()

CSS Carousel/Slide Animation through elements of an array

I have data being sent from my backend to my frontend and then the data is parsed and displayed into a table. However, at it's max amount of elements in the array, there are too many rows in the table and it exceeds the area that I need the table to be in. So a carousel/slide animation would be the best bet and I want to be able to display elements 4 rows at a time and then invoke the slide animation the the next 4. I'm not quite sure how to do this in the current iteration of my function that sets the table data.
Can someone point me in the right direction?
function FormTable(props){
/**
* props = allStations
*/
console.log(props.data)
return(
<table className="form__table">
<div className="form__table-parentDiv">
<thead>
<tr>
<th className="form__table-header">Departing Station</th>
<th className="form__table-header">Arriving Station</th>
<th colSpan={2} className="form__table-header">Departure Time</th>
</tr>
</thead>
<tbody>
{
props.data.map( (stationIndex) => {
// console.log(stationIndex);
let cells = [];
for(let i = 1; i < stationIndex.length; i++){
cells.push(
<React.Fragment>
<td className="form__table-stations"> {stationIndex[i].station} </td>
<td className="form__table-stations"> {stationIndex[i].destination} </td>
<td className="form__table-arrivals"> {stationIndex[i].firstArrival} </td>
<td className="form__table-arrivals"> {stationIndex[i].secondArrival} </td>
</React.Fragment>
);
}
return <tr className="form__table-row" >{ cells }</tr>
})
}
</tbody>
</div>
</table>
)
}

How to save items to cart using localStorage

So I have a table like this:
<table border="1">
<tbody>
<tr>
<th> Book Title </th>
<th> Author </th>
<th> Book </th>
</tr>
<tr>
<td id= Book_Title>Gone </td>
<td id= Author>Micheal Grant</td>
<td><button id="AddToCart" onclick="addToLocalStorage()">Add To Cart</button> </td>
</tr>
<tr>
<td id= Book_Title>The Knife of never letting go</td>
<td id= Author>Ryan Howard</td>
<td><button id="AddToCart" onclick="addToLocalStorage()">Add To Cart</button> </td>
</tr>
</tbody>
My goal is to have, on button click for the data of a specific row to be saved to local storage. However, because the id's are the same for each row only the first instance of the id will save. I was wondering how I could use jquery closest() to fix my problem. Or even if there is any other solution to my problem.
In order to save the data contained in your table's row... Like the book title and author, I suggest you to use some objects contained in an array.
Then you'll have to stringify that prior to use localStorage.
When you'll want to retreive the stored data, you'll have to parse it back to an array of objects.
Sadly, SO snippets do not like the use of localStorage... So my working demo is on CodePen.
Here's the relevant code:
// The "add to cart" handler.
$("table").on("click", ".AddToCart", function(e){
// Get previous storage, if any.
var storage = JSON.parse(localStorage.getItem("cart"));
if(storage==null){
storage = [];
}
var row = $(this).closest("tr");
var title = row.find("td").eq(0).text().trim();
var author = row.find("td").eq(1).text().trim();
// Create an object to store.
var data = {author:author,title:title};
storage.push(data);
// Store it.
localStorage.setItem("cart",JSON.stringify(storage));
});
Use classes instead of IDs, and attach the listener using Javascript instead of inline attributes (which is as bad as eval). No need for jQuery. For example:
document.querySelector('table').addEventListener('click', (e) => {
if (e.target.className !== 'AddToCart') return;
// e.target refers to the clicked button:
const [bookTd, authorTd] = [...e.target.closest('tr').children];
addToLocalStorage({ title: bookTd.textContent, author: authorTd.textContent });
});
function addToLocalStorage(obj) {
console.log('adding ' + obj);
}
<table border="1">
<tbody>
<tr>
<th> Book Title </th>
<th> Author </th>
<th> Book </th>
</tr>
<tr>
<td class="Book_Title">Gone </td>
<td class="Author">Micheal Grant</td>
<td><button class="AddToCart">Add To Cart</button> </td>
</tr>
<tr>
<td class="Book_Title">The Knife of never letting go</td>
<td class="Author">Ryan Howard</td>
<td><button class="AddToCart">Add To Cart</button> </td>
</tr>
</tbody>
</table>

Angular , How to hide a table row on click of a button

I have a table in which each row has a delete button. on click of the button the data gets deleted. However to verify that record is deleted, I have to refresh the page. I want to hide the current row on click of the delete button. Here is my code.
<table>
<tr>
<th>Delete</th>
<th>Id</th>
<th>Name</th>
</tr>
<tr *ngFor="let person of people" *ngIf="!hideRow">
<td><button (click)="delete(person.id)" title="Delete">Delete</button></td>
<td>person.Id</td>
<td>person.Name</td>
</tr>
</table>
and in my component.ts On delete I change the value of hideRow
delete(id) {
this.hideTr = true;
this.personService.delete(id).subscribe(p=> console.log(p));
}
hideRow is a boolean variable with default value of false. The problem is that when I click on delete, all the rows become hidden(of course). How can I refer just to the current row?
When you want to delete the row then you should delete it in actual instead of hide row. No need of *ngIf="!hideRow". You no need to refresh the page, this is beauty of AngularJS. Below is code to delete particular row. Pass $index of the row:
HTML code:
<table>
<tr>
<th>Delete</th>
<th>Id</th>
<th>Name</th>
</tr>
<tr *ngFor="let person of people">
<td><button (click)="delete($index)" title="Delete">Delete</button></td>
<td>person.Id</td>
<td>person.Name</td>
</tr>
</table>
JavaScript Code:
// delete row
$scope.delete = function(index) {
$scope.people.splice(index, 1);
};
Simple yet more effective :
Template Side :
<tr *ngFor="let person of people" *ngIf="!person?.hideRow">
<td><button (click)="delete(person)" title="Delete">Delete</button></td>
<td>person.Id</td>
<td>person.Name</td>
</tr>
Component Side :
delete(person) {
person.hideRow = true;
this.personService.delete(person.id).subscribe(p=> console.log(p));
}
Without changing user's (property) interface
Template Side :
<tr *ngFor="let person of people;let i = index;">
<td><button (click)="delete(i , person.id)" title="Delete">Delete</button></td>
<td>person.Id</td>
<td>person.Name</td>
</tr>
Component Side :
delete(index , id) {
this.people.splice(index, 1);
this.personService.delete(id).subscribe(p=> console.log(p));
}
Based from the code you provided, I would remove this part *ngIf="!hideRow" and add this to your component
delete(id) {
this.personService.delete(id).subscribe(p=> {
console.log(p);
this.people.filter( person => person.id !== id)
// or you can use splice by using the index
});
}
Now your html is simpler and no need to use *ngIf
<table>
<tr>
<th>Delete</th>
<th>Id</th>
<th>Name</th>
</tr>
<tr *ngFor="let person of people">
<td><button (click)="delete(person.id)" title="Delete">Delete</button></td>
<td>person.Id</td>
<td>person.Name</td>
</tr>
</table>

HTML editable Table -> get edited Fields

I have a HTML-Table
<table style="width:100%">
<tr>
<th>id</th>
<th>Lastname</th>
<th>Age</th>
</tr>
<tr>
<td>2</td>
<td contenteditable="true">Smith</td>
<td contenteditable="true">50</td>
</tr>
<tr>
<td>3</td>
<td contenteditable="true">Jackson</td>
<td contenteditable="true">94</td>
</tr>
</table>
(Just a TEST-Table)
It is editable, but how do I get all the rows (with ID) which were edited, to send them to a PHP-Backend which saves the changes to DB?
Thanks in advance,
Patrick.
You can save ids in an Array whenever field content is changed.
Here is the Working Example: https://jsfiddle.net/79egs9tc/
var idArr = [];
$(".edited").focusout(function() {
var id = $(this).parent().attr('id');
if($.inArray(id, idArr) === -1){
idArr.push(id);
}
console.log(idArr);
});
You can add check for content is changes or not.
Hope, it will work for you.

Categories

Resources