import React from "react";
import {
Button,
Form,
FormGroup,
Label,
Input,
FormText,
Row
} from "reactstrap";
import Icon from "react-icons-kit";
import { filter } from "react-icons-kit/fa/filter";
import { pencil, bin, search } from "react-icons-kit/icomoon";
import { ic_delete, ic_create } from "react-icons-kit/md";
import { Link } from "react-router-dom";
import { activeStyle } from "../projects/Projects.css";
import {
orange,
contentStyle,
displayContainer,
pageHeading,
hrStyle,
buttonStyle,
floatRight1,
exampletable,
savebtn1,
bankdiv,
btnstyle
} from "../Layout.css";
import { hyperLink } from "../settings/LayoutSettings.css";
import { Header } from "../Header";
import { Footer } from "../Footer";
import $ from "jquery";
var result = [];
var URL = "http://localhost:3033/";
var parsed = "";
export class ClaimList extends React.Component {
constructor() {
super();
this.state = {
data: []
};
}
componentDidMount() {
this.Claimlist();
}
Claimlist() {
alert("called");
$.ajax({
url: URL + "/ClaimList",
type: "GET",
dataType: "json",
ContentType: "application/json",
success: function(parsed) {
parsed = JSON.stringify(parsed);
console.log(parsed);
for (var x in parsed) {
result.push(parsed[x]);
}
result = $.parseJSON(parsed);
data = JSON.stringify(data);
this.setState(result);
console.log("hello ramesh");
}.bind(this),
error: function(jqXHR) {
console.log(jqXHR);
}.bind(this)
});
}
renderProducts() {
return this.state.result.map(product => {
return (
<tr>
<td>{product.ID}</td>
<td>{product.ExpenseName}</td>
<td>{product.Amount}</td>
</tr>
);
});
}
render() {
return (
<div>
<table>
<tbody>
{this.state.result.map(function(item, key) {
return (
<tr key={key.id}>
<td>{item.ID}</td>
<td>{item.ExpenseName}</td>
<td>{item.Amount}</td>
<td>{item.Description}</td>
</tr>
);
})}
</tbody>
</table>
<Header />
<div className={displayContainer}>
<p className={pageHeading}>Claims</p>
<hr className={hrStyle} />
<span className={floatRight1}>
<form class="form-row" method="GET">
<input type="search" placeholder="Search" />
<div
class="dropdown"
style={{ position: "relative", left: "-1vw" }}
>
<button
class="btn btn-outline-light"
type="button"
id={btnstyle}
data-toggle="dropdown"
aria-haspopup="true"
aria-expanded="false"
>
<Icon icon={filter} />
</button>
<div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
<a class="dropdown-item">Employee ID</a>
<a class="dropdown-item">Expense Title</a>
<a class="dropdown-item">Date</a>
<a class="dropdown-item">Amount</a>
</div>
</div>
</form>
</span>
<table class="table table-bordered table-striped table-responsive-md">
<thead>
<tr className={orange}>
<th>Employee ID</th>
<th>Employee Name</th>
<th>Expense Title</th>
<th>Description</th>
<th>Amount</th>
<th>Date</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{/* {this.MyTableGrid()} */}
{this.renderProducts()}
</tbody>
</table>
<div
className={bankdiv}
style={{ marginTop: "7vw", marginLeft: "-7.7vw" }}
>
<Link to="/AddClaims">
<button className="btn btn-outline-warning">Add New Claim</button>
</Link>
</div>
</div>
<Footer />
</div>
);
}
}
I'm unable to fetch the data from json and map it into the datagrid. I'm using reactjs and json to get the values from the backend(go).localhost:3033 is my go server and mysql is my database.
I'm getting an error as
Uncaught TypeError: Cannot read property 'map' of undefined
maybe by simply set a default value for result in your constructor that for the moment is undefined in the first render of your class :
constructor() {
super();
this.state = {
data: [],
result: []
};
}
Although as #Jitendra suggest, you can use JSX syntax
render() {
return {this.state.result && <Fragment> ... </Fragment>}
}
You needs to check inside render if this.state.result is null or not before mapping it.
render(){
if (!this.state.result)
return
else
{do other stuffs}
Related
So I'm trying to make a table that use ngFor for every data in the API. I tried a tutorial in Youtube video and it is working fine. Now I'm trying it with the API given to me, but the problem is the data is not coming out in the table
<!-- Main content -->
<section class="content">
<div class="container-fluid">
<div class="row">
<div class="col-md-12">
<!-- TABLE: LATEST ORDERS -->
<div class="card">
<div class="card-header border-transparent">
<h3 class="card-title">Latest Orders</h3>
<div class="card-tools">
<button type="button" class="btn btn-tool" data-card-widget="collapse">
<i class="fas fa-minus"></i>
</button>
<button type="button" class="btn btn-tool" data-card-widget="remove">
<i class="fas fa-times"></i>
</button>
</div>
</div>
<!-- /.card-header -->
<div class="card-body p-0">
<div class="table-responsive">
<table class="table m-0">
<thead>
<tr>
<th>Order ID</th>
<th>Item</th>
<th>Status</th>
<th>Popularity</th>
</tr>
</thead>
<tbody>
<tr>
<td>OR9842</td>
<td>Call of Duty IV</td>
<td><span class="badge badge-success">Shipped</span></td>
<td>
<div class="sparkbar" data-color="#00a65a" data-height="20">90,80,90,-70,61,-83,63</div>
</td>
</tr>
<tr *ngFor="let campaign of campaigns | async">
<td>{{campaign.id}}</td>
<td>{{campaign.name}}</td>
<td><span class="badge badge-warning">Pending</span></td>
<td>
<div class="sparkbar" data-color="#f39c12" data-height="20">90,80,-90,70,61,-83,68</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- /.table-responsive -->
</div>
<!-- /.card-body -->
<div class="card-footer clearfix">
</div>
<!-- /.card-footer -->
</div>
<!-- /.card -->
</div>
<!-- /.col -->
</div> <!-- /.row -->
campaign.component.ts
import { Component, OnInit } from '#angular/core';
import { GetServiceService } from '../get-service.service';
#Component({
selector: 'app-campaign',
templateUrl: './campaign.component.html',
styleUrls: ['./campaign.component.css']
})
export class CampaignComponent implements OnInit {
campaigns;
constructor(
private campaignService: GetServiceService,
) { }
ngOnInit(): void {
this.campaigns = this.campaignService.getCampaign();
}
}
get-service.service.ts
import { Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http';
#Injectable({
providedIn: 'root'
})
export class GetServiceService {
constructor(
private http: HttpClient
) { }
getCampaign(){
return this.http.get('https://emaillead.aturtoko.id/api/v1/campaign')
}
}
So my expectation is that this code would give out the list of data in my API (ignore the first ). What actually happen is that the table only show the first , which means the data is not showing up on the table.
The error in the console is
ERROR Error: Cannot find a differ supporting object '[object Object]' of type 'object'. NgFor only supports binding to Iterables such as Arrays.
at NgForOf.ngDoCheck (common.js:3184)
at callHook (core.js:2536)
at callHooks (core.js:2495)
at executeCheckHooks (core.js:2427)
at refreshView (core.js:9474)
at refreshComponent (core.js:10636)
at refreshChildComponents (core.js:9261)
at refreshView (core.js:9515)
at refreshEmbeddedViews (core.js:10590)
at refreshView (core.js:9489)
The data in api from postman get is
{
"success": true,
"message": "success",
"data": [
{
"id": 1,
"name": "buattoko"
},
{
"id": 2,
"name": "omnipos"
},
{
"id": 3,
"name": "pluscampaign"
}
]
}
what do I need to do to get the data to the table?
Add pipe and map rxjs operator to transform the result as response.data.
get-service.service.ts
import { map } from 'rxjs/operators';
getCampaign() {
return this.http.get('https://emaillead.aturtoko.id/api/v1/campaign')
.pipe(map((response: any) => response.data));
}
Sample Solution on StackBlitz
I add two react js component in my html, but one not worked
in chrome console i see error in js file in 1 line
import React from 'react'
Uncaught SyntaxError: Unexpected identifier
first js file work correctly, this import React form 'react' i used in our page and this worked correctly
why?
My js file:
import React from 'react'
const Header = (props) => (
<h1>{props.title}</h1>
)
const e = React.createElement;
class BookEditPage extends React.Component {
constructor(props) {
super(props);
this.state = {comments: [],books: []};
}
componentDidMount() {
Promise
.all(
[fetch('/api/comments').then(response => response.json())
,fetch('/api/books').then(response => response.json())])
.then(([comments,books]) => this.setState({comments,books}));
}
render() {
return e(
<React.Fragment>
<Header title={'Books'}/>
<table>
<thead>
<tr>
<th>ID</th>
<th>Book</th>
<th>Author </th>
<th>Genre</th>
</tr>
</thead>
<tbody>
{
this.state.books.map((book, i) => (
<tr key={book.id} >
<td>{book.id}</td>
<td>{book.bookName}</td>
<td>{book.author.authorName +' ' + book.author.authorSurname}</td>
<td>{book.genre.genreName}</td>
</tr>
))
}
</tbody>
</table>
<Header title={'Comments'}/>
<table>
<thead>
<tr>
<th>ID</th>
<th>Book name</th>
<th>Comment body</th>
</tr>
</thead>
<tbody>
{
this.state.comments.map((comment, i) => (
<tr key={i}>
<td>{comment.id}</td>
<td>{comment.book.bookName}</td>
<td>{comment.commentBody}</td>
</tr>
))
}
</tbody>
</table>
</React.Fragment>
)
}
}
const domContainer = document.querySelector('#book-edit-table');
ReactDOM.render(e(BookEditPage), domContainer);
my html file:
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8"/>
<title>Edit book</title>
<style type="text/css">
body {
padding: 50px;
}
label {
display: inline-block;
width: 100px;
}
input:read-only {
background: lightgray;
}
.row {
margin-top: 10px;
}
</style>
</head>
<body>
<div id="like-button"></div>
<div id="book-edit-table"></div>
<script src="https://unpkg.com/react#16/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom#16/umd/react-dom.development.js" crossorigin></script>
<script src="/LikeButton.js"></script>
<script src="/BookEditPage.js"></script>
</body>
</html>
You have to use the babel JSX in order to write jsx.
Delete the first line import React from 'react'
Look at how this fiddle is builded.
I have one small label where i am showing total result count of one table data.below i am using one table,On that i'm showing list of data.when i'm deleting one row in table,table is refreshing but in that label result count is not refreshing.Here is my data..
import { VsnApplicationsServiceProxy, VsnApplicationDto , CreateOrEditVsnApplicationDto } from '#shared/service-proxies/service-proxies';
#Component({
selector: 'vsn-applicationmappings',
templateUrl: './applicationmappings.component.html',
styleUrls: ['./applicationmappings.component.less'],
encapsulation: ViewEncapsulation.None,
animations: [appModuleAnimation()]
})
export class ApplicationMappingsComponent extends AppComponentBase implements OnInit {
applications: any;
constructor(
injector: Injector,
private _vsnApplicationsServiceProxy: VsnApplicationsServiceProxy,
private _activatedRoute: ActivatedRoute,
) {
super(injector);
}
ngOnInit() {
this._vsnApplicationsServiceProxy.getAll("", "", "", "", "", "", "", 0, 100).subscribe((Applications: any) => {
this.applications = Applications.totalCount;
console.log(' application value', Applications.totalCount);
});
}
getVsnApplications(event?: LazyLoadEvent) {
if (this.primengTableHelper.shouldResetPaging(event)) {
this.paginator.changePage(0);
return;
}
this.primengTableHelper.showLoadingIndicator();
this._vsnApplicationsServiceProxy.getAll(
this.filterText,
this.nameFilter,
this.businessNameFilter,
this.vsnApplicationTypeNameFilter,
this.vsnApplicationCategoryNameFilter,
this.vsnApplicationSubCategoryNameFilter,
this.primengTableHelper.getSorting(this.dataTable),
this.primengTableHelper.getSkipCount(this.paginator, event),
this.primengTableHelper.getMaxResultCount(this.paginator, event)
).subscribe(result => {
this.primengTableHelper.totalRecordsCount = result.totalCount;
this.primengTableHelper.records = result.items;
this.primengTableHelper.hideLoadingIndicator();
});
}
reloadPage(): void {
this.paginator.changePage(this.paginator.getPage());
}
createVsnApplication(): void {
this.createOrEditVsnApplicationModal.show();
}
deleteVsnApplication(vsnApplication: VsnApplicationDto): void {
this.message.confirm(
'',
(isConfirmed) => {
if (isConfirmed) {
this._vsnApplicationsServiceProxy.delete(vsnApplication.id)
.subscribe(() => {
this.reloadPage();
this.notify.success(this.l('SuccessfullyDeleted'));
});
}
}
);
}
<div class="col-sm-2">
<div class="box">
<div><br><br>
<h4>{{applications}}</h4>
</div>
<div> <span>
<h6>Applications</h6>
</span></div>
</div>
</div>
<div class="m-content">
<div class="m-portlet m-portlet--mobile">
<div class="m-portlet__body">
<div class="primeng-datatable-container" [busyIf]="primengTableHelper.isLoading">
<p-table #dataTable (onLazyLoad)="getVsnApplications($event)" [value]="primengTableHelper.records"
rows="{{primengTableHelper.defaultRecordsCountPerPage}}" [paginator]="false" [lazy]="true"
[scrollable]="true" ScrollWidth="100%" [responsive]="primengTableHelper.isResponsive"
[resizableColumns]="primengTableHelper.resizableColumns">
<ng-template pTemplate="header">
<tr>
<th style="width: 150px" pSortableColumn="vsnApplicationType.name">
{{l("ApplicationName")}}
<p-sortIcon field="vsnApplication.name"></p-sortIcon>
</th>
<th style="width: 130px"
[hidden]="!isGrantedAny('Pages.Administration.VsnApplicationTypes.Edit', 'Pages.Administration.VsnApplicationTypes.Delete')">
{{l('Actions')}}</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-record="$implicit">
<tr>
<td style="width:150px">
<span class="ui-column-title"> {{l("ApplicationName")}}</span>
{{record.vsnApplication.businessName}}
</td>
<td style="width: 130px"
[hidden]="!isGrantedAny('Pages.Administration.VsnApplications.Edit', 'Pages.Administration.VsnApplications.Delete')">
<div class="btn-group dropdown" dropdown container="body">
<button class="dropdown-toggle btn btn-sm btn-primary" dropdownToggle>
<i class="fa fa-cog"></i><span class="caret"></span> {{l("Actions")}}
</button>
<ul class="dropdown-menu" *dropdownMenu>
<li>
<a href="javascript:;"
(click)="viewVsnApplicationModal.show(record)">{{l('View')}}</a>
</li>
<li>
<a href="javascript:;"
*ngIf="permission.isGranted('Pages.Administration.VsnApplicationTypes.Edit')"
(click)="createOrEditVsnApplicationModal.show(record.vsnApplication.id)">{{l('Edit')}}</a>
</li>
<li>
<a href="javascript:;"
*ngIf="permission.isGranted('Pages.Administration.VsnApplicationTypes.Delete')"
(click)="deleteVsnApplication(record.vsnApplication)">{{l('Delete')}}</a>
</li>
</ul>
</div>
</td>
</tr>
</ng-template>
</p-table>
<div class="primeng-no-data" *ngIf="primengTableHelper.totalRecordsCount == 0">
{{l('NoData')}}
</div>
<div class="primeng-paging-container">
<p-paginator rows="{{primengTableHelper.defaultRecordsCountPerPage}}" #paginator
(onPageChange)="getVsnApplications($event)"
[totalRecords]="primengTableHelper.totalRecordsCount"
[rowsPerPageOptions]="primengTableHelper.predefinedRecordsCountPerPage">
</p-paginator>
<span class="total-records-count">
{{l('TotalRecordsCount', primengTableHelper.totalRecordsCount)}}
</span>
</div>
</div>
</div>
</div>
<createOrEditVsnApplicationModal #createOrEditVsnApplicationModal (modalSave)="getVsnApplications()">
</createOrEditVsnApplicationModal>
<viewVsnApplicationModal #viewVsnApplicationModal></viewVsnApplicationModal>
</div>
When deleting one row, the table is refreshing and showing updated records.but in that result count lable is not refreshing.I searched in stack overflow,I found that we have to give like splice(id,1)
but it is not working,any suggestions would great help..
So, I have been trying to use google-maps and fill my data with marker and show info-window.
For reference see img
But, my goal is to make the page responsive also, i have got many thing done but making infowindow resposnive is a prob.
My goal is to show info-window full screen upon click event. But currently its a stupid.
See img for reference
So, how to make my infowindow to show full screen upon click.
Thanks and appreciate your help.
EDIT:
my code
import React, { Component } from 'react';
import { Map, InfoWindow, Marker, GoogleApiWrapper } from 'google-maps-react';
import DRINKING_WATER_PUMP from './pins/strop3.png'
import ROOFTOP from './pins/strop2.png'
import IRRIGATION_PUMP from './pins/strop1.png'
import PATVAN from './pins/strop5patvan.png'
import MINIGRID from './pins/strop4.png'
import farmer from './pins/user.png'
import axios from 'axios'
import config from './config.js'
import Swal from 'sweetalert2'
const mapStyles = {
width: '100%',
height: '100%',
position:'relative',
display: 'flex',
flexFlow: 'row nowrap',
justifyContent: 'center',
};
class MapList extends Component{
constructor(props) {
super(props);
this.markersRendered = false;
}
shouldComponentUpdate(nextProps, nextState) {
if (JSON.stringify(this.props.places) === JSON.stringify(nextProps.places) && this.markersRendered) {
return false;
}
this.markersRendered = true;
return true;
}
render() {
return (
<span>
{
this.props.places.map((marker, index) => {
let assetType=marker.assetType
let icon={
url:'' ,
anchor: new this.props.google.maps.Point(12,23),
origin: new this.props.google.maps.Point(0,0),
scaledSize: new this.props.google.maps.Size(20,20)
}
switch(assetType){
case 'PATVAN':icon.url=PATVAN; break;
case 'MINIGRID':icon.url=MINIGRID; break;
case 'IRRIGATION_PUMP':icon.url=IRRIGATION_PUMP; break;
case 'DRINKING_WATER_PUMP':icon.url=DRINKING_WATER_PUMP; break;
case 'ROOFTOP':icon.url=ROOFTOP; break;
default: break;
}
return (
<Marker {...this.props} key={index} assetId={marker.assetId} assetType={assetType} icon={icon} position={{lat: parseFloat(marker.lat), lng: parseFloat(marker.lng)}} />
)
})
}
</span>
)
}
}
class MapContainer extends Component {
constructor(props){
super(props)
this.state = {
showingInfoWindow: false, //Hides or the shows the infoWindow
activeMarker: {}, //Shows the active marker upon click
selectedPlace: {'owner':{}} //Shows the infoWindow to the selected place upon a marker
};
this.onMarkerClick=this.onMarkerClick.bind(this)
this.onClose=this.onClose.bind(this)
}
onMarkerClick(props, marker, e){
let url;
switch(props.assetType){
case 'PATVAN':url=config.patvan; break;
case 'MINIGRID':url=config.minigrid; break;
case 'IRRIGATION_PUMP':url=config.irrigation; break;
case 'DRINKING_WATER_PUMP':url=config.drinkingwater; break;
case 'ROOFTOP':url=config.rooftop; break;
default: break;
}
axios({
url:url,
method:'POST',
data:{
assetId:props.assetId
},
headers:{
'Content-Type': 'application/json'
}
}).then((res)=>{
if(res.data.data!==null){
let data=res.data.data
data['assetType']=props.assetType
this.setState({
selectedPlace: data,
activeMarker: marker,
showingInfoWindow: true
});
}
else if(res.data.error!==undefined){
if(res.data.error.errorCode===153){
window.location.href='../login.html?redirect=dashboard';
}
else{
Swal({
type: 'error',
title: 'Oops...',
text: res.data.error.errorMsg,
})
}
}
})
}
onClose(props) {
if (this.state.showingInfoWindow) {
this.setState({
showingInfoWindow: false,
activeMarker: null
});
}
}
render() {
return (
<Map id="map"
mapTypeControl={false}
gestureHandling= {'greedy'}
zoomControl= {false}
streetViewControl={false}
fullscreenControl={false}
google={this.props.google}
zoom={5}
style={mapStyles}
initialCenter={{
lat: 21.5937,
lng: 78.9629
}}
>
<MapList google={this.props.google} places={this.props.datapins} onClick={this.onMarkerClick} />
<InfoWindow className="infoWindowCard"
pixelOffset={new this.props.google.maps.Size(185,310)}
marker={this.state.activeMarker}
visible={this.state.showingInfoWindow}
onClose={this.onClose}
// disableAutoPan={true}
>
<div style={{'overflow':'hidden'}}>
{this.state.selectedPlace.owner.image!=='NA'&&this.state.selectedPlace.owner.image!==null?(
<img src={this.state.selectedPlace.owner.image} alt='farmer' className="infoWindowImg"/>
):(
<img src={farmer} alt='farmer' className="infoWindowImg"/>
)}
<h4 className="infoWindowName" style={{'maxWidth': '262px'}}> {this.state.selectedPlace.owner.name} </h4>
<h6 className="infoWindowName"> Customer ID: {this.state.selectedPlace.id} </h6>
<div>
<ul className="infoWindowDetail">
<li>
<div className="row">
<div className="col-md-2">
<i className="fa fa-calendar" aria-hidden="true"></i>
</div>
<div className="col-md-10">
<span>Installed on {this.state.selectedPlace.dateOfInstallation}</span>
</div>
</div>
</li>
<li>
<div className="row">
<div className="col-md-2">
<i className="fa fa-map-marker" aria-hidden="true"></i>
</div>
<div className="col-md-10">
<span>{this.state.selectedPlace.owner.block}</span>
<p>{this.state.selectedPlace.owner.district}, {this.state.selectedPlace.owner.state} </p>
</div>
</div>
</li>
<li>
<div className="row">
<div className="col-md-2">
<i className="fa fa-tint" aria-hidden="true"></i>
</div>
<div className="col-md-10">
{ this.state.selectedPlace.assetType==='IRRIGATION_PUMP' &&
<div>
<span>Irrigation Pump <b>{this.state.selectedPlace.pumpCapacity} {this.state.selectedPlace.powerType} {this.state.selectedPlace.pumpType}</b></span>
<p>Solar Panel Capacity {this.state.selectedPlace.panelRating} </p>
</div>
}
{ this.state.selectedPlace.assetType==='MINIGRID' &&
<span>Minigrid <b>{this.state.selectedPlace.assetName} </b></span>
}
{ this.state.selectedPlace.assetType==='PATVAN' &&
<div>
<span>Patvan <b>{this.state.selectedPlace.pumpCapacity} {this.state.selectedPlace.powerType} {this.state.selectedPlace.pumpType}</b></span>
<p>Solar Panel Capacity {this.state.selectedPlace.panelRating} </p>
</div>
}
{ this.state.selectedPlace.assetType==='DRINKING_WATER_PUMP' &&
<div>
<span>Drinking Water Pump <b>{this.state.selectedPlace.pumpCapacity} {this.state.selectedPlace.powerType} {this.state.selectedPlace.pumpType}</b></span>
<p>Solar Panel Capacity {this.state.selectedPlace.panelRating} </p>
</div>
}
{ this.state.selectedPlace.assetType==='ROOFTOP' &&
<div>
<span>Rooftop</span>
<p>Solar Panel Capacity {this.state.selectedPlace.panelRating} </p>
</div>
}
</div>
</div>
</li>
</ul>
<div className="portal">
<span>Visit portal</span><a target="_blank" rel="noopener noreferrer" href={ "../all_rms/rmspage.html?ID=" + this.state.selectedPlace.id } ><i className="fa fa-external-link-square" aria-hidden="true"></i></a>
</div>
</div>
</div>
</InfoWindow>
</Map>
);
}
}
export default GoogleApiWrapper({
apiKey: 'MYAPI'
})(MapContainer);
I tried to set a responsive table with angular-datatables (for angular 7) and bootstrap 4 but this is the current aspect of the table:
Current HTML code:
<div class="row">
<div class="col-12">
<div class="table-responsive">
<table datatable [dtOptions]="dtOptions" [dtTrigger]="dtTrigger" class="table table-hover table-bordered">
<thead class="thead-colored thead-primary">
<tr class="text-center">
<th>ID</th>
<th>NICKNAME</th>
<th>EMAIL</th>
<th>REGISTRO</th>
<th>ESTATUS</th>
<th>ALTA</th>
<th>ACCIONES</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let usuario of usersArray" class="text-center">
<td>{{usuario.ID}}</td>
<td>{{usuario.NICKNAME}}</td>
<td>{{usuario.EMAIL}}</td>
<td>{{usuario.REGISTRO | date: 'dd-MMMM-yyyy' | uppercase}}</td>
<td>
<span class="bg-success pd-y-3 pd-x-10 text-white tx-11 tx-roboto">
{{usuario.ESTATUS | toStatusReadable}}
</span>
</td>
<td>{{usuario.PROVEEDORACCESO}}</td>
<td>
<div type="button" class="dropdown">
<a [routerLink]="" class="tx-gray-800 d-inline-block" data-toggle="dropdown">
<div class="ht-45 pd-x-20 bd d-flex align-items-center justify-content-center">
<span class="mg-r-10 tx-13 tx-medium">Opciones</span>
<img src="https://via.placeholder.com/500" class="wd-25 rounded-circle" alt="">
<i class="fas fa-angle-down"></i>
</div>
</a>
<div class="dropdown-menu pd-10 wd-200">
<nav class="nav nav-style-2 flex-column">
<a [routerLink]="" class="nav-link"><i class="icon fas fa-edit"></i> Editar datos</a>
</nav>
</div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
TS File code for the table:
export class AdministradoresComponent implements OnInit, OnDestroy {
/* dtOptions: DataTables.Settings = {}; */
dtOptions: any = {};
dtTrigger: Subject<any> = new Subject<any>();
usersArray: Array<Users> = [];
constructor(
private devInfo: DevelopmentService,
private dtService: DatatableService,
private administradoresService: AdministradoresService
) {
this.ObtenerUsuariosSmartlive();
}
ngOnInit() {
document.getElementById('mainSystemPanel').removeAttribute('class');
document.getElementById('mainSystemPanel').className = 'br-mainpanel';
this.dtOptions = this.dtService.getDataTableConfig();
}
ngOnDestroy() {
this.dtTrigger.unsubscribe();
}
async ObtenerUsuariosSmartlive() {
const usuarios = <any []> await this.administradoresService.getSmartliveUsersList();
for ( let i = 0; i < usuarios.length; i++) {
this.usersArray.push(JSON.parse(usuarios[i]));
}
this.dtTrigger.next();
}
}
The service to provide config of the table:
export class DatatableService {
constructor() {
}
getDataTableConfig() {
return {
language: {
url: 'assets/content/smartlive/spanish.json'
},
responsive: true
};
}
}
angular.json snippet:
"styles": [
"node_modules/#fortawesome/fontawesome-free/css/all.min.css",
"node_modules/animate.css/animate.min.css",
"src/assets/content/template/lib/ionicons/css/ionicons.min.css",
"src/assets/content/template/lib/rickshaw/rickshaw.min.css",
"src/assets/content/template/lib/select2/css/select2.min.css",
"src/assets/content/template/css/bracket.css",
"src/assets/content/template/css/bracket.oreo.css",
"node_modules/datatables.net-dt/css/jquery.dataTables.min.css",
"node_modules/datatables.net-bs/css/dataTables.bootstrap.min.css",
"node_modules/datatables.net-responsive-dt/css/responsive.dataTables.min.css",
"src/styles.css"
],
"scripts": [
"node_modules/jquery/dist/jquery.js",
"node_modules/datatables.net/js/jquery.dataTables.js",
"node_modules/datatables.net-bs/js/dataTables.bootstrap.min.js",
"node_modules/datatables.net-responsive/js/dataTables.responsive.min.js"
]
I already installed all the packages files for the datatable but i can't set a correct 100% of width and always the pagination and search input have a bad location over the table.
A bit late but it might help someone else ;-)
Try:
npm install datatables.net-bs4
Then call:
"styles": [
...
"./node_modules/datatables.net-bs4/css/dataTables.bootstrap4.min.css",
...
],
"scripts": [
...
"./node_modules/datatables.net-bs4/js/dataTables.bootstrap4.min.js",
...
],