Add an onClick to a submit button in React - javascript

I have this button in react
{editing && (
<Button extraClasses="m1" onClick={this.handleEditing} type="submit">
Save
</Button>
)}
But the submit doesn't work, if I delete the onClick, the submit works. How can I make both, the onClick and the submit to work?
This is the onSubmit event:
handleSubmit(e) {
e.preventDefault();
const params = this.state.params || this.props.selected.params;
const { exportTypes } = this.props;
const {
startDate: startDateMoment,
endDate: endDateMoment,
companyId,
exportTypeId,
id,
} = this.state;
const type = exportTypes.find(o => o.id === Number(exportTypeId));
let enrichedParams = [];
if (type.params.length > 0) {
enrichedParams = params.reduce((acc, { paramName, paramValue }) => {
const { id: exportParameterId } = type.params.find(p => p.name === paramName);
return [...acc, { exportParameterId, paramName, paramValue }];
}, []);
}
const startDate = startDateMoment.format();
const endDate = endDateMoment.format();
const record = { companyId, exportTypeId, startDate, endDate, id, params: enrichedParams };
const filteredQuery = Object.keys(record).reduce(
(acc, k) => (record[k] ? { ...acc, [k]: record[k] } : acc),
{},
);
if (!Object.keys(filteredQuery).length) return;
this.props.updateExport(filteredQuery);
}

You could remove the onClick event handler from your Button and invoke the handleEditing method inside your handleSubmit method instead.
Example
class App extends React.Component {
handleEditing = () => {
// ...
};
handleSubmit = (e) => {
// ...
this.handleEditing();
};
render() {
return (
<div>
{/* ... */}
{editing && (
<Button extraClasses="m1" type="submit">
Save
</Button>
)}
{/* ... */}
</div>
);
}
}

Related

How to update state in onSubmit form & send data through components?

I have a state which I need to update with the ID returned from an endpoint call so I can call another another endpoint using that ID, I've made a state in the parent component and I use it in my first form to set the ID. I pass that id as a prop to the component that needs it but when I console.log the state, it doesn't change.
How can I pass the ID through the components?
I've added comments on the main places to look at
Here is my first form where I need the ID from -
const AddWebAppTypeForm = (props: any, ref: any) => {
const { setWebAppTypes, setNewAppValues}: AddWebAppTypeFormProps =
props;
const {
handleSubmit,
control,
reset,
formState: { isDirty },
} = useForm();
const onSubmit = (data: any) => {
let formData = new FormData();
formData.append("name", data.Title);
formData.append("description", data.Description);
formData.append("uploaded_file", data.Image[0]);
if (isDirty) {
createWebAppType(formData);
}
};
const createWebAppType = async (body: any) => {
await fetch(`${process.env.REACT_APP_API_URL}/webapptype`, {
method: "POST",
body: body,
})
.then((response) => response.json())
.then((data: IWebAppType) => {
const model: IWebAppType = {
id: data.id,
name: data.name,
image: data.image,
description: data.description,
image_url: data.image_url,
};
setNewAppValues(model.id); // <--- Set the state here
setWebAppTypes((prev) =>
prev.map((item) => (item.id === 0 ? model : item))
);
enqueueSnackbar(`Created App Succesfully`, {
variant: "success",
});
});
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<button hidden={true} ref={ref} type="submit" />
</form>
);
};
export default forwardRef(AddWebAppTypeForm);
My parent component with the states -
function WebAppTypeAccordion({ a, setWebAppTypes }: WebAppTypeAccordionProps) {
const [formEl, setFormEl] = useState(null);
const [addFormEl, setAddFormEl] = useState(null);
const [newAppValues, setNewAppValues] = useState<number>(0); // <--- state with 0 as initialised value
const handleRef = (el: any) => {
if (el !== null) {
setFormEl(el);
}
};
const handleAddRef = (el: any) => {
if (el !== null) {
setAddFormEl(el);
}
};
return (
<Accordion defaultExpanded={a.id === 0}>
<AccordionSummary
// onClick={(e) => handleOnClick(a, e)}
expandIcon={<ExpandMoreIcon />}
aria-controls="panel1a-content"
id="panel1a-header"
>
<Typography>{a.name}</Typography>
</AccordionSummary>
<AccordionDetails>
{a.id === 0 ? (
<AddWebAppTypeForm
setWebAppTypes={setWebAppTypes}
ref={handleAddRef}
setNewAppValues={setNewAppValues} // <--- Passing setState to set id
/>
) : (
null
)}
<MappedAccordion
waobj={a}
key={a.id}
setWebAppTypes={setWebAppTypes}
editRef={formEl}
addRef={addFormEl}
newAppValues={newAppValues} // <--- Passing ID
/>
</AccordionDetails>
</Accordion>
);
}
export default WebAppTypeAccordion;
Here is where I am trying to use the ID to call another endpoint
function MappedAccordion({
waobj,
setWebAppTypes,
editRef,
addRef,
newAppValues,
}: MappedAccordionProps) {
const handleCreate = (data: FieldT) => {
let wtype: string = String(waobj.id);
if (addRef !== null) {
if (newAppValues !== 0) {
wtype = String(newAppValues); // <--- Try to use the ID but get default value
createFetch(data, wtype); // <--- Try to use the ID but get default value
}
}
createFetch(data, wtype);
};
const createFetch = (data: FieldT, wtype: string) => {
let formData = new FormData();
formData.append("name", data.name);
formData.append("link", data.link);
formData.append("wtype", wtype);
fetch(`${process.env.REACT_APP_API_URL}/webapp/`, {
method: "POST",
body: formData,
})
.then((response) => {
if (!response.ok) {
let err = new Error("HTTP status code: " + response.status);
enqueueSnackbar(`Environment already exists`, {
variant: "error",
});
throw err;
}
return response.json();
})
.then((data: IWebApp) => {
const model: FieldT = {
wid: data.id,
name: data.name,
link: data.link,
};
enqueueSnackbar(`Created Environment ${model.wid}`, {
variant: "success",
});
});
};
const onSubmit = (data: FormFields) => {
if (addRef !== null) addRef?.click(); // <--- Submit AddWebAppTypeForm form, set the ID
else editRef?.click();
let onSubmitData: FieldT[] = data.myFieldValues;
onSubmitData.map((a: FieldT, index) => {
let originalField: FieldT = initialFields[index];
if (a.wid === undefined) {
handleCreate(a);
} else {
if (JSON.stringify(a) !== JSON.stringify(originalField)) {
handleEdit(a);
}
}
});
};
return (
<div>
<form onSubmit={handleSubmit(onSubmit)} id="environment-form">
<div style={{ paddingTop: 10 }}>
<Button
type="submit" // <--- Submit form
variant="outlined"
size="small"
sx={{ marginRight: 1 }}
>
Save
</Button>
<Button
variant="outlined"
size="small"
onClick={handleAppDelete}
disabled={waobj.id === 0 ? true : false}
>
Delete
</Button>
</div>
</form>
</div>
);
}
export default MappedAccordion;
Thanks for taking a look, I appreciate any help!

Checkbox value not being saved in LocalStorage and after clicking edit item the add button is not coming again

I was trying to make a ToDo Site and I wanted to save if the checkbox is checked or not in LocalStorage. But whenever I am checking the button the values inside the last are vanishing and it is not even being saved in the LocalStorage.
The following is my code:
import React from "react";
import Navbar from './components/Navbar'
import '../src/App.css'
export default function TodoInput() {
const saveLocalTasks = () => {
let savedTasks = localStorage.getItem('tasks');
console.log(savedTasks)
if (savedTasks) {
return JSON.parse(localStorage.getItem('tasks'));
} else {
return [];
}
}
const [task, setTask] = React.useState('')
// const [count, setCount] = React.useState(0)
const [taskList, setTaskList] = React.useState(saveLocalTasks)
const [disable, setDisable] = React.useState(true)
const [edit, setEdit] = React.useState(true)
const [isTaskEdit, setIsTaskEdit] = React.useState(null)
React.useEffect(() => {
localStorage.setItem('tasks', JSON.stringify(taskList))
}, [taskList]);
const updateTaskList = () => {
if (task && !edit) {
setTask('')
setTaskList(
taskList.map((item) => {
if(item.key === isTaskEdit) {
return {...item, object: task}
}
setEdit(true)
return item
}
)
)
}else {
setTaskList([...taskList, {object: task, key: Date.now(), completed: false}])
setTask('')
// setCount(count + 1)
setDisable(true)
}
}
const inputValue = e => {
setTask(e.target.value)
e.target.value === '' || task === '' || task.length === 0
?
setDisable(true)
:
setDisable(false)
}
console.log(task.length)
const deleteTaskListItem = (key) => {
const updatedList = taskList.filter((item) => {
return (
item.key !== key
)
})
setTaskList(updatedList)
// setCount(count - 1)
}
const editTask = (key) => {
let newTask = taskList.find((item) => {
return (
item.key === key
)
})
console.log(newTask)
setEdit(false)
setTask(newTask.object)
setIsTaskEdit(key)
}
const boxChecked = (key) => {
let checkedTask = taskList.map((item) => {
if (item.key === key) {
taskList.completed = !taskList.completed
}
return (
task
)
})
setTaskList(checkedTask)
}
return (
<div>
<Navbar />
<header>
<div className="todolist-border">
<div className="todo-input-form">
<input
className = "inputText"
placeholder="Add a Task"
value={task}
onChange = {inputValue}
/>
{
edit
?
<button
disabled = {disable}
onClick = {updateTaskList} className="todo-add-button">
+
</button>
:
<button className="edit-button" onClick={updateTaskList}>
<i className="fas fa-edit"></i>
</button>
}
</div>
<div>
{taskList.map((item) => {
return (
<div key = {item.key} className="todolist-div">
<input type="checkbox" className="list-checkbox" id="completed"
onChange={() => boxChecked(item.key)}
checked = {item.completed}
key = {item.key}
>
</input>
<p>{item.object}</p>
<div>
<button className="edit-button" onClick={() => editTask(item.key)}>
<i className="fas fa-edit"></i>
</button>
<button onClick={()=>deleteTaskListItem(item.key)} className="delete-button">
X
</button>
</div>
</div>
)
})}
</div>
</div>
</header>
</div>
)
}
The following error occurs when I check the checkbox:
And also I whenever I click the edit button, option to edit comes on the imput box and the add button changes to edit button. I put the state setEdit(True) after the edit button click but the following error shows up whenever I click on the edit button:
Kindly check and please correct the errors in the code
The link to the site is:
https://to-do-ist.netlify.app/
The site does not have the above code, but has the bugs I mentioned(edit button and checkbox)
The code for the site is as follows:
import React from "react";
import Navbar from './components/Navbar'
import '../src/App.css'
export default function TodoInput() {
const saveLocalTasks = () => {
let savedTasks = localStorage.getItem('tasks');
console.log(savedTasks)
if (savedTasks) {
return JSON.parse(localStorage.getItem('tasks'));
} else {
return [];
}
}
const [task, setTask] = React.useState('')
const [count, setCount] = React.useState(0)
const [taskList, setTaskList] = React.useState(saveLocalTasks)
const [disable, setDisable] = React.useState(true)
const [edit, setEdit] = React.useState(true)
const [isTaskEdit, setIsTaskEdit] = React.useState(null)
React.useEffect(() => {
localStorage.setItem('tasks', JSON.stringify(taskList))
}, [taskList]);
const updateTaskList = () => {
if (task && !edit) {
setTaskList(
taskList.map((item) => {
if(item.key === isTaskEdit) {
return {...item, object: task}
}
return item
})
)
}else {
setTaskList([...taskList, {object: task, key: Date.now()}])
setTask('')
setCount(count + 1)
setDisable(true)
}
// setEdit(true)
}
const inputValue = e => {
setTask(e.target.value)
e.target.value === '' || task === '' || task.length === 0
?
setDisable(true)
:
setDisable(false)
}
console.log(task.length)
const deleteTaskListItem = (key) => {
const updatedList = taskList.filter((item) => {
return (
item.key !== key
)
})
setTaskList(updatedList)
setCount(count - 1)
}
const editTask = (key) => {
let newTask = taskList.find((item) => {
return (
item.key === key
)
})
console.log(newTask)
setEdit(false)
setTask(newTask.object)
setIsTaskEdit(key)
}
return (
<div>
<Navbar />
<header>
<div className="todolist-border">
<div className="todo-input-form">
<input
className = "inputText"
placeholder="Add a Task"
value={task}
onChange = {inputValue}
/>
{
edit
?
<button
disabled = {disable}
onClick = {updateTaskList} className="todo-add-button">
+
</button>
:
<button className="edit-button" onClick={updateTaskList}>
<i className="fas fa-edit"></i>
</button>
}
</div>
<div>
{taskList.map((item) => {
return (
<div key = {item.key} className="todolist-div">
<input type="checkbox" className="list-checkbox">
</input>
<p>{item.object}</p>
<div>
<button className="edit-button" onClick={() => editTask(item.key)}>
<i className="fas fa-edit"></i>
</button>
<button onClick={()=>deleteTaskListItem(item.key)} className="delete-button">
X
</button>
</div>
</div>
)
})}
</div>
</div>
</header>
</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 } }))

How i can realise button on react for todolist?

I'm new to the react and I would like to know I made a function that makes filtering depending on the boolean values
let [filterState, setFilterSTate] = useState("all");
let filteredUser = todos.filter((е) => {
if (filterState === "active") {
return !е.done;
}
if (filterState === "completed") {
return е.done;
}
return true;
});
in the console, everything is displayed, but I can't figure out how to make it work in the browser itself and only the necessary tricks are displayed
import React, { useState } from "react";
import ReactDOM from "react-dom";
import "./index.css";
const TodoList = () => {
const [newTodo, setNewTodo] = useState("");
const [todos, setTodos] = useState([
{ done: true, text: "Hey", id: 1 },
{ done: false, text: "There", id: 2 },
{ done: false, text: "Dima", id: 3 },
]);
const [id, setId] = useState(4);
const toggleDone = (id) => {
setTodos(
todos.map((todo) => ({
...todo,
done: id === todo.id ? !todo.done : todo.done,
}))
);
};
const updateTodo = (id, e) => {
setTodos(
todos.map((todo) => ({
...todo,
text: id === todo.id ? e.target.value : todo.text,
}))
);
};
const onDelete = (id) => {
setTodos(todos.filter((todo) => todo.id !== id));
};
const updateNewTodo = (e) => {
setNewTodo(e.target.value);
};
const onAdd = () => {
setTodos([
...todos,
{
text: newTodo,
done: false,
id,
},
]);
setId(id + 1);
setNewTodo("");
};
let [filterState, setFilterSTate] = useState("all");
let filteredUser = todos.filter((е) => {
if (filterState === "active") {
return !е.done;
}
if (filterState === "completed") {
return е.done;
}
return true;
});
// let filteredComplited = todos.filter(function (e) {
// return e.done === true;
// });
// console.log("filteredComplited", filteredComplited);
// let filteredActive = todos.filter(function (e) {
// return e.done === false;
// });
// console.log("filteredActive", filteredActive);
// let filteredAll = todos;
// console.log("filteredAll", filteredAll);
return (
<div className="todos">
Todo List
{todos.map((todo) => (
<div key={todo.id} className="todo">
<input
type="checkbox"
value={todo.done}
onChange={() => toggleDone(todo.id)}
/>
<input
type="text"
value={todo.text}
onChange={(evt) => updateTodo(todo.id, evt)}
/>
<button onClick={() => onDelete(todo.id)}>Delete</button>
</div>
))}
<div className="todo">
<input type="text" value={newTodo} onChange={updateNewTodo} />
<button onClick={() => onAdd()}>Add</button>
</div>
<button
onclick={() =>
todos.map((t) => `${t.done ? "x" : ""} ${t.text}`).join("\n")
}
>
Save
</button>
<button onClick={() => setFilterSTate("completed")}>Complited</button>
<button onClick={() => setFilterSTate("active")}>Active</button>
<button onClick={() => setFilterSTate("all")}>All</button>
<pre>filterState: {JSON.stringify(filterState, null, 2)}</pre>
<br />
<pre>{JSON.stringify(filteredUser, null, 2)}</pre>
</div>
);
};
ReactDOM.render(<TodoList />, document.getElementById("todos"));

show loading bar when parent component pass data to and render child component. React.JS

I am loading a child component on parent component in React.js. With a click on the button, data will be pass to child component through props, and child component will map through that data and render on screen. I am getting data from localstorage and processing its data structure to child component.
But, the issue is when I click on the button and data is being passed and rendered, the button is shown and after the child component is rendered that shows up. I need the loading spinner when I click on the button and it disappears and shows the actual component.
I have tried methods like loading: false in the state but to no avail.
Thanks for your help
import ShowPatientAppointments from './ShowPatientAppointments.component';
class PatientAppointmnent extends Component {
state = {
doctorSlots: null,
timingSlot: null,
bookDay: null,
bookTime: null,
hasTiming: false,
}
getSlots = () => {
let slot = [];
let time = [];
for (let i=0; i< localStorage.length; i++) {
let key = localStorage.key(i);
let value = JSON.parse(localStorage[key]);
slot.push(key);
time.push(value);
this.setState({doctorSlots: slot, timingSlot: time});
}
console.log(this.state.doctorSlots, this.state.timingSlot);
}
render() {
const { doctorSlots, timingSlot, hasTiming } = this.state;
return(
<div>
<button onClick={this.getSlots} className='button'>Show me dates</button>
{doctorSlots === null ? <p></p> : <PatientSelectDay props={doctorSlots} timing={timingSlot} getTimings={this.getTiming} />}
</div>
)
}
}
export default PatientAppointmnent;
class PatientSelectDay extends Component {
state = {
options: [...this.props.props].map(obj => {
return {value: `${obj}`, label: `${obj}`}
}),
timingOptions: [...this.props.timing],
open_id: [],
part_id: '',
doctorDay: 'day',
doctorTiming: 'timing',
}
changeSingleHandler = e => {
this.setState({ part_id: e ? e.value : '' });
};
changeHandler = e => {
let add = this.state.open_id;
add.push(e.map(x => x.value));
this.setState({ open_id: e ? add : [] });
};
saveState = (option) => {
...save selected options
}
render() {
const {options, timingOptions} = this.state;
return (
<div>
<div className='carousel'>
{options.map((option, index) => {
const timing = timingOptions[index].map(obj => {
return {value: `${obj}`, label: `${obj}`}});
return(
<div key={index}>
<Select
name="open_id"
value={option}
onChange={this.changeSingleHandler}
options={option}
className='select'
/>
<Select
name="open_id"
value={this.state.open_id}
onChange={this.changeHandler}
options={timing}
className='select'
/>
<button onClick={() => this.saveState(option)} className='button-left'>Select Days</button>
</div>
)
})}
</div>
</div>
)
}
}
export default PatientSelectDay;
You need to update your code adding a loading state variable.
class PatientAppointmnent extends Component {
state = {
doctorSlots: null,
timingSlot: null,
bookDay: null,
bookTime: null,
hasTiming: false,
loading: false
}
getSlots = () => {
let slot = [];
let time = [];
this.setState({
loading: true
})
for (let i=0; i< localStorage.length; i++) {
let key = localStorage.key(i);
let value = JSON.parse(localStorage[key]);
slot.push(key);
time.push(value);
this.setState({doctorSlots: slot, timingSlot: time, loading: false});
}
console.log(this.state.doctorSlots, this.state.timingSlot);
}
renderButton = () => {
const { doctorSlots, timingSlot, loading } = this.state;
if(doctorSlots === null && timingSlot === null) {
return <div>
{loading ? <p>Loading...</p> : <button onClick={this.getSlots} className='button'>Show me dates</button>}
</div>
}
return null;
}
render() {
const { doctorSlots, timingSlot, hasTiming, loading } = this.state;
return(
<div>
{this.renderButton()}
{doctorSlots === null ? <p></p> : <PatientSelectDay props={doctorSlots} timing={timingSlot} getTimings={this.getTiming} />}
</div>
)
}
}
export default PatientAppointmnent;
class PatientSelectDay extends Component {
state = {
options: [...this.props.props].map(obj => {
return {value: `${obj}`, label: `${obj}`}
}),
timingOptions: [...this.props.timing],
open_id: [],
part_id: '',
doctorDay: 'day',
doctorTiming: 'timing',
}
changeSingleHandler = e => {
this.setState({ part_id: e ? e.value : '' });
};
changeHandler = e => {
let add = this.state.open_id;
add.push(e.map(x => x.value));
this.setState({ open_id: e ? add : [] });
};
saveState = (option) => {
...save selected options
}
render() {
const {options, timingOptions} = this.state;
return (
<div>
<div className='carousel'>
{options.map((option, index) => {
const timing = timingOptions[index].map(obj => {
return {value: `${obj}`, label: `${obj}`}});
return(
<div key={index}>
<Select
name="open_id"
value={option}
onChange={this.changeSingleHandler}
options={option}
className='select'
/>
<Select
name="open_id"
value={this.state.open_id}
onChange={this.changeHandler}
options={timing}
className='select'
/>
<button onClick={() => this.saveState(option)} className='button-left'>Select Days</button>
</div>
)
})}
</div>
</div>
)
}
}
export default PatientSelectDay;

Categories