remove the selected item from the Table. React - javascript

I need to click on the button to delete the line with the selected checkbox.
I don't know how to use the filter method. I read the documentation, but there is little information there. help me correct the code
class Table extends Component {
constructor(props) {
super(props);
this.state = {
droplets: [],
allSelected: false,
isChecked: false
}
this.toggleSelectAll = this.toggleSelectAll.bind(this);
this.toggleSelect = this.toggleSelect.bind(this);
this.handleChecked = this.handleChecked.bind(this);
**this.handleDelete = this.handleDelete.bind(this);**
}
async componentDidMount() {
const res = await fetch('http://api.npoint.io/324f4ca2cdd639760638');
const droplets = await res.json();
this.setState({ 'droplets': droplets })
}
toggleSelect(dropletToToggle) {
this.setState({isChecked: !this.state.isChecked});
this.setState((prevState) => {
const newDroplets = prevState.droplets.map((dplt) => {
if (dplt === dropletToToggle) {
return { ...dplt, checked: !dplt.checked };
}
return dplt;
});
return {
...prevState,
droplets: newDroplets,
allSelected: newDroplets.every((d) => !!d.checked)
};
});
}
toggleSelectAll() {
this.setState({isChecked: !this.state.isChecked});
this.setState((prevState) => {
const toggle = !prevState.allSelected;
const newDroplets = prevState.droplets.map((x) => ({
...x,
checked: toggle
}));
return {
...prevState,
droplets: newDroplets,
allSelected: toggle
};
});
}
handleChecked () {
this.setState({isChecked: !this.state.isChecked});
}
**handleDelete = isChecked => {
this.setState(state => {
const { droplets } = state;
const filteredDroplets = droplets.filter(item => item.id !== isChecked);
return {
droplets: filteredDroplets
};
});
};**
render() {
return (
<div className="body">
<div className="title">Таблица пользователей</div>
<table className="panel">
<Tablehead
toggleSelectAll={this.toggleSelectAll}
allSelected={this.state.allSelected}
/>
<tbody className="row">
<TableBody
droplets={this.state.droplets}
toggleSelect={this.toggleSelect}
/>
</tbody>
</table>
**<button className="button" onClick = {this.handleDelete} >Удалить выбранные</button>**
</div>
);
}
}
the second file in which the item to delete
const TableBody = ({ droplets, toggleSelect}) => {
return (
<>
{droplets.map((droplet, item) => (
<tr className={s.area} key={item.id} >
<td>
<Checkbox
handleClick={() => toggleSelect(droplet)}
isChecked={!!droplet.checked}
/>
</td>
<td>{droplet.num}</td>
<td>{droplet.first_name + " " + droplet.last_name}</td>
<td>{date_form(droplet.date_of_birth)}</td>
<td>{height_form(droplet.height)}</td>
<td>{weight_form(droplet.weight)}</td>
<td>{salary_form(droplet.salary)}</td>
<td>
<button type="submit" className={s.button}>
<Edit />
</button>
</td>
<td>
<button type="submit" className={s.button}>
<Trash />
</button>
</td>
</tr>
))}
</>
);
};
https://codesandbox.io/s/sweet-butterfly-0s4ff?file=/src/Table.jsx

I have altered your sandbox and added some functionality in order to delete the rows.
The comparison is based on full name but you can change it to whatever fits your needs.
https://codesandbox.io/s/keen-silence-i51wz

On your handleDelete function your filter condition seems wrong
Currently you have:
// Filters all droplets that have an id different to the value of isChecked.
const filteredDroplets = droplets.filter(item => item.id !== isChecked);
And it should be
// Returns all the droplets that are not checked
// Meaning that all the checked items are dropped from the array
const filteredDroplets = droplets.filter(item => !item.isChecked);

Related

When I remove an item from a array, how to change the status to deleted?

When the user adds a value to an object that is inside an array the status is updated to added.
I'm trying to do the same thing when that value is deleted, to update the status to deleted.
const initialName = [
{
name: "",
status: "",
},
];
export default function changeNames(){
const [name, setName] = useState([initialName ]);
const handleAdd = () => {
setName([...name, ""]);
};
const handleItemChanged = (event, index) => {
const value = event.target.value;
const list = [...name];
list[index] = { name: value + "-" + id, status: "added" };
setName(list);
};
...
}
So when I add an input field and type the name, the array looks like this:
[{…}]
0:
name: "John-id"
status: "added"
When I remove John from the array, I want smth like this:
[{…}]
0:
name: "John-id"
status: "deleted"
This is the remove function
const handleRemoveClick = (index) => {
const list = [...name];
list.splice(index, 1);
setName(list);
};
<div>
{name.map((o, i) => {
return (
<tr key={"item-" + i}>
<td>
<div>
<input
type="text"
value={o.item}
onChange={(event) => handleItemChanged(event, i)}
placeholder="Name it"
/>
</div>
</td>
<td>
<button type="button" onClick={handleRemoveClick}>
Delete
</button>
</td>
</tr>
);
})}
<div>
<button Click={handleAddClick}>
Add Language
</button>
</div>
</div>
);
How can I make it work?
I think this might help you.thank you
import { useState } from "react";
import "./styles.css";
export default function App() {
const [Name, setName] = useState([]);
const [input, setInput] = useState({ name: "", status: "" });
const handleItemChanged = (event, index) => {
const { value } = event.target;
setInput({ name: value + "-id", status: "added" });
};
const addHandler = () => {
setName((prev) => {
return [...prev, input];
});
};
const removeHandler = (i) => {
const arr = [...Name];
arr[i].status = "deleted";
setName(arr);
};
return (
<div className="App">
<input type="text" name="name" onChange={(e) =>
handleItemChanged(e)} />
<button onClick={addHandler} style={{ margin: "1rem" }}>
Add
</button>
<div>
{Name &&
Name.map((data, i) => {
return (
<div key={i}>
<h3>
{data.name} {data.status}
<button
style={{ margin: "1rem" }}
onClick={() => removeHandler(i)}
>
Delete
</button>
</h3>
</div>
);
})}
</div>
</div>
);
}
You need to change the "status" property, because there is no way of removing item and setting its property.
const handleRemoveClick = (event, index) => {
const list = [...name];
list[index].status = "deleted";
setName(list);
};
And later while rendering you have to either perform a check in map function (not really elegant), or first filter your array and then map it:
// first, not elegant in my opinion
...
{name.map(item => item.status !== "deleted" ? <div>item.name</div> : null)}
// second approach
...
{name.filter(item => item.status !== "deleted").map(item => <div>item.name</div>)}

edit notes on a Google Keep clone app with React js

I am building a clone of the Google Keep app with react js. I added all the basic functionality (expand the create area, add a note, delete it) but I can't seem to manage the edit part. Currently I am able to edit the inputs and store the values in the state, but how can I replace the initial input values for the new values that I type on the input?
This is Note component
export default function Note(props) {
const [editNote, setEditNote] = useState(false);
const [currentNote, setCurrentNote] = useState({
id: props.id,
editTitle: props.title,
editContent: props.content,
});
const handleDelete = () => {
props.deleteNote(props.id);
};
const handleEdit = () => {
setEditNote(true);
setCurrentNote((prevValue) => ({ ...prevValue }));
};
const handleInputEdit = (event) => {
const { name, value } = event.target;
setCurrentNote((prevValue) => ({
...prevValue,
[name]: value,
}));
};
const updateNote = () => {
setCurrentNote((prevValue, id) => {
if (currentNote.id === id) {
props.title = currentNote.editTitle;
props.content = currentNote.editContent;
} else {
return { ...prevValue };
}
});
setEditNote(false);
};
return (
<div>
{editNote ? (
<div className='note'>
<input
type='text'
name='edittitle'
defaultValue={currentNote.editTitle}
onChange={handleInputEdit}
className='edit-input'
/>
<textarea
name='editcontent'
defaultValue={currentNote.editContent}
row='1'
onChange={handleInputEdit}
className='edit-input'
/>
<button onClick={() => setEditNote(false)}>Cancel</button>
<button onClick={updateNote}>Save</button>
</div>
) : (
<div className='note' onDoubleClick={handleEdit}>
<h1>{props.title}</h1>
<p>{props.content}</p>
<button onClick={handleDelete}>DELETE</button>
</div>
)}
</div>
);
}
And this is the Container component where I am renderind the CreateArea and mapping the notes I create. I tried to map the notes again with the new values but it wasn't working.
export default function Container() {
const [notes, setNotes] = useState([]);
const addNote = (newNote) => {
setNotes((prevNotes) => {
return [...prevNotes, newNote];
});
};
const deleteNote = (id) => {
setNotes((prevNotes) => {
return prevNotes.filter((note, index) => {
return index !== id;
});
});
};
// const handleUpdateNote = (id, updatedNote) => {
// const updatedItem = notes.map((note, index) => {
// return index === id ? updatedNote : note;
// });
// setNotes(updatedItem);
// };
return (
<div>
<CreateArea addNote={addNote} />
{notes.map((note, index) => {
return (
<Note
key={index}
id={index}
title={note.title}
content={note.content}
deleteNote={deleteNote}
//handleUpdateNote={handleUpdateNote}
/>
);
})}
</div>
);
}
There are a couple of mistakes in your code.
The state properties are in the camel case
const [currentNote, setCurrentNote] = useState({
...
editTitle: props.title,
editContent: props.content,
});
But the names of the input are in lowercase.
<input
name='edittitle'
...
/>
<textarea
name='editcontent'
...
/>
Thus in handleInputEdit you don't update the state but add new properties: edittitle and editcontent. Change the names to the camel case.
In React you cant assign to the component prop values, they are read-only.
const updateNote = () => {
...
props.title = currentNote.editTitle;
props.content = currentNote.editContent;
You need to use the handleUpdateNote function passed by the parent component instead. You have it commented for some reason.
<Note
...
//handleUpdateNote={handleUpdateNote}
/>
Check the code below. I think it does what you need.
function Note({ id, title, content, handleUpdateNote, deleteNote }) {
const [editNote, setEditNote] = React.useState(false);
const [currentNote, setCurrentNote] = React.useState({
id,
editTitle: title,
editContent: content,
});
const handleDelete = () => {
deleteNote(id);
};
const handleEdit = () => {
setEditNote(true);
setCurrentNote((prevValue) => ({ ...prevValue }));
};
const handleInputEdit = (event) => {
const { name, value } = event.target;
setCurrentNote((prevValue) => ({
...prevValue,
[name]: value,
}));
};
const updateNote = () => {
handleUpdateNote({
id: currentNote.id,
title: currentNote.editTitle,
content: currentNote.editContent
});
setEditNote(false);
};
return (
<div>
{editNote ? (
<div className='note'>
<input
type='text'
name='editTitle'
defaultValue={currentNote.editTitle}
onChange={handleInputEdit}
className='edit-input'
/>
<textarea
name='editContent'
defaultValue={currentNote.editContent}
row='1'
onChange={handleInputEdit}
className='edit-input'
/>
<button onClick={() => setEditNote(false)}>Cancel</button>
<button onClick={updateNote}>Save</button>
</div>
) : (
<div className='note' onDoubleClick={handleEdit}>
<h1>{title}</h1>
<p>{content}</p>
<button onClick={handleDelete}>DELETE</button>
</div>
)}
</div>
);
}
function CreateArea() {
return null;
}
function Container() {
const [notes, setNotes] = React.useState([
{ title: 'Words', content: 'hello, bye' },
{ title: 'Food', content: 'milk, cheese' }
]);
const addNote = (newNote) => {
setNotes((prevNotes) => {
return [...prevNotes, newNote];
});
};
const deleteNote = (id) => {
setNotes((prevNotes) => {
return prevNotes.filter((note, index) => {
return index !== id;
});
});
};
const handleUpdateNote = ({ id, title, content }) => {
const _notes = [];
for (let i = 0; i < notes.length; i++) {
if (i === id) {
_notes.push({ id, title, content });
} else {
_notes.push(notes[i]);
}
}
setNotes(_notes);
};
return (
<div>
<CreateArea addNote={addNote} />
{notes.map((note, index) => {
return (
<Note
key={index}
id={index}
title={note.title}
content={note.content}
deleteNote={deleteNote}
handleUpdateNote={handleUpdateNote}
/>
);
})}
</div>
);
}
function App() {
return (
<div>
<Container />
</div>
);
}
ReactDOM.render(
<App />,
document.getElementById('root')
);
<script src="https://unpkg.com/react#17/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom#17/umd/react-dom.development.js" crossorigin></script>
<div id="root"></div>
Also, you can store the notes in an object or hash map instead of an array. For example
const [notes, setNotes] = React.useState({
'unique_id': { title: 'Words', content: 'hello, bye' }
});
Then in handleUpdateNote you have
setNotes((prev) => ({ ...prev, unique_id: { title, content } }))

Set input to a controller input using button onclick method in React JS

I find myself struggling to change the form input value from the button onClick handler. My problem is escalated by the fact that I have the line items on a form and things become even more complex that way. I tried to bring in a ref to set value,,, the value is displayed but at the form state after submission it remains empty which means the value is not being set. Below are all my code files. May someone kindly help me on where I may be missing the point.
class VehicleTemplate extends React.Component {
constructor(props){
super(props);
this.ws = new WebSocket('ws://localhost:8000/ws/weightData/');
this.socketRef = null;
this.state = {
data: 0,
name: '',
model: '',
plate_number: '',
type: 'truck',
wagons: [{ index: uuid(), label: '', type: 'once', weight: '' }],
total: 0,
};
this.onSubmit = this.onSubmit.bind(this);
this.handleChange= this.handleChange.bind(this);
this.handleChangeTable = this.handleChangeTable.bind(this);
this.addNewRow = this.addNewRow.bind(this);
this.deleteRow = this.deleteRow.bind(this);
this.handleLineItemChange = this.handleLineItemChange.bind(this);
}
componentDidMount() {
this.ws.onopen = () => {
// on connecting, do nothing but log it to the console
console.log('connected')
}
this.ws.onmessage = evt => {
// listen to data sent from the websocket server
// const message = JSON.parse(evt.data)
const {data} = this.state;
this.setState({data: evt.data})
// this.setState({this.state.lines.weight: data})
}
this.ws.onclose = () => {
console.log('disconnected')
// automatically try to reconnect on connection loss
}
};
onSubmit = (e) => {
e.preventDefault();
const {
name,
model,
plate_number,
type,
wagons,
} = this.state;
const vehicle = {
name,
model,
plate_number,
type,
wagons,
};
this.props.addVehicle(vehicle, this.props.token);
console.log(vehicle);
this.setState({
name: '',
model: '',
plate_number: '',
wagons: [],
});
};
handleLineItemChange = (elementIndex) => (event) => {
let wagons = this.state.wagons.map((item, i) => {
if (elementIndex !== i) return item
return {...item, [event.target.name]: event.target.value}
})
this.setState({wagons})
}
handleChange = name => event => {
this.setState({
[name]: event.target.value,
});
};
handleChangeTable = (name, id) => event => {
this.updateItem(id, { [name]: event.target.value });
};
addNewRow = (event) => {
this.setState({
wagons: this.state.wagons.concat(
[{index: uuid(), label: '', type: 'once', weight: '' }]
)
})
}
deleteRow = (index) => (event) => {
this.setState({
wagons: this.state.wagons.filter((item, i) => {
return index !== i
})
})
}
handleReorderLineItems = (newLineItems) => {
this.setState({
wagons: newLineItems,
})
}
clickOnDelete(record) {
this.setState({
wagons: this.state.lines.filter(r => r !== record)
});
}
render() {
const { classes } = this.props;
const {
data,
name,
model,
plate_number,
wagons,
} = this.state;
return (
<InformationTechnologyLayout>
<PapperBlock title="ADD VEHICLE" icon="ios-document-outline" desc="VEHICLE">
<Form>
<div style={{ clear: 'both' }} />
<h1>WEIGHT: {data}KG</h1>
<Grid container>
<Grid item xs={6}>
<Controls.Input
name="name"
label="Name"
value={name}
onChange={this.handleChange('name')}
/>
<Controls.Input
name="model"
label="MODEL"
value={model}
onChange={this.handleChange('model')}
/>
</Grid>
<Grid item xs={6}>
<Controls.Input
name="plate_number"
label="PLATE NUMBER"
value={plate_number}
onChange={this.handleChange('plate_number')}
/>
</Grid>
</Grid>
<Extensions
items={wagons}
addHandler={this.addNewRow}
changeHandler={this.handleLineItemChange}
focusHandler={this.handleFocusSelect}
deleteHandler={this.deleteRow}
reorderHandler={this.handleReorderLineItems}
data ={data}
/>
<div className='valueTable'>
<div className='row'>
<div className='label'>Subtotal</div>
<div className='value'>{this.calcLineItemsTotal()}KG</div>
</div>
<div className='row'>
<div className='label'>Total Due</div>
<div className='value'>{this.calcGrandTotal()}KG</div>
</div>
</div>
<Button variant="contained" onClick={this.onSubmit}>SUBMIT</Button>
</Form>
</PapperBlock>
</InformationTechnologyLayout>
);
}
}
On top is the main form component which has got Vehicle exetnsions and I am getting my weight from a websocket connection streaming scale outputs.
class Extensions extends Component {
handleDragEnd = (result) => {
if (!result.destination) return
// helper function to reorder result (src: react-beautiful-dnd docs)
const reorder = (list, startIndex, endIndex) => {
const result = Array.from(list)
const [removed] = result.splice(startIndex, 1)
result.splice(endIndex, 0, removed)
return result
}
// perform reorder
const lineItems = reorder(
this.props.items,
result.source.index,
result.destination.index
)
// call parent handler with new state representation
this.props.reorderHandler(lineItems)
}
render = () => {
const {
items,
addHandler,
changeHandler,
focusHandler,
deleteHandler,
reorderHandler,
products,
data,
readOnly,
} = this.props
return (
<form>
<div className='lineItems'>
<div className='gridTable'>
<DragDropContext onDragEnd={this.handleDragEnd}>
<Droppable droppableId="droppable">
{(provided, snapshot) => (
<div
ref={provided.innerRef}
className= 'listDraggingOver'
>
{this.props.items.map((item, i) => (
<Draggable key={item.index} draggableId={item.index} index={i}>
{(provided, snapshot) => (
<div
ref={provided.innerRef}
{...provided.draggableProps}
{...provided.dragHandleProps}
style={provided.draggableProps.style}
className='listItemDragging'
>
<Extension
addHandler={addHandler}
changeHandler={changeHandler}
focusHandler={focusHandler}
deleteHandler={deleteHandler}
reorderHandler={reorderHandler}
data={data}
style={{color: 'red'}}
key={i + item.index}
index={i}
name={item.index}
label={item.label}
weight={item.weight}
/>
</div>
)}
</Draggable>
))}
{provided.placeholder}
</div>
)}
</Droppable>
</DragDropContext>
</div>
<div className='addItem'>
<button type="button" onClick={addHandler}><AddIcon size="1.25em" className='addIcon' /> Add Item</button>
</div>
</div>
</form>
)
}
}
This are the extensions and the last file is where I would like to capture weight from
class LineItem extends Component {
constructor(props){
super(props);
this.ref = React.createRef();
this.state = {
buttonState: false,
};
}
requestWeight = () => {
const { weight } = this.props;
const {buttonState} =this.state;
this.ref.current.value = this.props.data;
this.setState({
buttonState: true
})
};
render = () => {
const { index, label, weight } = this.props;
const {buttonState} = this.state;
return (
<div className='lineItem'>
<div>{index + 1}</div>
<Controls.Input
name="label"
label="LABEL"
value={label}
onChange={this.props.changeHandler(index)}
/>
<input
className='currency'
type='number'
readOnly={true}
ref={this.ref}
name='weight'
onChange={this.props.changeHandler(index)}
/>
<div>
<button type="button"
className='requestItems'
onClick={this.requestWeight}
disabled={buttonState}
>REQUEST WEIGHT</button>
</div>
<div>
<button type="button"
className='deleteItem'
onClick={this.props.deleteHandler(index)}
><DeleteIcon size="1.25em" /></button>
</div>
</div>
)
}
}
export default LineItem
If I add the value and put weight on the input then the ref stops working. I assume I might be missing something between my handleChange function and the requestWeight function but I really dont know what exaclty

How get a value in a select before select one?

I have a problem with my DropDown list with react, i want pre select a value in the list but i dont know how i can do it.
For exemple: before i select a value in the list, i want when get one before i select a value, for exemple the first element i get in my database.
class App :
class App extends Component {
constructor(props) {
super(props);
this.state = {
data: [],
station: [],
stationValue: ''
}
}
getParking = async () => {
try {
const reponse = await axios.get(URL + "station/");
this.setState({
station: reponse.data['hydra:member']
});
} catch (e) {
console.log(e)
}
};
getData = async () => {
try {
const response = await axios.get(URL + "events?station=" + this.state.stationValue);
this.setState({
data: response.data["hydra:member"]
});
} catch (error) {
console.log(error)
}
};
componentDidMount() {
this.getData();
this.getParking()
setInterval(this.appendData, 1000)
}
setStation=(stationValue)=>{
this.setState({stationValue:stationValue})
}
render() {
const {data, station} = this.state;
return (
<div>
<header>
<Dropdown dataStation={station} setStation={this.setStation} value={this.handleChange}/>
</header>
{
data.map((item, key) =>
<div key={key}>
<>
{item.label}
</>
</div>
)
}
</div>
)
}
}
composent DropDown :
const Dropdown = ({dataStation, setParking, value}) => {
const [showMenu, setShowMenu] = useState(false);
const [selectItem, setSelectItem] = useState(showMenu);
const showList = () => {
setShowMenu(!showMenu)
};
const toggleSelected = (list) => {
setSelectItem(list.name);
setShowMenu(false)
};
return (
<>
<div className="dropdown-list-style" onClick={showList}>
<div style={{display: 'inline'}}>
{showMenu
? (<div style={{textAlign: 'right'}}><ChevronUp/></div>)
: (<div style={{textAlign: 'right'}}><ChevronDown/></div>)
}
{selectItem}
</div>
</div>
<div className="dropdown-list-style" style={{display: showMenu ? 'block' : 'none'}}>
{
dataStation.map((list, index) =>
<div key={index} onClick={() => toggleSelected(list); props.setStation(list)}}>
{list.name}
</div>
)
}
</div>
</>
)};
i tried something like
dataStation[0].name
but its not good, someone can help me please?
You can use useEffect hook. When the get request for the stations finishes and props change, it will select the first element from the array as the default value.
useEffect(() => {
if (Array.isArray(dataStation) && dataStation[0]) {
selectItem(dataStation[0].name);
}
}, [dataStation]);

React: search form with multiple inputs is submitting separate search each time additional input is used

My search form is dynmically created using a ajax call for the inputs. Each input can then be used alone or in combination with other inputs to narrow down the search results. The problem I am having is that the submit method is running a new search each time an additional input is added to the form. For example: User just searches with one input. Submit method runs once. User searches with two inputs. Search runs once for the single input and then another time for the two inputs. And so on...
Here is my parent file..
class SearchPage extends React.Component {
constructor(props, context) {
super(props, context);
this.state = {
labels: [],
contracts: [],
formValues:[],
pdfs:[],
titles:[],
alertShow: false,
show: false,
};
this.onClick = this.handleContract.bind(this);
this.handleShow = this.handleShow.bind(this);
this.handleClose = this.handleClose.bind(this);
this.handleShowAlert = this.handleShowAlert.bind(this);
this.handleCloseAlert = this.handleCloseAlert.bind(this)
}
initialState = {
formValues: {},
}
state = this.initialState
componentDidMount(){
this.loadLabels();
}
componentWillUnmount(){
}
toggleHidden () {
this.setState({
isHidden: !this.state.isHidden
})
}
handleFormReset = () => {
this.setState(() => this.initialState)
this.setState({contracts:[]})
}
handleClose() {
this.setState({ show: false });
}
handleShow() {
this.setState({ show: true });
}
handleCloseAlert() {
this.setState({ alertShow: false });
}
handleShowAlert() {
this.setState({ alertShow: true });
}
loadLabels = () => {
API.getLabels()
.then(res => {
const labels = res.data;
this.setState({ labels })
})
.catch(err => console.log(err));
};
handleInputChange = (key, value) => {
const newFormValues = Object.assign({}, this.state.formValues, {[key]: value});
this.setState({ formValues: newFormValues })
};
handleContract = (id) => {
API.openRow(id)
.then(res => {
const pdfs = res.data;
this.setState({pdfs});
this.props.history.push({
state: { labels:this.state.labels,
pdfs:this.state.pdfs,
titles:this.state.titles }
})
})
.catch(err => console.log(err));
API.titles(id)
.then(res => {
const titles = res.data;
this.setState({titles});
})
this.setState({ show: true });
}
handleFormSubmit = event => {
event.preventDefault();
const formData = this.state.formValues
let query = '';
let keys = Object.keys(formData);
keys.map(k => {
if (query !== "")
query += `&`;
query += `filter=`
query += `${k}|${formData[k]}`
return this.loadContracts(query);
})
};
noResults() {
this.setState({alertShow:true})
}
loadContracts = (query) => {
API.search(query)
.then(res => {
const contracts = res.data;
if (contracts.length > 0 ){
this.setState({ contracts });
}
else {
this.noResults();
this.setState({contracts:[]});
};
})
.catch(err => console.log(err));
};
render() {
return (
<div className="container" style={{ marginTop: "80px" }}>
<div className="jumbotron">
<div className="container">
<h1>Contract Document Search</h1>
</div>
<br/>
<Container>
<SearchForm
labels={this.state.labels}
handleFormSubmit={this.handleFormSubmit}
handleInputChange={this.handleInputChange}
handleReset={this.handleReset}
handleFormReset={this.handleFormReset}
/>
<div className='modal'>
<Modal show={this.state.alertShow}
onHide={this.handleCloseAlert}
{...this.props}
size="sm"
aria-labelledby="contained-modal-title-vcenter"
centered>
<Modal.Header closeButton>
<Modal.Body>No results found</Modal.Body>
</Modal.Header>
</Modal>
</div>
</Container>
</div>
<div className="container">
<div className="jumbotron-fluid">
</div>
<SearchResults
labels={this.state.labels}
contracts={this.state.contracts}
pdfs={this.state.pdfs}
handleContract={this.onClick}
handleTitles={this.onClick}
/>
<br/>
<br/>
</div>
);
}
}
export default SearchPage;
And My search form component..
export default class SearchForm extends Component {
constructor(...args) {
super(...args);
this.state = {
};
}
render() {
return (
<form className="form-inline col-md-12" onReset={this.props.handleFormReset}>
{this.props.labels.map(label => (
<div className="card border-0 mx-auto" style={styles} key={label.Id}>
<ul className="list-inline ">
<span>
<li>
<Labels htmlFor={label.DisplayName} >{label.DisplayName}:</Labels>
</li>
<li >
<Input
key={label.Id}
onChange={(event) => {
this.props.handleInputChange(label.DataField, event.target.value)}}
value={this.props.newFormValues}
maxLength="999"
style={{height:34}}
name="value"
type="search"
className={"form-control mb-2 mr-sm-2"}
id={label.DataField}
/>
</li>
</span>
</ul>
</div>
))}
<div className=" col-sm-12">
<Button
style={{ float: "left", marginBottom: 10 }}
className="btn btn-success"
type="submit"
onClick={this.props.handleFormSubmit}
>
Search
</Button>
<Help />
<Button
style={{ float: "left", marginBottom: 10 }}
className="btn btn-secondary"
type="reset"
onClick={this.props.handleFormReset}
>
Reset
</Button>
</div>
</form>
);
}
}
The problem was that I had my return statement inside the input mapping.
handleFormSubmit = event => {
event.preventDefault();
const formData = this.state.formValues
let query = '';
let keys = Object.keys(formData);
keys.map(k => {
if (query !== "")
query += `&`;
query += `filter=`
query += `${k}|${formData[k]}`
**return this.loadContracts(query);**
})
};
Solved by moving the return statement outside the mapping.
handleFormSubmit = event => {
event.preventDefault();
const formData = this.state.formValues
let query = '';
let keys = Object.keys(formData);
keys.map(k => {
if (query !== "")
query += `&`;
query += `filter=`
query += `${k}|${formData[k]}`
})
**return this.loadContracts(query);**
};

Categories