Set multiple search filter in ReactJS - json

I need help because i'm stuck in my reactjs project. I'm trying to make multiple search input box with different filter each in reactJS, but i can't achieve it with more than one filter. I tried googling it but i cannot make it work.
searchFilter = () => {
return <form>
<input name="filterTitle" type="text" value={this.state.filterTitle} onChange={this.filterList}/>
<input name="filterYear" type="text" value={this.state.filterYear} onChange={this.filterList}/>
<input name="filterReso" type="text" value={this.state.filterReso} onChange={this.filterList}/>
</form>
}
filterList = (event) => {
var items = this.state;
var updatedItems = this.state.items.filter(item => {
var filterTitle = this.state.filterTitle != "" ? item.titulo.toLowerCase().indexOf(event.target.value.toLowerCase()) !== -1 : true;
var filterYear = this.state.filterYear != "" ? item.ano.toLowerCase().indexOf(event.target.value.toLowerCase()) !== -1 : true;
var filterReso = this.state.filterReso != "" ? item.reso.toLowerCase().indexOf(event.target.value.toLowerCase()) !== -1 : true;
return filterTitle && filterYear && filterReso;
})
this.setState({ updatedItems: updatedItems });
console.log(updatedItems);
}
UPDATE 1:
new code so far, please help!
handleSearchFilter = (event) => {
const inputValue = event.target.value;
this.setState({ input: inputValue });
this.filterList(inputValue);
};
searchFilter = () => {
return <form>
<input name="filterTitle" type="text" value={this.filterTitle} onChange={(e)=>this.handleSearchFilter(e)} />
<input name="filterYear" type="text" value={this.filterYear} onChange={(e)=>this.handleSearchFilter(e)} />
<input name="filterReso" type="text" value={this.filterReso} onChange={(e)=>this.handleSearchFilter(e)} />
</form>
}
filterList = (inputValue) => {
const {items, updatedItems} = this.state;
const itemsUpdate = this.state.items.filter(item => {
var filterTitle = item.titulo.toLowerCase().indexOf(inputValue.toLowerCase()) > 1;
var filterYear = item.ano.toLowerCase().indexOf(inputValue.toLowerCase()) > 1;
var filterReso = item.reso.toLowerCase().indexOf(inputValue.toLowerCase()) > 1;
return filterTitle + filterYear + filterReso;
})
this.setState({ updatedItems: itemsUpdate });
console.log(updatedItems);
}

first you need to save search key seperate in state then make AND or OR comparison to retrive result like this
import React from "react";
class TestPage extends React.Component {
state = {
items: [
{
titulo: "titulo1",
ano: "ano1",
reso: "reso1",
},
{
titulo: "titulo2",
ano: "ano2",
reso: "reso2",
},
],
updatedItems: [],
filterTitle: "",
filterYear: "",
filterReso: "",
};
searchFilter = () => {
return (
<form>
<input
name="filterTitle"
type="text"
value={this.filterTitle}
onChange={(e) => this.handleSearchFilter(e, "filterTitle")}
/>
<input
name="filterYear"
type="text"
value={this.filterYear}
onChange={(e) => this.handleSearchFilter(e, "filterYear")}
/>
<input
name="filterReso"
type="text"
value={this.filterReso}
onChange={(e) => this.handleSearchFilter(e, "filterReso")}
/>
</form>
);
};
handleSearchFilter = (event, key) => {
const inputValue = event.target.value;
this.setState({ [key]: inputValue }, () => {
this.filterList();
});
};
filterList = () => {
const itemsUpdate = this.state.items.filter((item) => {
var filterTitle =
item.titulo
.toLowerCase()
.indexOf(this.state.filterTitle.toLowerCase()) > -1;
var filterYear =
item.ano.toLowerCase().indexOf(this.state.filterYear.toLowerCase()) >
-1;
var filterReso =
item.reso.toLowerCase().indexOf(this.state.filterReso.toLowerCase()) >
-1;
return filterTitle && filterYear && filterReso;
});
this.setState({ updatedItems: itemsUpdate }, () => {
console.log(this.state.updatedItems);
});
};
renderList = () => {
const { updatedItems } = this.state;
return (
<div>
{updatedItems.map((updatedItem) => {
return (
<div>
{updatedItem.titulo}
{updatedItem.ano}
{updatedItem.reso}
</div>
);
})}
</div>
);
};
render() {
return (
<div>
{this.searchFilter()}
{this.renderList()}
</div>
);
}
}
export default TestPage;

First of all you need to store the input values corresponding to each input in state and post that you need to filter the items array.
I assume you wish to do an AND operation on filters. IF you wish to do an OR operation just change it in the code below
handleSearchFilter = (event) => {
const {value, name} = event.target;
this.setState({ [name]: value }, () => {
this.filterList();
}); // use setState callback to now filter the list
};
searchFilter = () => {
return <form>
<input name="filterTitle" type="text" value={this.state.filterTitle} onChange={this.handleSearchFilter} />
<input name="filterYear" type="text" value={this.state.filterYear} onChange={(e)=>this.handleSearchFilter} />
<input name="filterReso" type="text" value={this.state.filterReso} onChange={this.handleSearchFilter} />
</form>
}
filterList = () => {
const {items, updatedItems, filterTitle, filterYear, filterReso} = this.state;
const itemsUpdate = this.state.items.filter(item => {
var filterTitleRes = item.titulo.toLowerCase().indexOf(filterTitle.toLowerCase()) > 1;
var filterYearRes = item.ano.toLowerCase().indexOf(filterYear.toLowerCase()) > 1;
var filterResoRes = item.reso.toLowerCase().indexOf(filterReso.toLowerCase()) > 1;
return filterTitleRes && filterYearRes && filterResoRes;
// Change the above condition to or if you wish to do an OR check
})
this.setState({ updatedItems: itemsUpdate });
console.log(itemsUpdate);
}

You can use js-search for optimized searching across multiple keys in JSON object.
In your case, you can simply create a smaller JSON array where you only store keys in which you want to search for example
import * as JsSearch from 'js-search';
var theGreatGatsby = {
isbn: '9781597226769',
title: 'The Great Gatsby',
author: {
name: 'F. Scott Fitzgerald'
},
tags: ['book', 'inspirational']
};
var theDaVinciCode = {
isbn: '0307474275',
title: 'The DaVinci Code',
author: {
name: 'Dan Brown'
},
tags: ['book', 'mystery']
};
var angelsAndDemons = {
isbn: '074349346X',
title: 'Angels & Demons',
author: {
name: 'Dan Brown',
},
tags: ['book', 'mystery']
};
var search = new JsSearch.Search('isbn');
search.addIndex('title');
search.addIndex(['author', 'name']);
search.addIndex('tags')
search.addDocuments([theGreatGatsby, theDaVinciCode, angelsAndDemons]);
search.search('The'); // [theGreatGatsby, theDaVinciCode]

Related

change value of input field react

I have an input field in which I am pre populating the value of, with the value from the DB. it is a record that already exists, in which I would like to edit. The input field however, is not letting me edit the field. Please find it below:
import React, { useState, useEffect } from "react";
import axios from "axios";
import { useHistory } from "react-router-dom";
const EditServicesPage = () => {
const history = useHistory()
const [myData, setMyData] = useState({});
const [isLoading, setIsLoading] = useState(false);
const [showEditButton, setShowEditButton] = useState(false);
const [fields, setFields] = useState({
updatedByCNUM: "",
content: "",
site: ""
})
var idFromListServicesPage = history.location.state.id
console.log("22: " + idFromListServicesPage)
useEffect(() => {
axios
.post('/getDocToEdit', {id : idFromListServicesPage})
.then((res) => {
console.log("line 28 esp.js: " + res.data)
setMyData(res.data);
setIsLoading(true);
})
.catch((error) => {
// Handle the errors here
console.log(error);
})
.finally(() => {
setIsLoading(false);
});
}, []);
const deleteById = (id) => {
console.log(id);
axios
.post(`/deleteDoc`, { id: id })
.then(() => {
console.log(id, " worked");
window.location = "/admin/content";
})
.catch((error) => {
// Handle the errors here
console.log(error);
});
};
const handleInputChange = e => setFields(f => ({...f, [e.target.name]: e.target.value}))
const editById = (id, site, content, updatedByCNUM) => {
console.log(id, site, content, updatedByCNUM);
axios
.post(
'/editDoc',
({
id: id,
location: site,
content: content,
updatedByCNUM: updatedByCNUM
})
)
.then(() => {
console.log(id, " worked");
window.location = "/admin/content";
})
.catch((error) => {
console.log(error);
});
};
const onClickEdit = (e, _id) => {
e.preventDefault();
var site = document.getElementById("site").value;
var content = document.getElementById("content").value;
var updatedByCNUM = document.getElementById("updatedByCNUM").value;
console.log(site, content, updatedByCNUM)
editById(_id, site, content, updatedByCNUM);
};
const onTyping = (value) => {
if (value.length > 0) {
setShowEditButton(true);
} else {
setShowEditButton(false);
}
};
return (
<table id="customers">
<h1>Edit Services Page</h1>
<tr>
<th>site</th>
<th>content</th>
<th>updatedByCNUM</th>
<th>Actions</th>
</tr>
<tr>
<td>
<input
// ref={site.ref}
type="text"
value={myData.site}
onInput={(e) => onTyping(e.target.value)}
onChange={handleInputChange}
placeholder={myData.site}
name="site"
id="site"
/>{" "}
{/* <input
type="text"
placeholder={site}
onChange={(e) => onTyping(e.target.value)}
name="site"
id="site"
/> */}
</td>
<td>
<input
// ref={content.ref}
type="text"
value={myData.content}
onInput={(e) => onTyping(e.target.value)}
onChange={handleInputChange}
placeholder={myData.content}
name="content"
id="content"
/>
</td>
<td>
<input
type="text"
placeholder={myData.updatedByCNUM}
name="updatedByupdatedByCNUMhide"
id="updatedByupdatedByCNUMhide"
readOnly
/>{" "}
</td>
<td>
{/* <input type="hidden" placeholder={myData.updatedByCNUM} name="updatedByCNUM" id="updatedByCNUM" value={updatedByCNUM}/>{" "} */}
</td>
<td>
<button
onClick={(e) => {
e.preventDefault();
deleteById(idFromListServicesPage);
}}
disabled={isLoading}
>
Delete
</button>
<button
onClick={(e) => {
e.preventDefault();
editById(idFromListServicesPage);
}}
>
Edit
</button>
{showEditButton && (
<button onClick={(e) => onClickEdit(e, idFromListServicesPage)}>Submit Edit</button>
)}
</td>
</tr>
</table>
);
};
export default EditServicesPage;
showButton:
const onTyping = (value) => {
if (value.length > 0) {
setShowEditButton(true);
} else {
setShowEditButton(false);
}
};
when I try to type into the input field, it doesn't allow me to type, but keeps the pre existing value there already. how can I fix this?
You need a state which has the initial values from the DB
const [data, setData] = useState({
site: newData.site || "",
content: newData.content || "",
});
const handleInputChange = (e) => {
const { name, value } = e.target;
setData((currentData) => ({ ...currentData, [name]: value }));
};
return (
// .....
<input
// ref={site.ref}
type="text"
value={data.site} // use data.site here instead of the newData
onChange={handleInputChange}
placeholder={myData.site}
name="site"
id="site"
/>
// .....
);
Just add setMyData like this:
const onTyping = (name, value) => {
setMyData({ ...myData, [name]: value });
if (value.length > 0) {
setShowEditButton(true);
} else {
setShowEditButton(false);
}
};
And
onInput={(e) => onTyping(e.target.name, e.target.value)}

How to load data onto a React State from an API instead of local json file?

So as part of my project I'm trying to ammend this boilerplate of React-Pdf-Highlighter to accept pdf highlights from flask-api instead of a local file( the example came with a local/json import) ..
I have tried to check with console.log the fetch is not the problem, but I feel for somereason the 'testHighlights' state is not what it should be .
<<App.js>>
// #flow
/* eslint import/no-webpack-loader-syntax: 0 */
import React, { Component } from "react";
import PDFWorker from "worker-loader!pdfjs-dist/lib/pdf.worker";
import {
PdfLoader,
PdfHighlighter,
Tip,
Highlight,
Popup,
AreaHighlight,
setPdfWorker
} from "react-pdf-highlighter";
import Spinner from "./Spinner";
import Sidebar from "./Sidebar";
import testHighlights from "./test-highlights";
import type {
T_Highlight,
T_NewHighlight
} from "react-pdf-highlighter/src/types";
import "./style/App.css";
setPdfWorker(PDFWorker);
type Props = {};
type State = {
url: string,
highlights: Array<T_Highlight>
};
const getNextId = () => String(Math.random()).slice(2);
const parseIdFromHash = () =>
document.location.hash.slice("#highlight-".length);
const resetHash = () => {
document.location.hash = "";
};
const HighlightPopup = ({ comment }) =>
comment.text ? (
<div className="Highlight__popup">
{comment.emoji} {comment.text}
</div>
) : null;
const PRIMARY_PDF_URL = "https://arxiv.org/pdf/1708.08021.pdf";
const SECONDARY_PDF_URL = "https://arxiv.org/pdf/1604.02480.pdf";
const searchParams = new URLSearchParams(document.location.search);
const initialUrl = searchParams.get("url") || PRIMARY_PDF_URL;
class App extends Component<Props, State> {
state = {
url: initialUrl,
highlights: testHighlights[initialUrl]
? [...testHighlights[initialUrl]]
: []
};
state: State;
resetHighlights = () => {
this.setState({
highlights: []
});
};
toggleDocument = () => {
const newUrl =
this.state.url === PRIMARY_PDF_URL ? SECONDARY_PDF_URL : PRIMARY_PDF_URL;
this.setState({
url: newUrl,
highlights: testHighlights[newUrl] ? [...testHighlights[newUrl]] : []
});
};
scrollViewerTo = (highlight: any) => {};
scrollToHighlightFromHash = () => {
const highlight = this.getHighlightById(parseIdFromHash());
if (highlight) {
this.scrollViewerTo(highlight);
}
};
componentDidMount() {
window.addEventListener(
"hashchange",
this.scrollToHighlightFromHash,
false
);
}
getHighlightById(id: string) {
const { highlights } = this.state;
return highlights.find(highlight => highlight.id === id);
}
addHighlight(highlight: T_NewHighlight) {
const { highlights } = this.state;
console.log("Saving highlight", highlight);
this.setState({
highlights: [{ ...highlight, id: getNextId() }, ...highlights]
});
}
updateHighlight(highlightId: string, position: Object, content: Object) {
console.log("Updating highlight", highlightId, position, content);
this.setState({
highlights: this.state.highlights.map(h => {
const {
id,
position: originalPosition,
content: originalContent,
...rest
} = h;
return id === highlightId
? {
id,
position: { ...originalPosition, ...position },
content: { ...originalContent, ...content },
...rest
}
: h;
})
});
}
render() {
const { url, highlights } = this.state;
return (
<div className="App" style={{ display: "flex", height: "100vh" }}>
<Sidebar
highlights={highlights}
resetHighlights={this.resetHighlights}
toggleDocument={this.toggleDocument}
/>
<div
style={{
height: "100vh",
width: "75vw",
position: "relative"
}}
>
<PdfLoader url={url} beforeLoad={<Spinner />}>
{pdfDocument => (
<PdfHighlighter
pdfDocument={pdfDocument}
enableAreaSelection={event => event.altKey}
onScrollChange={resetHash}
// pdfScaleValue="page-width"
scrollRef={scrollTo => {
this.scrollViewerTo = scrollTo;
this.scrollToHighlightFromHash();
}}
onSelectionFinished={(
position,
content,
hideTipAndSelection,
transformSelection
) => (
<Tip
onOpen={transformSelection}
onConfirm={comment => {
this.addHighlight({ content, position, comment });
hideTipAndSelection();
}}
/>
)}
highlightTransform={(
highlight,
index,
setTip,
hideTip,
viewportToScaled,
screenshot,
isScrolledTo
) => {
const isTextHighlight = !Boolean(
highlight.content && highlight.content.image
);
const component = isTextHighlight ? (
<Highlight
isScrolledTo={isScrolledTo}
position={highlight.position}
comment={highlight.comment}
/>
) : (
<AreaHighlight
highlight={highlight}
onChange={boundingRect => {
this.updateHighlight(
highlight.id,
{ boundingRect: viewportToScaled(boundingRect) },
{ image: screenshot(boundingRect) }
);
}}
/>
);
return (
<Popup
popupContent={<HighlightPopup {...highlight} />}
onMouseOver={popupContent =>
setTip(highlight, highlight => popupContent)
}
onMouseOut={hideTip}
key={index}
children={component}
/>
);
}}
highlights={highlights}
/>
)}
</PdfLoader>
</div>
</div>
);
}
}
export default App;
<<test-highlights.js >>
const testHighlights =async () => {
const res= await fetch('http://127.0.0.1:5000/jsonapi')
const data =await res.json()
console.log(data)
this.state.testHighlights = data
return testHighlights;
}
export default testHighlights;
You can't assign state like this
this.state.testHighlights = data
You must use this.setState function to do it
this.setState({ testHighlights: data });
That is why your testHighlights state isn't what you was expected

Delete a Row using Fetch API Use Effect - ReactJS

am trying to delete a row based on product code entered, i have 2 functions, one is for search and another is for delete..
Search Function
const handleName = e => {
const idAddProducts = e.target.value;
e.preventDefault();
pnName({ ...poName, idaddproducts: idAddProducts });
handleTable(idAddProducts);
// handleSubmit(idAddProducts);
console.log(poName);
};
async function handleTable(idAddProducts) {
const id = poName.idaddproducts;
const res = await fetch(
"http://localhost:4000/productslist/" + idAddProducts
);
const data = await res.json();
pnName(data.data);
console.log(data.data);
}
useEffect(() => {
handleTable();
}, []);
Another one is Delete Function
const handleN = e => {
const idAddProducts = e.target.value;
e.preventDefault();
pnName({ ...poName, idaddproducts: idAddProducts });
handleSubmit(idAddProducts);
console.log(poName);
};
async function handleSubmit(idAddProducts) {
const res = await fetch(
"http://localhost:4000/productslist/delete/" + idAddProducts
);
const data = await res.json();
pnName(data.data);
console.log(data.data);
}
useEffect(() => {
handleSubmit();
}, []);
Here is the Rendering Part where i map the searched result
<TableBody>
{poName && poName.length ? (
poName.map(row => (
<TableRow key={row.idaddproducts}>
<TableCell component="th" scope="row">
{row.idaddproducts}
</TableCell>
<TableCell component="th" scope="row">
{row.productName}
</TableCell>
<TableCell align="right">{row.productId}</TableCell>
<TableCell align="right">{row.productBrand}</TableCell>
<TableCell align="right">{row.productQuantity}</TableCell>
<TableCell align="right">{row.productPrice}</TableCell>
<TableCell align="right">{row.productType}</TableCell>
</TableRow>
))
) : (
<span>Not Found</span>
)}
</TableBody>
</Table>
</TableContainer>
<div style={{ paddingBlockEnd: "0px" }}>
<Fab color="secondary" aria-label="edit" onClick={handleN}>
<EditIcon />
</Fab>
</div>
So when i add the handleSubmit function directly in to handleName, its getting deleted as i type, so i had to create seperate function as HandleN and call handle submit so that when i click button it should execute,
instead sql throws as Error:
ER_TRUNCATED_WRONG_VALUE: Truncated incorrect DOUBLE value:
'undefined'
or
Error: ER_TRUNCATED_WRONG_VALUE: Truncated incorrect DOUBLE value:
'[object]%20[object]'
Any help ?
export default function DeleteProductsForm() {
const initialState = {
idaddproducts: "",
productName: "",
productId: "",
productBrand: "",
productQuantity: "",
productPrice: "",
productType: ""
};
const [values, setValues] = React.useState(initialState);
const handleName = e => {
const idAddProducts = e.target.value;
console.log(idAddProducts);
e.preventDefault();
setValues({ ...values, [e.target.name]: idAddProducts });
handleList1(idAddProducts);
console.log(values);
};
const handleN = e => {
const idAddProducts = values.idaddproducts;
console.log(idAddProducts);
e.preventDefault();
setValues({ ...values, [e.target.name]: idAddProducts });
handleList(idAddProducts);
console.log(values);
};
async function handleList1(idAddProducts) {
const res = await fetch(
"http://localhost:4000/productslist/" + idAddProducts
);
const data = await res.json();
setValues(data.data);
console.log(data.data);
}
useEffect(() => {
handleList1();
}, []);
async function handleList(idAddProducts) {
const res = await fetch(
"http://localhost:4000/productslist/delete/" + idAddProducts
);
const data = await res.json();
setValues(data.data);
console.log(data.data);
}
useEffect(() => {
handleList();
}, []);
const classes = useStyles();
return (
<form className={classes.root} noValidate autoComplete="off" align="center">
<div className={classes.formGroup}>
<FormControl>
<Input
type="search"
label="Product ID"
variant="outlined"
size="small"
placeholder="Enter Product Code"
value={values.idaddproducts}
name="idaddproducts"
onChange={e => handleName(e)}
/>
</FormControl>
<Button onClick={e => handleN(e)}>Click</Button>
{values && values.length ? (
values.map(row => <h5 key={row.idaddproducts}>{row.productName}</h5>)
) : (
<h5>Not Found</h5>
)}
</div>
</form>
);
}
if i delete handleList1 function it works fine.. but it wont display data

Creating a slider by two input type="range" in reactjs

I have a JSON file called by a fetch() request. I have two input of type="range" .I want to merge the two.
Something like this.
I'd like to make the double slider , however if I position two elements on top of one another, only the top one is accepting mouse clicks. I do not wish to use any external library in React for the slider or the space between the two handlers, which is colourised.
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
data: [],
library: null,
librarySecond: null,
perPage: 20,
currentPage: 1,
maxPage: null,
filterTotalF: "",
filterTotalS: "",
rangevalTotalF: "",
rangevalTotalS: ""
};
}
componentDidMount() {
fetch("/json,bc", {
method: "get"
})
.then(response => response.text())
.then(text => {
let Maindata = JSON.parse(text.replace(/\'/g, '"'));
this.setState(
state => ({
...state,
data: Maindata
}),
() => {
this.reorganiseLibrary();
}
);
})
.catch(error => console.error(error));
}
reorganiseLibrary = () => {
const { filterTotalF, filterTotalS, perPage, data } = this.state;
let library = data;
let librarySecond = data;
librarySecond = _.chunk(librarySecond, perPage);
this.setState({
librarySecond,
currentPage: 1,
maxPage: librarySecond.length === 0 ? 1 : librarySecond.length
});
let defaultFilterF = null;
defaultFilterF = filterTotalF
? filterTotalF
: this.renderMinFilter(librarySecond);
let defaultFilterS = null;
defaultFilterS = filterTotalS
? filterTotalS
: this.renderMaxFilter(librarySecond);
if (defaultFilterF !== "" && defaultFilterS !== "") {
library = library.filter(
item =>
item.totalCom >= defaultFilterF && item.totalCom <= defaultFilterS
);
}
if (filterExitTimeDepF !== "" && filterExitTimeDepS !== "") {
library = library.filter(
item =>
this.rendershowexittimeDep(
item.info.departureinformation.ticketinfooo.exitinfo.showexittime
) >= filterExitTimeDepF &&
this.rendershowexittimeDep(
item.info.departureinformation.ticketinfooo.exitinfo.showexittime
) <= filterExitTimeDepS
);
}
if (filterExitTimeDesF !== "" && filterExitTimeDesS !== "") {
library = library.filter(
item =>
this.rendershowexittimeDes(
item.info.returninformation.ticketinfooo.exitinfo.showexittime
) >= filterExitTimeDesF &&
this.rendershowexittimeDes(
item.info.returninformation.ticketinfooo.exitinfo.showexittime
) <= filterExitTimeDesS
);
}
library = _.chunk(library, perPage);
this.setState({
library,
currentPage: 1,
maxPage: library.length === 0 ? 1 : library.length
});
};
renderMinFilter = librarySecond => {
return librarySecond.reduce((acc, lib) => {
const libMin = Math.min(...lib.map(item => item.totalCom));
return acc === undefined ? libMin : libMin < acc ? libMin : acc;
}, undefined);
};
renderMaxFilter = librarySecond => {
return librarySecond.reduce((acc, lib) => {
const libMax = Math.max(...lib.map(item => item.totalCom));
return libMax > acc ? libMax : acc;
}, 0);
};
// Previous Page
previousPage = event => {
this.handleClick(event);
this.setState({
currentPage: this.state.currentPage - 1
});
};
// Next Page
nextPage = event => {
this.handleClick(event);
this.setState({
currentPage: this.state.currentPage + 1
});
};
// handle filter
handleFilterTotal = evt => {
let value = evt.target.value;
let key = evt.target.getAttribute("data-key");
if (key == "1") {
this.setState(
{
filterTotalF: evt.target.value,
rangevalTotalF: evt.target.value
},
() => {
this.reorganiseLibrary();
}
);
} else if (key == "2") {
this.setState(
{
filterTotalS: evt.target.value,
rangevalTotalS: evt.target.value
},
() => {
this.reorganiseLibrary();
}
);
}
};
// handle per page
handlePerPage = evt =>
this.setState(
{
perPage: evt.target.value
},
() => this.reorganiseLibrary()
);
// handle render of library
renderLibrary = () => {
const { library, currentPage } = this.state;
if (!library || (library && library.length === 0)) {
return (
<div className="nodata">
<div className="tltnodata">برای جستجوی شما نتیجه ای یافت نشد!</div>
<div className="textnodata">
شما می توانید با انجام مجدد عملیات جستجو,نتیجه مورد نظر خود را
بیابید
</div>
</div>
);
}
return library[currentPage - 1]
.sort((a, b) => a.total - b.total)
.map((item, i) => (
<div className="item">
<span>{item.id}</span>
</div>
));
};
renderMinTotal = () => {
const { librarySecond } = this.state;
if (!librarySecond || (librarySecond && librarySecond.length === 0)) {
return "";
}
return librarySecond.reduce((acc, lib) => {
const libMin = Math.min(...lib.map(item => item.totalCom));
return acc === undefined ? libMin : libMin < acc ? libMin : acc;
}, undefined);
};
renderMaxTotal = () => {
const { librarySecond } = this.state;
if (!librarySecond || (librarySecond && librarySecond.length === 0)) {
return "";
}
return librarySecond.reduce((acc, lib) => {
const libMax = Math.max(...lib.map(item => item.totalCom));
return libMax > acc ? libMax : acc;
}, 0);
};
render() {
const {
library,
currentPage,
perPage,
maxPage,
rangevalTotalF,
rangevalTotalS,
librarySecond
} = this.state;
let defaultRangeF = null;
defaultRangeF = rangevalTotalF ? (
<span>{rangevalTotalF}</span>
) : (
<span>{this.renderMinTotal()}</span>
);
let defaultRangeS = null;
defaultRangeS = rangevalTotalS ? (
<span>{rangevalTotalS}</span>
) : (
<span>{this.renderMaxTotal()}</span>
);
return (
<div>
<div className="filter-box">
<div className="wrapper">
<input
type="range"
min={this.renderMinTotal()}
max={this.renderMaxTotal()}
defaultValue={this.renderMaxTotal()}
step="1000"
onChange={this.handleFilterTotal}
data-key="2"
className="exitTimeSecond"
/>
<div className="rangevalSecond">{defaultRangeS}</div>
</div>
<div className="wrapper">
<input
type="range"
min={this.renderMinTotal()}
max={this.renderMaxTotal()}
defaultValue={this.renderMinTotal()}
step="1000"
onChange={this.handleFilterTotal}
data-key="1"
className="exitTimeFirst"
/>
<div className="rangevalFirst">{defaultRangeF}</div>
</div>
</div>
{this.renderLibrary()}
<ul id="page-numbers">
<li className="nexprevPage">
{currentPage !== 1 && (
<button onClick={this.previousPage}>
<span className="fa-backward" />
</button>
)}
</li>
<li className="controlsPage active">{this.state.currentPage}</li>
<li className="restControls">...</li>
<li className="controlsPage">{this.state.maxPage}</li>
<li className="nexprevPage">
{currentPage < maxPage && (
<button onClick={this.nextPage}>
<span className="fa-forward" />
</button>
)}
</li>
</ul>
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("Result"));

Cannot modify value nor placeholder of HTML forms

I'm building this app with react, when pass the actual value like
<div class="form-group">
<input
value={this.state.setupList[0]} onChange{this.handleChange}
name="date" class="form-control" placeholder={this.state.setupList[0]} />
</div>
I can see the text but no modifications allowed, that's the function I'm using for the form:
handleChange(e) {
this.setState({ [e.target.name]: e.target.value });
}
Please someone suggest a better approach to fix the issue
Structure of the constructor
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
this.state = {
setupList: [],
title: '',
description: '',
show: false,
};
}
A random function I found on internet to store input in a value
handleChange(e) {
this.setState({ [e.target.name]: e.target.value });
}
With that I update the db
updateData = e => {
this.setState({ loading: true})
const { currentUser } = fire.auth();
e.preventDefault();
let title = this.state.title;
let description = this.state.description;
fire.database().ref(`/master/${currentUser.uid}/setup/`)
.update({
title: this.state.title,
description: this.state.description,
})
.then(() => {
this.setState({ loading: false, show:false})
});
}
And probably the issue is here
componentDidMount = () => {
fire.database().ref(`/master/${currentUser.uid}/setup/`)
.on('value', snapshot => {
var obj = snapshot.val()
var setupList = []
var keys = []
for(let a in obj){
setupList.push(obj[a])
keys.push(a)
}
this.setState({
setupList:setupList,
keys:keys,
...
Changing value to defaultValue works as expected. Such an easy solution
<div class="form-group">
<input
defaultValue={this.state.setupList[0]} onChange{this.handleChange}
name="date" class="form-control" placeholder={this.state.setupList[0]} />
</div>