html/css - add rows numbers - html

I am trying to add row numbers in html/css.
Here is the html, react populating the rows.
<table className="table table-striped">
<thead>
<tr>
{/*<th>ID</th>*/}
<th>symbol</th>
<th>close</th>
<th>percent</th>
<th>PE</th>
<th>Rake</th>
<th />
</tr>
</thead>
<tbody>
{ this.props.item_sett_list.map(item_sett_list_item => (
<tr key={item_sett_list_item.id}>
{/*<td>{item_sett_list_item.id}</td>*/}
<td>{item_sett_list_item.symbol}</td>
<td>{item_sett_list_item.close}</td>
<td>{item_sett_list_item.percent}</td>
<td>{item_sett_list_item.pe}</td>
{
this.props.rake_sett_list.length ?
this.props.rake_sett_list.map(rake_sett_list_item => (
<td>{rake_sett_list_item.rake}</td>
)) : <td><button className='btn btn-primary btn-sm'>RAKE</button></td>
}
<td><button onClick={this.props.deleteDCASettings.bind(this, item_sett_list_item.id)}className='btn btn-danger btn-sm'>Delete</button></td>
</tr>
)) }
</tbody>
</table>
I tried to use custom.css from this answer:
The custom.css loads, I can see custom properties in some other elements. However the rows don't get the rows numbers.

How about map indexes:
{ this.props.item_sett_list.map((item_sett_list_item, index) => (
<tr key={item_sett_list_item.id}>
{/*<td>{index}</td>*/}
<td>{item_sett_list_item.symbol}</td>
<td>{item_sett_list_item.close}</td>
<td>{item_sett_list_item.percent}</td>
<td>{item_sett_list_item.pe}</td>
{
this.props.rake_sett_list.length ?
this.props.rake_sett_list.map(rake_sett_list_item => (
<td>{rake_sett_list_item.rake}</td>
)) : <td><button className='btn btn-primary btn-sm'>RAKE</button></td>
}
<td><button onClick={this.props.deleteDCASettings.bind(this, item_sett_list_item.id)}className='btn btn-danger btn-sm'>Delete</button></td>
</tr>
)) }

Related

Applying an ngClass on only 1 element of a table in angular

In my table, I'm attempting to add a read more button to each row that has a paragraph. The button is displayed for each row, and when I click one, it operates concurrently for each row.
Here is my code:
<table class="table">
<thead>
<tr>
<th scope="col">Text</th>
<th scope="col">Date</th>
<th scope="col">Comments</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let p of posts[0].posts">
<div [ngClass]="{'limitTextHeight': isReadMore}">
<td>{{p.post_text}}</td>
</div>
<button type="button" (click)="showText()" style="margin-top:15px">
{{ isReadMore ? 'Read More': 'Read Less' }}
</button>
<td>{{p.post_date}}</td>
<td>{{p.post_comments.length}} comment</td>
</tr>
</tbody>
</table>
and my showText() function:
showText() {
this.isReadMore = !this.isReadMore
}
This is happening because you're using single boolean variable i.e, isReadMore for all the looped tr tag.
What you can do is posts[0].posts map this posts with one more key that can be anything for example isReadMore in your case, then you will get unique instance to handle for each para, like this.
{{ p?.isReadMore ? 'Read More': 'Read Less' }}.
Hope you understood what I'm trying to say.
You are using a common variable for all the rows. That's why when you click one they all change. You should use local ones, one for each row like so:
<table class="table">
<thead>
<tr>
<th scope="col">Text</th>
<th scope="col">Date</th>
<th scope="col">Comments</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let p of posts[0].posts">
<div [ngClass]="{'limitTextHeight': isReadMore}">
<td>{{p.post_text}}</td>
</div>
<button type="button" (click)="showText(p)" style="margin-top:15px">
{{ p.isReadMore ? 'Read More': 'Read Less' }}
</button>
<td>{{p.post_date}}</td>
<td>{{p.post_comments.length}} comment</td>
</tr>
</tbody>
</table>
and the showText() function:
showText(post) {
post.isReadMore = !post.isReadMore
}
You could also add an *ngIf to check if there is text long enough before showing the button:
<button type="button" *ngIf="p.post_text?.length > 20" (click)="showText(p)" style="margin-top:15px">
{{ p.isReadMore ? 'Read More': 'Read Less' }}
</button>

Refresh data table after edit row in to database

I have data table in the manage.component.html (portion of code):
<table
class="table table-striped table-hover table-responsive-lg"
[mfData]="links$ | async"
#mf="mfDataTable"
[mfRowsOnPage]="10">
<thead>
<tr>
<th style="width: 5%">
<mfDefaultSorter by="id" #sortId>
ID
<span *ngIf="sortId.isSortedByMeAsc" class="cil-arrow-top" aria-hidden="true"></span>
<span *ngIf="sortId.isSortedByMeDesc" class="cil-arrow-bottom" aria-hidden="true"></span>
</mfDefaultSorter>
</th>
<th style="width: 50%">
<mfDefaultSorter by="linkCategory" #sortCategory>
Category
<span *ngIf="sortCategory.isSortedByMeAsc" class="cil-arrow-top" aria-hidden="true"></span>
<span
*ngIf="sortCategory.isSortedByMeDesc"
class="cil-arrow-bottom"
aria-hidden="true"
></span>
</mfDefaultSorter>
</th>
<th style="width: 50%"></th>
</tr>
</thead>
<tbody>
<tr *ngFor="let link of mf.data">
<td>{{ link.id }}</td>
<td>{{ link.linkCategory }}</td>
<td>
<button type="button" class="btn btn-primary mr-2 btn-edit" (click)="editLink(link.id)">
Edit
</button>
<button type="button" class="btn btn-danger ml-2 btn-delete" (click)="deleteLink(link.id)">
Delete
</button>
</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="9">
<mfBootstrapPaginator [rowsOnPageSet]="[5, 10, 15]"></mfBootstrapPaginator>
</td>
</tr>
</tfoot>
</table>
I have service for manage.component with links$ Observable as well:
export class ManageService {
private _links$ = new BehaviorSubject<model.Link[]>([]);
private _query$: BehaviorSubject<string> = new BehaviorSubject('');
links$: Observable<model.Link[]>;
query$: Observable<string>;
constructor(private httpClient: HttpClient) {
this.refreshLinks();
this.links$ = combineLatest([this._links$, this._query$]).pipe(
map(([links, query]) => links.filter(link => link.linkName.toLowerCase().includes(query)))
);
}
getLinks(): Observable<model.Link[]> {
return this.httpClient.get<model.Link[]>('/api/links');
}
findLink(query: string) {
this._query$.next(query);
}
private refreshLinks() {
this.getLinks().subscribe(links => {
this._links$.next(links);
});
}
}
For know everything is working correctly. I see table with data and buttons in every row.
I've prepared new edit.component for edit button:
form in HTML with data prefilled
scss styles
submit button which who is calling createLink method as below (method from edit.service):
public createLink() {
this.link.id = parseInt(this.linkId);
this.service.createLink(this.link).subscribe(res => {
console.log(res);
this.router.navigate(['/links/manage']);
});
this.publishModal.hide();
}
edit.service.ts (portion of code):
createLink(link: model.Link): Observable<model.Link> {
return this.httpClient.post<model.Link>('/api/createLink', link, this.httpOptions);
}
My changed data are sending to database correctly and after submit I have newer data in DB and I'm navigate back to table with whole links.
I see table of links$ but I have to refresh the browser to see updated rows as well.
In console.log(res); I see updated object, in DB I see it also but I don't see them on the screen.
What's wrong?

ngx-pagination is not getting updated after filtering data

I am using custom filters and ngx-pagination on my JSON data. The problem here is when I am filtering the data my pagination control is not getting updated, still showing the old page size and allowing pagination even if the data is not available. Please suggest.
Right now, it has 21 results without any filter applied
Now, I have applied filters n now it's showing only 1 record but pagination is still showing 5 pages (considering 5 per page size).
table-filter.pipe.ts
import { Pipe, PipeTransform } from "#angular/core";
#Pipe({
name: "tableFilter"
})
export class TableFilterPipe implements PipeTransform {
transform(list: any[], filters: any) {
const keys = Object.keys(filters).filter(key => filters[key]);
const filterUser = (user: { [x: string]: any; }) =>
keys.every(key => {
if (key == "sdob") {
return new Date(user["dob"]) >= new Date(filters[key]);
} else if (key == "edob") {
return new Date(filters[key]) >= new Date(user["dob"]);
} else {
return user[key] === filters[key];
}
});
return keys.length ? list.filter(filterUser) : list;
}
}
app.component.html
<table class="table table-sm table-responsive">
<thead>
<tr>
<th></th>
<th>First Name</th>
<th>Last Name</th>
<th>Email</th>
<th>Gender</th>
<th>DOB (mm/dd/yyyy)</th>
<th>Impact</th>
<th>Score</th>
<th></th>
</tr>
</thead>
<tbody>
<tr class="record-row" (click)="viewUser(user)" *ngFor="let user of allUser | tableFilter: form.value | paginate: { id: 'listing_pagination', itemsPerPage: 5, currentPage: page, totalItems: totalRecords }">
<td><input *ngIf="!isEdit" [(ngModel)]="user.checked" type="checkbox" (change)="checkboxClicked()"></td>
<td>{{user.first_name}}</td>
<td>{{user.last_name}}</td>
<td>{{user.email}}</td>
<td>{{user.gender}}</td>
<td>{{user.dob}}</td>
<td>{{user.impact}}</td>
<td>
<div [ngClass]="getClass(user)">{{user.score}}</div>
</td>
<td>
<button *ngIf="!isEdit" class="btn btn-primary btn-sm" (click)="editUser(user)">Edit</button>
<button class="btn btn-primary btn-sm btn-sm ml-2" (click)="deleteUser(user)">Delete</button>
</td>
</tr>
</tbody>
</table>
<pagination-controls id="listing_pagination" directionLinks="true" (pageChange)="page = $event"></pagination-controls>

ng-click not working in html table

I am trying to use ng-click inside table but its not working, however outside the table its working fine.
Below is HTML
<table class="table table-striped">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Section</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="product in products">
<td>{{product.ID}}</td>
<td>{{product.Name}}</td>
<td>{{product.Section}}</td>
<td><input type="button" name="name" value="Delete" class="btn btn-danger" ng-click="deleteProduct({{product.ID}});" /></td>
</tr>
</tbody>
</table>
On click of Delete button deleteProduct method doesn't call.
Problems :
You are traversing through a collection/object named rules and getting single item as rule. So you should access each single items properties with rule.yourProperty. How did product come here?
You don't need any double curly braces to for ng-click function parameters. Simply pass the property of the object. ng-click directive works this way.
HTML :
<div ng-controller="mainCtrl">
<table class="table table-striped">{{msg}}
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Section</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="rule in rules">
<td>{{rule.ID}}</td>
<td>{{rule.Name}}</td>
<td>{{rule.Section}}</td>
<td><input type="button" name="name" value="Delete" class="btn btn-danger" ng-click="deleteProduct(rule.ID)" /></td>
</tr>
</tbody>
</table>
</div>
angular :
angular.module('myapp', []).controller('mainCtrl', ['$scope', function($scope){
var data = [
{
ID : "1",
Name : "A1",
Section : "A1"
},
{
ID : "2",
Name : "A2",
Section : "A2"
},
{
ID : "3",
Name : "A3",
Section : "A3"
},
{
ID : "4",
Name : "A4",
Section : "A4"
}
];
$scope.rules = data;
$scope.deleteProduct = function(id){
alert(id);
// delete your item here
};
}]);
jsFiddle
Try this:-
ng-click="deleteProduct(product.ID)"

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