React.JS - changing input based on another input - javascript

I am trying to change value of input field based on another one and vice versa.
That's create issue, any changed value not displayed in input. Anything I type is not show by input field.
Following which I tried, You can see I am trying to change value of input 1 based on 2 and 2nd input value based on first:
import React, { useState, useEffect } from 'react';
const App = () => {
useEffect(() => {
//fetch api call here
});
const [firstVal, setFirstVal] = useState(0);
const [secondVal, setSecondVal] = useState(0);
const changeFirstValue = (e) => {
setSecondVal(e.target.value / 2);
}
const changeSecondValue = (e) => {
setFirstVal(e.target.value * 2);
}
return (
<div>
<input type='number' value={firstVal} onChange={changeFirstValue}></input>
<input type='number' value={secondVal} onChange={changeSecondValue}></input>
</div>
)
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
Any help would be greatly appreciated.

If you want to show the division and multiplication relationship between these two elements. Try below code:
const changeFirstValue = (e) => {
setSecondVal(e.target.value);
setFirstVal(e.target.value * 2);
}
const changeSecondValue = (e) => {
setFirstVal(e.target.value);
setSecondVal(e.target.value / 2);
}
return (
<div>
<input type='number' value={firstVal} onChange={changeSecondValue}></input>
<input type='number' value={secondVal} onChange={changeFirstValue}></input>
</div>
);

From what I understood, I think you have to reverse the call of the two functions,
so your code will look like this:
...
<input type='number' value={firstVal} onChange={changeSecondValue}></input>
<input type='number' value={secondVal} onChange={changeFirstValue}></input>
...

Related

How to preserve spacing when storing a string into an array? JavaScript React.js

I have a form with a <textarea>. On submit that string gets stored into an array. Sometimes the strings have blank lines or additional spacing and I want to preserve this spacing. Right now, the only spacing preserved is the spacing between words. The handleSubmit component consist of a useRef hook that is pushed into the array. I'm looking for another approach for storing the string that would preserve spacing. I appreciate all ideas! Thank you for your time!
const textAreaRef = useRef();
const [entryArray, setEntry] = useState([]);
const handleSubmit = (event) => {
event.preventDefault();
const updatedList = [...entryArray];
updatedList.push(textAreaRef.current.value);
textAreaRef.current.value = ""; // Clears value
setEntry(updatedList);
}
return (
<div>
<form class="entryForm" onSubmit={handleSubmit} >
<label for="newEntryId">
<span>New Entry:</span>
<textarea type="text" id="newEntryId" name="newEntryName" rows="30" cols="75"
defaultValue="What's on your mind?" ref = {textAreaRef}
/>
</label>
<button type="submit">Submit</button>
</form>
</div>
)
Can't replicate the issue, works fine.
Vanilla js example, but works the same in React
const area = document.querySelector('textarea')
const button = document.querySelector('button')
const saved = []
button.addEventListener('click', () => {
saved.push(area.value)
area.value = ''
console.log(saved)
})
<textarea></textarea>
<button>save</button>

How to validate phone number onClick in React?

I want to validate phone number onClick of a button. This is what I have done, I am new to ReactJS. Please help me in this. When I click submit that time it will show an error message.
const [phoneNo, setPhoneNo] = useState(false)
const [errorMessage, setErrorMessage] = useState("")
const validateFunc = () => {
setPhoneNo(true)
}
const onChangeValidate= (e) => {
var phone = e.target.value;
if( !(phone.match('[0-9]{10}')) ){
setPhoneNo(false);
setErrorMessage("Please enter 10 digit")
}else{
}
setPhoneNo(true)
}
----
<input onChange ={() => onChangeValidate(e)} />
<button onClick = {validateFunc()}>Submit</button>
<p>{errorMessage}</p>
You seem to understand the basic construct of a function component using state but there are a couple of issues.
All event handlers will receive that event as an argument. So you can write <input onChange ={onChangeValidate} /> and <button onClick={validateFunc}>Submit</button>.
It maybe better to use test rather than match in this instance: /[0-9]{10}/.test(phone).
But I also think that you should allow the form to do the validation for you, rather than JS. This way you don't need the error state as the validation is all handled automatically.
Wrap your input and button in a <form> element with its own onSubmit handler, make the input required, and add a type="submit" to the button. You can use CSS to change the style of the input if it's not valid.
const { useState } = React;
function Example() {
const [phoneNo, setPhoneNo] = useState('');
// Update the phone number state when the
// input changes
function handleChange(e) {
setPhoneNo(e.target.value);
}
// In this example prevent the form from
// submitting so we can log the state, but you'll probably
// want to do an AJAX call here to submit the form
function handleSubmit(e) {
e.preventDefault();
console.log(phoneNo);
}
// Add your regex pattern to the input
// and make it required. If you submit an invalid
// number you'll get a neat little tooltip warning
// you of the issue, and the form won't submit until
// it has been fixed
return (
<form onSubmit={handleSubmit}>
<input
pattern="[0-9]{10}"
placeholder="Add a phone number"
onChange={handleChange}
required
/>
<button type="submit">Submit</button>
</form>
);
}
ReactDOM.render(
<Example />,
document.getElementById('react')
);
input:invalid { border: 1px solid red; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
<div id="react"></div>
const onChangeValidate= (e) => {
var phone = e.target.value;
if( !(phone.match('[0-9]{10}')) ){
setPhoneNo(false);
setErrorMessage("Please enter 10 digit")
}else{
setPhoneNo(true)
}
}
<p>{setPhoneNo===false?errorMessage:''}</p>
Set like these if there will be setphone no false then msg will be shown
Try this!
const [phoneNo, setPhoneNo] = useState(false)
const [errorMessage, setErrorMessage] = useState("")
const validateFunc = () => {
if(phoneNo) {
// perform submittion
}
}
const onChangeValidate= (e) => {
var phone = e.target.value;
if( !(phone.match('[0-9]{10}')) ){
setPhoneNo(false);
setErrorMessage("Please enter 10 digit");
}else{
setPhoneNo(true);
setErrorMessage("");
}
}
----
<input onChange ={(e) => onChangeValidate(e)} />
<button type="button" onClick = {validateFunc()}>Submit</button>
<p>{errorMessage}</p>

Do calculations with users input

I'm trying to do simple calculations with a new value in an updated state. I'm simply trying to divide a users input, with another number. I am a total beginner, so forgive me for the rooky question! Here's my code which isn't working for me. There are no errors, it's just not showing the resulting figure from the calculation -
import { useState } from "react";
const Counter = () => {
const [area, setArea] = useState("");
const newArea = () => {
setArea(area.target.value);
};
const deckBoards = (newArea) => {
(newArea / 0.145).toFixed(2);
};
return (
<div label="Deck">
<h2>Total area of deck</h2>
Area
<input
placeholder="Enter area here"
type="text"
onChange={newArea}
type="number"
/>
<br />
<h2>Deck boards</h2>Deck boards at 140mm wide : {deckBoards} lineal metres
</div>
You are missing event in the newArea function and DeckBoards needs to be area in JSx
Try this
import { useState } from "react";
const Counter = () => {
const [area, setArea] = useState("");
const deckBoards = (newArea) => {
// it was missing return statement
return (newArea / 0.145).toFixed(2);
};
const newArea = (e) => {
const value = e.target.value;
// Calculate here
const calculated = deckBoards(value);
// Update value
setArea(calculated);
};
return (
<div label="Deck">
<h2>Total area of deck</h2>
Area
<input
placeholder="Enter area here"
type="text"
onChange={newArea}
type="number"
/>
<br />
<h2>Deck boards</h2>Deck boards at 140mm wide : {area} lineal metres
</div>
);
}

how to disable a button if more than once check box is checked in React JS

I have to create a button that activates when a check box is checked and disables when unchecked.
I was able to achieve this by the following code.
import React from "react";
import "./styles.css";
import{useState} from 'react'
export default function App() {
const [change, setChange] = useState(true);
function buttonHandler(){
setChange(!change)
}
return (
<div className="App">
<button disabled={change}>Click Me</button>
<input type="checkbox" onChange={buttonHandler}/>
<input type="checkbox" onChange={buttonHandler}/>
<input type="checkbox" onChange={buttonHandler}/>
</div>
);
}
Now I have another challenge where I have to keep it disabled if more than 1 check box is checked. I tried to use object and array manipulation but it does not work. Any advice on how this can be achieved.
import React from "react";
import{useState} from 'react'
export default function App() {
const [checkboxStatus, setCheckboxStatus] = useState(Array(3).fill(false));
function buttonHandler(index){
let status = [...checkboxStatus];
status[index] = !status[index]
setCheckboxStatus(status)
}
return (
<div className="App">
<button disabled={checkboxStatus.filter(status => status === true).length != 1}>Click Me</button>
{Array(3).fill(0).map((_, index) => <input type="checkbox" checked={checkboxStatus[index]} onChange={() => buttonHandler(index)}/>)}
</div>
);
}
You can do that by keeping track of the status of the checkbox rather than tracking the status of the button. This is because if you know the status of all the checkboxes, you can easily calculate the status of the button.
I have also taken the liberty of converting the checkbox to map it since the content is the same. You can do the same by passing the index to each of them. Something like <input type="checkbox" onChange={() => buttonHandler(0}/> and so on for each of the inputs.
Wrap your input elements in a parent element like form or div.
Maintain state; an array that contains each box status (either true or false). When a box is changed call the handleChange which will update the state.
The button disabled property should call a function called isDisabled which will check to see if there are zero boxes checked or more than one box checked, returning true if the condition is matched.
const { useEffect, useState } = React;
function Example() {
const [boxes, setBoxes] = useState([]);
// In the text I suggested wrapping the inputs in
// a parent element. This was so we could use the following
// code to find its index within the list of inputs
// without adding any more code to the JSX
// Cribbed from https://stackoverflow.com/a/39395069/1377002
function handleChange(e) {
// Destructure the children from the parent of
// the element that was changed (ie all the input elements)
const { parentNode: { children } } = e.target;
// Find the index of the box that was changed
const index = [...children].indexOf(e.target);
// Copy the state
const newState = [...boxes];
// Toggle the boolean at the index of
// the `newState` array
newState[index] = !newState[index];
// Set the state with the updated array
setBoxes(newState);
}
// `filter` the boxes that return true.
// Return true if the length is 0 or > 1.
function isDisabled() {
const len = boxes.filter(box => box).length;
return len === 0 || len > 1;
}
return (
<div className="App">
<button disabled={isDisabled()}>Click Me</button>
<form>
<input type="checkbox" onChange={handleChange}/>
<input type="checkbox" onChange={handleChange}/>
<input type="checkbox" onChange={handleChange}/>
</form>
</div>
);
}
ReactDOM.render(
<Example />,
document.getElementById('react')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
<div id="react"></div>
Additional documentation
Destructuring assignment
Spread syntax

How to restrict user input to hexadecimal value in React?

This is my input:
This is its definition:
<Input
// type="number"
id="numeroSerie"
name="num_serie"
defaultValue={this.state.num_serie}
onChange={this.onChange}
required
pattern="[a-fA-F0-9]+"
maxlength="1"
/>;
Using pattern="[a-fA-F0-9]+" means that the user can enter whatever he wants and then the validation will be performed when he clicks on the form submit button.
What I would like is:
When the user clicks on any letter or a number that isn't hexadecimal, the input value would not change. Just like when the input type is number, and the user tries to enter a text.
Is this possible to implement?
To avoid illegal input (the input value would not change):
Add a regex condition inside the handler function would be fine.
/^[0-9a-f]+$/.test(yourValue) // hexadecimal
Test case: hexadecimal: https://www.regextester.com/93640
const {useState} = React;
const App = () => {
const [value, setValue] = useState("");
const onChange = e => {
const input = e.currentTarget.value;
if (/^[0-9a-f]+$/.test(input) || input === "") {
setValue(input);
}
};
return (
<div className="App">
<input
id="numeroSerie"
name="num_serie"
value={value}
onChange={onChange}
/>
</div>
);
}
ReactDOM.render(<App />, document.getElementById("root"));
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.12.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.12.0/umd/react-dom.production.min.js"></script>
This solution uses the onkeyup event of the input element to test the content against an arbitrary regular expression. That means that the input element might momentarily display an illegal character but after the regex test reveals the content to be illegal, the prior contents will be restored. Using the onkeyup event greatly simplifies processing.
function setupField(field, re)
{
field.autocomplete = "off";
field.saveValue = field.value;
field.onkeyup = function() {
var v = field.value;
if (v === '' || re.test(v)) {
field.saveValue = v;
}
else {
field.value = field.saveValue;
}
};
}
setupField(document.getElementById('hex'), /^[A-Fa-f0-9]+$/);
<input type="text" id="hex" size="8">

Categories

Resources