Get data from a table row by selecting an icon - javascript

I have a table that is powered by data coming from Firebase.
In the table listing, I have the option to generate the pdf of the entire history, with the map function.
But I would also like to generate the pdf of a single item when selecting the 'pdf' icon in the 'actions' column. But I'm not able to get only the line when I select the icon, could you help me?
// List code
useEffect(function(){
let listaEPI = [];
firebase.firestore().collection('epis').get().then(async function(resultado){
await resultado.docs.forEach(function(doc){
// console.log(doc.id)
if (doc.data().nome.indexOf(busca) >= 0){
listaEPI.push({
id: doc.id,
nome: doc.data().nome,
funcao: doc.data().funcao
});
}
})
setEpis(listaEPI);
})
});
return <div className='table table-bordered table-responsive'>
<table className="table">
<thead>
<tr className='text-center'>
{/* <th scope='row'> # </th> */}
<th scope='col'> Nome </th>
<th scope='col'> Função </th>
<th scope='col' className='col-acao'> Ações </th>
</tr>
</thead>
{
props.arrayEpis.map((epi) => {
return <tr key={epi.key} className="text-center">
<td className='nome'> {epi.nome} </td>
<td> {epi.funcao} </td>
<Link to='#' onClick={(e) => epiIndPDF(epis)}> <i className='far fa-file-pdf'></i> </Link>
</td>
</tr>
})
}
</table>
</div>
// Code trying to get the values ​​of the selected row
function epiIndPDF(epis){
pdfMake.vfs = pdfFonts.pdfMake.vfs;
var nRe;
const filterDad = "";
var e;
const dados = epis.map((epi) => {
return [
epi.nome,
epi.funcao,
epi.numero_registro,
nRe = epi.numero_registro,
console.log(nRe)
]
})
console.log(filterDad);
// console.log(...dados);
// for (var i = 0; i < dados.length; i++){
// const found = dados.find(epi => {
// return epi.key === epi.key;
// })
// console.log(found)
// }
const docDefinitios = {
pageSize: 'A4',
pageOrientation: 'landscape', // Orientação da página
pageMargins: [10, 50, 10, 40],
header: [header],
content: [infor2, termo, assinat],
// footer: [Rodape]
}
pdfMake.createPdf(docDefinitios).download();
}
export default epiIndPDF;

Related

How to input array into 1 column table

How to input array into 1 column table ? Audience number 2 have 2 Films B & C. I want to become 1 column. ex [Film B, Film C] in Column Film.
My Table =>
The Table Image
const AudienceListComponent = () => {
const [audience, setAudience] = useState([])
console.log("audience", audience)
const getAllAudience = () => {
AudienceService.getAllAudiences().then((response) => {
console.log('response', response)
setAudience(response.data)
})
}
useEffect(() => {
getAllAudience()
}, [])
return (
<div>
<table className="table table-bordered table-bordered">
<thead className="table-dark">
<tr>
<th>No</th>
<th>Audience Name</th>
<th>Film</th>
</tr>
</thead>
<tbody>
{
audience.map((aud, i) => (
<tr key={aud.id}>
<td>{i + 1}</td>
<td>{aud.name}</td>
{aud.film.map(films =>
<td>{films.title}</td>
)}
</tr>
))
}
</tbody>
</table>
</div>
);
};
export default AudienceListComponent;
Solved by #Hamza Khan in a comment:
You need to run the map loop inside your td element like this: <td> {aud.film.map(films => films.title )} </td>

How to fetch and get data from one .json data to another .json data using the same linked id?

Here I have got the two .json files named users.json and subscription.json. In JSON file users.id links to subscription.user_id. I have view the data of subscription.json in the table.
Now I want to get the username using id of users.json linked to user_id of subscription.json
import React, {useEffect, useState} from 'react'
import '../UserList/userlist.css'
const Suscriber = () => {
const [search, setSearch] = useState([]);
const [data,setData]=useState([]);
const [order, setorder] = useState("ASC");
const [users,setUsers] = useState([{}])
useEffect(()=>{
fetch('data/users.json').then((res)=>res.json()).then((data)=>{
setUsers(data)
})
},[])
const getData=()=>{
fetch('./data/subscriptions.json'
,{
headers : {
'Content-Type': 'application/json',
'Accept': 'application/json'
}
}
)
.then(function(response){
console.log(response)
return response.json();
})
.then(function(myJson) {
console.log(myJson);
setData(myJson)
});
}
useEffect(()=>{
getData()
},[])
const sorting = (col) => {
if (order === "ASC") {
const sorted = [...data].sort((a,b)=>
a[col].toString().toLocaleLowerCase() > b[col].toString().toLocaleLowerCase() ? 1 : -1
// ||
// a[col].Number.toLocaleLowerCase() < b[col].Number.toLocaleLowerCase() ? 1 : -1
);
setData(sorted);
setorder("DSC");
}
if (order === "DSC") {
const sorted = [...data].sort((a,b)=>
a[col].toString().toLocaleLowerCase() < b[col].toString().toLocaleLowerCase() ? 1 : -1
);
setData(sorted);
setorder("ASC");
}
}
return (
<div className="main">
<div className="search_option">
<h1 className="table-head">Subscribed User Data List</h1>
<div className="input-icons">
<i class="fa fa-search icon" aria-hidden="true"></i>
<input type="search"
className="input-field"
placeholder="Search......."
onChange={(event) => {
setSearch(event.target.value);
}}
/>
</div>
</div>
<table>
<thead>
<tr>
<th scope="col" onClick={()=>sorting("id")}>ID <i class="fas fa-sort sortings"></i></th>
<th scope="col" onClick={()=>sorting("user_id")}>User ID <i class="fas fa-sort sortings"></i></th>
<th scope="col">Username <i class="fas fa-sort sortings"></i></th>
<th scope="col" onClick={()=>sorting("package")}>Package <i class="fas fa-sort sortings"></i></th>
<th scope="col" onClick={()=>sorting("expires_on")}>Expire on <i class="fas fa-sort sortings"></i></th>
</tr>
</thead>
<tbody>
{data.filter((val) => {
if (search === ""){
return val
}
else if (
val.id.toString().toLocaleLowerCase().includes(search.toString().toLocaleLowerCase())
// || val.email.toLocaleLowerCase().includes(search.toLocaleLowerCase())
// || val.user_id.toString().toLocaleLowerCase().includes(search.toLocaleLowerCase())
|| val.package.toLocaleLowerCase().includes(search.toString().toLocaleLowerCase())
// || val.expires_on.toString().toLocaleLowerCase().includes(search.toLocaleLowerCase())
){
return val
}
return false;
}).map((val, key) => {
const user = users.find(uid => uid.id === val.user_id);
return <tr key={key}>
<td data-label="ID">{val.id}</td>
<td data-label="User ID">{val.user_id}</td>
<td data-label="Username">{user.username}
{/* {
subscribe.map((detail, index) => {
return <div>{detail.username}</div>
})
} */}
{/* {
subscribe.filter(uid => uid.id === val.user_id).map(details =>(
<>{details.username}</>
))
} */}
</td>
<td data-label="Package">{val.package}</td>
<td data-label="Expire on">{val.expires_on}</td>
</tr>
})}
</tbody>
</table>
</div>
)
}
export default Suscriber
The table includes all the data in subscriptions.json now need to find and display the same user_id and username from users.json and view it on the table below.
Below are users.json data picture:
Below are subscriptions.json data picture:
Instead of using Filter you can use the find method .
.map((val, key) => {
// Find the user
const user = subscribe.find(uid => uid.id === Number(val.user_id));
return <tr key={key}>
<td data-label="ID">{val.id}</td>
<td data-label="User ID">{val.user_id}</td>
<td data-label="Username">{ user?.username || '-' }</td>
<td data-label="Package">{val.package}</td>
<td data-label="Expire on">{val.expires_on}</td>
</tr>
})}

How to make open url on click on button in reactjs

In my code I am trying to do when I select row and click on button then this url open http://codeskulptor-assets.commondatastorage.googleapis.com/assets_clock_minute_arrow.png.
But right now in my code when I select row and click on button then url is not open.
How can we do that to open this url when I select row and click button the open url http://codeskulptor-assets.commondatastorage.googleapis.com/assets_clock_minute_arrow.png.
My code here https://codesandbox.io/embed/react-example-forked-o8tu5?codemirror=1
Anyone plz suggest any idea and help me out. I m stuck on that.
import React from 'react';
import axios from 'axios';
class ProvFileRptSearchResult extends React.Component {
constructor(props) {
super();
this.state = {
pymtDetails:[],
data: [],
rowDetails:[],
checkbox: false
};
// this.handleFile=this.handleFile.bind(this);
this.handleClick=this.handleClick.bind(this);
}
handleClick() {
const apiUrl = "http://localhost:9090/PrvFileRpt/getPrvFileData";
if (this.state.checkbox) {
fetch(apiUrl)
.then((response) => response.json())
.then((data) => {
this.setState({ data: data });
console.log("This is your data", data);
window.open("https://example.com", "_blank");
})
} else {
alert("Data not fetched!");
}
// console.log('click');
}
// handleClick(e) {
// e.preventDefault();
// console.log("The link was clicked");
// }
// handleFile()
// {
// //fetch birt report from here
// console.log("inside file ",this.state.rowDetails);
// }
rowSelected(j) {
// e.preventDefault();
console.log(j)
const rownum=j;
console.log("rownum=",rownum)
console.log(this.props.customerDetails[rownum] )
this.setState({rowDetails:this.props.customerDetails[rownum]}, () => {
});
}
render()
{
return(
<div>
<div className="table-employee" style={{ marginTop:"20px",border:" 1.5px solid darkgray" }}>
<table className="table table-hover table-bordered table-sm">
<thead>
<tr >
<th scope="col">Select</th>
<th scope="col"> LOAD DATE</th>
<th scope="col"> FILE DATE</th>
<th scope="col"> SERVICE</th>
<th scope="col"> PROVISIONER CODE </th>
<th scope="col"> DESCRIPTION</th>
</tr>
</thead>
<tbody>
{
this.props.customerDetails.map((type,j)=>{
return(
<tr>
<td ><input type="radio" preventDefault name="select" key={j} onClick={(e) =>this.rowSelected(j)} value={this.state.checkbox}
onChange={(e) =>
this.setState({ checkbox: !this.state.checkbox })
}/></td>
<td> {type.provis_file_stamp}</td>
<td> {type.provis_file_hdrdt}</td>
<td> {type.service_code}</td>
<td>{type.provisioner_code}</td>
<td>{type.provisioner_desc}</td>
</tr>
)
})
}
</tbody>
</table>
</div>
<div className="btn-submit" >
<button className="btn btn-primary" style={{marginRight:"30px"}} type="submit" onClick={this.handleClick}>FILE</button>
</div>
</div>
)
}
}
export default ProvFileRptSearchResult;
Call the openInNewTab with the URL. It will open the URL in a new browser tab. Remove '_blank', if you want to open it in the same tab.
const openInNewTab = (url) => {
const newWindow = window.open(url, '_blank', 'noopener,noreferrer')
if (newWindow) newWindow.opener = null
}
Well, if I understand correctly, you're trying to open a URL on button click?
If that's right, using window.open('https://example.com', '_blank') in your click handler will allow you to open any URL in a new tab.
First you need to find correct object using find method and then you can open url with window.open
Try following code:-
handleClick = () => {
const apiUrl = "https://mocki.io/v1/b512f8b8-64ab-46e4-9e0c-9db538a0ad9e";
if (this.state.checkbox) {
fetch(apiUrl)
.then((response) => response.json())
.then((data) => {
this.setState({ data: data });
const urlData = data.find(element => element.id === 3); // filter data with id
window.open(urlData.url, '_blank'); // open url here
});
} else {
alert("check the radio!");
}
};

Angular Column level filters in table having reactive form and formArray

I want to implement highly dynamic table with column level filters applied to it and editable rows with validation applied to each cell of table.
I have implemented Dynamic table display with editable rows and dynamic validations. But struggling with Column level filters.
My Problem statement:
UI will receive table headers to display and corrosponding table rows data.
e.g. headers = ['name','age'] and data [{name:'abc',age:'xyz'},{name:'pqr',age:'xyz'}, ..]
with above setup I have implemented reactive form using formArray.
sample setup is created in stackblitz
here is my form :
<form [formGroup]="data_form">
<table class="table table-border">
<thead>
<tr>
<th>
name
</th>
<th>
age
</th>
<th><button class="btn btn-primary ">Save</button></th>
</tr>
<tr>
<th *ngFor="let th of rowKeys">
<ng-container *ngIf="th !=='isEditable'">
<input type="text" formControlName="{{th}}" />
</ng-container>
</th>
<th></th>
</tr>
</thead>
<tbody formArrayName="persons">
<ng-container *ngFor="let item of persons.controls;let j = index">
<tr [formGroupName]="j">
<ng-container *ngIf="!item.value.isEditable; else editable">
<td>{{ item.value.name }}</td>
<td>{{ item.value.age }}</td>
</ng-container>
<ng-template #editable>
<td><input formControlName="name" /></td>
<td><input formControlName="age" /></td>
</ng-template>
<td>
<button (click)="toggleEdit(j)">
{{ !item.value.isEditable ? "Edit": "Cancel"}}
</button>
</td>
</tr>
</ng-container>
</tbody>
</table>
</form>
<h2>
{{data_form.status}}
</h2>
and ts:
import { Component } from "#angular/core";
import {
FormArray,
FormBuilder,
FormControl,
FormGroup,
Validators
} from "#angular/forms";
#Component({
selector: "my-app",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.css"]
})
export class AppComponent {
name = "Angular";
constructor(private fb: FormBuilder) {}
patterns = [
/^[.\d]+$/,
/^(yes|no)$/i,
/^[a-zA-Z0-9 _/]+$/,
/^(0[1-9]|1[0-2])\/(0[1-9]|1\d|2\d|3[01])\/(19|20)\d{2}$/
];
data = [
{
name: "Sachin",
age: 27,
isEditable: false
},
{
name: "Gopal",
age: 27,
isEditable: false
},
{
name: "Pankaj",
age: 24,
isEditable: false
}
];
rowKeys = Object.keys(this.data[0]);
keys = [...new Set(this.data.map(item => Object.keys(item)).flat())];
keyPattern = this.keys.map(item => ({
key: item,
pattern: this.patterns.find(pattern =>
this.data.every(i => pattern.test(i[item]))
)
}));
data_form = this.fb.group({
persons: this.fb.array(
this.data.map(item =>
this.fb.group(
this.keyPattern.reduce(
(prev, { key, pattern }) => ({
...prev,
[key]: [
item[key],
[Validators.required, Validators.pattern(pattern)]
]
}),
{}
)
)
)
)
});
get persons(): FormArray {
return this.data_form.get("persons") as FormArray;
}
toggleEdit(j) {
const currentEditStatus = this.persons.controls[j].get("isEditable").value;
this.persons.controls[j].get("isEditable").setValue(!currentEditStatus);
}
ngOnInit(){
this.rowKeys.forEach((num) => {
if (num == "isEditable") return;
const fc = new FormControl('');
this.data_form.addControl(num, fc)
});
/**
* How to filter formsArray ?
*/
// this.data_form.get('cuisp').valueChanges.pipe(
// debounceTime(100),
// distinctUntilChanged(),
// ).subscribe(val => {
// console.log(val)
// const result = this.persons.value.filter(res => {
// if (res['cuisp'] === val) {
// return res
// }
// });
// this.persons.patchValue(result)
// console.log(result)
// });
}
}
How to implement column level search so then when I search in Name column then respective name should get displayed.
Consider below approach using reactive programing.
The Steps are as below
Convert all your inputs to observables
Set up a Subject to use as a trigger for filtering
Combine the data and the subject using the combineLatest([...]) operator from rxjs
Below is a working code, See this demo on stackblitz
constructor(private fb: FormBuilder) {}
patterns = [
/^[.\d]+$/,
/^(yes|no)$/i,
/^[a-zA-Z0-9 _/]+$/,
/^(0[1-9]|1[0-2])\/(0[1-9]|1\d|2\d|3[01])\/(19|20)\d{2}$/
];
data$ = of([
{
name: "Sachin",
age: 27,
isEditable: false
},
{
name: "Gopal",
age: 27,
isEditable: false
},
{
name: "Pankaj",
age: 24,
isEditable: false
}
]);
filterStringSubject$ = new BehaviorSubject({});
filterStringAction$ = this.filterStringSubject$.asObservable();
filterString$ = this.filterStringAction$.pipe(
map(stringObject =>
Object.entries(stringObject).map(item => ({
key: item[0],
value: item[1]
}))
)
);
rowKeys$ = this.data$.pipe(
map(data => Object.keys(data[0])),
tap(rowKeys => {
rowKeys.forEach(num => {
if (num == "isEditable") return;
this.filterStringSubject$.next({
...this.filterStringSubject$.value,
[num]: ""
});
});
})
);
keys$ = this.data$.pipe(
map(data => [...new Set(data.map(item => Object.keys(item)).flat())])
);
keyPattern$ = combineLatest(this.keys$, this.data$).pipe(
map(([keys, data]) => {
return keys.map(item => ({
key: item,
pattern: this.patterns.find(pattern =>
data.every(i => pattern.test(i[item]))
)
}));
})
);
data_form: FormGroup;
dataFiltered$ = combineLatest([this.data$, this.filterString$]).pipe(
map(([data, filterString]) =>
this.persons?.value.filter(item =>
filterString.every(a => `${item[a.key]}`.includes(`${a.value}`))
)
)
);
dataForm$ = combineLatest([ this.data$,
this.keyPattern$]).pipe(
tap(([data, keyPattern]) => {
this.data_form = this.fb.group({
persons: this.fb.array(
data.map(item =>
this.fb.group(
keyPattern.reduce(
(prev, { key, pattern }) => ({
...prev,
[key]: [
item[key],
[Validators.required, Validators.pattern(pattern)]
]
}),
{}
)
)
)
)
});
}),
)
v$ = combineLatest([
this.dataForm$,
this.rowKeys$,
this.filterString$,
this.dataFiltered$
]).pipe(
map(([, rowKeys, filterString, dataFiltered]) => ({
rowKeys,
filterString,
dataFiltered
}))
);
get persons(): FormArray {
return this.data_form?.get("persons") as FormArray;
}
toggleEdit(j) {
const currentEditStatus = this.persons.controls[j].get("isEditable").value;
this.persons.controls[j].get("isEditable").setValue(!currentEditStatus);
}
filterBy(item, value) {
this.filterStringSubject$.next({
...this.filterStringSubject$.value,
[item]: value
});
}
ngOnInit() { }
In your HTML
<form [formGroup]="data_form" *ngIf='v$ | async as v'>
<table class="table table-border">
<thead>
<tr>
<th>
name
</th>
<th>
age
</th>
<th><button class="btn btn-primary ">Save</button></th>
</tr>
<tr>
<td *ngFor="let item of v.rowKeys">
<input *ngIf='item != "isEditable"' type="text"
(input)="filterBy(item, $event.target.value)" />
</td>
<th></th>
</tr>
</thead>
<tbody formArrayName="persons">
<ng-container *ngFor="let item of v.dataFiltered;let j = index">
<tr [formGroupName]="j">
<ng-container *ngIf="!persons.controls[j]?.get('isEditable').value; else editable">
<td>{{ item.name }}</td>
<td>{{ item.age }}</td>
</ng-container>
<ng-template #editable>
<td><input formControlName="name" /></td>
<td><input formControlName="age" /></td>
</ng-template>
<td>
<button (click)="toggleEdit(j)">
{{ !persons.controls[j]?.get('isEditable').value ? "Edit": "Cancel"}}
</button>
</td>
</tr>
</ng-container>
</tbody>
</table>
</form>
<h2>
{{data_form?.status}}
</h2>

how to add new row dynamically in reactable

I am trying to add new row onclick of accordion i.e while expand using reactable, attached the expected result.
I have showed the table structured data using Tr and Td from reactable but however, not sure to add the new row.
onclick of the arrow the dynamic row should expand,I tried to do so but wasn't able to achieve that.
class PolicyDetails extends Component {
showPolicyOperation = (e,models) => {
e.preventDefault();
const {callbacks} = this.props
const activeClass = document.querySelectorAll('.fa-angle-up')
const currentTarget = e.currentTarget;
if(currentTarget.classList.contains('fa-angle-up')){
currentTarget.classList.remove('fa-angle-up');
currentTarget.classList.add('fa-angle-down');
}else{
currentTarget.classList.remove('fa-angle-down');
currentTarget.classList.add('fa-angle-up');
}
activeClass && activeClass.forEach(node => {
node.classList.remove('fa-angle-up');
node.classList.add('fa-angle-down');
})
callbacks.fetchPoliciesWithId(models.id)
}
getHeaders = () => {
let headers = ([
<Th key="0" column=""></Th>,
<Th key="1" column="id">Policy Id</Th>,
<Th key="2" column="serviceType">Service</Th>,
<Th key="3" column="name">Policy Name</Th>,
<Th key="4" column="description">Policy Description</Th>,
<Th key="5" column="policyLabel">Policy Label</Th>,
<Th key="6" column="policyType">Policy Type</Th>,
<Th key="7" column="operation">Operation</Th>,
<Th key="8" column="action">Actions</Th>
])
return headers;
}
pageChange = (page) => {
this.cPoliciesData.params.page = page - 1 || undefined;
this.props.callbacks.fetchPolicies();
}
getRows = (models, idx) => {
const state = this.props.options._vState
let rows = ([
<Td key="0" column="">
<i className="fa pointer fa-angle-down"
aria-hidden="true" key = {idx} onClick={e => {
state.isPolicySelected = !state.isPolicySelected;
this.showPolicyOperation(e,models)
}}></i></Td>,
<Td key="1" column="id">{<a>{models.id}</a>}</Td>,
<Td key="2" column="serviceType">{models.serviceType || "--"}</Td>,
<Td key="3" column="name">{models.name || "--"}</Td>,
<Td key="4" column="description">{models.description || "--"}</Td>,
<Td key="5" column="policyLabel">{"--"}</Td>,
<Td key="6" column="policyType">{models.serviceType == 'tag' && models.policyType == 0 ? "Tag Based" : POLICY_TYPE[models.policyType].label}</Td>,
<Td key="7" column="operation">{"--"}</Td>,
<Td key="8" column="action">{"--"}</Td>,
]);
let operation = state.isPolicySelected && <Tr className="special-row">
<Th column="name">
<strong className="name-header">First Name, Last Name</strong>
</Th>
<Th column="age">
<em className="age-header">Age, years</em>
</Th>
</Tr>
rows.push(operation)
return rows;
}
render() {
const {options , callbacks} = this.props;
const {cPoliciesData, _vState} = options
return (
<Row className="m-t-md">
{/* <Col md={12}> */}
<PanelBody>
<Table data={cPoliciesData}
tableAttr={{ className: "table table-hover" }}
getHeaders={this.getHeaders}
getRowData={this.getRows}
pagination={true}
pageChange={this.pageChange}
>
</Table>
</PanelBody>
{/* </Col> */}
</Row>
)
}
}
You just need to add in array . and then with
UseEffect(()=>{
},[options._vState])

Categories