How to check Material UI checkbox Manually? - javascript

I am trying to check the checkbox in componentDidUpdate by setting the "checked" to true but it's not working.
My State is stored in redux, I update the checkbox state in "onChange()" and in componentDidUpdate, I check if the state value is true or false based on which I am adding and removing the "checked" attribute. but this doesn't seem to work
import React, { Component } from "react";
import { saveOptions, getOptions } from '../api'
import { connect } from 'react-redux';
import { setUploadeSettings } from '../actions/settings'
import { Button, Checkbox, FormControl, TextField, withStyles } from '#material-ui/core/';
const styles = theme => ({
root: {
padding: theme.spacing(2)
},
button: {
marginTop: theme.spacing(1)
}
})
class UploadSettings extends Component{
async componentDidMount(){
const settingsFields = [...this.form.elements].map(i => i.name).filter(i => i)
let savedOptions = await getOptions( { option_names: settingsFields } )
savedOptions = savedOptions.data.data;
const reduxState = {}
savedOptions.forEach(i => reduxState[i.option_name] = i.option_value );
this.props.setUploadeSettings(reduxState)
}
componentDidUpdate(prevProps){
if(prevProps.uploadSettings !== this.props.uploadSettings){
[...this.form.elements].forEach(i => {
if(i.name === "convert_web_res")
this.props.convert_web_res ? i.setAttribute("checked", true) : i.removeAttribute('checked') //<- This Doesn't Seem to work
i.value = this.props.uploadSettings[i.name]
})
}
}
handleSubmit = async (e) => {
e.preventDefault();
try{
const formData = new FormData(e.target);
const elements = [...e.target.elements]
const eleIndex = elements.findIndex(i => i.name === 'convert_web_res')
const checked = elements[eleIndex].checked;
formData.set('convert_web_res', checked);
await saveOptions(formData)
} catch(e){
console.error(e)
}
}
render(){
const { classes, uploadSettings, setUploadeSettings } = this.props;
return(
<div className={classes.root}>
<form onSubmit={this.handleSubmit} ref={(form) => this.form = form}>
<FormControl>
<label>
<Checkbox
color="primary"
name="convert_web_res"
onChange={(e) => {
const state = uploadSettings;
state.convert_web_res = e.target.checked
setUploadeSettings(state)
}}
/> Convert Web Resolution
</label>
<TextField
defaultValue = {uploadSettings.resolution}
id="resolution"
name="resolution"
label="Resolution"
margin="normal"
/>
<TextField
defaultValue = {uploadSettings.dpi}
id="dpi"
name="dpi"
label="DPI"
margin="normal"
/>
<Button type="submit" variant="contained" color="primary" className={classes.button}>
Save
</Button>
</FormControl>
</form>
</div>
)
}
}
const mapStateToProps = state => {
return {
uploadSettings: state.settings.upload_settings
}
}
const mapDispatchToProps = dispatch => {
return {
setUploadeSettings: settings => dispatch(setUploadeSettings(settings))
}
}
export default connect(mapStateToProps, mapDispatchToProps)(withStyles(styles)(UploadSettings));
The Goal is to set the default value of the checkbox.
I tried adding the "checked" attribute directly on my checkbox component, Like so
<label>
<Checkbox
color="primary"
name="convert_web_res"
checked={uploadSettings.convert_web_res === "true" ? true : false}
onChange={(e) => {
const state = uploadSettings;
state.convert_web_res = e.target.checked
setUploadeSettings(state)
}}
/> Convert Web Resolution
</label>
this checks the checkbox but it gets frozen, User loses the ability to toggle the checkbox,

Use value and checked.
handleChange = event => {
// fire redux action
this.props.setUploadeSettings({ convert_web_res: event.target.checked });
};
<label>
<Checkbox
color="primary"
name="convert_web_res"
value={'Convert Web Resolution'}
checked={this.props.uploadSettings.convert_web_res}
onChange={(e) => this.handleChange(e)}
/> Convert Web Resolution
</label>

Related

Whats an elegant way of changing fetch address based on checkboxes

my backend does queryset filtering against the url parameters. On my frontend, depending whether a checkbox is ticked or not i wanna add a string (for example "?category=cardgame") to the axios url. Im not too sure how to do it
i was thinking of something like
button1ticked && (url += string-associated-with-button1)
but idk how to actually write it in react. I know its a beginner question but thanks for helping!
Use The WHATWG URL API
You can use the urlSearchParams.set(name, value)
import { useEffect, useState } from "react";
import "./styles.css";
import axios from "axios";
function CheckBox({ name, onChange, category, initialState = false }) {
const [isChecked, setIsChecked] = useState(initialState);
function handleOnChange(event) {
const isChecked = !!event.target.checked;
setIsChecked(isChecked);
if (onChange) onChange(isChecked, { category: category });
}
return (
<div className="App">
<input
onChange={handleOnChange}
name={name}
checked={isChecked}
type="checkbox"
/>
</div>
);
}
export default function App() {
const [url, setUrl] = useState("https://randomuser.me/api/?results=5");
function onChange(checked, filter) {
getList(filter, checked);
}
function buildUrl(filter, addFilter) {
let newUrl = new URL(url);
if (filter) {
Object.keys(filter).forEach((key) => {
if (addFilter) {
newUrl.searchParams.set(key, filter[key]); // append param
} else {
newUrl.searchParams.delete(key); // remove param
}
});
}
return newUrl.toString();
}
function getList(filter, addFilter) {
const newURL = buildUrl(filter, addFilter);
setUrl(newURL);
axios
.get(newURL)
.then(response => {
console.log(response);
})
.then(users => {
this.setState({
users,
isLoading: false
});
})
.catch(error => this.setState({ error, isLoading: false }));
}
useEffect(() => {
getList(null, false);
}, []);
return (
<div className="App">
<CheckBox
onChange={onChange}
category="cardgame"
name="check-box-name"
initialState={true}
/>{" "}
Checkbox 1
<CheckBox
onChange={onChange}
category="boardgame"
name="check-box-name"
initialState={true}
/>{" "}
Checkbox 2
<CheckBox
onChange={onChange}
category="videogame"
name="check-box-name"
initialState={true}
/>{" "}
Checkbox 3
</div>
);
}

Reactjs: Input field not working properly

In my project, there is an input field to add email tags. which I created using react js.
That file working properly, when I convert the file into type script I can't type or paste values to the input field, but there is no error showing in the terminal
js file
import React from "react";
import ReactDOM from "react-dom";
import Chip from "#material-ui/core/Chip";
import "./styles.css";
import TextField from "#material-ui/core/TextField";
class App extends React.Component {
state = {
items: [],
value: "",
error: null,
};
handleKeyDown = evt => {
if (["Enter", "Tab", ","].includes(evt.key)) {
evt.preventDefault();
var value = this.state.value.trim();
if (value && this.isValid(value)) {
this.setState({
items: [...this.state.items, this.state.value],
value: ""
});
}
}
};
handleChange = evt => {
this.setState({
value: evt.target.value,
error: null
});
};
handleDelete = (item) => {
this.setState({
items: this.state.items.filter(i => i !== item),
});
};
handleItemEdit = item =>{
const result = this.state.items.filter(values=>values!==item)
this.setState({
value: item,
error: null,
items: result
});
}
handlePaste = evt => {
evt.preventDefault();
var paste = evt.clipboardData.getData("text");
var emails = paste.match(/[\w\d\.-]+#[\w\d\.-]+\.[\w\d\.-]+/g);
if (emails) {
var toBeAdded = emails.filter(email => !this.isInList(email));
this.setState({
items: [...this.state.items, ...toBeAdded]
});
}
};
isValid(email) {
let error = null;
if (this.isInList(email)) {
error = `${email} has already been added.`;
}
if (!this.isEmail(email)) {
error = `${email} is not a valid email address.`;
}
if (error) {
this.setState({ error });
return false;
}
return true;
}
isInList(email) {
return this.state.items.includes(email);
}
isEmail(email) {
return /[\w\d\.-]+#[\w\d\.-]+\.[\w\d\.-]+/.test(email);
}
render() {
return (
<>
{/* {this.state.items.map(item => (
<div className="tag-item" key={item} onClick={() => this.handleItemEdit(item)}>
{item}
<button
type="button"
className="button"
onClick={(e) => this.handleDelete(e,item)}
>
×
</button>
</div>
))} */}
<TextField id="outlined-basic" variant="outlined"
InputProps={{
startAdornment: this.state.items.map(item => (
<Chip
key={item}
tabIndex={-1}
label={item}
onDelete={() => this.handleDelete(item)}
onClick={() => this.handleItemEdit(item)}
/>
)),
}}
ref={this.state.items}
className={"input " + (this.state.error && " has-error")}
value={this.state.value}
placeholder="Type or paste email addresses and press `Enter`..."
onKeyDown={this.handleKeyDown}
onChange={this.handleChange}
onPaste={this.handlePaste}
/>
{this.state.error && <p className="error">{this.state.error}</p>}
</>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
ts file
import React, { useRef, useState } from "react";
import ReactDOM from "react-dom";
import Chip from "#material-ui/core/Chip";
import TextField from "#material-ui/core/TextField";
interface details{
item: string
}
// type Props = {
// test: string,
// // error: string,
// };
export const TagActions = () => {
// var { test } = props
const [items, setItem] = useState<string[]>([]);
const [value, setValue] = useState('')
const [error, setError]= useState('')
const divRef = useRef<HTMLDivElement>(null)
const handleDelete = (item:any) => {
const result = items.filter(i => i !== item)
setItem(result)
};
const handleItemEdit = (item:any) =>{
const result = items.filter(i => i !== item)
setItem(result)
setValue(value)
};
const handleKeyDown = (evt:any) => {
if (["Enter", "Tab", ","].includes(evt.key)) {
evt.preventDefault();
var test = value.trim();
if (test && isValid(test)) {
items.push(test)
setValue("")
}
}
};
const isValid = (email:any)=> {
let error = null;
if (isInList(email)) {
error = `${email} has already been added.`;
}
if (!isEmail(email)) {
error = `${email} is not a valid email address.`;
}
if (error) {
setError(error);
return false;
}
return true;
}
const isInList = (email:any)=> {
return items.includes(email);
}
const isEmail = (email:any)=> {
return /[\w\d\.-]+#[\w\d\.-]+\.[\w\d\.-]+/.test(email);
}
const handleChange = (evt:any) => {
setValue(evt.target.value)
// setError("")
};
const handlePaste = (evt:any) => {
evt.preventDefault();
var paste = evt.clipboardData.getData("text");
var emails = paste.match(/[\w\d\.-]+#[\w\d\.-]+\.[\w\d\.-]+/g);
if (emails) {
var toBeAdded = emails.filter((email:any) => !isInList(email));
setItem(toBeAdded)
}
};
return (
<>
<TextField id="outlined-basic" variant="outlined"
InputProps={{
startAdornment: items.map(item => (
<Chip
key={item}
tabIndex={-1}
label={item}
onDelete={() => handleDelete(item)}
onClick={() => handleItemEdit(item)}
/>
)),
}}
ref={divRef}
value={value}
placeholder="Type or paste email addresses and press `Enter`..."
onKeyDown={(e) => handleKeyDown}
onChange={(e) => handleChange}
onPaste={(e) => handlePaste}
/>
{error && <p className="error">{error}</p>}
</>
);
}
I am a beginner in react typescript. So I don't know what's going on. At first, I referred some documents and applied some solutions, but the expected result did not come. Please share some suggestions to solve this problem
That's a very good start - but there are a few simple issues.
The first big difference between JS and TS is of course the typing - so your functions should definetely be checking that the correct values are being passed! For example:
const isEmail = (email:any)=> {
return /[\w\d\.-]+#[\w\d\.-]+\.[\w\d\.-]+/.test(email);
}
should be:
const isEmail = (email:string)=> {
return /[\w\d\.-]+#[\w\d\.-]+\.[\w\d\.-]+/.test(email);
}
This ensures that you can only pass a string to isEmail function.
The same goes for the event handlers - one trick I like to use when figuring out the function signature is hovering over the declaration in TSX:
If you hover over onChange in TSX, it will tell you that its of type React.ChangeEventHandler<HTMLTextAreaElement | HTMLInputElement>, so to get the type of event evt in your function, just remove the handler bit:
const handleChange = (evt: React.ChangeEvent<HTMLTextAreaElement | HTMLInputElement>) => {
// code here
}
Another thing ythat's wrong currently is the way you call the function. In your code you do:
<TextField
id="outlined-basic"
variant="outlined"
...
onChange={e => handleChange}
/>
You aren't actually invoking the handleChange function, so you could do this:
<TextField
id="outlined-basic"
variant="outlined"
...
onChange={e => handleChange(e)}
/>
Or this instead:
<TextField
id="outlined-basic"
variant="outlined"
...
onChange={handleChange}
/>
I made a codesandbox with a working example (but I omitted some parts for simplicity).
But it definetely works, you're on the right tracks:

Cannot select Options from Material UI's Autocomplete Component

I cannot select the options being displayed from MUI's autocomplete component. The reason I think is that I am using renderOption. I want to display the image along the title in the options of my component and without using renderOption, I have not been able to do that. But, doing so (using renderOption), I cannot select any option.
import React, { useState } from 'react';
import { fetchSearchAnimeEndpoint } from '../../redux';
import { connect } from 'react-redux';
import { debounce } from 'lodash';
import TextField from '#mui/material/TextField';
import Autocomplete from '#mui/material/Autocomplete';
import CircularProgress from '#mui/material/CircularProgress';
import './searchbar.css';
const SearchBar = (props: any) => {
const [openPopper, setOpenPopper] = useState(false);
const [inputValue, setInputValue] = useState('');
const { anime } = props;
const handleKeyPress = debounce(
(event: React.FormEvent<HTMLInputElement>) => {
const value = (event.target as HTMLInputElement).value;
props.fetchSearchAnime(value);
},
700
);
return (
<div>
{/*
Cannot select the options being displayed either by clicking or using keyboard
Want to display the title on the textfield by selecting desired option */}
<Autocomplete
id="combo-box-demo"
options={anime.results.data ? anime.results.data : []}
style={{ width: 300, marginTop: '2rem' }}
isOptionEqualToValue={(option, value) => option.title === value.title}
getOptionLabel={(option: any) => option.title}
renderOption={(option: any, optionAnime) => {
return (
<h4 key={optionAnime.mal_id} className="search-container">
<img
className="search-image"
alt="anime"
src={optionAnime.image_url}
/>
{optionAnime.title}
</h4>
);
}}
renderInput={(params) => (
<TextField
onInput={(e) => {
if ((e.target as HTMLInputElement).value.length >= 3) {
setOpenPopper(true);
} else {
setOpenPopper(false);
}
return handleKeyPress(e);
}}
{...params}
label="Anime"
/>
)}
open={openPopper}
onClose={() => {
setOpenPopper(false);
}}
/>
</div>
);
};
const mapStateToProps = (state: any) => {
return {
anime: state,
};
};
const mapDispatchToProps = (dispatch: any) => {
return {
fetchSearchAnime: (name: string) =>
dispatch(fetchSearchAnimeEndpoint(name)),
};
};
export default connect(mapStateToProps, mapDispatchToProps)(SearchBar);
I am getting the options and just cannot select them. What I want is to select them by clicking on them or using the keyboard and get the title value on the textfield
Hey so they changed the renderInput function as it now takes props and options
so for this example
<TextField
onInput={(e) => {
if ((e.target as HTMLInputElement).value.length >= 3) {
setOpenPopper(true);
} else {
setOpenPopper(false);
}
return handleKeyPress(e);
}}
{...props}
label="Anime"
/>
)}
open={openPopper}
onClose={() => {
setOpenPopper(false);
}}
/>
for more info on the problem, theres an example on github:
https://github.com/mui/material-ui/issues/29943

unable to only select a single material ui checkbox

I am new to react and I am making a simple todo app using react js and material ui. What I have is a separate component for taking the user input (TodoInput), and a separate component for rending each individual todo task (TodoCards). What I want to do is enable the user to click the checkbox rendered in the TodoCards component once they have completed the task. I ran into an issue where when a single checkbox is clicked, all the checkboxes for every card component is checked. I'm unsure to as why this is happening, any guidance or explanation towards the right direction would be greatly appreciated.
TodoInput.js
import React, { useState } from 'react';
import { makeStyles } from '#material-ui/core/styles';
import { TextField, Button } from '#material-ui/core';
import { TodoCards } from '../UI/TodoCards';
import { Progress } from '../UI/Progress';
const useStyles = makeStyles((theme) => ({
root: {
'& > *': {
margin: theme.spacing(1),
width: '25ch',
textAlign: 'center'
},
},
}));
export default function TodoInput() {
const classes = useStyles();
const [userInput, setUserInput] = useState({
id: '',
task: ''
});
const [todos, setTodos] = useState([])
//state for error
const [error, setError] = useState({
errorMessage: '',
error: false
})
//add the user todo with the button
const submitUserInput = (e) => {
e.preventDefault();
//add the user input to array
//task is undefined
if (userInput.task === "") {
//render visual warning for text input
setError({ errorMessage: 'Cannot be blank', error: true })
console.log('null')
} else {
setTodos([...todos, userInput])
console.log(todos)
setError({ errorMessage: '', error: false })
}
console.log(loadedTodos)
}
//set the todo card to the user input
const handleUserInput = function (e) {
//make a new todo object
setUserInput({
...userInput,
id: Math.random() * 100,
task: e.target.value
})
//setUserInput(e.target.value)
//console.log(userInput)
}
const loadedTodos = [];
for (const key in todos) {
loadedTodos.push({
id: Math.random() * 100,
taskName: todos[key].task
})
}
return (
<div>
<Progress taskCount={loadedTodos.length} />
<form className={classes.root} noValidate autoComplete="off" onSubmit={submitUserInput}>
{error.error ? <TextField id="outlined-error-helper-text" label="Today's task" variant="outlined" type="text" onChange={handleUserInput} error={error.error} helperText={error.errorMessage} />
: <TextField id="outlined-basic" label="Today's task" variant="outlined" type="text" onChange={handleUserInput} />}
<Button variant="contained" color="primary" type="submit">Submit</Button>
{userInput && <TodoCards taskValue={todos} />}
</form>
</div>
);
}
TodoCards.js
import React, { useState } from 'react'
import { Card, CardContent, Typography, FormControlLabel, Checkbox } from '#material-ui/core';
export const TodoCards = ({ taskValue }) => {
const [checked, setChecked] = useState(false);
//if checked, add the task value to the completed task array
const completedTasks = [];
const handleChecked = (e) => {
setChecked(e.target.checked)
//console.log('complete')
for (const key in taskValue) {
completedTasks.push({
id: Math.random() * 100,
taskName: taskValue[key].task
})
}
}
return (
< div >
<Card>
{taskValue.map((individual, i) => {
return (
<CardContent key={i}>
<Typography variant="body1">
<FormControlLabel
control={
<Checkbox
color="primary"
checked={checked}
onClick={handleChecked}
/>
}
label={individual.task} />
</Typography>
</CardContent>
)
})}
</Card>
</div >
)
}
This is because all of your checkboxes are connected to only one value (checked). There is two way you could potentially solve this.
Method one:
Instead of a single value, you create a list that consists of as many values as you have checkboxes. Eg:
const [checked, setChecked] = useState([true, false, false]) //this is your list
//...
{taskValue.map((individual, index) =>
<Checkbox
color="primary"
checked={checked[index]}
onClick={() => handleChecked(index)}
/>
}
In handleChecked you should only change that one value based on the index.
Method number two (what I would probably do:
You create a new component for the check boxes
checktask.js
import {useState} from "react";
function CheckTask(props){
const [checked, setChecked] = useState(false);
return (
<Checkbox
color="primary"
checked={checked[index]}
onClick={() => handleChecked(index)}
/>
)
}
export default CheckTask;
This way you could give each checkbox its own state.

selected options from radio and checkbox are not passing data

I am trying to make a set of questions through multiple pages, so I need the selected answer from page 1 and page 2 to be passed to page 3 because page 3 is like the confirmation page which will show all the selected answer from the past 2 pages.
The interface is successfully shown, well, easy but it seems like there is no data passed at all, oh, and the types of questions are radio and checkbox, so it's kinda hard for me because these 2 types are something new for me (if textarea or normal input, is easy).
This is the mainpage.jsx
// MainForm.jsx
import React, { Component } from 'react';
import AircondQuantity from './AircondQuantity';
import ServicePackage from './ServicePackage';
import Confirmation from './Confirmation';
import Success from './Success';
class MainForm extends Component {
state = {
step: 1,
oneAircond: ''
}
nextStep = () => {
const { step } = this.state
this.setState({
step : step + 1
})
}
prevStep = () => {
const { step } = this.state
this.setState({
step : step - 1
})
}
handleChange = input => event => {
this.setState({ [input] : event.target.value })
}
render(){
const {step} = this.state;
const { oneAircond } = this.state;
const values = { oneAircond };
switch(step) {
case 1:
return <AircondQuantity
nextStep={this.nextStep}
handleChange = {this.handleChange}
values={values}
/>
case 2:
return <ServicePackage
nextStep={this.nextStep}
prevStep={this.prevStep}
handleChange = {this.handleChange}
values={values}
/>
case 3:
return <Confirmation
nextStep={this.nextStep}
prevStep={this.prevStep}
values={values}
/>
case 4:
return <Success />
}
}
}
export default MainForm;
this is the first page, AircondQuantity.jsx
// AircondQuantity.jsx
import React, { Component } from 'react';
import { Form, Button, FormRadio, Radio } from 'semantic-ui-react';
class AircondQuantity extends Component{
saveAndContinue = (e) => {
e.preventDefault()
this.props.nextStep()
}
render(){
const { values } = this.props;
return(
<Form >
<h1 className="ui centered"> How many aircond units do you wish to service? </h1>
<Form.Field>
<Radio
label='1'
name='oneAircond'
value='oneAircond'
//checked={this.state.value === this.state.value}
onChange={this.props.handleChange('oneAircond')}
defaultValue={values.oneAircond}
/>
</Form.Field>
<Button onClick={this.saveAndContinue}> Next </Button>
</Form>
)
}
}
export default AircondQuantity;
this is the next page, ServicePackage.jsx
// ServicePackage.jsx
import React, { Component } from 'react';
import { Form, Button, Checkbox } from 'semantic-ui-react';
import { throws } from 'assert';
class ServicePackage extends Component{
saveAndContinue = (e) => {
e.preventDefault();
this.props.nextStep();
}
back = (e) => {
e.preventDefault();
this.props.prevStep();
}
render(){
const { values } = this.props
return(
<Form color='blue' >
<h1 className="ui centered"> Choose your package </h1>
<Form.Field>
<Checkbox
label={<label> Chemical Cleaning </label>} />
</Form.Field>
<Form.Field>
<Checkbox
label={<label> Deep Cleaning </label>} />
</Form.Field>
<Button onClick={this.back}> Previous </Button>
<Button onClick={this.saveAndContinue}> Next </Button>
</Form>
)
}
}
export default ServicePackage;
this is the confirmation.jsx page, the page that will show all the selected options
// Confirmation.jsx
import React, { Component } from 'react';
import { Button, List } from 'semantic-ui-react';
import AircondQuantity from './AircondQuantity';
class Confirmation extends Component{
saveAndContinue = (e) => {
e.preventDefault();
this.props.nextStep();
}
back = (e) => {
e.preventDefault();
this.props.prevStep();
}
render(){
const {values: { oneAircond }} = this.props;
return(
<div>
<h1 className="ui centered"> Confirm your Details </h1>
<p> Click Confirm if the following details have been correctly entered </p>
<List>
<List.Item>
<List.Content> Aircond Quantity: {oneAircond}</List.Content>
</List.Item>
</List>
<Button onClick={this.back}>Back</Button>
<Button onClick={this.saveAndContinue}>Confirm</Button>
</div>
)
}
}
export default Confirmation;
I am very new in using React and I know that I have some mistakes in transferring values or variables but I can't detect it, coz I am a newbie, so em, can you help me? thank you.
This doesn't look right to me:
onChange={this.props.handleChange('oneAircond')}
Firstly, it's going to be called instantly, before onChange is actually called, to fix that do this:
onChange={() => this.props.handleChange('oneAircond')}
However you'll also need to pass the change event from the radio button, try this:
onChange={(event) => this.props.handleChange('oneAircond')(event)}
The handleChange function below is a function that returns another function, the first one taking the 'oneAircond' string (input) and returning a function that is expecting the event from the radio button to be passed which is what you're missing
handleChange = input => event => {
this.setState({ [input] : event.target.value })
}
Ok, first i convert solution into hooks:
// MainForm.jsx
import React, { Component, useState, useEffect } from 'react';
import AircondQuantity from './AircondQuantity';
import ServicePackage from './ServicePackage';
import Confirmation from './Confirmation';
// import Success from './Success';
let MainForm = (props) => {
const [step, setStep] = useState(1)
const [input, setInput] = useState([])
const [oneAircond, setoneAircond] = useState('')
const nextStep = () => {
setStep(step + 1)
}
const prevStep = () => {
setStep(step - 1)
}
const handleChange = input => event => {
setInput({ [input] : event.target.value})
console.log(input)
}
const values = { oneAircond };
return(
<React.Fragment>
{(() => {
switch(step) {
case 1:
return <AircondQuantity
nextStep={nextStep}
handleChange = {handleChange}
values={values}
/>
case 2:
return <ServicePackage
nextStep={nextStep}
prevStep={prevStep}
handleChange = {handleChange}
values={values}
/>
case 3:
return <Confirmation
nextStep={nextStep}
prevStep={prevStep}
values={values}
/>
case 4:
// return <Success />
}
})()}
</React.Fragment>
)
}
export default MainForm;
Next I transform AirCondQuantity.jsx, and create new component Radio.jsx, which holds Radio structure (it is a component into which we inject data directly)
So here is:
// AircondQuantity.jsx
import React, { Component, useState } from 'react';
import { Form, Button, FormRadio, } from 'semantic-ui-react';
import Radio from './Radio';
let AircondQuantity = (props) => {
const [radio, setRadio] = useState();
const radioSelect = (name, e) => {
localStorage.setItem('FirstStep', name);
setRadio({ selectedRadio: name })
console.log(radio)
}
const saveAndContinue = (e) =>{
e.preventDefault()
props.nextStep()
}
return(
<Form >
<h1 className="ui centered"> How many aircond units do you wish to service? </h1>
<Form.Field>
<Radio
handleRadioSelect={radioSelect}
selectedRadio={radio}
name ="oneAircond"/>
<Radio
handleRadioSelect={radioSelect}
selectedRadio={radio}
name ="twoAircond"/>
</Form.Field>
<Button onClick={saveAndContinue}> Next </Button>
</Form>
)
}
export default AircondQuantity;
I added function, which setting the item to LocalStorage + send it in radio state
Additional here is a Radio component:
import React, { Component, useState } from 'react';
const Radio = (props) => {
return (
<div className = "RadioButton"
onClick={() => props.handleRadioSelect(props.name)} >
<div>
<input id={props.id} value={props.value} type="radio" checked={props.selectedRadio === props.name} />
{props.name}
</div>
</div>
);
}
export default Radio;
The solution works, despite one thing - it doesn't check the box, I have no idea how to fix it.

Categories