How to make open url on click on button in reactjs - javascript

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

Related

Get data from a table row by selecting an icon

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;

React : Add backend filter to fetched data

I have the following component where I fetch data from a table, display them and have the ability to perform a search.
I want to add an additional filter to the fetched element. The filter is already coded and working in Laravel as following :
public function search(Request $request){
$search = $request ->get('q');
$Patient = Patient::where('name','Like','%'.$search.'%');
if ($request->has('gender')) {
$Patient->where('gender', $request->gender);
}
return $Patient->get();
}
As you can see in the controller you can perform a search and a filtering. So an example of directly accessing it will be :
http://localhost:8000/api/patients/search?q=John&gender=male
For now I'm able to display data and search it in react, but I have no idea on how to add additional filters to the link to fetch from. How to do so ?
Component :
class Patient extends React.Component {
constructor(props) {
super(props)
this.state = {
patients : [],
};
this.handleSearchChange = this.handleSearchChange.bind(this);
}
handleSearchChange(key){
console.log(key);
fetch('http://localhost:8000/api/patients/search?q='+key)
.then(response => response.json())
.then(response => {
this.setState({
patients: response})
console.log(response);
})
.catch(err => console.log(err));
}
componentDidMount() {
axios.get('api/patients')
.then(response => {
this.setState({
patients: response.data})
})
.catch(err => console.log(err));
}
render() {
return (
<div>
<Container>
<div>
<input
type="text"
className="form-control"
placeholder="Search..."
onChange={e => this.handleSearchChange(e.target.value)}
/>
<div class="dropdown">
<button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Dropdown button
</button>
<div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
<a class="dropdown-item" href="#">Male</a>
<a class="dropdown-item" href="#">Female</a>
</div>
</div>
</div>
<Table>
<Thead>
<Tr>
<Th>ID</Th>
<Th>FIRST NAME</Th>
<Th>LAST NAME</Th>
</Tr>
</Thead>
<Tbody>
{this.state.patients.reverse().map((patient) => (
<Tr>
<Td>
{patient.id}
</Td>
<Td>
{patient.firstname}
</Td>
<Td>
{patient.lastname}
</Td>
</Tr>
))}
</Tbody>
</Table>
</Container>
</div>
);
}
}
export default Patient;
You are quite close to it.
Your current implementation generates the search url as soon as the <input> field changes. If you want some other filters, you will need to store those filters values in a state before actually generating the url and fetching the data.
Here is how the gist would look like.
class Patient extends React.Component {
constructor(props) {
super(props)
this.state = {
patients : [],
filters: {q: '', gender: ''} // we add the filter property to the state
};
this.updateFilter = this.updateFilter.bind(this);
}
// this will fetch the new patients as soon as one of the filter has been updated
fetchPatients() {
const searchParams = new URLSearchParams();
const {q, gender} = this.state.filters
if (q) {
searchParams.set('q', q);
}
if (gender) {
searchParams.set('gender', gender);
}
const url = `http://localhost:8000/api/patients/search?${searchParams.toString()}`;
fetch(url)
.then(response => response.json())
.then(response => this.setState({patients: response}))
.catch(err => console.log(err));
}
// this will update a single filter
updateFilter(filter, value) {
const currentFilters = this.state.filters;
this.setState({filters: {...currentFilters, [filter]: value}});
this.fetchPatients()
}
render() {
return (
/*...*/
<input type="text" onChange={ev => this.updateFilter('q', ev.target.value)} />
/*...*/
<input type="text" onChange={ev => this.updateFilter('gender', ev.target.value)} />
);
}
}
check this example from pingcrm (build with laravel, inertiajs and vue), specifically when use lodash/pickBy conversion to replace a request URL
form: {
handler: throttle(function() {
let query = pickBy(this.form)
this.$inertia.replace(this.route('contacts', Object.keys(query).length ? query : { remember: 'forget' }))
}, 150),
deep: true,
},
Hope help.

Adding data fetched from an API into a Table automatically

I am fetching data from an API using Axios. I have a listRequest() method that is a GET request to the API, the addRow() method is used to add rows to the table automatically.
I want to be able to add the rows automatically with the fetched data.
Here is my code:
import React from 'react';
import axios from "axios";
class ShipmentsTable extends React.Component{
constructor(props){
super(props);
this.state = {
shipment: {
requestType: "Request Type",
customerName: "",
email: "",
companyName: "",
}
};
this.listRequest = this.listRequest.bind();
}
listRequest = () =>{
axios.get("http://localhost:8000/app/list/")
.then((response) =>{
let result = response.data;
console.log(result);
this.setState({shipment: result.data});
}).catch((error) =>{
console.log(error);
});
}
componentDidMount(){
this.listRequest();
}
addRow = () =>{
//destructuring
const {requestType, customerName, email, companyName} = this.state.shipment;
return this.state.shipment.map((shipment, index) =>{
<tr>
<td>{requestType}</td>
<td>{customerName}</td>
<td>{email}</td>
<td>{companyName}</td>
</tr>
});
}
render(){
return(
<table className="submittedShipmentsTable">
<thead>
<tr>
<td>
<th>Request Type</th>
</td>
<td>
<th>Customer Name</th>
</td>
<td>
<th>Email</th>
</td>
<td>
<th>Company Name</th>
</td>
</tr>
</thead>
<tbody>
{/*Adding Rows Automatically*/}
{this.addRow}
</tbody>
</table>
);
}
}
export default ShipmentsTable;
Question:
I want the data fetched from the API to be added to the table in the form of a row automatically
For map to work you need an array, ie:
this.state = {
shipments: [
{
requestType: "Request Type",
customerName: "",
email: "",
companyName: ""
}
]
};
Then you can do this in your render:
<tbody>
{this.state.shipments.map((shipment, index) => this.addRow(shipment))}
</tbody>
And add row will simply return the row:
addRow = ({ requestType, customerName, email, companyName }) => {
return (
<tr>
<td>{requestType}</td>
<td>{customerName}</td>
<td>{email}</td>
<td>{companyName}</td>
</tr>
);
};

Cannot get a data on the table using react js

I developed a table with reactjs and I want to get the data and appears it on this table.
The data appears on the console but it doesn't appears on the table.
My code is :
constructor(props){
super(props);
this.state = {
categories: [],
file:''};
this.onchange = this.onchange.bind(this)
this.handleAdd = this.handleAdd.bind(this);
}
componentDidMount() {
axios({
method: 'get',
url: 'http://172.16.234.24:8000/api/allCategories',
headers: {
'Cors-Allow-Credentials':true,
'Access-Control-Allow-Credentials':true,
'Access-Control-Allow-Origin': '172.16.234.24:8000',
'Access-Control-Allow-Headers':'Content-Type,
Authorisation',
'Content-Type': 'multipart/form-data'
}
}).then(response => {
try { if (response && response.data) {
this.setState({ categories: response.data});
console.log(response)
}
console.log(this.state.categories)
}
catch(error)
{console.log('noo')}
}).catch(error => console.log(error));
}
handleAdd() {
try {
console.log("Add Categorie")
this.props.history.push('/addcategorie');
}
catch (error) {
this.setState({ error });
}
}
render() {
let {
categories
} = this.state;
return (
<div>
<Table><thead><tr>
<th scope="col">Name</th>
<th scope="col">Photo</th>
</tr>
</thead>
<tbody>{categories.length && this.state.categories.map(categorie => (
<tr key={categorie.id}>
<td>{categorie.name}</td>
<td>{categorie.file}</td>
</tr>
))} </tbody>
</Table>
</div>
when I run it I get index.js:1446 Warning: validateDOMNesting(...): Text nodes cannot appear as a child of <tbody>. and I get the data on the console but my table is empty.
How to fix it ?
You have some white spaces between tbody starting and ending tag
Just replace below code as it is and try
<tbody>{categories.length && categories.map(categorie => (
<tr key={categorie.id}>
<td>{categorie.name}</td>
<td>{categorie.file}</td>
</tr>
))}</tbody>
It might seem silly, but you're actually rendering the tbody and some whitespace (i.e. text).
To be more clear
Change
))} </tbody>
To
))}</tbody>
try to change your JSX expression (i added {}):
{categories.length && this.state.categories.map(categorie => { return (
<tr key={categorie.id}>
<td>{categorie.name}</td>
<td>{categorie.file}</td>
</tr>
))}}
You need to move your code logic from the tbody to the tr for iteration or remove the tbody tag.

How to render fetched data from API

I'm trying to fetch data from an API that I want to render in a table. I am following this example, and have also tried others as well:
https://blog.hellojs.org/fetching-api-data-with-react-js-460fe8bbf8f2
When I try to console.log the state I get state is undefined. When I console.log the data I receive the correct data. I know how to solve my problem with pure JavaScript, but really want to make it work this way.
import React from "react";
import Row from '../components/Row';
class Table extends React.Component {
constructor() {
super();
this.state = {
users: [],
};
this.createNewUser = this.createNewUser.bind(this);
this.deleteExistingUser = this.deleteExistingUser.bind(this);
}
componentDidMount() {
console.log("Component did mount!");
fetch("http://localhost:8080/users")
.then(response => {
return response.json();
}).then(data => {
let users = data.response.map((row) => {
return (
<tr>
<td>{row.name}</td>
<td>{row.email}</td>
<td>{row.phone}</td>
<td>{row.age}</td>
<td>
<button className="red waves-effect waves-light btn">
Delete
</button>
</td>
</tr>
);
});
this.setState({users: users});
console.log("state", this.state.users);
});
}
render() {
return (
<table id="" className="highlight centered">
<thead>
<tr>
<th>Name</th>
<th>Email</th>
<th>Phone</th>
<th>Age</th>
<th>Delete</th>
</tr>
</thead>
<tbody id="table_body">
{this.state.users}
</tbody>
</table>
);
}
}
export default Table;
Okey, so after a little tinkering i was able to solve it.
I changed from:
let users = data.response.map((row) => {
return (
<tr>
<td>{row.name}</td>
<td>{row.email}</td>
<td>{row.phone}</td>
<td>{row.age}</td>
<td>
<button className="red waves-effect waves-light btn">
Delete
</button>
</td>
</tr>
);
});
to:
let users = data.map((row) => {
return <Row key={row.email} name={row.name} email={row.email}
phone={row.phone} age={row.age}/>
});

Categories