Hello I have question about how I can make user select one checkbox at a time. So for example, if there is three checkbox(none are selected when page loads) on react component and user select one checkbox, the other checkbox will not be checked unless user uncheck it. I am trying to use useref to make it to work... but seems like it is not working..
const refCheckBoxOne = useRef(null);
const refCheckBoxTwo = useRef(null);
const refCheckBoxThree = useRef(null);
const onchangefunction = (propertyname, value) => {
if(refcheckBoxOne.current.check){
refcheckBoxOne.current.check = false;
refcheckBoxOne.current.check = false;
}
}
<input id="one" ref={refCheckBoxOne} userefonchange={(e) => onchangefunction("checkboxOne",e.target.value) }/>
<input id="two" ref={refCheckBoxTwo} onchange={(e) => onchangefunction("checkboxTwo",e.target.value) }/>
<input id="three" ref={refCheckBoxThree} onchange={(e) => onchangefunction("checkboxThree",e.target.value) }/>
I have tried many ways to do it... but cant get it to work. I would be really appreciated if anyone can give me an idea on how to approach this kind of issue.
Thank you
If two items you can use this
const App = () => {
const [checked, setChecked] = React.useState(false);
const handleChange = () => {
setChecked(!checked);
};
return (
<div>
<label>
<input
type="checkbox"
checked={checked}
onChange={handleChange}
/>
</label>
</div>
);
};
If multiple value then use it
export default function App() {
const [checkedState, setCheckedState] = useState(
[false,false,false]
);
const handleOnChange = (position) => {
const updatedCheckedState = checkedState.map((item, index) =>
index === position ? !item : item
);
setCheckedState(updatedCheckedState);
};
return (
<div className="App">
<h3>Select Toppings</h3>
<ul className="toppings-list">
<li key=0>
<div className="toppings-list-item">
<div className="left-section">
<input
type="checkbox"
id=`custom-checkbox-1`
checked={checkedState[0]}
onChange={() => handleOnChange(0)}
/>
</div>
</div>
</li>
<li key=1>
<div className="toppings-list-item">
<div className="left-section">
<input
type="checkbox"
id=`custom-checkbox-1`
checked={checkedState[1]}
onChange={() => handleOnChange(1)}
/>
</div>
</div>
</li>
<li key=2>
<div className="toppings-list-item">
<div className="left-section">
<input
type="checkbox"
id=`custom-checkbox-2`
checked={checkedState[2]}
onChange={() => handleOnChange(2)}
/>
</div>
</div>
</li>
</ul>
</div>
If you have any question , Comment below here .
Related
I have a form which has both boolean and string data to be shown in. I was able to control text fields with the help of state, but boolean fields are controlled with the help of enable and disable radio button. Was not able to control the boolean fields as there are many to be done. Is there any way that I can get the inputs for the fields?
import React, { useState } from 'react';
import moment from 'moment';
export const ConfigurationPage = (props) => {
const { t } = useTranslation();
const [configResp, setConfigResp] = useState({});
const [configSet,setConfigSet]=useState(null);
const [checked,isChecked]=useState(false);
React.useEffect(() => {
fetchConfig();
}, []);
React.useEffect(() => {
setInputConfig();
}, [configResp]);
const setInputConfig=()=>{
setConfigSet(configResp);
}
const fetchConfig = async() => {
try {
const resp = await APIEndpoint.get(`customer/app/config`);
if(resp.success){
const {result}=resp;
setConfigResp(result);
}
}
catch (resp) {
console.log(resp.msg)
}
}
const onChange = (e) => {
setConfigSet({[e.target.name]: e.target.value})
}
const getDate=()=>{
return moment().subtract(1, 'days').format('YYYY-MM-DD')+"T18:30:00.000Z"
}
return (
<div className="overlay" role="dialog">
<div className="dialog sm-scrollbar">
<div className="dialog__content">
<h2 className="dialog__title subheading-text-medium fontMedium">{preCompile.title}</h2>
<hr />
<div class="dialog__body_container flexRow justifyContentSpaceBetween flexWrap">
<div class="flexCol justifyContentSpaceEvenly ">
<div class=" dialog__container_item input-container">
<div class="dialog__description">
<label class="req_conf">Account Alias</label>
<input
id={''}
name="accountAlias"
onChange={(e)=>onChange(e)}
value={configSet?configSet.accountAlias:""}
type={'text'}
className='edit-input'
/>
</div>
</div>
</div>
<div class="flexCol justifyContentSpaceEvenly ">
<div class=" dialog__container_item input-container">
<div class="dialog__description">
<label class="req_conf">mSwipe</label>
<>
<div className={`dialog__description__radio`}>
<label>Enable</label>
{configSet.mswipeEnabled?<input id="" type="radio"
name="mswipeEnabled"
value={configSet.mswipeEnabled}
checked={configSet?.mswipeEnabled}
onChange={(e)=>onChange(e)} />:<input id="" type="radio"
name="mswipeEnabled"
value={!configSet.mswipeEnabled}
checked={!configSet?.mswipeEnabled}
onChange={(e)=>onChange(e)} />}
<label>Disable</label>
<input id="" type="radio"
name="mswipeEnabled"
value={configSet?configSet.mswipeEnabled:checked}
checked={configSet?.mswipeEnabled}
onChange={(e)=>onChange(e)} />
</div>
</>
</div>
</div>
</div>
</div>
<div className="dialog__footer flexCol alignItemsCenter">
<button className="done-button" onClick={props.onSubmit}>{props.title === 'Edit Item' ? 'Update' : 'Save'}</button>
</div>
</div>
</div>
);
}
Here I am trying to change values of mswipe fields which is a boolean with enable and disabled. Is there any way to do this?
I have two fields and a button. I want to render input values on the click of a button. Can you guys please tell me how to do it?
function Home() {
const [name, setName] = useState('')
const [age, setAge] = useState(0)
const submitForm = () => {
console.log(name, age)
}
return (
<div>
<div>
<label htmlFor="name">Name:</label>
<input type="text" value={name} onChange={e => setName(e.target.value)} />
</div>
<div>
<label htmlFor="age">age:</label>
<input type="number" value={age} onChange={e => setAge(e.target.value)} />
</div>
<button onClick={submitForm}>Submit</button>
<h1>render "name" gere</h1>
<h2>render "age" gere</h>
</div>
)
}
export default Home
You can add a state to track the display state, as
const [visible, setVisible] = useState(false)
Alter it in form submit as:
const submitForm = () => {
setVisible(true)
}
And render it as:
{visible && <><h1>render {name} gere</h1>
<h2>render {age} gere</h2> </>}
I fix it like this.
function Home() {
const [name, setName] = useState('')
const [age, setAge] = useState(0)
const [data, setData] = useState({})
const submitForm = () => {
setData({name, age})
}
return (
<div>
<div>
<label htmlFor="name">Name:</label>
<input type="text" value={name} onChange={e => setName(e.target.value)} />
</div>
<div>
<label htmlFor="age">age:</label>
<input type="number" value={age} onChange={e => setAge(e.target.value)} />
</div>
<button onClick={submitForm}>Submit</button>
<h1>{data.name}</h1>
<h2>{data.age}</h2>
</div>
)
}
export default Home
Try this and see if it helps.
function Home() {
const {register, handleSubmit} = useForm()
const onSubmit = (data) => {
console.log(data)
}
return (
<form onSubmit = {handleSubmit(onSubmit)}>
<div>
<div>
<label htmlFor="name">Name:</label>
<input type="text" value={name} onChange={e => setName(e.target.value)} />
</div>
<div>
<label htmlFor="age">age:</label>
<input type="number" value={age} onChange={e => setAge(e.target.value)} />
</div>
<button onSubmit={submitForm}>Submit</button>
<h1>render "name" gere</h1>
<h2>render "age" gere</h>
</div>
<form/>
);
}
I'm using next js for my application, and I am designing a search field. The suggestions start coming in once the user types something, but I would like to hide it when the input bar is not in focus.
When the user clicks on it again, I would like to show it back. The search suggestions contain routes, so I am not able use onFocus and onBlur as the element loses focus when I register a click and the route happens only when I release it.
I tried css too, but I'm not able to register the focus out, or is there a way?
Please help me out!!
Here is my sample code:
const [suggestionState,setSuggestionState] = useState(false);
<input type="input"
ref={inputRef}
autoFocus
className={styles['search-bar-input']}
onFocus={()=>{setSuggestionState(true)}}
onBlur={()=>{setSuggestionState(false)}}
placeholder="Search Bloggo"
onChange={(e)=>{
var trimmedQuery = e.target.value;
trimmedQuery = trimmedQuery.trim();
setSearchQuery(trimmedQuery);
getSuggestions(trimmedQuery)
}}
onKeyDown={(e)=>{handleKeypress(e)}}
/>
{
searchQuery.length == 0 || suggestionState == false? '':
<div className={styles['search-bar-suggestions']}>
<Link>... </Link>
</div>
}
You could do this with css :focus-within
.suggestions {
display: none;
}
form:focus-within .suggestions {
display: block;
}
input:focus~.suggestions {
display: block;
}
<form>
<input type="input" placeholder="Search Bloggo" value="">
<div class="suggestions">Suggestions...
<div>Suggestion 1</div>
<div>Suggestion 2</div>
<div>Suggestion 3</div>
<div>Suggestion 4</div>
</div>
</form>
Applying the above in react might looks something like this:
import "./styles.css";
import { useState, useEffect } from "react";
export default function App() {
const [searchQuery, setSearchQuery] = useState("");
const [results, setResults] = useState([]);
useEffect(() => {
if (!searchQuery) {
setResults([]);
return;
}
fetch(`https://rickandmortyapi.com/api/character/?name=${searchQuery}`)
.then((response) => response.json())
.then(({ results }) => setResults(results));
}, [searchQuery]);
return (
<form>
<input
value={searchQuery}
type="input"
autoFocus
placeholder="Search Bloggo"
onChange={(e) => {
setSearchQuery(e.target.value);
}}
/>
{!!results.length && (
<div className={`suggestions `}>
<h3>Suggestions</h3>
{results.map((result) => {
return (
<Link key={result.id} url={result.url}>
{result.name}
</Link>
);
})}
</div>
)}
</form>
);
}
const Link = ({ url, children }) => (
<div>
<a href={url}>{children}</a>
</div>
);
I'm new to React and looking for a clue to disable an input text box when a corresponding checkbox is ticked. Below is my code:
const [checked, setChecked] = useState(false);
const [disable, setDisable] = useState(true);
<div>
<div>
<input
type="checkbox"
value={!checked}
onChange={() => setDisable(!disable)}
disable={!disable}
/>
</div>
<div>
<input
type="text"
placeholder="Enter correct detail"
disabled={!disable}
onChange={() => setChecked(true)}
/>
</div>
</div>;
The above code works for only a row. How do I implement this logic to be able to work for several other rows.
You can create an another component and isolate the state to that
Component: InputWithCheckBox
const InputWithCheckBox = () => {
const [checked, setChecked] = useState(false);
const [disable, setDisable] = useState(true);
return (
<>
<div>
<input
type="checkbox"
value={!checked}
onChange={() => setDisable(!disable)}
disable={!disable}
/>
</div>
<div>
<input
type="text"
placeholder="Enter correct detail"
disabled={!disable}
onChange={() => setChecked(true)}
/>
</div>
</>
)
}
Import the InputWithCheckBox where you want to display it. Then you can add multiple rows as you want
<div>
<InputWithCheckBox/>
<InputWithCheckBox/>
</div>;
Ok so here's my code:
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
var uuid = require("uuid-v4");
// Generate a new UUID
var myUUID = uuid();
// Validate a UUID as proper V4 format
uuid.isUUID(myUUID); // true
var questionNum = 0;
class App extends Component {
constructor(props) {
super(props);
this.state = {
key: uuid(),
title: "",
author: "",
questions: [],
answers: []
};
this.handleChange = this.handleChange.bind(this);
this.addQuestion = this.addQuestion.bind(this);
this.removeItem = this.removeItem.bind(this)
}
componentDidMount() {
// componentDidMount() is a React lifecycle method
this.addQuestion();
}
handleChange(event) {
const target = event.target;
const value = target.type === "checkbox" ? target.checked : target.value;
const name = target.name;
this.setState({
[name]: value
});
}
removeItem (index) {
questionNum--;
this.setState(({ questions }) => {
const mQuestions = [ ...questions ]
mQuestions.splice(index, 1)
return { questions: mQuestions }
})
this.setState(({ answers }) => {
const mAnswers = [ ...answers]
mAnswers.splice(index, 4)
return { answers: mAnswers}
})
console.log(
"answers",
this.state.answers,
"questions",
this.state.questions,
questionNum,
this.state.title,
this.state.author
);
}
addQuestion() {
questionNum++;
this.setState(previousState => {
const questions = [
...previousState.questions,
<input
type="text"
onChange={this.handleChange}
name="question"
key={uuid()}
/>
];
const answers = [
...previousState.answers,
];
for (var i = 0; i < 4; i++) {
answers.push(
<input
type="checkbox"
name={uuid()}>
<input
type="text"
onChange={this.handleChange}
name={uuid()}
/>
</input>
);
}
return { questions, answers };
});
console.log(
"answers",
this.state.answers,
"questions",
this.state.questions,
questionNum,
this.state.title,
this.state.author
);
}
render() {
return (
<div className="App">
<div>
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h1 className="App-title">Quiz Form 3.0</h1>
</header>
<p className="App-intro">
To get started, edit <code>src/App.js</code> and save to reload.
</p>
</div>
<div className="formDiv">
<form>
<div className="Intro">
Give your Quiz a title:{" "}
<input
type="text"
value={this.state.title}
onChange={this.handleChange}
name="title"
/>
<br />
Who's the Author?{" "}
<input
type="text"
value={this.state.author}
onChange={this.handleChange}
name="author"
/>
<br />
<br />
</div>
<div className="questions">
<div className="questions">
Now let's add some questions... <br />
<ol>
{this.state.questions.map(question => {
return (
<li>
<div key={uuid()}>
Question
{question}<br />
Answer Choices<br />
{Array.from({ length: 4 }, () => (
<input type="text" key={uuid()} onChange={this.handleChange} />
))}
</div>
</li>
);
})}
</ol>
</div>
{
// This is what it would look like for the structure
// I proposed earlier.
// this.state.questions.map((question) {
// return (
// <div>{question.quesion}</div>
// {
// question.answers.map((answer) => {
// return (<div>{answer}</div>);
// })
// }
// );
// })
// This would output all questions and answers.
}
</div>
</form>
<button id="addQuestionButton" onClick={this.addQuestion}>Add Question</button>
{ this.state.questions.map((question, index) => {
return <button key={uuid()} onClick={ () => this.removeItem(index) }>Remove Question</button>
}) }
</div>
</div>
);
}
}
export default App;
Ok so here's a link to a quick video demonstrating what it does as of now. In the video you can see the Remove Question buttons that are created (at the bottom of the form) each time a question is added. I would like to have each question's Remove Question button be next to it/in the same div. I'm not entirely sure how I would go about doing this. Any thoughts?
UPDATE: Ok so I have put the buttons inside of the same div with the actual question, but I realized that i am adding a button for each object in the array. Which means that when a question is added a button to remove it is added to every question on the form. I need to make it so it does not .map this. I'm not entirely sure what other function I will do for this, maybe I don't even need a function. I will try my best to work it out. Here's the updated code (some of it):
<div className="questions">
Now let's add some questions... <br />
<ol>
{this.state.questions.map(question => {
return (
<li>
<div key={uuid()}>
Question
{question}<br />
{
this.state.questions.map((question, index) => {
return <button key={uuid()} onClick={ () => this.removeItem(index) }>Remove Question</button>
})
}
Answer Choices<br />
{Array.from({ length: 4 }, () => (
<div>
<input type="checkbox" />
<input type="text" key={uuid()} onChange={this.handleChange} />
</div>
))}
</div>
</li>
);
})}
</ol>
</div>
Something like this...
<ol>
{this.state.questions.map((question, index) => {
return (
<li>
<div key={uuid()}>
Question
{question}<br />
<button onClick={ () => this.removeItem(index) }>
Remove Question
</button>
Answer Choices<br />
{Array.from({ length: 4 }, () => (
<div key={uuid()}>
<input type="checkbox" />
<input type="text" onChange={this.handleChange} />
</div>
))}
</div>
</li>
);
})}
</ol>