CheckBox with variable default value - html

What's the best way to create a checkbox that gets a default status but can still be modified.
<div className="master">
<input className="tgl tgl-skewed" id={id} type="checkbox" onChange={onChange} name={flag} checked={lock}/>
<label className="slave tgl-btn" data-tg-off={flag + " is OFF"} data-tg-on={flag + " is ON"} htmlFor={id}></label>
</div>
In this example above I get a default status (lock) that can be "true" or "false" this changes the checkbox from "checked" to "unchecked". Unfortunately this also makes it impossible to change this status by clicking on the relevant checkbox.
Any ideas ?

You can use defaultChecked props for the input tag in react.
<input className="tgl tgl-skewed" id={id} type="checkbox" onChange={onChange} name={flag} defaultChecked={lock}/>

Put the lock into state, and have the change handler toggle the boolean:
const App = ({ lock }) => {
const [checked, setChecked] = React.useState(lock);
const onChange = () => setChecked(!checked);
const id = 'foo';
return (
<div className="master">
<input className="tgl tgl-skewed" id={id} type="checkbox" onChange={onChange} checked={checked}/>
<label className="slave tgl-btn" htmlFor={id}></label>
</div>
);
};
ReactDOM.render(<App lock={true} />, document.querySelector('.react'));
<script crossorigin src="https://unpkg.com/react#16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom#16/umd/react-dom.development.js"></script>
<div class="react"></div>

Related

How to restrict end date before start date after selected start date in React.JS or in html input type=date""

function App() {
let [account, setAccount] = React.useState({
startdate: "",
enddate: "",
reason: "",
leavetype: "",
});
function handleChange(e) {
let name = e.target.name;
let value = e.target.value;
account[name] = value;
setAccount(account);
}
function Submit(e) {
e.preventDefault();
console.log(account);
}
return (
<div>
<fieldset>
<form className="" method="post" onSubmit={Submit}>
Start Date:
<input
type="date"
name="startdate"
min={new Date().toISOString().split("T")[0]}
onChange={handleChange}
required
/>
End Date:
<input
type="date"
name="enddate"
// min={}
onChange={handleChange}
required
/>
</form>
</fieldset>
</div>
);
}
ReactDOM.render(<App/>, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="root"></div>
You need to use the state that you have.
function App() {
const [account, setAccount] = React.useState({
startdate: "",
enddate: "",
reason: "",
leavetype: "",
});
function handleChange(e) {
const name = e.target.name;
const value = e.target.value;
// treat state as immutable!
// you need to creaet a new object here
// See https://stackoverflow.com/a/25333702/17487348 for how to create a property from a string in ES6
setAccount({...account, [name]: value});
}
function Submit(e) {
e.preventDefault();
console.log(account);
}
return (
<div>
<fieldset>
<form className="" method="post" onSubmit={Submit}>
<legend>Your trip</legend>
<label for="startdate">Start Date:</label>
<input
type="date"
name="startdate"
min={new Date().toISOString().split("T")[0]}
onChange={handleChange}
required
/>
<label for="enddate">End Date:</label>
<input
type="date"
name="enddate"
disabled={account.startdate === "" ? true: false}
min={account.startdate ? new Date(account.startdate).toISOString().split("T")[0]: ""}
onChange={handleChange}
required
/>
</form>
</fieldset>
</div>
);
}
ReactDOM.render(<App/>, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="root"></div>
When you look at the code there are some other changes which you should consider.
I would disable the end date date picker as long as there is no start date selected or set sensible default values for start end end date (e.g. today for both) and set those when defining the state.
More important: You should treat state as immutable that means you need to create a new object every time the state changes as React only does a shallow comparison. Otherwise the component won't re-render. So use setAccount({...account, [name]: value}); to update your state. You need to use [] here so the variable content is interpreted as the name of the property. See this thread.
You also probably want to use <label> and maybe <legend>. See the MDN docs for <fieldset>.
For more options to control the datepicker see MDN docs for <input type="date">.

Input text no longer editable when using register with react-hook-form

I'm trying to set up react-fook-form to validate my forms, but when I use the register function on a text input (in my case the username input), this input is no longer editable, I can't type anything inside.
const {register, handleSubmit, formState: { errors }} = useForm();
const [username, setUsername] = useState('');
.....
<form onSubmit={handleSubmit(onSubmit)}>
<label htmlFor="username">Username : </label>
<input type="text" value={username}
onChange={e => setUsername(e.target.value)}
{...register('username', { required: 'Please, type in your username' })}
/>
{errors.username && <span style={{color: 'red'}}><br/>{errors.username.message}</span>}
<br/>
<label htmlFor="password">Password : </label>
<input type="password" value={password} onChange={e => setPassword(e.target.value)}/>
<br/>
<button type="submit">Login</button>
</form>
Ok I finally found the solution myself.
Since the version 7 of react-hook-form library, we have to place "onChange" inside the register function like so :
<input type="text" value={username} {...register('username', {
required: 'Please, type in your username',
onChange: e => setUsername(e.target.value)
})}/>

oninvalid attribute not rendering in React js

I am trying to add oninvalid attribute in HTML element under React js code. (using react hooks not class based)
const openEndedAnswer = answer => {
return (<>
<input type="text" className="form-control"
required="required"
oninvalid="this.setCustomValidity('Enter User Name Here')"
oninput="this.setCustomValidity('')"
maxLength="255"
id={`answer_${question.id}`}
name={`answer_${question.id}`}
onChange={e => updatePostForm(e)}
pattern=".*[^ ].*"
title=" No white spaces"
/>
</>)
}
But it never renders in the browser. all other attributes can be seen in F12 source view.
The attribute names should onInvalid instead of oninvalid and onInput instead of oninput. Additionally, you need to call the setCustomValidity function on the input field as follow (because the input field is the target of the event):
onInvalid={e => e.target.setCustomValidity('Enter User Name Here')}
onInput={e => e.target.setCustomValidity('')}
If you are using React with javascript this should work:
onInvalid={e => e.target.setCustomValidity('Your custom message')}
onInput={e => e.target.setCustomValidity('')}
But if you are working with React with typescript you also need to add this:
onInvalid={e => (e.target as HTMLInputElement).setCustomValidity('Enter User Name Here')}
onInput={e => (e.target as HTMLInputElement).setCustomValidity('')}
Try onInvalid instead:
export default function App() {
return (
<form>
Name:{" "}
<input
type="text"
onInvalid={() => console.log("working!")}
name="fname"
required
/>
<input type="submit" value="Submit" />
</form>
);
}

React checkbox and button control

I am trying to implement a check box for the full consent of membership registration.
const [agree1, setAgree1] = useState(false); //agree1
const [agree2, setAgree2] = useState(false); //agree2
const [agree3, setAgree3] = useState(false); //agree3
const [total, settotal] = useState(false); // all agree
const buttonState = useCallback(() => {
if((agree1===true)&&(agree2===true)&&(agree3===true)){
settotal(true);
setDisabled('');
}
else {
setDisabled('disabled');
}
},[agree1,agree2,agree3,total]);
const totalchange = () => {
if(total ===true) { //전체동의가 true라면 다시 클릭 했을때 전부 unchecked
settotal(!total);
setAgree1(!agree1);
setAgree2(!agree2);
setAgree3(!agree3);
} else{ //그외(하나만 체크되 있거나 아무것도 없다면) 전부 checked로 만듬
settotal(true);
setAgree1(true);
setAgree2(true);
setAgree3(true);
// setDisabled('');
}
}
<div>
<div>
<input type="checkbox" name="total_agree" value="total_agree" checked={total} onChange={totalchange} />
<label>전체 동의</label>
</div>
<div>
<input type="checkbox" name="agree1" value="agree1" checked={agree1} onChange={changeState1} />
<label>회원 약관</label>
<span>전체보기</span>
</div>
<div>
<input type="checkbox" name="agree2" value="agree2" checked={agree2} onChange={changeState2} />
<label>개인정보 수집 및 이용</label>
<span>전체보기</span>
</div>
<div>
<input type="checkbox" name="agree3" value="agree3" checked={agree3} onChange={changeState3} />
<label>위치 정보 이용 동의</label>
<span>전체보기</span>
</div>
</div>
<br/>
입력해주신 이메일 정보는 회원가입 시 이메일로 설정됩니다.
<br/>
<div>
<label>이메일</label>
<input type = "email" onChange = {EmailHandler}/>
<button name="button" onClick = {clickFunction}>인증코드 발송</button>
</div>
If you activate the full terms and conditions, all the checkboxes below will be activated.
If you deactivate all terms and conditions, all the checkboxes below will also be deactivated.
Individually, all checkboxes should be enabled.
If you activate all checkboxes individually, the entire terms and conditions will also be activated.
If any of the checkboxes below are deactivated, the entire terms and conditions are deactivated.
When the entire terms and conditions are activated, the member sign-up button is activated.
I tried several methods, but failed to activate the button.
How can I implement it?
Please help...
Essentially what you need to do here is remove the states for total and disabled as they can be derived from the state of the other checkboxes.
The checkbox for "total" is checked if and only if all three are checked. When it is checked or unchecked, we handle that by setting the state of the other three.
Code Sandbox Demo
const Form = ({ onSubmit }) => {
const [agree1, setAgree1] = useState(false);
const [agree2, setAgree2] = useState(false);
const [agree3, setAgree3] = useState(false);
const isAgreedAll = agree1 && agree2 && agree3;
const handleCheckAll = (e) => {
setAgree1(e.target.checked);
setAgree2(e.target.checked);
setAgree3(e.target.checked);
};
const [email, setEmail] = useState("");
// placeholder so that you can implement your own validation
const emailLooksValid = email.length > 5;
const isDisabled = !isAgreedAll || !emailLooksValid;
return (
<>
<div>
<div>
<input
type="checkbox"
name="total_agree"
value="total_agree"
checked={isAgreedAll}
onChange={handleCheckAll}
/>
<label>전체 동의</label>
</div>
<div>
<input
type="checkbox"
name="agree1"
value="agree1"
checked={agree1}
onChange={(e) => setAgree1(e.target.checked)}
/>
<label>회원 약관</label>
<span>전체보기</span>
</div>
<div>
<input
type="checkbox"
name="agree2"
value="agree2"
checked={agree2}
onChange={(e) => setAgree2(e.target.checked)}
/>
<label>개인정보 수집 및 이용</label>
<span>전체보기</span>
</div>
<div>
<input
type="checkbox"
name="agree3"
value="agree3"
checked={agree3}
onChange={(e) => setAgree3(e.target.checked)}
/>
<label>위치 정보 이용 동의</label>
<span>전체보기</span>
</div>
</div>
<br />
입력해주신 이메일 정보는 회원가입 시 이메일로 설정됩니다.
<br />
<div>
<label>이메일</label>
<input
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
<button
disabled={isDisabled}
name="button"
onClick={onSubmit(email)}
>
인증코드 발송
</button>
</div>
</>
);
};
export default Form;
If you want to, you could combine some of the logic for the three checkboxes into a renderCheckbox function.
If you don't want/need button visible prior to being active I like to use && for display. ex:
( isFlag1 && isFlag2 && isFlag3 && <button>Active Now</button>)

Can't check or uncheck checkboxes in react if I initialize checked

I'm building a react app with some checkbox inputs, and if I set checked to an initial value when I create my checkboxes, I can't check or uncheck them on the page. Does any one know what might be going on, or how to fix this? Thanks.
<label><input type="checkbox" name="reportFlags" value="fraud" checked={reportFlags[0]}/>Fraud </label>
Considering that reportFlags is an array, and it can have value like .[ "fraud", ..]. In this case, it should be written as:
<label>
<inut
type="checkbox"
name="reportFlags"
value="fraud"
checked={reportFlags[0] === "fraud"}
/>Fraud{" "}
</label>
checked props should have a Boolean value true or false.. If you keep some truthy value like checked={"fraud"} for example, you can never uncheck it.
function App() {
return (
<div>
<label>
<input
type="checkbox"
name="reportFlags"
value="fraud"
checked={"fraud"}
/>Always checked
</label>
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
Maybe add an onClick for your input
<label><input type="checkbox" name="reportFlags" value="fraud" checked={reportFlags[0]} onClick={e=>{reportFlags[0] = e.checked}}/>Fraud </label>