get value in input field from virtual keyboard in react - javascript

I am working on a countdown watch which have a virtual numpad (given in code as button) and three input (hour,minute and second). now i want that whenever i click input box and type in virtual numpad ,it print the value in that box only.
there i used three ref to getElement of input and change set their value but dont know how to set for specific box
const inputOne = useRef(null);
const inputTwo = useRef(null);
const inputThree = useRef(null);
const changeValue = (val) => {
inputOne.current.value = setTime({hour: updatedHour + val, minute: updatedMinute, second: updatedSecond});
inputTwo.current.value = setTime({hour: updatedHour, minute: updatedMinute + val, second: updatedSecond});
inputThree.current.value = setTime({hour: updatedHour, minute: updatedMinute, second: updatedSecond + val});
}
const changeTime = (e) => {
setTime({ ...time, [e.target.name]: e.target.value });
};
this is input fields i use , updatedHour,updatedMinute and updatedSecond is part of setTime state.
<input ref={props.inputOne} onChange={props.changeTime} name="hour" placeholder="Hour" value={props.updatedHour} />
<input ref={props.inputTwo} onChange={props.changeTime} name="minute" placeholder="Minute" value={props.updatedMinute} />
<input ref={props.inputThree} onChange={props.changeTime} name="second" placeholder="Second" value={props.updatedSecond} />
this is buttons which create virtual keyboard
<button className="grid-item" tpye='button' onClick={()=> props.changeValue('1')}>1</button>
<button className="grid-item" tpye='button' onClick={()=> props.changeValue('2')}>2</button>
<button className="grid-item" tpye='button' onClick={()=> props.changeValue('3')}>3</button>
<button className="grid-item" tpye='button' onClick={()=> props.changeValue('4')}>4</button>
<button className="grid-item" tpye='button' onClick={()=> props.changeValue('5')}>5</button>
<button className="grid-item" tpye='button' onClick={()=> props.changeValue('6')}>6</button>
<button className="grid-item" tpye='button' onClick={()=> props.changeValue('7')}>7</button>
<button className="grid-item" tpye='button' onClick={()=> props.changeValue('8')}>8</button>
<button className="grid-item" tpye='button' onClick={()=> props.changeValue('9')}>9</button>
<button className="grid-item" tpye='button' >Prev</button>
<button className="grid-item" tpye='button' onClick={()=> props.changeValue('0')}>0</button>
<button className="grid-item" tpye='button' >Next</button>

I've just copied whatever you've been writing and added it to stackblitz, and I've added some changes to it the link is below, hope you find it useful:
link to stackblitz for the solution

Related

React state change from within button's click handler is preventing form submission

Consider the code below:
function Item({name, _key})
{
console.log('rendering Item')
const [updatingName, setUpdatingName] = useState(false);
const nameInputElement = useRef();
useEffect(() => {
if (updatingName) {
nameInputElement.current.focus();
}
}, [updatingName]);
function onUpdateClick() {
setUpdatingName(true);
}
function onCancelClick() {
setUpdatingName(false);
}
return (
<div>
<input ref={nameInputElement} type="text" defaultValue={name} name="name"
disabled={!updatingName} />
{!updatingName
? <>
<button key={1} type="button" onClick={onUpdateClick}>Update</button>
<button key={2} type="submit" name="delete" value={_key}>Remove</button>
</>
: <>
<button key={3} type="submit" name="update" onClick={(e) => {setUpdatingName(false)}}>Save</button>
<button key={4} type="button" onClick={onCancelClick}>Cancel</button>
</>}
</div>
)
}
function ItemList({title})
{
return <>
<h1>{title}</h1>
<form method="post" onSubmit={(e) => {console.log('submitting');e.preventDefault()}}>
<Item name={'small'} _key={0} />
</form>
</>
}
export default ItemList;
The problem that I am facing is the click of the Save button. When it's clicked, as you can see, I trigger a state change. But at the same time, I also want the button to cause the underlying <form>'s submission.
(To check whether the form is submitted, I've prevented its default submit mechanism and instead gone with a simple log.)
However, it seems to be the case that when the state change is performed from within the onClick handler of the Save button, it ceases to submit the form. If I remove the state change from within the handler, it then does submit the form.
Why is this happening?
Live CodeSandbox demo
When you call setUpdatingName(false) in save button's click handler, the button is removed from the DOM before submitting. You can add the logic for showing the buttons in ItemList, like below:
function ItemList({ title }) {
const [updatingName, setUpdatingName] = useState(false);
return (
<>
<h1>{title}</h1>
<form
method="post"
onSubmit={(e) => {
e.preventDefault();
setUpdatingName(false);
console.log("submitting");
}}
>
<Item
name={"small"}
_key={0}
updatingName={updatingName}
setUpdatingName={setUpdatingName}
/>
</form>
</>
);
}
export default ItemList;
function Item({ name, _key, updatingName, setUpdatingName }) {
console.log("rendering Item");
const nameInputElement = useRef();
useEffect(() => {
if (updatingName) {
nameInputElement.current.focus();
}
}, [updatingName]);
function onUpdateClick() {
setUpdatingName(true);
}
function onCancelClick() {
setUpdatingName(false);
}
return (
<div>
<input
ref={nameInputElement}
type="text"
defaultValue={name}
name="name"
disabled={!updatingName}
/>
{!updatingName ? (
<>
<button key={1} type="button" onClick={onUpdateClick}>
Update
</button>
<button key={2} type="submit" name="delete" value={_key}>
Remove
</button>
</>
) : (
<>
<button key={3} type="submit" name="update">
Save
</button>
<button key={4} type="button" onClick={onCancelClick}>
Cancel
</button>
</>
)}
</div>
);
}
Also, you could use useTransition to ask React to delay the state update, so the submission happens first:
function Item({ name, _key }) {
console.log("rendering Item");
const [isPending, startTransition] = useTransition();
const [updatingName, setUpdatingName] = useState(false);
const nameInputElement = useRef();
useEffect(() => {
if (updatingName) {
nameInputElement.current.focus();
}
}, [updatingName]);
function onUpdateClick() {
setUpdatingName(true);
}
function onCancelClick() {
setUpdatingName(false);
}
return (
<div>
<input
ref={nameInputElement}
type="text"
defaultValue={name}
name="name"
disabled={!updatingName}
/>
{!updatingName ? (
<>
<button key={1} type="button" onClick={onUpdateClick}>
Update
</button>
<button key={2} type="submit" name="delete" value={_key}>
Remove
</button>
</>
) : (
<>
<button
key={3}
type="submit"
name="update"
onClick={(e) => {
startTransition(() => setUpdatingName(false));
}}
>
Save
</button>
<button key={4} type="button" onClick={onCancelClick}>
Cancel
</button>
</>
)}
</div>
);
}

Formik API : send different value in handleSubmit based on button click

I have the following code of a child component which is sending the form values to the parent when a user clicks .
Save and Continue button
Submit button
The Save and Continue button in the code is defined as follows:
<div className="form-field">
<Button size="large" variant="contained" color="primary" style={{marginLeft: '5px'}} type="submit">Save & Continue</Button>
</div>
When a user clicks Save and Continue button, I want to return requestStatuses: props.SimpleRequest && props.SimpleRequest.statusId || '10',.
However, when a user clicks the following Submit button:
<Button size="large" variant="contained" color="primary"
type="submit">Submit</Button>
I want to return props.SimpleRequest && props.SimpleRequest.statusId || '6',.
The default value for Status is 6 when a user interacts with the form and the dropdown is disabled so user can't change it. However, I want to send different values of it as I explained above based on different button clicks. Is it possible?
Minimal Code with relavent Formik form information is below:
const SimpleRequestForm = (props) => {
const {values, setFieldValue, touched, errors, isSubmitting, handleReset, handleChange} =
props;
const growl = React.createRef()
return (
<div>
<div id="formDiv">
<Growl ref={growl}/>
<Form className="form-column-3">
<div className="SimpleRequest-form">
<div className="form-field">
<CustomSelectField name="requestStatuses" disabled type="select" placeholder="Status"/>
</div>
<div className="form-field">
<CustomSelectField name="requestPrioritieses" type="select" value='Normal' placeholder="Priority"/>
</div>
<div className="form-field">
<CustomSelectField name="assignees" type="select" placeholder="Assignee"/>
</div>
<div className="form-field">
<Button size="large" variant="contained" color="primary" style={{marginLeft: '5px'}} type="submit">Save & Continue</Button>
</div>
</div>
<div className="btn-group-right">
<Button size="large" variant="contained" color="primary"
type="submit">Submit</Button>
<Button size="large" variant="contained" color="primary" onClick={handleReset}
style={{marginLeft: '5px'}} type="button">Reset</Button>
<Button size="large" variant="contained" color="primary" onClick={props.onCancel}
style={{marginLeft: '5px'}} type="button">Cancel</Button>
</div>
</Form>
</div>
</div>
)
};
export const SimpleRequestEnhancedForm = withFormik(
{
mapPropsToValues: props => {
return {
requestId: props.SimpleRequest && props.SimpleRequest.requestId || '',
requestStatuses: props.SimpleRequest && props.SimpleRequest.statusId || '6',
requestPrioritieses: props.SimpleRequest && props.SimpleRequest.priorityId || '3',
assignees: props.SimpleRequest && props.SimpleRequest.assigneeId || '',
}
},
validationSchema:validationSchema,
handleSubmit(values, {props, resetForm, setErrors, setSubmitting}) {
console.log("submit Simple Request Form....")
values.assets = JSON.parse(sessionStorage.getItem('uploadedFiles'));
props.handleSubmit(values)
setSubmitting(false)
},
setFieldValue(field, value, shouldVal) {
console.log('In setFieldValue')
},
displayName: 'Simple Request Form',
})(SimpleRequestForm)

REACT, form submit after preventDefault not working until submit button is clicked a second time

import React , {useState } from "react";
import Button from 'react-bootstrap/Button';
import Form from "react-bootstrap/Form"
import 'bootstrap/dist/css/bootstrap.min.css';
import {push,ref} from "firebase/database";
import db from "./firebase";
function App() {
const [age, setAge] = useState("");
const [hes, setHes] = useState("");
const [visa, setVisa] = useState("");
const [islem , setIslem] = useState("");
const handleSubmit = (event) =>{
event.preventDefault();
setAge(event.target[0].value);
setHes(event.target[1].value);
setVisa(event.target[2].value);
push(ref(db,"info"),{
age: age,
hes: hes,
visa : visa,
islem : islem
})
}
return (
<div>
<Form onSubmit={
handleSubmit
}>
<Form.Group className="mb-3 mx-3" >
<Form.Label>AGE</Form.Label>
<Form.Control name="age" type="text" placeholder="AGE: " />
</Form.Group>
<Form.Group className="mb-3 mx-3" >
<Form.Label>HES</Form.Label>
<Form.Control name="hes" type="text" placeholder="Hes CODE: " />
</Form.Group>
<Form.Group className="mb-3 mx-3" >
<Form.Label>VISA</Form.Label>
<Form.Control name="visa" type="text" placeholder="Visa: " />
</Form.Group>
<div className="d-grid gap-2">
<Button onClick = {() =>{
setIslem("NC")
}}variant="secondary" type="submit" size="lg">
New Customer
</Button>
<Button onClick = {() =>{
setIslem("NCC");
}}variant="secondary" type="submit" size="lg">
New Cards
</Button>
<Button onClick = {() =>{
setIslem("FI");
}}variant="secondary" type="submit" size="lg">
For information
</Button>
<Button onClick = {() =>{
setIslem("WDM");
}}variant="secondary" type="submit" size="lg">
Withdraw / Deposit Money
</Button>
<Button onClick = {() =>{
setIslem("IO");
}}variant="secondary" type="submit" size="lg">
Insurance Operations
</Button>
<Button onClick = {() =>{
setIslem("RO");
}}variant="secondary" type="submit" size="lg">
Retirement Operations
</Button>
<Button onClick = {(e) =>{
setIslem("PT")
}}variant="secondary" type="submit" size="lg">
Paying Fines / Taxes / Debt
</Button>
<Button onClick = {() =>{
setIslem("SME");
}}variant="secondary" type="submit" size="lg">
SME Operations
</Button>
<Button onClick = {() =>{
setIslem("INO");
}}variant="secondary" type="submit" size="lg">
Investment Operations
</Button>
<Button onClick = {() =>{
setIslem("MM");
}}variant="secondary" type="submit" size="lg">
Money Management
</Button>
</div>
</Form>
</div>
);
}
export default App;
This is my code, database writing data after only 2nd submission and it is writing old data. I want to write data in first submission.
For example:
in first submission my data is : age = 15,
in second submission my data is : age = 16,
In database it is written like: [age = "" , age = "15"]. It is coming always 1 step behind. How can I solve this.
It would be better if you update the states at the time of modification and not at the time of submission, anyway, to fix the problem you have I suggest you send the parameters of the form instead of the states since React will not change the value of these until the next render.
const handleSubmit = (event) =>{
event.preventDefault();
setAge(event.target[0].value);
setHes(event.target[1].value);
setVisa(event.target[2].value);
push(ref(db,"info"),{
age: event.target[0].value,
hes: event.target[1].value,
visa : event.target[2].value,
islem : islem
})
}
In this case however the state variables (setAge, setHes, setVisa) are unnecessary I would say

How to concat number to a div?

I am making a calculator with HTML, CSS, and JS. Currently, I want a number to be concatenated to the output everytime I click a number button. Does anyone know how to do this because my code isn't working. The console keeps returning output.concat is not a function
const numbers = document.querySelectorAll("[data-number]");
numbers.forEach(number => {
number.addEventListener("click", () => {
output.concat(number);
})
})
<div>
<div data-output></div>
<button data-clear>C</button>
<button data-operator>/</button>
<button data-number>7</button>
<button data-number>8</button>
<button data-number>9</button>
<button data-operator>*</button>
<button data-number>4</button>
<button data-number>5</button>
<button data-number>6</button>
<button data-operator>-</button>
<button data-number>1</button>
<button data-number>2</button>
<button data-number>3</button>
<button data-operator>+</button>
<button data-number>0</button>
<button data-number>.</button>
<button data-equals>=</button>
</div>
You need to define output, as currently it is undefined. Do it like this:
const output = document.querySelector("[data-output]");
And then, you must treat it like an element, not like a string. The same is true for the number variable: it is not a string (nor number), but a button element. So read and add content using the textContent property on both involved elements:
output.textContent += number.textContent;
NB: You have an error in your first line. It needs a closing ] in the selector:
const numbers = document.querySelectorAll("[data-number]");
Code:
const output = document.querySelector("[data-output]");
const numbers = document.querySelectorAll("[data-number]");
numbers.forEach(number => {
number.addEventListener("click", () => {
output.textContent += number.textContent;
})
})
<div>
<div data-output></div>
<button data-clear>C</button>
<button data-operator>/</button>
<button data-number>7</button>
<button data-number>8</button>
<button data-number>9</button>
<button data-operator>*</button>
<button data-number>4</button>
<button data-number>5</button>
<button data-number>6</button>
<button data-operator>-</button>
<button data-number>1</button>
<button data-number>2</button>
<button data-number>3</button>
<button data-operator>+</button>
<button data-number>0</button>
<button data-number>.</button>
<button data-equals>=</button>
</div>
I probably won't take this approach but building on your code you probably want something like
const numbers = document.querySelectorAll("[data-number]");
const operator = document.querySelectorAll("[data-operator]");
const clear = document.getElementById("clear");
const output = document.getElementById("output");
resu=""
numbers.forEach(number => {
number.addEventListener("click", () => {
resu+=number.textContent
output.textContent=resu
})
})
operator.forEach(op => {
op.addEventListener("click", () => {
if(output.textContent.charAt(output.textContent.length-1)===op.textContent) return
else {resu+=op.textContent
output.textContent=resu}
})
})
clear.addEventListener("click",()=>{
output.textContent=""
})
<div>
<div data-output></div>
<button data-clear id="clear">C</button>
<button data-operator>/</button>
<button data-number>7</button>
<button data-number>8</button>
<button data-number>9</button>
<button data-operator>*</button>
<button data-number>4</button>
<button data-number>5</button>
<button data-number>6</button>
<button data-operator>-</button>
<button data-number>1</button>
<button data-number>2</button>
<button data-number>3</button>
<button data-operator>+</button>
<button data-number>0</button>
<button data-number>.</button>
<button data-equals>=</button>
</div>
<div id="output">#######</div>

how to get value of column in react

I have table column like this which have value that comes from my reducer. the same column has increment/decrement button. so when use clicks on button I have to get value from that <td> and trigger my action. I am searching here but its for input text which have event onChange. please anyone let me know how to do this?
Here is my <td> column:
<td>
{this.props.prog}%
<button type="button" className="btn btn-danger">
<span className="glyphicon glyphicon-arrow-up" />
</button>
<button type="button" className="btn btn-danger">
<span className="glyphicon glyphicon-arrow-down" />
</button>
</td>
EDIT 1:
I have tried something basically my onClick triggered properly but I am not able to pass the value
<td>
<button type="button" className="btn btn-danger" onClick={this.props.resetGrowth}>Reset</button>
{this.props.prog}%
<button type="button" className="btn btn-danger" onClick = {(event) => this.props.updated(this.props.prog) }>
<span className="glyphicon glyphicon-arrow-up"/>
</button>
<button type="button" className="btn btn-danger">
<span className="glyphicon glyphicon-arrow-down"/>
</button>
</td>
it will pass to it this component
<Table updated={value => this.props.udated(value)}/>
this is my container it triggers value
<VolumeComponent
udated = {(value) => updated(value)}/>
const mapDispatchToProps= (dispatch) => (
bindActionCreators({updated},dispatch)
)
Since you are using a reducer I am guessing you are using redux. If {this.props.prog}is your value, you could use this in the OnClick function you pass to the increase/ decrease buttons. For example:
handleDecrease(){
const newValue = this.props.prog + 1;
this.props.updateValue(newValue)
}
handleIncrease(){
const newValue = this.props.prog - 1;
this.props.updateValue(newValue)
}
render(){
return (
...
<button onClick={this.handleIncrease}/>
);
}

Categories