I have a table that divides the its items per 20 lines and, above the table, a searching input to filter items that matches the written words. Both the tools works ok alone. I can navigate through the pages when there are more than 20 items and i can find the items when i type it in the inut.
The problem is: everytime i have more than one page i try to search something, the item appears in the first page and if i am in the second page i can see nothing unless i go back to the first page.
I think that the correct thing to do is to decrease the number of pages to matche the quantity of items that i found, but i don’t know how to do it.
You can take a look in the page and the code below:
The code:
const [currentPage, setcurrentPage] = useState(1);
const itemsPerPage = 15;
// Calculo dos índices para exibir os itens da página atual
const indexOfLastItem = currentPage * itemsPerPage;
const indexOfFirstItem = indexOfLastItem - itemsPerPage;
// const currentItems = produtos.slice(indexOfFirstItem, indexOfLastItem);
const totalPages = Math.ceil(produtos.length / itemsPerPage);
const changePage = (newPage) => {
if(showDetalhes === true){
setShowDetalhes(false);
}
setcurrentPage(newPage);
};
//jsx return
<table className="table" id='table-estoque'>
<thead>
<tr>
<th scope="col" id="titulo-tabela-padrao">Categoria</th>
<th scope="col" id="titulo-tabela-padrao">Código</th>
<th scope="col" id="titulo-tabela-padrao" style={{ width: '40%' }}>Produto</th>
<th scope="col" id="titulo-tabela-padrao">Preço</th>
<th scope="col" id="titulo-tabela-padrao">Preço Promocional</th>
<th scope="col" id="titulo-tabela-padrao" style={{width:'2%', color:'#FFEA00'}}><i className="fa-solid fa-pen fa-sm"></i></th>
<th scope="col" id="titulo-tabela-padrao" style={{width:'2%', color:'#eb2632'}}><i className="fa-solid fa-trash fa-sm"></i></th>
</tr>
</thead>
<tbody>
{produtos
.filter((item) => {
// return search.toLowerCase() === '' || item.pro_descricao.toLowerCase().includes(search.toLowerCase()); //se digitar algo aparece na lista
const searchWords = search.toLowerCase().split(' '); //atribui à searchWirds tudo que foi digitado dividido por space
return searchWords.every((word) => //faz a busca para cada palavra digitada mesmo que fora de sequencia
item.pro_descricao.toLowerCase().includes(word)
);
})
.slice(indexOfFirstItem, indexOfLastItem) //Mudei a logica para paginacao para antes do map e nao la em cima como antes
.map((produto, index) => (
<React.Fragment key={index}>
<tr>
<td className={index % 2 === 0 ? 'td-item-par' : 'td-item-impar'} id="item-tabela-padrao">{produto.cat_descricao}</td>
<td className={index % 2 === 0 ? 'td-item-par' : 'td-item-impar'} id="item-tabela-padrao">{produto.pro_codigo}</td>
<td className={index % 2 === 0 ? 'td-item-par' : 'td-item-impar'} id="item-tabela-padrao">{produto.pro_descricao}</td>
<td className={index % 2 === 0 ? 'td-item-par' : 'td-item-impar'} id="item-tabela-padrao">{new Intl.NumberFormat('pt-BR', {minimumFractionDigits: 2,maximumFractionDigits: 2}).format(produto.pro_preco1)}</td>
{produto.pro_preco_promocao > 0 ? <td className={index % 2 === 0 ? 'td-item-par' : 'td-item-impar'} id="item-tabela-padrao">{new Intl.NumberFormat('pt-BR', {minimumFractionDigits: 2,maximumFractionDigits: 2}).format(produto.pro_preco_promocao)}</td>
:
<td className={index % 2 === 0 ? 'td-item-par' : 'td-item-impar'} id="item-tabela-padrao">--</td>
}
<td className={index % 2 === 0 ? 'td-item-par' : 'td-item-impar'} id="item-tabela-padrao"><div id="a-editar" onClick={(e) => OpenModalProduto(produto.pro_id)} ><i className="fa-solid fa-pen fa-sm"></i></div></td>
<td className={index % 2 === 0 ? 'td-item-par' : 'td-item-impar'} id="item-tabela-padrao"><div id="a-excluir" onClick={(e) => confirmarExclusao(produto.pro_id)}><i className="fa-solid fa-trash fa-sm"></i></div></td>
</tr>
{showDetalhes && detalhesIndex === index && (
<tr>
<td className={index % 2 === 0 ? 'td-item-par' : 'td-item-impar'} colSpan="12" style={{ borderBottom: '1px solid #000' }}>
<div style={{ padding: '15px' }}>
{
jsonOpcionais?.map(item => {
return <div className='row' key={item.poi_id}>
<div className='col-1 ms-auto me-3'>
{item.status === 'N' ? <span id='status-itens-op' className='badge bg-secondary ms-2'>Inativo</span> : <span id='status-itens-op' className='badge bg-success ms-2'>Ativo</span>}
</div>
<div className='col-4'>
<span>{item.poi_descricao}</span>
</div>
<div className='col-1 me-auto'>
{item.poi_valor === 0 ? <span id='span-zero'>{new Intl.NumberFormat('pt-BR', {style: 'currency', currency:'BRL'}).format(item.poi_valor)} </span> : <span id='span-maior-zero' key={index}>{new Intl.NumberFormat('pt-BR', {style: 'currency', currency:'BRL'}).format(item.poi_valor)} </span>}
</div>
</div>
})
}
</div>
</td>
</tr>
)}
</React.Fragment>
))}
</tbody>
</table>
{totalPages > 1 && (
<div className="pagination">
<button className="btn btn-secondary btn-sm ms-auto" onClick={() => changePage(currentPage - 1)} disabled={currentPage === 1}> Anterior</button>
<span className="span-pagina ms-1 me-1 ">Página {currentPage} / {totalPages}</span>
<button className="btn btn-secondary btn-sm" onClick={() => changePage(currentPage + 1)} disabled={currentPage === totalPages}>Próxima</button>
</div>
)}
2
Answers
i found a way:
function Produtos() {
Set current page as 1 everytime i type in search input and totalPages = Math.ceil(filteredProdutos.length / 15); after filtering
//replace this
//new code
secondly try to keep this in parent and pass it as props to table component
and i assume the onChange function of search field is something like this