I have a number guessing game in React, the reset button is not clearing the fields.
This is my code:
import React, { useState } from "react";
import Button from "react-bootstrap/Button";
import Form from "react-bootstrap/Form";
let luckyNumber = Math.floor(Math.random() * 100) + 1;
function GuessingGame() {
const [guess, setGuess] = useState("");
const [count, setCount] = useState(0);
const [guesses, setGuesses] = useState([]);
const [luckyN, setLuckyN] = useState(luckyNumber);
const [message, setMessage] = useState(" Start guessing...");
const [disabled, setDisabled] = useState(false);
const handlerValueChange = (event) => {
setGuess(event.target.value);
};
const submitHandler = () => {
if (+luckyNumber === +guess) {
setMessage(" Congratulations! You guessed the Lucky Number!.");
setDisabled(true);
} else if (count === 2) {
setMessage(" Game over, maximum guess attempts have been reached.");
setDisabled(true);
} else if (luckyNumber < guess) {
setMessage(" Guess is too high.");
} else if (luckyNumber > guess) {
setMessage(" Guess is too low.");
}
setCount(count + 1);
setGuesses([...guesses, guess]);
};
const resetBtn = () => {
setDisabled(false);
setGuess = 0;
setCount = 0;
guess = ('')
message = "";
setGuess = ([])
setLuckyN = (0);
setMessage = (' Start guessing...');
setLuckyN(Math.floor(Math.random()* 100) + 1)
};
return (
<>
<h4>
I am thinking of a number between 1 and 100. Guess the Lucky Number!
</h4>
<p>You have made {count} guesses </p>
<p>Your guess is too high! Your guess is too low!</p>
<p> Your current guess is {guess}</p>
<Form>
<Form.Control
disabled={disabled}
type="text"
value={guess}
onChange={handlerValueChange}
></Form.Control>
<Button disabled={disabled} onClick={submitHandler}>
Guess
</Button>
<br />
<br />
<Button onClick={resetBtn}>Reset</Button>
</Form>
<p>message:{message}</p>
<p>Total plays: {count}</p>
<p>You are trying to guess this lucky number: {luckyNumber}!</p>
<p>Your guesses: </p>
{guesses?.map((item, index) => {
return <span key={index}>{item} </span>;
})}
</>
);
}
export default GuessingGame;
The button needs to clear the fields, load the random number and start again, it is not doing that and even after the validation of 3 incorrect attempts, if I hit reset and hit guess again, the count keeps going and the program runs like if there is no validation...
Any helps with this? Thanks!!
Call the setStates as a function, not as an assignment in your resetBtn function.
For example:
const resetBtn = () => {
setDisabled(false);
setCount(0);
setGuess(0);
setMessage('');
setGuess([])
setLuckyN(0);
setMessage(' Start guessing...');
setLuckyN(Math.floor(Math.random()* 100) + 1);
};
Related
I need to get the value of a input to be displayed in real time but I need to show some default text if the Input is empty or only spaces, but I cant seem to get it to work
const [productName, setProductName] = useState("");
const defaultProductName = "Name";
const handleChange = (event) => {
setProductName(event.target.value);
const inputValue = event.target.value;
const inputId = document.getElementById("productNameInput").innerHTML;
if (event.target.value.length == 0) {
document.getElementById("productNameID").innerHTML = defaultProductName;
} else {
document.getElementById("productNameID").innerHTML = inputValue;
}
};
<div className="productName" id="productNameID">
{defaultProductName}
</div>
<form>
<input type="text" id="productNameInput" onChange={handleChange} />
</form>
you can try:
if(document.getElementByID("productNameInput").value == " " | document.getElementByID("productNameInput").value.length == 0){
console.log("Input is empty")
}
I have an Virtual keyboard with Javascript the keyboard is typing in two inputs after reached maxlength it is focusing to second input. my problem is when i want to type in first input i should clicked to first input to focus it than typing with keyboard numbers
My question is How i can typing using this keyboard without clicking inside input, the first input should start typing immediately after i clicked on the buttons numbers
const maxLength = 7;
const firstInput = document.querySelector("#pin");
const secondInput = document.querySelector("#key");
const changedEvent = new Event("change")
let activeInput;
firstInput.addEventListener("focus", (event) => {
activeInput = event.target;
});
firstInput.addEventListener("change", (event) => {
console.log("i'm changing!");
if (firstInput.value.length >= maxLength) {
activeInput = secondInput;
secondInput.focus();
}
});
secondInput.addEventListener("focus", (event) => {
activeInput = event.target;
});
function resetNumber() {
if (!activeInput) {
console.log("pin");
return;
}
activeInput.value = "";
}
function setNumber(number) {
if (!activeInput) {
console.log("pin");
return;
}
activeInput.value = activeInput.value === number ? "" : (activeInput.value += number);
// manually tell the input that it has changed, so that the event listener defined above gets called. this usually only will happen with actual keyboard input
activeInput.dispatchEvent(changedEvent);
}
<button onclick="resetNumber()">Reset</button>
<button onclick="setNumber(0)">0</button>
<button onclick="setNumber(1)">1</button>
<button onclick="setNumber(2)">2</button>
<button onclick="setNumber(3)">3</button>
<button onclick="setNumber(4)">4</button>
<button onclick="setNumber(5)">5</button>
<button onclick="setNumber(6)">6</button>
<button onclick="setNumber(7)">7</button>
<button onclick="setNumber(8)">8</button>
<button onclick="setNumber(9)">9</button>
<br />
<input type="text" id="pin" />
<input type="text" id="key" />
<button id="reset" onclick="resetNumber()">Reset</button>
<br />
<input type="text" id="pin" />
<input type="text" id="key" />
<script>
const maxLength = 7;
const firstInput = document.querySelector('#pin');
const secondInput = document.querySelector('#key');
const resetBtn = document.querySelector('#reset');
for (let i = 9; i >= 0; i--) {
const numBtn = document.createElement('button');
numBtn.className = 'number';
numBtn.innerText = i;
resetBtn.parentElement.insertBefore(numBtn, resetBtn.nextSibling);
}
const numberBtns = document.querySelectorAll('.number');
const resetNumber = () => {
firstInput.setAttribute('value', '');
secondInput.setAttribute('value', '');
};
const setVal = (e) => {
const num = parseInt(e.target.innerText, 10);
if (firstInput.value.length <= maxLength) return firstInput.setAttribute('value', firstInput.value + num);
secondInput.setAttribute('value', secondInput.value + num);
};
numberBtns.forEach((btn) => btn.addEventListener('click', setVal));
</script>
I'm pretty new to react so please bear with me. I'm trying to create a custom increment/decrement quantity selector. Everything is working as I want it to except it's not allowing me to manually change the value of the input box. I can't figure out how to enable manual input.
I want to allow the user to be able to change the value using the increment/decrement buttons or manually enter a numeric value. Thanks in advance!!
const Quantity = ({max}) => {
const [qty, setQty] = useState(0)
let increaseQty = () => setQty(qty + 1)
let decreaseQty = () => setQty(qty - 1)
if(qty<=0){
decreaseQty = () => setQty(0)
}
if(qty>=max){
increaseQty = () => setQty(max)
}
return (
<div>
<Button onClick={decreaseQty}> - </Button>
<input type="text" value={qty}/>
<Button onClick={increaseQty}> + </Button>
</div>
)
}
export default Quantity
onChange={onChange} is required for the user to be able to enter the value manually.
import React, { useState } from "react";
const Quantity = ({ max }) => {
const [qty, setQty] = useState(0);
const decreaseQty = () => {
if (qty <= 0) {
setQty(0);
} else {
setQty(qty - 1);
}
};
const increaseQty = () => {
if (qty >= max) {
setQty(max);
} else {
setQty(qty + 1);
}
};
const onChange = (e) => {
const value = parseInt(e.target.value);
if (value >= 0 && value <= max) {
setQty(value);
}
};
return (
<div>
<button onClick={decreaseQty}> - </button>
<input type="text" onChange={onChange} value={qty} />
<button onClick={increaseQty}> + </button>
</div>
);
};
export default Quantity;
const StackOverflow = ({max}) => {
const [qty, setQty] = useState(0)
let increaseQty = () => setQty((qty) => qty+ 1)
let decreaseQty = () => setQty(qty - 1)
if(qty<=0){
decreaseQty = () => setQty(0)
}
if(qty>=max){
increaseQty = () => setQty(max)
}
const manuallyUpdate = (event) => {
let newvalue=parseInt(event.target.value)
if(newvalue <= 0){
setQty(0)
}else if(newvalue >= parseInt(max)){
setQty(max)
}else{
setQty(newvalue)
}
}
return (
<Container maxWidth="lg" style={{paddingTop:"5%"}}>
<div>
<Button onClick={decreaseQty}> - </Button>
<input type="text" value={qty} onChange={(e) => manuallyUpdate(e)}/>
<Button onClick={increaseQty}> + </Button>
</div>
</Container>
)
}
The issue is the functional component only runs once at render time. Therefore, the if statements checking for 0 or max won't run when this is changed. Instead, if you include the if statement in the function body then it will run each time the function is fired.
You could implement something similar to this:
const Quantity = ({ max }) => {
const [qty, setQty] = useState(0);
function decreaseQty() {
if (qty <= 0) {
setQty(0);
} else {
setQty(qrt - 1);
}
}
function increaseQty() {
if (qty >= max) {
setQty(max);
} else {
setQty(qrt + 1);
}
}
function onChange(e) {
const v = e.target.value;
if (v <= 0) setQty(0);
else if (v >= max) setQty(max);
else setQty(v);
}
return (
<div>
<Button onClick={decreaseQty}> - </Button>
<input type="text" value={qty} onChange={(e) => onChange(e)} />
<Button onClick={increaseQty}> + </Button>
</div>
);
};
export default Quantity;
I want to run a react file in the background.js but I keep getting the following error Uncaught SyntaxError: Cannot use import statement outside a module.
The react file Timer.js is a count down timer with user input which includes a number of libraries.
I have tried add type:module to my package.json but that has not solved the problem for me either.
Is there a way my background.js can be a react file that will continue to run in the background of my chrome extension?
Timer.js
import React, { useState } from 'react'
import { CountdownCircleTimer } from "react-countdown-circle-timer";
import Confetti from 'react-confetti'
const Timer = (props) => {
// Use states
const [currentTime, setTime] = useState(false)
var [time, setValue] = useState(60)
const [key, setKey] = useState(0);
const [print, setPrint] = useState(false)
const [userInput, setuserInput] = useState(null)
const [flag, setFlag] = useState(0)
const [recycle, setRecycle] = useState(false)
//Setting use state for 3 user inputs
const [timerValue, setTimer] = React.useState({
hour: 0,
minute: 0,
second: 2,
})
// Plays time
function startTime() {
setTime(true)
}
//Pause time
function stopTime() {
setTime(false)
}
function resetTime() {
setKey(prevKey => prevKey + 1)
setTime(false)
}
const renderTime = ({ remainingTime }) => {
// Converts user input value into hh:mm:ss format
var date = new Date(null);
date.setSeconds(remainingTime); // specify value for SECONDS here
var result = date.toISOString().slice(11, 19);
// Timer changing value when reaches 0
if (remainingTime === 0) {
console.log("STILL RAN IN THE BACKGROUND AND FINSIHED ")
setFlag(1000)
setTimeout(function () {
setRecycle(false)
}, 2000);
return <div className="timer"><h2 id="timerText">Well done!</h2></div>;
}
setRecycle(true)
setFlag(0)
return (
<div >
<div className="value"><h2 id="timerText">{result}</h2></div>
</div>
);
};
// assigns 3 user inputs to var
function userinput(event) {
const value = event.target.value;
setTimer({
...timerValue,
[event.target.name]: value
});
console.log(timerValue)
}
// Takes 3 user input converts them into seconds then adds them together to be set as timer duration
function valueToTime(event) {
var hour = parseInt(timerValue.hour)
var minute = parseInt(timerValue.minute)
var second = parseInt(timerValue.second)
hour = hour * 3600
minute = minute * 60
// Only number are allowed as user inputs
if (isNaN(hour, minute, second) || /[^a-zA-Z0-9]/.test(hour, minute, second)) {
hour = 0
minute = 0
second = 0
alert("bonger")
}
var totalTime = hour + minute + second
setValue(time = totalTime)
}
const width = window.innerWidth
const height = window.innerHeight
return (
<div>
<div className="timerWrapper" >
<br />
{
print ?
<h1>{userInput}</h1>
: null
}
<div className="timer-wrapper" >
<CountdownCircleTimer
key={key}
isPlaying={currentTime}
// By default time == 60 seconds, renderTime converts it into HH:MM:SS. Time can also be changed by userInput which is also in seconds. result == 00:01:00
duration={time}
colors={"#5d4192"}
onComplete={() => [false, 1000]}
size={250}
strokeWidth={15}
strokeLinecap={"round"}
trailColor={'#000'}
isLinearGradient={false}
>
{renderTime}
</CountdownCircleTimer>
<div className="test">
<div id="timeInput">
<p className="timeText" id="hour">Hours</p>
<p className="timeText" id="minute">Minutes</p>
<p className="timeText" id="second">Seconds</p>
<div id="hourWrapper" className="timeUnitWrapper">
<input id="hour" onChange={userinput} maxLength="2" type="text" name="hour" value={timerValue.hour}></input>
</div>
<div id="minuteWrapper" className="timeUnitWrapper">
<input id="minute" onChange={userinput} maxLength="2" type="text" name="minute" value={timerValue.minute}></input>
</div>
<div id="secondWrapper" className="timeUnitWrapper">
<input id="second" onChange={userinput} maxLength="2" type="text" name="second" value={timerValue.second}></input>
</div>
</div>
<div className="buttonWrapper">
<button className="customButton" id="set" onClick={valueToTime}>Set</button>
<button className="customButton" id="play" onClick={startTime}>Start</button>
<button className="customButton" id="pause" onClick={stopTime}>Pause</button>
<button className="customButton" id="reset" onClick={resetTime}>Reset</button>
</div>
</div>
</div>
</div>
<div className="wrapper" >
<Confetti
// creates scroll bar, find better fix
width={width - 15}
height={height}
run={true}
recycle={recycle}
numberOfPieces={flag}
confettiSource={{ x: 0, y: 0, w: width, h: 0 }}
gravity={0.2}
/>
</div>
</div>
)
}
export default Timer
Blockquote I CAN NOT PUSH MY RESULT TO THE PAGE, BUT new1Num and new2Num as well as newOper is
Blockquote reflected just fine. result only shows up inside console.log(result); I already tried taking var result outside of main function and tried const and also tried "let [result, setNewAnsw] = useState(0); " just like i did for new1Num but still no luck.
import React, { useState } from 'react';
// If the component accepts a parameter, this is referred to as a "prop."
// Props allows to pass values INTO my components from a parent document / component.
function Calculator (props)
{ // Every component should return JSX.
const [new1Num, setNew1Num] = useState(0);
const [new2Num, setNew2Num] = useState(0);
const [newOper, setNewOper] = useState('add');
// let [result, setNewAnsw] = useState(0);
var result;
const onFormSubmit = event =>
{
event.preventDefault();
console.log(new1Num);
const a = parseFloat(new1Num);
console.log(newOper);
console.log(new2Num);
const b = parseFloat(new2Num);
let result;
if (newOper == 'add'){
result = a + b;
console.log(result);
}
else if (newOper == 'subtract'){
result = a - b;
}
else if (newOper == 'divide' && b !=0){
result = a / b;
}
else if (newOper == 'multiply'){
result = a * b;
}
return newResult = result; //IN THIS SECTION I CAN'T TAKE MY RESULT TO RENDER INSIDE DOM
}
let heading = props.heading;
let input1 = props.input1;
let input2 = props.input2;
let newResult = props.newResult;
return (
<div>
<h1> { heading } </h1>
<form onSubmit = {onFormSubmit}>
<h2> { input1 } </h2>
<input
type="number" min="0" step="1"
onChange={e => { setNew1Num( e.target.value ) }}
value={new1Num}
className='field' />
<h2>Operator</h2>
<select
onChange={e => { setNewOper( e.target.value ) }}
value={newOper}
className='oper' >
<option value='add'>+</option>
<option value='subtract'>-</option>
<option value='divide'>/</option>
<option value='multiply'>*</option>
</select>
<h2> {input2}</h2>
<input
type="number" min="0" step="1"
onChange={e => { setNew2Num( e.target.value ) }}
value={new2Num}
className='field' />
<h2></h2>
<input type='submit' className='submitBtn success' value='Submit'/>
<h3>RESULT:
{new1Num}
{newOper}
{new2Num}
{newResult}
</h3>
</form>
</div>
);//new1Num and newOper and new2Num are populating inside browser just fine
}
export default Calculator
In order to publish the result to the page react would need to rerender. This can be achieved by saving the result into state and updating when completing a computation.
Use const [result, setNewAnsw] = useState(0); to set/access the result, and setNewAnsw(result) in the form's onFormSubmit callback. Delete let newResult = props.newResult; as newResult isn't passed as a prop, it's computed in state. Also, use "===" vs "==" for comparisons.
...
const [result, setNewAnsw] = useState(0);
const onFormSubmit = (event) => {
event.preventDefault();
console.log(new1Num);
const a = parseFloat(new1Num);
console.log(newOper);
console.log(new2Num);
const b = parseFloat(new2Num);
let result;
if (newOper === "add") {
result = a + b;
console.log(result);
} else if (newOper === "subtract") {
result = a - b;
} else if (newOper === "divide" && b) { // b any value other than 0 is truthy!
result = a / b;
} else if (newOper === "multiply") {
result = a * b;
}
setNewAnsw(result);
};
...