How to expand a table using html / angular / javascript - javascript

I'm new in angular 2+. I have created a table in angular web api. I need to do it like this - when I press the button (icon) expand the table with the data from my web api.
I did it that way but it's not working. Could someone help me with a solution?
app.component.html
<div class="card-body">
<table datatable class="table table-striped table-bordered hover" [dtOptions]="dtOptions" style="width:100%">
<thead>
<tr>
<th width="2%" class="text-center"></th>
<th width="8%" class="text-center">Name</th>
<th width="8%" class="text-center">Price</th>
</tr>
</thead>
<tbody>
<tr *ngIf="empty">
<td colspan="8" class="text-center" translate>shared.table.not-found</td>
</tr>
<tr *ngFor="let product of products; index as i" (click)="onSelectLine(i)"
[ngClass]="{'tr-selected': selectedIndex === i}">
<td class="text-left">
<a type="button" (click)="onProductComponent(product)">
<i class="fa fa-chevron-right"></i>
</a>
</td>
<td class="text-left">{{product.name}}</td>
<td class="text-left">{{product.price}}</td>
</tr>
<thead>
<tr>
<td colspan="12" >
<div *ngIf="isShown" class="row container-fluid" id="divshow" >
<td class="text-left">{{product.name}}</td>
<td class="text-left">{{product.price}}</td>
</div>
</td>
</tr>
</thead>
</tbody>
</table>
</div>
</div>
app.component.ts
isShown = false;
onProductComponent(product: Product) {
this.isShown = ! this.isShown;
this._product = product;
this.productComponentService.getProduct(this._product.id)
.subscribe(element => {
});
}
It would be like this

You can add isShown property to every product. And change only that value.
If you want to have multiple rows opened than just remove the this.products.map() part from onProductComponent
public products = [
{ name: "Product 1", price: 101, isShown: false },
{ name: "Product 2", price: 102, isShown: false },
{ name: "Product 2", price: 103, isShown: false },
{ name: "Product 3", price: 104, isShown: false },
{ name: "Product 5", price: 105, isShown: false }
];
onProductComponent(product) {
this.products.map(p => {
if (product !== p) {
p.isShown = false;
}
});
product.isShown = !product.isShown;
}
This will lead to change in HTML because you can move the hidden section inside of the loop. Because you don't need to save product.
<div class="card-body">
<table datatable class="table table-striped table-bordered hover" style="width:100%">
<thead>
<tr>
<th width="2%" class="text-center"></th>
<th width="8%" class="text-center">Name</th>
<th width="8%" class="text-center">Price</th>
</tr>
</thead>
<tbody>
<ng-container *ngFor="let product of products; index as i">
<tr>
<td class="text-left">
<a type="button" (click)="onProductComponent(product)">
<i class="fa fa-chevron-right"></i>
Open
</a>
</td>
<td class="text-left">{{product.name}}</td>
<td class="text-left">{{product.price}}</td>
</tr>
<thead>
<tr>
<td colspan="12">
<div *ngIf="product.isShown" class="row container-fluid" id="divshow">
<span class="text-left">{{product.name}}</span>
<span class="text-left">{{product.price}}</span>
</div>
</td>
</tr>
</thead>
</ng-container>
</tbody>
</table>
</div>
You can check a working example here

Related

How to get one column on row click with javascript?

<table class="spectrum-Table spectrum-Table--sizeM spectrum-Table--spacious" id="tblMain">
<thead class="spectrum-Table-head">
<tr>
<th class="spectrum-Table-headCell is-sortable" aria-sort="none">
Case Id
</th>
<th class="spectrum-Table-headCell">
Construction Permit Request Id
</th>
<th class="spectrum-Table-headCell is-sortable is-sorted-desc" aria-sort="descending" tabindex="0">
Type
</th>
<th class="spectrum-Table-headCell is-sortable is-sorted-desc" aria-sort="descending" tabindex="0">
Apartments Quantity
</th>
<th class="spectrum-Table-headCell is-sortable is-sorted-desc" aria-sort="descending" tabindex="0">
Commectial Properties Quantity
</th>
<th class="spectrum-Table-headCell is-sortable is-sorted-desc" aria-sort="descending" tabindex="0">
Is Construction Complete?
</th>
</tr>
</thead>
<tbody class="spectrum-Table-body">
#foreach (var permit in Model)
{
<tr class="spectrum-Table-row" data-id="#permit.Id" onclick="showInfoOnClick(#permit.Id)">
<td class="spectrum-Table-cell" tabindex="0">#permit.CaseId</td>
<td class="spectrum-Table-cell" tabindex="0" id=constructionid>#permit.ContructionPermitRequestId</td>
<td class="spectrum-Table-cell" tabindex="0">#permit.Type</td>
<td class="spectrum-Table-cell" tabindex="0">#permit.ApartmentsQty</td>
<td class="spectrum-Table-cell" tabindex="0">#permit.CommercialPropertiesQty</td>
<td class="spectrum-Table-cell" tabindex="0">#permit.IsContructionCompleted</td>
</tr>
}
</tbody>
</table>
<br />
<br />
<overlay-trigger type="modal" placement="none" id="dialog">
<sp-dialog-wrapper slot="click-content"
headline="Use Permit Request"
confirm-label="Open Construction Permit"
secondary-label="Replace"
cancel-label="Cancel"
footer="Content for footer"
size="l"
underlay>
Content of the dialog
</sp-dialog-wrapper>
<div slot="trigger"
onclick="
const overlayTrigger=this.parentElement;
const dialogWrapper=overlayTrigger.clickContent;
function handleEvent({type}) {
dialogWrapper.open = false;
dialogWrapper.removeEventListener('confirm', handleEvent);
dialogWrapper.removeEventListener('secondary', handleEvent);
dialogWrapper.removeEventListener('cancel', handleEvent);
}
dialogWrapper.addEventListener('confirm', openConstruction);
dialogWrapper.addEventListener('secondary', handleEvent);
dialogWrapper.addEventListener('cancel', handleEvent);
"></div>
</overlay-trigger>
*This is a ASP.NET project. I'm doing some kind of a basic register project. And I got trying to get ConstructionId from my table, and I need it to display my modal with the right id. I got somewhat close with giving my an id, but i kept on getting only 1 as value, where it should be dependent on what row i click on. *

How do I add enitre row of data of an table in an array of objects?

I'm trying to add entire row data of a table to my array of object whenever someone click on anchor tag named view/edit. I wrote some logic but I guess I'm missing something.
index.html file
<table class="table">
<thead>
<tr>
<th scope="col">User Name</th>
<th scope="col">Order No</th>
<th scope="col">Order Date</th>
<th scope="col">Status</th>
<th scope="col">Total Amount</th>
<th scope="col">Total Qty</th>
<th scope="col">Total Products</th>
<th scope="col">View/Edit</th>
</tr>
</thead>
<tbody>
<tr>
<td id="user-name">Alice</td>
<td id="order-no">8536</td>
<td id="order-date">13/07/2020</td>
<td id="status" >Pending</td>
<td id="total-amount" >1800</td>
<td id="total-qty" >3</td>
<td id="total-products" >3</td>
<td>
<a id="view-data" href="#" class="text-success stretched-link">View/Edit</a>
</td>
</tr>
<tr>
<td id="user-name">Michael</td>
<td id="order-no">4354</td>
<td id="order-date">12/07/2020</td>
<td id="status" >Approved</td>
<td id="total-amount" >1500</td>
<td id="total-qty" >2</td>
<td id="total-products" >2</td>
<td>
<a id="view-data" href="#" class="text-success stretched-link">View/Edit</a>
</td>
</tr>
</tbody>
</table>
app.js file
let usersData = []; // array to store user table objects
$('#view-data').click(function(){
var row = $(this).closest("tr");
// userData object to store data from a table complete row
var userData = {
"order_no": row.find('#order-no').text(),
"order_date": row.find('#order-date').text(),
"totalproducts": row.find('#total-products').text(),
"total_amount": row.find('#total-amount').text(),
"total_qty": row.find('#total-qty').text(),
"status": row.find('#status').text(),
"user_name": row.find('#user-name').text(),
}
usersData.push(userData)
console.log(usersData)
})
Note: I should use button instead a tag but I'm using anchor tag because it'll open another tab in future for same data manipulation.
Selector need to change to class (view-data) instead of id
let usersData = []; // array to store user table objects
$('.view-data').click(function(ev){
ev.preventDefault();
ev.stopPropagation();
var row = $(ev.currentTarget).closest("tr");
// userData object to store data from a table complete row
var userData = {
"order_no": row.find('#order-no').text(),
"order_date": row.find('#order-date').text(),
"totalproducts": row.find('#total-products').text(),
"total_amount": row.find('#total-amount').text(),
"total_qty": row.find('#total-qty').text(),
"status": row.find('#status').text(),
"user_name": row.find('#user-name').text(),
}
usersData.push(userData)
console.log(userData)
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table class="table">
<thead>
<tr>
<th scope="col">User Name</th>
<th scope="col">Order No</th>
<th scope="col">Order Date</th>
<th scope="col">Status</th>
<th scope="col">Total Amount</th>
<th scope="col">Total Qty</th>
<th scope="col">Total Products</th>
<th scope="col">View/Edit</th>
</tr>
</thead>
<tbody>
<tr>
<td id="user-name">Alice</td>
<td id="order-no">8536</td>
<td id="order-date">13/07/2020</td>
<td id="status" >Pending</td>
<td id="total-amount" >1800</td>
<td id="total-qty" >3</td>
<td id="total-products" >3</td>
<td>
<a id="view-data" href="#" class="view-data text-success stretched-link">View/Edit</a>
</td>
</tr>
<tr>
<td id="user-name">Michael</td>
<td id="order-no">4354</td>
<td id="order-date">12/07/2020</td>
<td id="status" >Approved</td>
<td id="total-amount" >1500</td>
<td id="total-qty" >2</td>
<td id="total-products" >2</td>
<td>
<a id="view-data" href="#" class="view-data text-success stretched-link">View/Edit</a>
</td>
</tr>
</tbody>
</table>

how to extract attribute value using javascript

I'm having trouble extracting "href" value of "LINE_NAME" (expected value is "www.link.com").
It's a content of a table which always has only header + 1 row, column order and number can be different though. "LINE_NAME" column is always there in the exact format
this call returns "undefined":
var url = $('.a-IRR-table tbody').children().eq(2).find('td[headers="LINE_NAME"] a').attr('href');
console.log(url);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table summary="Search Results" class="a-IRR-table" id="79" style="margin-top: -45px;">
<tbody>
<tr>
<th class="a-IRR-header"><a class="a-IRR-headerLink" data-column="625" role="presentation">Av</a>
<div class="t-fht-line"></div>
</th>
<th class="a-IRR-header"><a class="a-IRR-headerLink" data-column="437" role="presentation">CS</a>
<div class="t-fht-line"></div>
</th>
<th class="a-IRR-header"><a class="a-IRR-headerLink" data-column="167" role="presentation">LINE_NAME</a>
<div class="t-fht-line"></div>
</th>
<tr>
<td class=" u-tC" headers="AVAILABLE" aria-labelledby="AVAILABLE">
<img src="...png" alt="Av_ICON" title="Available" style="width:16px; padding-top:1px;">
</td>
<td class=" u-tL" headers="STATUS" aria-labelledby="STATUS">online</td>
<td class=" u-tL" headers="LINE_NAME" aria-labelledby="LINE_NAME">
url_link
</td>
</tr>
</tbody>
</table>
Your problem is that .eq() function from jQuery is 0 based, so to get the 2nd element you have to use .eq(1).
var url = $('.a-IRR-table tbody').children().eq(1).find('td[headers="LINE_NAME"] a').attr('href');
console.log(url)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table summary="Search Results" class="a-IRR-table" id="79">
<tbody>
<tr>
<th class="a-IRR-header"><a class="a-IRR-headerLink" data-column="625" role="presentation">Av</a><div class="t-fht-line"></div></th>
<th class="a-IRR-header"><a class="a-IRR-headerLink" data-column="437" role="presentation">CS</a><div class="t-fht-line"></div></th>
<th class="a-IRR-header"><a class="a-IRR-headerLink" data-column="167" role="presentation">LINE_NAME</a><div class="t-fht-line"></div></th>
<tr>
<td class=" u-tC" headers="AVAILABLE" aria-labelledby="AVAILABLE">
<img src="...png" alt="Av_ICON" title="Available" style="width:16px; padding-top:1px;">
</td>
<td class=" u-tL" headers="STATUS" aria-labelledby="STATUS">online</td>
<td class=" u-tL" headers="LINE_NAME" aria-labelledby="LINE_NAME">
url_link
</td>
</tr>
</tbody>
</table>
var url = $('.a-IRR-table').find('td[headers="LINE_NAME"] a').attr('href');
console.log('url = ' + url);
should work

How to reorder columns in angularjs

this is my html
<table class="table table-bordered table-responsive mar0 tablebg table-width">
<thead>
<tr>
<th ng-repeat="field in jsonData.fieldsNameList track by $index" class="field-name">
<span ng-click="onclicktableHeader(field)">{{field.fieldName}}</span>
<span class="check-align" ng-if="field.fieldType=='field'"><i ng-click="enableFilter(field)" tooltip="Enable Filtering" tooltip-append-to-body="true" tooltip-placement="up" ng-class="{'fa fa-check-square-o': !field.enableFiltering, 'fa fa-plus-circle': field.enableFiltering}"></i></span>
<span class="check-align" ng-if="field.fieldType=='field'"><i ng-click="enableSort(field)" tooltip="Enable Sorting" tooltip-append-to-body="true" tooltip-placement="up" ng-class="{'fa fa-check-square-o': !field.enableSorting, 'fa fa-plus-circle': field.enableSorting}"></i></span>
<i ng-click="deleteColumn(field)" class="fa fa-times"></i>
</th>
</tr>
</thead>
<tbody>
<tr>
<td ng-repeat="field in jsonData.fieldsNameList track by $index">
{{field.fieldName}}
</td>
</tr>
<tr>
<td ng-repeat="field in jsonData.fieldsNameList track by $index">
{{field.fieldName}}
</td>
</tr>
<tr>
<td ng-repeat="field in jsonData.fieldsNameList track by $index">
{{field.fieldName}}
</td>
</tr>
</tbody>
</table>
and this is my array which i am repeating
$scope.jsondata.fieldsNameList = [{ "enableFiltering": false, "enableSorting": false, "fieldId": "56adc5276e65744a03ed0c00", "fieldName": "fnamev2", "fieldType": "field" }, { "enableFiltering": false, "enableSorting": false, "fieldId": "56adc5276e65744a03ed0d21", "fieldName": "fnamev1", "fieldType": "field" }];
i want to reorder the columns of table by dragging it left and right, how to do this, and is their any way using angularjs or javascript

Angular Controller Scope

I am new to Angular JS and I am binding following JSON to my HTML:
{
"CompanyName": "Company Ltd.",
"Products": [
{
"ProductId": 1245,
"Name": "Trial",
"ProductItems": [
{
"ProductId": 1254,
"ProductItemName": "Service 1",
"ProductItemType": "Service"
},
{
"ProductId": 7789,
"ProductItemName": "Service 2",
"ProductItemType": "Service"
}
]
}
]
}
My HTML is a table basically like following:
<table ng-controller="ProductController as productCtrl">
<thead>
<tr>
<th id="CompanyName">
<h1 class="h1">{{productCtrl.data.CompanyName}}</h1>
</th>
<th ng-repeat="product in productCtrl.data.Products">
<h2>{{product.Name}}</h2>
<h3>
<span>{{product.ProductPrice}}</span>
<span> {{product.CurrencySymbol}} / {{product.PriceTimePeriod}} </span>
</h3>
</th>
</tr>
</thead>
<tbody>
<!-- Need `product` here so that I can loop on their ProductItems -->
<tr ng-repeat="item in product.ProductItems">
<td>{{item.ProductItemName}}</td>
<td>{{item.Amount}}</td>
</tr>
</tbody>
<tfoot>
</tfoot>
</table>
Foreach Product in Products I am generating a column in thead and for each of Item in ProductItems of each Product I want to generate a row in tbody but since loop over all products is limited to thead I cannot bind ProductItems properly.
Any suggestion as how to overcome this?
Can you check this
<tr ng-repeat="item in productCtrl.data.Products.ProductItems">
<td>{{item.ProductItemName}}</td>
<td>{{item.Amount}}</td>
</tr>
When replaced to div it will be like this. Anyway you will have to style it to give a table structure
<div ng-controller="ProductController as productCtrl">
<div id="CompanyName">
<h1 class="h1">{{productCtrl.data.CompanyName}}</h1>
</div>
<div ng-repeat="product in productCtrl.data.Products">
<h2>{{product.Name}}</h2>
<h3>
<span>{{product.ProductPrice}}</span>
<span> {{product.CurrencySymbol}} / {{product.PriceTimePeriod}} </span>
</h3>
</div>
<!-- Need `product` here so that I can loop on their ProductItems -->
<div ng-repeat="item in product.ProductItems">
<span>{{item.ProductItemName}}</span>
<span>{{item.Amount}}</span>
</div>
</div>
Ideally the maximum product items count any product can have in the json has to be known before rendering the tbody rows, as a row will be created for each productitem of a product.
Check out this plunker sample: http://plnkr.co/edit/Pl6t69ShUje0WLQDWEdU?p=preview
The sample logic for rendering given below.
<table ng-controller="tblCntrl" class="table">
<thead>
<tr>
<th colspan="2" ng-repeat="product in json.Products">{{product.Name}}</th>
</tr>
<tr>
<th ng-repeat-start="product in json.Products">Item name</th>
<th ng-repeat-end>Amount</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="item in items">
<td ng-repeat-start="product in json.Products">{{product.ProductItems[$parent.$index].ProductItemName}}</td>
<td ng-repeat-end>{{product.ProductItems[$parent.$index].amount}}</td>
</tr>
</tbody>
</table>

Categories

Resources