I try to create simple bootstrap table in Angular 7.2 project however it does not use any styles. I just see raw text. Any ideas why it does not work?
component.ts:
elements: any = [
{id: 1, first: 'Mark', last: 'Otto', handle: '#mdo'},
{id: 2, first: 'Jacob', last: 'Thornton', handle: '#fat'},
{id: 3, first: 'Larry', last: 'the Bird', handle: '#twitter'},
];
headElements = ['ID', 'First', 'Last', 'Handle'];
component.html:
<table mdbTable striped="true">
<thead>
<tr>
<th *ngFor="let head of headElements" scope="col">{{head}} </th>
</tr>
</thead>
<tbody>
<tr mdbTableCol *ngFor="let el of elements">
<th scope="row">{{el.id}}</th>
<td>{{el.first}}</td>
<td>{{el.last}}</td>
<td>{{el.handle}}</td>
</tr>
</tbody>
</table>
angular.json:
"styles": [
"src/styles.scss",
"node_modules/bootstrap/dist/css/bootstrap.min.css",
"src/assets/sass/paper-kit.scss",
"src/assets/css/demo.css",
"src/assets/css/nucleo-icons.css"
],
"scripts": [
"node_modules/jquery/dist/jquery.slim.min.js",
"node_modules/popper.js/dist/umd/popper.js",
"node_modules/bootstrap/dist/js/bootstrap.min.js"
],
styles.scss:
#import "~bootstrap/dist/css/bootstrap.css";
app.modules.ts:
import { NgbModule } from '#ng-bootstrap/ng-bootstrap';
...
imports: [
...,
NgbModule.forRoot(),
...
],
...
bootstrap: [AppComponent]
To use Bootstrap table, just add the class table, for striped, add table-striped
<table class="table table-striped">
</table
But your HTML shows you have used mdbootstrap. You need to install angular-bootstrap-md
npm i angular-bootstrap-md
Related
I am trying to fill my table HTML using an API, however, I want to fill the given HTML table into a column instead of a row to look like the following image layout, but however, I am getting filled as row as you can see in my second image. is there a way to convert it into a column-based filling?
row fill
const arr = [
{
"demo": [
{
"_id": "T0810",
"title": "Historian",
"tags": [
"demo"
],
"queries": [],
},
{
"_id": "T0817",
"title": "book",
"tags": [
"demo"
],
"queries": [],
},
],
"demo_2": [
{
"_id": "T0875",
"title": "Program",
"tags": [
"demo_2",
"Control"
],
"queries": [],
},
{
"_id": "T0807",
"title": "Interface",
"tags": [
"demo_2"
],
"queries": [],
}
]
}
]
const keys = Object.keys(arr[0]);
export default function Demo() {
return (
<div className="wrapper">
<table className="table">
<thead>
<tr>
{keys.map((i) => (
<th key={i}>
<div className="column">
<div className="header">{i}</div>
</div>
</th>
))}
</tr>
</thead>
<tbody>
{keys.map((key) => (
<tr key={key}>
{arr[0][key].map((item) => (
<td key={item._id}>
<div className="column">
<div className="option">{item._id}</div>
</div>
</td>
))}
</tr>
))}
</tbody>
</table>
</div>
);
}
It's only slightly more involved than what you have put together. The first thing you have to consider is that your table will have as many rows as the lengthiest key, so if demo array has 2 element and demo_2 has 6 elements, the table will have 6 rows even though there will be nothing for 3 of those rows to display for demo.
As such your top level loop will have to loop not through keys but through a number representing the length of the lengthiest key, if that makes sense. So apart from getting the keys, you will need something like this:
const max_rows = keys.reduce((acc, cur) => {
if (arr[0][cur].length > acc) return arr[0][cur].length;
else return acc;
}, 0);
Then your nested loop will look like this:
<table className="table">
<thead>
<tr>
{keys.map((i) => (
<th key={i}>
<div className="column">
<div className="header">{i}</div>
</div>
</th>
))}
</tr>
</thead>
<tbody>
{Array(max_rows)
.fill(0)
.map((key, index) => (
<tr key={index}>
{keys.map((item, ind) => (
<td key={ind}>
<div className="column">
{arr[0][item][index] ? (
<div className="option">
{arr[0][item][index]._id}
</div>
) : null}
</div>
</td>
))}
</tr>
))}
</tbody>
</table>
Here is a Sandbox: https://codesandbox.io/s/adoring-wave-5fub7?file=/src/App.js
How to fetch and display data in ASP.net core using React js Line 26: 'cusList' is not defined no-undef error is coming up.
import React, { Component } from 'react';
import './Map';
export class FetchCustomer extends Component {
static displayName = FetchCustomer.Name;
constructor(props) {
super(props);
this.state = { customers: [], loading: true };
}
render() {
let contents = this.state.loading
? <p><em>Loading...</em></p>
: this.renderCustomerTable(this.state.cusList);
return <table className='table'>
<thead>
<tr>
<th></th>
<th>Id</th>
<th>Name</th>
<th>Address</th>
</tr>
</thead>
<tbody>
{cusList.map(cus =>
<tr key={cus.Id}>
<td></td>
<td>{cus.Id}</td>
<td>{cus.Name}</td>
<td>{cus.Address}</td>
<td>
<a className="action" onClick={(id) => this.handleEdit(cus.Id)}>Edit</a> |
<a className="action" onClick={(id) => this.handleDelete(cus.Id)}>Delete</a>
</td>
</tr>
)}
</tbody>
</table>;
fetch('api/Customer/Index')
.then(response => response.json())
.then(data => { this.setState({ cusList: data, loading: false }) });
}
}
Following changes are needed in your code...
In your constructor change the last line of code with following:
this.state = { customers: [], loading: true, cusList: [] };
And in the "tbody" section please change the code to:
<tbody>
{this.state.cusList.map(cus =>
<tr key={cus.Id}>
<td></td>
<td>{cus.Id}</td>
<td>{cus.Name}</td>
<td>{cus.Address}</td>
<td>
<a className="action" onClick={(id) => this.handleEdit(cus.Id)}>Edit</a> |
<a className="action" onClick={(id) => this.handleDelete(cus.Id)}>Delete</a>
</td>
</tr>
)}
</tbody>
This should work.
Also it's pretty clear from the error itself about what you are missing.
Hope it helps.
I am defining a bootstrap table in HTML:
<table data-toggle="table" data-url="/api/myapi" data-data-field="objects" data-total-field="num_results" data-side-pagination="server">
<thead>
<tr>
<th>name</th>
<th>email</th>
</tr>
</thead>
</table>
The API call is being made and JSON is getting returned:
{
"num_results": 1,
"objects": [
{
"company": "My Company",
"create_date": "2018-07-04T06:29:06.290000",
"email": "test#gmail.com",
"id": 1,
"name": "Joe Bloggs"
}
],
"page": 1,
"total_pages": 1
}
I would expect that specifying data-data-field="objects" would instruct Bootstrap-Table to iterate the objects array. Alas, it doesn't seem to work..
Any ideas?
Appears to be a bug in Bootstrap-Table where it ignores dataField unless pagination is enabled. Bug report.
Fixed like this:
<table data-toggle="table" data-url="/api/myapi" data-data-field="objects" data-total-field="num_results" data-pagination=true data-side-pagination="server" data-id-field="id">
I'm using .net core 2 as backend and Angular2 as frontend for this app. I encountered the issue where I need to check whether price difference between products in other shops are greater than price in BaseEshop for e.g. 10%, if yes then I need to change that '' background-color to red. There are like 100 products in each eshop which I need to check and change the background color
What is the best way to do it. This is my code:
import { ProductService } from './../../services/product.service';
import { Product } from './../../models/product';
import { Component, OnInit } from '#angular/core';
import { ToastyService } from 'ng2-toasty';
import { Router, ActivatedRoute } from '#angular/router';
import { Price } from '../../models/price';
#Component({
templateUrl: 'product-list.html'
})
export class ProductListComponent implements OnInit {
product: Product[];
prices: Price[];
constructor(private productService: ProductService) { }
ngOnInit() {
this.productService.getProducts().subscribe(product => this.product = product);
this.productService.getPrices().subscribe(prices => this.prices = prices);
}
}
Here is html file
<table class="table">
<thead>
<tr>
<th>Code</th>
<th>Name</th>
<th>BaseEshop</th>
<th>Eshop2</th>
<th>Eshop3</th>
<th>Eshop4</th>
<th>Eshop5</th>
<th></th>
</tr>
</thead>
<tbody>
<tr *ngFor="let p of product" >
<td>{{ p.code }}</td>
<td >{{ p.name }}</td>
<ng-container *ngFor="let pr of p.prices">
<td *ngIf=" pr.eshopId==1" >{{ pr.value }}</td>
<td *ngIf=" pr.eshopId==2" >{{ pr.value }} <span class='glyphicon glyphicon-arrow-up'></span></td>
<td *ngIf=" pr.eshopId==3" >{{ pr.value }}</td>
<td *ngIf=" pr.eshopId==4" >{{ pr.value }}</td>
<td *ngIf=" pr.eshopId==5" >{{ pr.value }}</td>
</ng-container>
</tr>
</tbody>
</table>
This what my json looks like
{
"id": 218374,
"name": "\"Dell Inspiron 15 5578 Silver, 15.6 \"\", Touchscreen, Full HD, 1920 x 1080 pixels, Gloss, Intel Core i5, i5-7200U, 8 GB, DDR4, SSD 256 GB, Intel HD, Linux, 802.11ac, Bluetooth version 4.2, Keyboard language English, Keyboard backlit\"",
"code": "272771020",
"edited": false,
"prices": [
{
"id": 448664,
"value": "929.79",
"updatedAt": "2018-04-16T22:41:59",
"eshopId": 1
},
{
"id": 490139,
"value": "811.00",
"updatedAt": "2018-04-20T11:42:26",
"eshopId": 2
},
{
"id": 490789,
"value": "781.00",
"updatedAt": "2018-04-20T11:22:42",
"eshopId": 3
}
]
}
You can do this:
<td *ngIf=" pr.eshopId==1" [ngClass]="{'RedClass': pr.value > 500}">{{ pr.value }}</td>
Instead of pr.value > 500 you can add your logic to work out the %. If true the class is applied, false and no class is applied.
You have 2 options: [ngStyle] or [ngClass]. I would prefer ngClass whenever you can use it. What it does is it applies certain css class to an element if some condition is met.
ref:https://angular.io/guide/template-syntax
I'm trying to populate rows in an HTML table using the Vue framework - the data is as seen below:
TeamRows: [
{ team: 'One', times: ['1', '2', '3'] },
{ team: 'Two', times: ['4', '5', '6'] },
{ team: 'Three', times: ['7', '8', '9'] }
]
I've tried following this codepen, but with bad result - this is my HTML:
<tbody>
<tr v-for="(row, rindex) in teamRows">
<td>{{rindex}}</td>
<template>
<cell v-for="(value, vindex) in row" :value="value" :vindex="vindex" :rindex="rindex"></cell>
</template>
</tr>
</tbody>
</table>
<template id="template-cell">
<td>{{ value }}</td>
</template>
And this is the Vue component:
Vue.component('cell', {
template: '#template-cell',
name: 'row-value',
props: ['value', 'vindex', 'rindex']
});
I would like the team to go in the first column in a row and the times to follow along in as many columns as there are times. Hope someone with more Vue knowledge is able to help me out here. Cheers.
Turns out the reason is you're using in-DOM template and browser moves unknown cell element above the v-for, and Vue can't access row value anymore: https://v2.vuejs.org/v2/guide/components.html#DOM-Template-Parsing-Caveats
A solution without cell component, just with inline cell elements, works fine. Also, template wrapper is not needed in a table template:
new Vue({
el: '#app',
data: {
teamRows: [
{ team: 'One', times: ['1', '2', '3'] },
{ team: 'Two', times: ['4', '5', '6'] },
{ team: 'Three', times: ['7', '8', '9'] }
]
}
});
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<div id="app">
<table>
<tbody>
<tr v-for="row in teamRows" :key="row.team">
<td>{{ row.team }}</td>
<td v-for="time in row.times">{{ time }}</td>
</tr>
</tbody>
</table>
</div>
Also, as a result of a discussion, you can still use a component if you wrap your table into another component for example, so that browser don't interfere and Vue has a chance to render everything properly:
new Vue({
el: '#app',
data: {
teamRows: [
{ team: 'One', times: ['1', '2', '3'] },
{ team: 'Two', times: ['4', '5', '6'] },
{ team: 'Three', times: ['7', '8', '9'] }
]
},
components: {
'mytable': {
template: `<table>
<tbody>
<tr v-for="row in rows" :key="row.team">
<td>{{ row.team }}</td>
<cell v-for="time in row.times" :value="time" :key="time"></cell>
</tr>
</tbody>
</table>`,
props: ['rows'],
components: {
'cell': {
template: `<td>{{ value }}</td>`,
props: ['value'],
}
}
}
}
});
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<div id="app">
<mytable :rows="teamRows"></mytable>
</div>