Pagination in reactstrap issue(updated) - reactjs

Here I have created the pagination(reactstrap) for the table. Backend has 100 data records. I display 10 records per page. It works fine as i change the page.I have written some code for displaying paginating numbers.Initially, It should display paginating numbers from 1-5. On clicking 5th page, paginating numbers should display from 6 to 10 and so on.. Please help me. Thanks in advance
import {getInitialUsers, getPageByPageUsers} from "services/userService";
const Users = () => {
const [payloads, setPayloads] = useState({
offset: 0,
limit: 10,
search: "",
page: 1,
rowsPerPage: 10,
count: 0,
});
const [start, setStartPage] = useState(0);
const [end, setEndPage] = useState(payloads.limit);
const [users, setUsers]= useState([]);
useEffect(() => {
fetchInitialData();
}, []);
const fetchInitialData = async () => {
try {
let res = await getInitialUserRequests();
setUsers(res.data.data)
payloads.count = res.data.size;
getPager(res.data.size, payloads.page); /* res.data.size means total number of records */
} catch (err) {
console.log("error")
}
};
const getPager = (count, page) => {
let totalPages = Math.ceil(count / payloads.rowsPerPage);
/* facing issues in the following conditions */
if (totalPages <= 5) {
setStartPage(1);
setEndPage(totalPages);
} else {
if (page <= 5) {
setStartPage(1);
setEndPage(5);
}
if (page >= end - start) {
setStartPage(end - start);
setEndPage(end - start + 4);
}
if (page + 4 >= totalPages) {
setStartPage(totalPages - 4);
setEndPage(totalPages);
}
}
};
const handleChangePage = async (e, newPage) => {
payloads.page = newPage;
try {
let res = await getPageByPageUserRequests(newPage);
setUsers(res.data.data)
getPager(payloads.count, newPage);
} catch (err) {
console.log("error")
}
};
return (
<>
<Container className="mt--7" fluid>
<Row>
<div className="col">
<Card className="shadow">
<CardHeader className="border-0">
<h3 className="mb-0">Users</h3>
</CardHeader>
<Table className="align-items-center table-flush" responsive>
<thead className="thead-light">
<tr>
<th scope="col">Username</th>
<th scope="col">E-mail</th>
<th scope="col">Phone Number</th>
</tr>
</thead>
<tbody>
{users.length > 0 ? (
users.map((user) => (
<tr key={user.id}>
<td>{user.username}</td>
<td>{user.email}</td>
<td>{user.phone}</td>
</tr>
))
) : (
<tr className="text-center">
<th colSpan="5">No Data Found!!</th>
</tr>
)}
</tbody>
</Table>
<CardFooter className="py-4">
<nav aria-label="...">
<Pagination
className="pagination justify-content-end mb-0"
listClassName="justify-content-end mb-0"
>
<PaginationItem
className={payloads.page <= 1 && `disabled`}
>
<PaginationLink
href="#"
onClick={(e) => handleChangePage(e, payloads.page - 1)}
tabIndex="-1"
>
<i className="fas fa-angle-left" />
<span className="sr-only">Previous</span>
</PaginationLink>
</PaginationItem>
{[
...Array(
Math.ceil(payloads.count / payloads.rowsPerPage)
),
].map((page, i) => {
if (i >= start && i < end) {
return (
<PaginationItem
className={i === payloads.page ? `active` : ""}
key={i}
>
<PaginationLink
tag="button"
onClick={(e) => handleChangePage(e, i)}
>
{i}
</PaginationLink>
</PaginationItem>
);
}
})}
<PaginationItem
className={
payloads.page ==
Math.ceil(payloads.count / payloads.rowsPerPage) ?
`disabled`:''
}
>
<PaginationLink
href="#"
onClick={(e) => handleChangePage(e, payloads.page + 1)}
>
<i className="fas fa-angle-right" />
<span className="sr-only">Next</span>
</PaginationLink>
</PaginationItem>
</Pagination>
</nav>
</CardFooter>
</Card>
</div>
</Row>
</Container>
</>
);
};

i usually use a simple mathematical formula for this
data?.slice(pageNumber * rowsPerPage, pageNumber * rowsPerPage + rowsPerPage)?.map((row, index){
<div key={index}>{row}</div>
})

Related

How to maintain state and scroll position in React

I'm trying to build a CURD operation component that GET the data from API. When a user clicks on the EDIT, it renders the component showing the details of the line item to be edited. But when the user hits the back button in the browser, the previous component with the post list re-renders and it loses the previous state and scroll position. Is there a way that I can bring the selected row to the first position if I scroll up it displays the previous data and if I scroll down it shows the next coming data?
import React, { useState, useEffect } from "react";
import axios from "axios";
import { Link } from "react-router-dom";
import "bootstrap/dist/css/bootstrap.min.css";
import { CSVLink, CSVDownload } from "react-csv";
import "./Home.css";
const Home = () => {
const [loading, setLoading] = useState(false);
const [users, setUsers] = useState([]);
const [searchTitle, setSearchTitle] = useState("");
const [prime, setPrime] = useState([]);
const [primeid, setPrimeid] = useState("");
const [category, setCategory] = useState([]);
const [categoryid, setCategoryid] = useState("");
const [subcategory, setSubcategory] = useState([]);
const [subcategoryid, setSubcategoryid] = useState("");
const usersList = users.length;
useEffect(() => {
loadUsers();
}, []);
// the below command is used to send the load data from the database
const loadUsers = async () => {
const result = await axios.get(`http://localhost:4000/api/email/`);
// setUsers(result.data);
setUsers(result.data);
// console.log(result)
};
useEffect(() => {
const getprime = async () => {
const resprime = await axios.get(
`http://localhost:4000/api/primewise${primeid}`
);
setPrime(resprime.data.reverse());
};
getprime();
}, []);
const handleprime = (event) => {
const getprimeid = event.target.value;
setPrimeid(getprimeid);
};
useEffect(() => {
const getcategory = async () => {
const rescategory = await axios.get(
"http://localhost:4000/api/categorywise"
);
setCategory(rescategory.data.reverse());
};
getcategory();
}, []);
const handlecategory = (event) => {
const getcategoryid = event.target.value;
setCategoryid(getcategoryid);
};
useEffect(() => {
const getsubcategory = async () => {
const ressubcategory = await axios.get(
"http://localhost:4000/api/subcategorywise"
);
setSubcategory(ressubcategory.data.reverse());
};
getsubcategory();
}, []);
const handleSubcategory = (event) => {
const getSubcategoryid = event.target.value;
setSubcategoryid(getSubcategoryid);
};
useEffect(() => {
if (users.length) {
const scrollPosition = sessionStorage.getItem("scrollPosition");
if (scrollPosition) {
window.scrollTo(0, parseInt(scrollPosition, 10));
sessionStorage.removeItem("scrollPosition");
}
}
}, [users]);
useEffect(() => {
if (users.length) {
const scrollPosition = sessionStorage.getItem("scrollPosition");
if (scrollPosition) {
window.scrollTo(0, parseInt(scrollPosition, 10));
sessionStorage.removeItem("scrollPosition");
}
}
}, [users]);
return (
<div className="App">
<div className="header-1">
<nav className="navbar">
<div className="container-fluid">
<div className="navbar-brand">Supplier Contact Information</div>
{/* <form className="d-flex">
<Link className="btn btn-outline-light" to="/users/statics">
Statics
</Link>
</form> */}
</div>
</nav>
<hr class="solid"></hr>
</div>
<div className="header">
<h4>CATEGORYWISE SUPPLIER INFORMATION</h4>
<div className="col-md-0">
<div class="row">
<div class="col-sm-3">
<div class="card">
<div class="card-body text-center ">
<input
type="text"
placeholder="Power Search..."
className="form-control"
onChange={(e) => setSearchTitle(e.target.value)}
/>
<br />
<select
name="prime"
className="form-control"
onChange={(e) => handleprime(e)}
>
<option value="">--Select Prime--</option>
{prime.map((resprime, index) => (
<option key={index} value={resprime.Prime_Descr}>
{resprime.Prime_Descr}{" "}
</option>
))}
</select>{" "}
</div>
</div>
</div>
<div class="col-sm-3">
<div class="card">
<div class="card-body">
<select
name="category"
className="form-control"
onChange={(e) => handlecategory(e)}
>
<option value="">--Select Category--</option>
{category.map((rescategory, index) => (
<option key={index} value={rescategory.CATEGORY}>
{rescategory.CATEGORY}{" "}
</option>
))}
</select>{" "}
<br />
<select
name="country"
className="form-control"
onChange={(e) => handlecategory(e)}
>
<option value="">--Select Category--</option>
{subcategory.map((ressubcategory, index) => (
<option key={index} value={ressubcategory.SUB_CATEGORY}>
{ressubcategory.SUB_CATEGORY}{" "}
</option>
))}
</select>{" "}
</div>
</div>
</div>
<div class="col-sm-6">
<div class="card-1">
<div class="card-body text-center ">
<CSVLink
filename="supplier contact info."
data={users}
class="btn btn-outline-light"
>
Export to csv
</CSVLink>
<br />
<br />
<div className="container-fluid">
<Link className="btn btn-outline-light" to="/users/add">
Add Supplier
</Link>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div className="outer-wrapper">
<div className="tabel-wrapper">
<table>
<thead>
<th scope="col">S.No</th>
<th scope="col">Prime</th>
<th scope="col">Category</th>
<th scope="col">Sub-Category</th>
<th scope="col">Supplier</th>
<th scope="col">Country</th>
<th scope="col">Region</th>
<th scope="col">Title/Designation</th>
<th scope="col">Representative</th>
<th scope="col">Department</th>
<th scope="col">Primary Contact No</th>
<th scope="col">Secondary Contact No</th>
<th scope="col">EmailId</th>
<th scope="col">Address</th>
<th>Action</th>
</thead>
<tbody>
{/* {usersList ? (
<h4>Loading ...</h4> */}
{loading ? (
<h4>Loading ...</h4>
) : (
users
.filter((value) => {
if (searchTitle === "") {
return value;
} else if (
// (value.PRIME &&
// value.PRIME.toLowerCase().includes(
// searchTitle.toLowerCase()
// )) ||
(value.CATEGORY &&
value.CATEGORY.toLowerCase().includes(
searchTitle.toLowerCase()
)) ||
(value.SUB_CATEGORY &&
value.SUB_CATEGORY.toLowerCase().includes(
searchTitle.toLowerCase()
)) ||
(value.SUPPLIER &&
value.SUPPLIER.toLowerCase().includes(
searchTitle.toLowerCase()
)) ||
(value.COUNTRY &&
value.COUNTRY.toLowerCase().includes(
searchTitle.toLowerCase()
)) ||
(value.REGION &&
value.REGION.toLowerCase().includes(
searchTitle.toLowerCase()
)) ||
(value.DESIGNATION &&
value.DESIGNATION.toLowerCase().includes(
searchTitle.toLowerCase()
)) ||
(value.REPRESENTATIVE_NAME &&
value.REPRESENTATIVE_NAME.toLowerCase().includes(
searchTitle.toLowerCase()
)) ||
(value.DIVISION &&
value.DIVISION.toLowerCase().includes(
searchTitle.toLowerCase()
)) ||
(value.CONTACT_NO &&
value.CONTACT_NO.toLowerCase().includes(
searchTitle.toLowerCase()
)) ||
(value.ALTERNATE_CONTACT_NUMBER &&
value.ALTERNATE_CONTACT_NUMBER.toLowerCase().includes(
searchTitle.toLowerCase()
)) ||
(value.EMAIL_ID &&
value.EMAIL_ID.toLowerCase().includes(
searchTitle.toLowerCase()
)) ||
(value.ADDRESS &&
value.ADDRESS.toLowerCase().includes(
searchTitle.toLowerCase()
))
) {
return value;
}
})
.map((user, index) => (
<tr>
<td scope="row">{index + 1}</td>
<td>{user.PRIME}</td>
<td>{user.CATEGORY}</td>
<td>{user.SUB_CATEGORY}</td>
<td>{user.SUPPLIER}</td>
<td>{user.COUNTRY}</td>
<td>{user.REGION}</td>
<td>{user.DESIGNATION}</td>
<td>{user.REPRESENTATIVE_NAME}</td>
<td>{user.DIVISION}</td>
<td>{user.CONTACT_NO}</td>
<td>{user.ALTERNATE_CONTACT_NUMBER}</td>
<td>{user.EMAIL_ID}</td>
<td>{user.ADDRESS}</td>
<td>
<Link
class="btn btn-outline-primary mr-2"
to={`/users/edit/${user.ID}`}
>
Edit
</Link>
</td>
</tr>
))
)}
</tbody>
</table>
</div>
</div>
</div>
);
};
export default Home;

React-table global filter Regex

Having trouble getting my GlobalFilter to update the table when using Regex to search for multiple results in a column.
export const Table = ({ data, columns }) => {
const filterTypes = useMemo(
() => ({
// Override the default text filter to use
// "startWith"
text: (rows, id, filterValue) => {
return rows.filter((row) => {
const rowValue = row.values[id];
const isRegexMatch = () => {
try {
return RegExp(filterValue).test(String(rowValue));
} catch (err) {
return false;
}
};
return rowValue !== undefined
? String(rowValue)
.toLowerCase()
.startsWith(String(filterValue).toLowerCase()) || isRegexMatch()
: true;
});
},
}),
[]
);
const {
getTableProps,
getTableBodyProps,
headerGroups,
prepareRow,
page,
canPreviousPage,
canNextPage,
pageOptions,
pageCount,
gotoPage,
nextPage,
previousPage,
setPageSize,
preGlobalFilteredRows,
setGlobalFilter,
state,
state: { pageIndex, pageSize },
} = useTable(
{
columns,
data,
filterTypes,
},
useFilters,
useGlobalFilter,
useSortBy,
usePagination
);
return (
<div className="col-12">
<div className="table-responsive mb-5">
<GlobalFilter
preGlobalFilteredRows={preGlobalFilteredRows}
globalFilter={state.globalFilter}
setGlobalFilter={setGlobalFilter}
/>
<table {...getTableProps()} className="table">
<thead>
{headerGroups.map((headerGroup) => (
<tr {...headerGroup.getHeaderGroupProps()}>
{headerGroup.headers.map((column) => (
<th {...column.getHeaderProps(column.getSortByToggleProps())}>
{column.render('Header')}
<span>
{column.isSorted ? (
column.isSortedDesc ? (
<ChevronDown baseLayer="icon" />
) : (
<ChevronUp baseLayer="icon" />
)
) : (
''
)}
</span>
</th>
))}
</tr>
))}
</thead>
<tbody {...getTableBodyProps()}>
{page.map((row, i) => {
prepareRow(row);
return (
<tr {...row.getRowProps()} key={i}>
{row.cells.map((cell) => {
return (
<td {...cell.getCellProps()}>{cell.render('Cell')}</td>
);
})}
</tr>
);
})}
</tbody>
</table>
<div className="pagination mt-3">
<button
onClick={() => gotoPage(0)}
disabled={!canPreviousPage}
className="btn btn-sm btn-link"
>
{'<<'}
</button>{' '}
<button
onClick={() => previousPage()}
disabled={!canPreviousPage}
className="btn btn-sm btn-link"
>
{'<'}
</button>{' '}
<button
onClick={() => nextPage()}
disabled={!canNextPage}
className="btn btn-sm btn-link"
>
{'>'}
</button>{' '}
<button
onClick={() => gotoPage(pageCount - 1)}
disabled={!canNextPage}
className="btn btn-sm btn-link"
>
{'>'}
</button>{' '}
<span className="mt-2 text-muted">
<small>
Page {pageIndex + 1} of {pageOptions.length}{' '}
</small>
</span>
<span className="mt-2 ms-1 me-1 text-muted">
<small> | Go to page:</small>
</span>
<span className="me-1">
<input
type="number"
className="form-control"
defaultValue={pageIndex + 1}
onChange={(e) => {
const page = e.target.value ? Number(e.target.value) - 1 : 0;
gotoPage(page);
}}
style={{ width: '80px' }}
/>
</span>
<select
value={pageSize}
style={{ width: '190px' }}
className="form-control"
onChange={(e) => {
setPageSize(Number(e.target.value));
}}
>
{[10, 20, 30, 40, 50].map((pageSize) => (
<option key={pageSize} value={pageSize}>
Show {pageSize} per page
</option>
))}
<option key={data.length} value={data.length}>
Show All
</option>
</select>
</div>
</div>
</div>
);
};
I only had success so far in the console with this function being able to filter the results, but so far no luck with the react-table package.
function regexFilter(rows, ids, filterValue) {
rows = rows.filter((row) => {
return ids.some((id) => {
const rowValue = row.values[id];
const isRegexMatch = () => {
try {
return RegExp(filterValue).test(String(rowValue));
} catch (err) {
return false;
}
};
return (
String(rowValue)
.toLowerCase()
.includes(String(filterValue).toLowerCase()) || isRegexMatch()
);
});
});
return rows;
}
What am I not doing correctly or mis-interpreting from the documentation on filterTypes?

Word is not getting added until the page is refreshed in TableItem component in React

TableItem component added without any data in UI. Could somebody help on this. On refereshing the UI, added data is shown with details in TableItem component.
Table Component Code
import TableItem from "./TableItem";
function Table({ searchWord }) {
const dispatch = useDispatch();
const dictData = useSelector((state) => state.dictionary);
useEffect(() => {
dispatch(getDictionaryAsync());
}, [dispatch]);
return (
<table className="table table-striped">
<thead>
<tr>
<th scope="col">Word</th>
<th scope="col">Description</th>
<th scope="col"></th>
</tr>
</thead>
<tbody>
{dictData &&
dictData
.filter((e) =>
searchWord === ""
? e
: e.word &&
e.word.toLowerCase().includes(searchWord.toLowerCase())
)
.map((item) => (
<TableItem item={item} key={item.id} searchWord={searchWord} />
))}
</tbody>
</table>
);
}
export default Table;
Below is the TableItem Component Code which i am trying to update,
When i add a word to dictionary it will fetch the details from the server and display it in the React app.
function TableItem({ item }) {
const [modal, setModal] = useState(false);
const openModal = () => {
setModal(true);
};
return (
<>
<tr key={item.id}>
<td style={{ textTransform: "capitalize" }}>{item.word}</td>
<td>
<b style={{ textTransform: "capitalize" }}>
{item.items && item.items[0].category} -{" "}
</b>
{item.items && truncate(item.items[0].definitions[0])}
</td>
<td>
<button className="btn btn-danger btn-sm " onClick={openModal}>
View
</button>
</td>
</tr>
<Modal isOpen={modal} ariaHideApp={true}>
<div className="modal-header">
<h3 className="modal-word-header">
{item.word && item.word.toUpperCase()}
</h3>
<button
className="btn btn-danger btn-sm"
onClick={() => setModal(false)}
>
<i class="fa fa-times" aria-hidden="true"></i>
</button>
</div>
<div className="model-content">
<p>
{item.items &&
item.items.map((e) => {
return (
<>
<i>{e.category}</i>
<ul>
{e.definitions.map((def) => {
return <li>{def}</li>;
})}
</ul>
</>
);
})}
</p>
</div>
</Modal>
</>
);
}
Better add your TableItem component code!
Below code works fine and updated the UI on change in the Data in TableItem,
useEffect(() => {
dispatch(getDictionaryAsync());
}, [dispatch, dictData]); *<--updated code*

SweetAlert2-react Cancel Button does not work

I'm trying to confirm a user delete using Sweetalert2 in react, but when I use the 'Cancel' button, it still sends the form to delete the user, as if I've pressed 'Confirm'. Here's my code
export default function Users() {
const [users, setUsers] = useState([])
const [isModalOpen, setModal] = useState(false)
const [hover, setHover] = useState('')
const [userModal, setuserModal] = useState('')
const [show, setShow] = useState(false)
const [userDelete, setUserDelete] = useState('')
useEffect(() => {
fetch(`${OC_API}/users`)
.then(res => res.json())
.then(res => {
setUsers(res)
console.log(res)
})
.catch(e => console.log(`Hubo un error Cod. 200 ${e}`))
},[])
function toggleModal(user) {
setuserModal(user)
setModal(!isModalOpen)
}
function handleDeleteUser(user) {
fetch(`${OC_API}/userdelete`, {
method: 'POST',
headers: {'Content-Type':'application/json'},
body: JSON.stringify({"user_id": user._id})
}).then(res => {
if (res.ok){
alert('¡Usuario eliminado!')
} else {
alert('¡Hubo un error! Cod. 201')
}
}).then(() => {
fetch(`${OC_API}/users`)
.then(res => res.json(),
error => {alert(`Error de conexión ${error.message}`); throw error;})
.then(data => {
console.log(data)
setUsers(data)
})
.catch(e => console.log(`Hubo un error Cod. 202 ${e}`))
})
}
if (users == undefined || users == [] || users == null ){
return (
<Loading />
)
} else {
return(
<div className="container">
<motion.div className="row justify-content-center"
initial={{ opacity: 0 }}
animate={{ opacity: 1}}
transition={{ duration: 1}}
style={{'paddingTop':'3em'}}
>
<div className="col col-md-12 text-right" >
<AddUserButton />
</div>
<div className="col col-md-12 text-center" >
<ParagraphStyle>
<div className="card" >
<div className="card-header text-left">
Administrar Usuarios
</div>
<div className="card-body">
<div className="table-responsive">
<AdminTableStyle>
<table className="table">
<thead >
<tr>
<th scope="col">Nombre</th>
<th scope="col">RUT</th>
<th scope="col">Correo</th>
<th scope="col">Rol</th>
<th scope="col">Acciones</th>
</tr>
</thead>
<tbody>
{users.map(user => (
<Fragment key={user.id}>
<SweetAlert
show={show}
icon={'warning'}
title="Eliminar Usuario"
text={`¿Desea borrar a usuario ${userDelete.name}?`}
showCancelButton={true}
confirmButtonColor={'#3085d6'}
cancelButtonColor={'#d33'}
cancelButtonText={'Cancelar'}
confirmButtonText={'Confirmar'}
onCancel={ () => {setShow(false)
return }}
onConfirm={() => {
handleDeleteUser(userDelete)
setShow(false)
}}
/>
<tr onMouseOver={() => setHover(user._id)} onMouseLeave={() => setHover('')}>
<td style={{'textAlign': 'left'}}>{user.name}</td>
<td>{user.rut}</td>
<td>{user.email}</td>
<td>{user.role}</td>
<td>
<span style={{'marginRight': '5px'}}>
{
hover==user._id?
<a href="#" onClick={() => toggleModal(user)}>
<FontAwesomeIcon
icon='edit'
/>
</a>
:
''
}
</span>
<span>
{
hover==user._id?
<a href="#" onClick={() => {
setUserDelete(user)
setShow(true)
}}
>
<FontAwesomeIcon
icon='trash'
/>
</a>
:
''
}
</span>
</td>
</tr>
</Fragment>
))}
</tbody>
</table>
</AdminTableStyle>
</div>
</div>
</div>
</ParagraphStyle>
</div>
</motion.div>
<UserEdit
setuserModal={setuserModal}
isModalOpen={isModalOpen}
userModal={userModal}
toggleModal={toggleModal}
/>
</div>
)
}
}
I tried adding an onCancel option in the Sweetalert component and set the Show state to false, but it continues executing the handleDeleteUser function
Any suggestions?

React print a component

There is a 'Print' button on SaleInvoice.js which shows the Modal containing Report.js.
Report.js is created only to describe how and what should be displayed in the printed page.
Report.js has a button 'Print' which opens the Print Preview in the browser.
How do I make the 'Print' button on SaleInvoice.js directly open the Print Preview in the browser?
SaleInvoice.js
...
<button
style={{marginRight: '200px'}}
onClick={() => this.setState({printView: true})}>
Print
</button>
{this.state.printView ? (
<Modal
type="Print"
{...this.props}
show={this.state.printView}
modalClosed={() => this.setState({printView: false})}
/>
) : null}
...
Report.js
import React from 'react';
import styles from './SaleInvoice.module.css';
const SaleInvoice = props => {
const {customerName} = props;
const rows = props.lineItems;
const alignRightMarginRight = [styles.alignRight, styles.marginRight].join(
' ',
);
const {amountBeforeFreight, freight, amountAfterFreight} = props;
const reverseDateString = date => {
let [yyyy, mm, dd] = date.split('-');
return dd + '-' + mm + '-' + yyyy;
};
const renderContent = () => {
let i = 0;
let contentRows = (i, d) => {
return (
<React.Fragment>
<td className={styles.serialNumber}>{i}</td>
<td className={styles.productName}>{d.product_name}</td>
<td className={alignRightMarginRight}>{d.product_qty}</td>
<td className={alignRightMarginRight}>{d.product_unit}</td>
<td className={alignRightMarginRight}>{d.product_rate}</td>
<td className={alignRightMarginRight}>{d.product_disc}</td>
<td className={alignRightMarginRight}>{d.sub_total}</td>
</React.Fragment>
);
};
return rows.map(d => {
i++;
if (i === rows.length) {
return null;
}
if (i % 10 === 0) {
return (
<tr key={i} className={styles.pagebreak}>
{contentRows(i, d)}
</tr>
);
} else {
return <tr key={i}>{contentRows(i, d)}</tr>;
}
});
};
return (
<React.Fragment>
<div className={styles.all}>
<div className={[styles.header].join(' ')}>
<button className={styles.hideInPrint} onClick={window.print}>
Print
</button>
<button className={styles.hideInPrint} onClick={props.modalClosed}>
Close
</button>
<h5 className={styles.docTitle}>Estimate</h5>
<h6 className={styles.customerName}>
{customerName}
<span className={styles.date}>
{reverseDateString(props.date.split('T')[0])}
</span>
</h6>
</div>
<table className={styles.content}>
<thead>
<tr>
<td>No</td>
<td>Name</td>
<td className={alignRightMarginRight}>Qty</td>
<td className={alignRightMarginRight}>Unit</td>
<td className={alignRightMarginRight}>Rate</td>
<td className={alignRightMarginRight}>Disc</td>
<td className={alignRightMarginRight}>Total</td>
</tr>
</thead>
<tbody className={styles.content}>{renderContent()}</tbody>
</table>
<div className={styles.footer}>
<div className={styles.foot}>
<label>Amount:</label>
<label className={styles.amount}>
{amountBeforeFreight.toFixed(2)}
</label>
</div>
<div className={styles.foot}>
<label>Freight:</label>
<label className={styles.amount}>
{freight ? freight.toFixed(2) : 0}
</label>
</div>
<div className={styles.foot}>
<label>Final Amount:</label>
<label className={styles.amount}>
{amountAfterFreight.toFixed(2)}
</label>
</div>
</div>
</div>
</React.Fragment>
);
};
export default SaleInvoice;
in your file SalesInvoice.js, we would be changing the event onClick, instead of what action does(setting modal view to true in your state) we want it to open the print window in the browser.
as follows
<button
style={{marginRight: '200px'}}
onClick={window.print} >
Print
</button>
you will not need this part I guess?
{this.state.printView ? (
<Modal
type="Print"
{...this.props}
show={this.state.printView}
modalClosed={() => this.setState({printView: false})}
/>
) : null}

Resources