Filter function by name React - javascript

I need a function to filter by name, The data comes from my Laravel API, I wanted to make a filter on the screen to search for the account name. I am new to React.
import Table from "react-bootstrap/Table";
import axios from "axios";
import { Link } from "react-router-dom";
import { useState, useEffect } from "react";
import Form from "react-bootstrap/Form";
import Button from "react-bootstrap/Button";
const endpoint = "http://localhost:8000/api";
const AccountShow = () => {
const [accounts, setAccounts] = useState([]);
useEffect(() => {
getAllAccounts();
}, []);
const getAllAccounts = async () => {
const response = await axios.get(`${endpoint}/accounts`);
setAccounts(response.data);
};
const deleteAccount = async (id) => {
await axios.delete(`${endpoint}/account/${id}`);
getAllAccounts();
};
return (
<div className="d-grid gap-2">
<div className="row">
<div className="col-8">
<Form className="d-flex m-1">
<Form.Control
type="search"
placeholder="Filtro"
className="me-2"
aria-label="Search"
/>
<Button variant="outline-secondary">Search</Button>
</Form>
</div>
<div className="col-4">
<Link
to="/account/create"
className="col-11 btn btn-outline-primary m-1 "
>
Create
</Link>
</div>
</div>
<Table hover className="">
<thead>
<tr>
<th scope="col">#</th>
<th className="col-2" scope="col">
Nome
</th>
<th className="col-2" scope="col">
Razão Social
</th>
<th scope="col">Status da Conta</th>
<th scope="col">Setor</th>
<th scope="col">Segmento Atuacao</th>
<th scope="col">Natureza Juridica</th>
<th scope="col">Capital</th>
<th scope="col">Funcionarios</th>
<th className="text-center" scope="col">
Ações
</th>
</tr>
</thead>
<tbody>
{accounts.map((account) => (
<tr key={account.id}>
<th>{account.id}</th>
<td>{account.nome}</td>
<td>{account.razaoSocial}</td>
<td>{account.statusConta}</td>
<td>{account.setor}</td>
<td>{account.segmentoAtuacao}</td>
<td>{account.naturezaJuridica}</td>
<td>{account.capital}</td>
<td>{account.funcionarios}</td>
<td className="text-center">
<Link
to={`edit/${account.id}`}
className="btn btn-outline-warning"
>
Editar
</Link>
<button
onClick={() => deleteAccount(account.id)}
className="btn btn-outline-danger m-1"
>
Deletar
</button>
</td>
</tr>
))}
</tbody>
</Table>
</div>
);
};
export default AccountShow;

This is a correct way to filter.
import Table from "react-bootstrap/Table";
import axios from "axios";
import { Link } from "react-router-dom";
import { useState, useEffect } from "react";
import Form from "react-bootstrap/Form";
import Button from "react-bootstrap/Button";
const endpoint = "http://localhost:8000/api";
const AccountShow = () => {
const searchQuery = useState("");
const [accounts, setAccounts] = useState([]);
const [accountToShow, setAccountsToShow] = useState([]);
useEffect(() => {
setAccountsToShow(accounts.filter((account) => /*filter by a specific parameter here depending on what you want to filter it by; by the account.nome field?*/ account.nome.includes(searchQuery)));
}, [accounts, searchQuery]);
useEffect(() => {
getAllAccounts();
}, []);
const getAllAccounts = async () => {
const response = await axios.get(`${endpoint}/accounts`);
setAccounts(response.data);
};
const deleteAccount = async (id) => {
await axios.delete(`${endpoint}/account/${id}`);
getAllAccounts();
};
return (
<div className="d-grid gap-2">
<div className="row">
<div className="col-8">
<Form className="d-flex m-1">
<Form.Control
onChange={({target}) => setSearchQuery(target.value)}
value={searchQuery}
type="search"
placeholder="Filtro"
className="me-2"
aria-label="Search"
/>
<Button variant="outline-secondary">Search</Button>
</Form>
</div>
<div className="col-4">
<Link
to="/account/create"
className="col-11 btn btn-outline-primary m-1 "
>
Create
</Link>
</div>
</div>
<Table hover className="">
<thead>
<tr>
<th scope="col">#</th>
<th className="col-2" scope="col">
Nome
</th>
<th className="col-2" scope="col">
Razão Social
</th>
<th scope="col">Status da Conta</th>
<th scope="col">Setor</th>
<th scope="col">Segmento Atuacao</th>
<th scope="col">Natureza Juridica</th>
<th scope="col">Capital</th>
<th scope="col">Funcionarios</th>
<th className="text-center" scope="col">
Ações
</th>
</tr>
</thead>
<tbody>
{accountsToShow.map((account) => (
<tr key={account.id}>
<th>{account.id}</th>
<td>{account.nome}</td>
<td>{account.razaoSocial}</td>
<td>{account.statusConta}</td>
<td>{account.setor}</td>
<td>{account.segmentoAtuacao}</td>
<td>{account.naturezaJuridica}</td>
<td>{account.capital}</td>
<td>{account.funcionarios}</td>
<td className="text-center">
<Link
to={`edit/${account.id}`}
className="btn btn-outline-warning"
>
Editar
</Link>
<button
onClick={() => deleteAccount(account.id)}
className="btn btn-outline-danger m-1"
>
Deletar
</button>
</td>
</tr>
))}
</tbody>
</Table>
</div>
);
};
export default AccountShow;

You can filter data using
useMemo()
const [accounts, setAccounts] = useState([]);
const [query, setQuery] = useState('');
const filterData = useMemo(() => {
if (accounts && accounts?.length > 0) {
return accounts.filter(item =>
item?.name
.toLocaleLowerCase('en')
.includes(query.trim().toLocaleLowerCase('en')),
);
}
}, [accounts, query]);
you can set query using textbox change event

Related

user list table showing twice

I have list components:
import React,{useState,useEffect} from 'react'
import { Link } from 'react-router-dom'
import UserService from '../services/UserService'
const UserList = () => {
const [users,setUsers] = useState([])
useEffect(() => {
UserService.findAll().then((response)=>{
setUsers(response.data)
}).catch(error=>{
console.log(error)
})
},[users])
const [selectedUserId, setSelectedUserId] = useState();
const handleRowClick = (id) => {
setSelectedUserId(id);
}
return (
<div className='container'>
<h2 className='text-center'>Users</h2>
<div>
<table className='table table-bordered table-stripped'>
<thead>
<th>First Name</th>
<th>Last Name</th>
<th>Email</th>
<th>Password</th>
</thead>
<tbody>
{
users.map(
user =>
<tr key={user.id} onClick={() => handleRowClick(user.id)} style={{backgroundColor: selectedUserId === user.id ? "lightblue" : ""}}>
<td>{user.firstName}</td>
<td>{user.lastName}</td>
<td>{user.email}</td>
<td>{user.password}</td>
</tr>
)
}
</tbody>
</table>
</div>
<Link className="btn btn-primary mx-2" to={"/users/save"} state='Create' >New</Link>
<Link className="btn btn-primary mx-2" to={'/update/'+selectedUserId} state='Update'> Edit</Link>
<Link className="btn btn-primary mx-2" to={"/update/"+selectedUserId} state='Delete' >Delete</Link>
</div>
)
}
export default UserList;
//<Link className="btn btn-primary mx-2" to={"/users/save"} onClick={() => setData('Create')} >New</Link>
It shows UserList twice:
I thought because of the React Strict Mode but it wasn't.
Why is my table showing twice? How can I fix this?

Not able to store data in local storage and use it on page refresh in React

I'am using Firebase version 8.10.0 as the DB in my app, and I succeeded to show the data in my page. So generally Firebase consumes useEffect to show the data.
Also I succeeded to drag and drop the positions of table that contains firebase data. By my pain is to store the drag and drop positions in state and that state should be stored in localStorage.
My destination is to create a separate state that to be stored dragged items in localStorage. I tried this code but no result:
import React, { useState, useEffect, useRef } from "react";
import "./BootTable.css";
import "./Appa.css";
import "../node_modules/bootstrap/dist/css/bootstrap.min.css";
import firebaseDB from "./firebased";
import { ToastContainer, toast } from "react-toastify";
import "react-toastify/dist/ReactToastify.css";
function App() {
const dragItem = useRef();
const dragOverItem = useRef();
const [getData, setGetData] = useState({});
//To Show the data
useEffect(() => {
firebaseDB.child("register").on("value", (details) => {
console.log(details.val());
setGetData(details.val());
});
}, []);
//To Store the dragged data into localStorage
useEffect(() => {
const data = window.localStorage.getItem("MY_DRAGGED_DATA");
if (data !== null) setGetData(JSON.parse(data));
}, []);
//To set the item to localstorage
useEffect(() => {
console.log("show data", getData);
window.localStorage.setItem("MY_DRAGGED_DATA", JSON.stringify(getData));
}, [getData]);
const deleteHandler = (key) => {
firebaseDB.child(`register/${key}`).remove(() =>
toast.error("Deleted!", {
position: "top-right",
})
);
};
const dragStart = (e, position) => {
dragItem.current = position;
console.log(e.target.innerHTML);
};
const dragEnter = (e, position) => {
dragOverItem.current = position;
console.log(e.target.innerHTML);
};
const drop = (e) => {
const copyListItems = [...Object.values(getData)];
const dragItemContent = copyListItems[dragItem.current];
copyListItems.splice(dragItem.current, 1);
copyListItems.splice(dragOverItem.current, 0, dragItemContent);
dragItem.current = null;
dragOverItem.current = null;
setGetData(copyListItems);
};
return (
<div className="full_Container">
<center>
<h6 className="h6_heading">Winners</h6>
</center>
<table className="table " id="data-table">
<thead className="table-hero">
<tr>
<th scope="col">S.no</th>
<th className="put_pointer" scope="col">
Name ▲▼
</th>
<th className="" scope="col">
Company Name
</th>
<th className="put_pointer" scope="col">
LTP
</th>
<th className="put_pointer" scope="col">
%
</th>
<th className="put_pointer" scope="col">
52 W.H
</th>
<th className="" scope="col">
52 W.L
</th>
<th scope="col">M.B</th>
<th className="" scope="col">
Mkt.Cap
</th>
<th className="" scope="col">
Volume
</th>
<th className="" scope="col">
Zauba
</th>
<th className="" scope="col">
M.C
</th>
<th className="" scope="col">
N
</th>
<th className="" scope="col">
C.I
</th>
<th className="" scope="col">
Del
</th>
</tr>
</thead>
<tbody>
{getData &&
Object.keys(getData).map((key, index) => (
<tr
style={{ cursor: "move" }}
onDragStart={(e) => dragStart(e, index)}
onDragEnter={(e) => dragEnter(e, index)}
onDragEnd={drop}
key={index}
draggablekey={index}
draggable
>
<td>{index + 1}</td>
<td>
<a
target="_blank"
style={{ color: "#212529" }}
href={getData[key].url}
>
{getData[key].name}
</a>
</td>
<td>
{" "}
<a
target="_blank"
style={{ color: "#212529" }}
href={getData[key].tradingview}
>
{getData[key].companyname}
</a>
</td>
<td>{getData[key].ltp}</td>
<td>{getData[key].percent}</td>
<td className="wk_low">{getData[key].weekhigh}</td>
<td className="wk_low">{getData[key].weeklow}</td>
<td className="wk_high">
{(getData[key].weekhigh / getData[key].weeklow).toFixed(2)}
</td>
<td>{getData[key].mcap}</td>
<td>{getData[key].volume}</td>
<td>
<a target="_blank" href={getData[key].zauba}>
<button
style={{
color: "#D39B16",
padding: "3px",
fontWeight: 1000,
}}
className="btn btn-sm"
>
Z
</button>
</a>
</td>
<td>
<a target="_blank" href={getData[key].mc}>
<button
style={{
color: "#FF60AB",
padding: "3px",
fontWeight: 1000,
}}
className="btn btn-sm"
>
M
</button>
</a>
</td>
<td>
<a target="_blank" href={getData[key].mc}>
<button
style={{
color: "#19be7b",
padding: "3px",
fontWeight: 1000,
}}
className="btn btn-sm"
>
N
</button>
</a>
</td>
<td>
<a target="_blank" href={getData[key].ci}>
<button
style={{
color: "#19be7b",
padding: "3px",
fontWeight: 1000,
}}
className="btn btn-sm"
>
C.I
</button>
</a>
</td>
<td>
<button
style={{ color: "#fff", padding: "3px", fontWeight: 1000 }}
className="btn btn-sm btn-danger"
onClick={() => deleteHandler(key)}
>
Del
</button>
</td>
{/* {`https://roohhi.com/convert?name=${(filteredPerson.company.toLowerCase().replace(".",""))}` } */}
</tr>
// <tr>{index}</tr>
// <tr><a>{getData[key].url}{getData[key].companyname}</a></tr>
))}
</tbody>
</table>
<ToastContainer theme="colored" />
</div>
);
}
export default App;
To have what you want you should first change how you are setting your initial state so that you pick what's in the localStorage if there is any and otherwise set it to null:
const [getData, setGetData] = useState(
localStorage.getItem("MY_DRAGGED_DATA")
? JSON.parse(localStorage.getItem("MY_DRAGGED_DATA"))
: null
);
And make sure you only use the data from Firebase if the initial data is null (I used null to have a falsy value) and that it's the first render (with loadRef), like so:
const loadRef = useRef(true);
useEffect(() => {
firebaseDB.child("register").on("value", (details) => {
if (getData && loadRef.current){
loadRef.current = false;
return
}
console.log(details.val());
setGetData(details.val());
});
}, []); // the linter might ask you to add getData in the dependency array but don't, and you will be fine.

How can I reduce the quantity with delivery button with react js?

As you can see in the react code, I am trying to reduce the quantity, but I struggle to do it in react. what I want is if click button then quantity should be reduced 1 by 1.
I don't understand what should I do here.
const ManageInventory = () => {
const [products, setProducts] = useProducts();
const handleDelevery = id => {
const handleDelivery = event => { event.preventDefault();
const deliveryInventoryItem = inventoryItem.quantity(quantity-1);
}
const handleDelete = id => {
const proceed = window.confirm('Are Your Sure?');
if(proceed){
const url =`http://localhost:5000/product/${id}`;
fetch(url, {
method: 'DELETE'
})
.then(res => res.json())
.then(data => {
console.log(data);
const remaining = products.filter(product => product._id !==id);
setProducts(remaining);
})
}
}
return (
<div className=''>
<h2 className='product-title'>All Products {products.length} </h2>
<div>
</div>
<div>
<Table striped bordered hover variant="dark">
<thead>
<tr>
<th>Image</th>
<th>Prodct Name</th>
<th>Price</th>
<th>Quantity</th>
<th>Supplier</th>
<th colSpan={2}>Edit</th>
</tr>
</thead>
<tbody>
{
products.map(product => <tr
key={product._id}
product={product}>
<td><img src={product.img} alt="" /> </td>
<td>{product.name}</td>
<td> {product.price}</td>
<td>{product.quantity}</td>
<td>{product.supplier}</td>
<td><button className='manage-btn' onClick={()=> handleDelete(product._id)}>Delete</button></td>
<td><button className='manage-btn' onClick={()=> handleDelevery()}>Delivered</button></td>
</tr>
)
}
</tbody>
</Table>
</div>
<button className='add-product-link'><Link to='/addproduct'>Add Product</Link></button>
</div>
);
};

Update input label which is render by array map in REACTJS

Hope you guys are fine.
I have the next code for dynamically show the quantity of each selected product
import React, { useState, useEffect } from 'react';
import db from '../firebase';
//const Swal = window.Swal;
const NewSale = () => {
const [products, setProducts] = useState([]);
const [selectedProducts, setSelectedProducts] = useState([]);
useEffect(() => {
if(products.length === 0){
db.collection('products').get().then((querySnapshot) => {
const docs = [];
querySnapshot.forEach((doc) => {
docs.push({
id: doc.id,
...doc.data()
});
});
docs.sort((a, b)=> a.name.localeCompare(b.name));
setProducts(docs);
});
}
});
const handleSelectChange = (e) => {
const value = e.target.value;
if(value){
const selectedProduct = products.filter(item => item.id === value)[0];
setSelectedProducts(selectedProducts => [...selectedProducts, {
id: value,
name: selectedProduct.name,
quantity: 1
}]);
}
}
const handleRangeChange = (target, index) => {
const currentValue = parseInt(target.value);
let currentArrayValue = selectedProducts;
currentArrayValue[index].quantity = currentValue;
setSelectedProducts(currentArrayValue);
}
const handleCancelButton = () => {
setSelectedProducts([]);
}
return (
<React.Fragment>
<div className='container'>
<h1 className='display-3 text-center'>New Sale</h1>
<div className='row'>
<div className='col'>
<div className='mb-3'>
<label htmlFor='product' className='form-label fs-3'>Service</label>
<select id='product' onChange={handleSelectChange} className='form-select form-select-lg' multiple aria-label='multiple select service'>
{products.length !== 0?
products.map(item => <option key={item.id} value={item.id}>{item.name}</option>) : <option>No product registered</option>
}
</select>
</div>
</div>
</div>
<div className='row mt-4'>
<div className='col'>
<table className='table caption-top'>
<caption>Sell List</caption>
<thead>
<tr>
<th scope='col'>#</th>
<th scope='col'>Product</th>
<th scope='col'>Quantity</th>
</tr>
</thead>
<tbody>
{selectedProducts.length !== 0?
selectedProducts.map((item, index) => (
<tr key={index}>
<th scope='row'>{(index + 1)}</th>
<td>{item.name}</td>
<td>
<label htmlFor={`customRange-${index}`} className='form-label'>{item.quantity} Units</label>
<input
type='range'
className='form-range'
value={item.quantity}
onChange={({target}) => handleRangeChange(target, index)}
min='1'
max='100'
step='1'
id={`customRange-${index}`}/>
</td>
</tr>
)) :
<tr>
<th className='text-center' colSpan='3'>Nothing selected!</th>
</tr>
}
</tbody>
</table>
</div>
</div>
<div className='row mt-2'>
<div className='col'>
<button className='btn btn-success'>Save</button>
</div>
<div className='col'>
<button className='btn btn-warning' onClick={handleCancelButton}>Cancel</button>
</div>
</div>
</div>
</React.Fragment>
)
};
export default NewSale;
The code shows this... I do not know if I'm allowed to do this kind of operations because I'm adding events every time I select a product so, I'm not sure this is the best way to do it.
And the problem is that I'm getting this unexpected result,
What I want to do is show the current Quantity for each selected item,
Thanks!!

How can I get the value from select option from Meteor/React?

I have implemented the webapp by Meteor/React with some functions.
Then I have one function which I need the value from select option.
I see some example to use setState. But the code I used is different.
I try to use some functions/ways but I cannot get the update value.
In this code I use day1Changed function to process select value to update.
Please help me to get the value from select from the following code:
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { Link } from 'react-router-dom';
import { Table, Alert, Button, FormGroup, FormControl } from 'react-bootstrap';
import { Meteor } from 'meteor/meteor';
import { createContainer } from 'meteor/react-meteor-data';
import { Registers } from '../../api/registers';
const handleRemove = (registerId) => {
if (confirm('Are you sure? This is permanent!')) {
Meteor.call('registers.remove', registerId, (error) => {
if (error) {
console.log(error.reason, 'danger');
} else {
console.log('success');
}
});
}
};
const toggleChecked = (registerId, paid) => {
Meteor.call('registers.setChecked', registerId, !paid);
}
const day1Changed = (registerId) => {
console.log(this.day1.value);
Meteor.call('registers.day1Changed', registerId, this.day1.value);
}
const DSRegisters = ({ registers, totalCount, match, history }) => (
<div className="Registers">
<div className="page-header clearfix">
<br />
<br />
<h4 className="pull-left">Registration </h4> <h4>All user {totalCount} </h4>
<br />
<br />
<Link className="btn btn-success" to={`${match.url}/upload`}>Upload User</Link>
<Link className="btn btn-success pull-right" to={`${match.url}/new`}>Add</Link>
</div>
{registers.length ? <Table striped responsive>
<thead>
<tr>
<th>Item</th>
<th>Salution</th>
<th>First Name</th>
<th>Last Name</th>
<th>Gender</th>
<th>Age</th>
<th>Province</th>
<th>Bhumdharm</th>
<th>Amount</th>
<th>Paid</th>
<th>15/9/60</th>
<th>16/9/60</th>
<th>17/9/60</th>
<th>Accommodation</th>
<th>Remark</th>
<th>Updated</th>
<th>Created</th>
<th>User</th>
<th />
<th />
</tr>
</thead>
<tbody>
{registers.map(({ _id, gender, salution, firstname, lastname, province, bhumdharmlevel, age, amount, paid, day1, day2, day3, accommodation, remark, username, createdAt, updatedAt }, index) => (
<tr key={_id}>
<td>{index+1}</td>
<td>{salution}</td>
<td>{firstname}</td>
<td>{lastname}</td>
<td>{gender}</td>
<td>{age}</td>
<td>{province}</td>
<td>{bhumdharmlevel}</td>
<td>{amount}</td>
<td>
<input
type="checkbox"
readOnly
checked={paid}
onClick={() => toggleChecked(_id,paid)}
/>
</td>
<td>
<FormGroup>
<FormControl
componentClass="select"
name="day1"
inputRef={day1 => (this.day1 = day1)}
defaultValue={day1}
onChange={() => day1Changed(_id, day1)}>
<option value=""></option>
<option value="leave">Leave</option>
<option value="come">Come</option>
<option value="absense">Absense</option>
</FormControl>
</FormGroup>
</td>
<td>{day2}</td>
<td>{day3}</td>
<td>{accommodation}</td>
<td>{remark}</td>
<td>{updatedAt.getDate()}/{updatedAt.getMonth()+1}/{updatedAt.getFullYear()+543} {updatedAt.getHours()}:{(updatedAt.getMinutes()<10?'0':'')+updatedAt.getMinutes()}</td>
<td>{createdAt.getDate()}/{createdAt.getMonth()+1}/{createdAt.getFullYear()+543}</td>
<td>{username}</td>
<td>
<Button
bsStyle="primary"
onClick={() => history.push(`${match.url}/${_id}/edit`)}
block
>Edit</Button>
</td>
<td>
<Button
bsStyle="danger"
onClick={() => handleRemove(_id)}
block
>Delete</Button>
</td>
</tr>
))}
</tbody>
</Table> : <Alert bsStyle="warning">Nobody yet!</Alert>}
</div>
);
DSRegisters.propTypes = {
regs: PropTypes.object,
registers: PropTypes.arrayOf(PropTypes.object).isRequired,
totalCount: PropTypes.number.isRequired,
match: PropTypes.object.isRequired,
history: PropTypes.object.isRequired,
};
export default createContainer(() => {
const subscription = Meteor.subscribe('registers');
return {
registers: Registers.find({}, { sort: { createdAt: 1 } }).fetch(),
totalCount: Registers.find({}).count(),
};
}, DSRegisters);
You can get the value from a select option like snippet bellow:
handleChange(name, e) {
this.setState([name]: e.target.value)
}
<select className="ui dropdown" onClick={this.handleChange.bind(this, 'STATE_NAME_HERE')}>
<option value="1">Male</option>
</select>
This code works with Meteor-React-SemanticUi

Categories

Resources