I want to prevent being able to choose a number less than zero with e.target.value - javascript

I want to prevent negative values ( < 0) to be chosen on input field. Being "0" the lowest value available for the input field.
Here is the javascript and html code:
// Button functions
const minusButton = document.getElementById('minus');
const plusButton = document.getElementById('plus');
const inputField = document.getElementById('amount');
minusButton.addEventListener('click', event => {
event.preventDefault();
const currentValue = Number(inputField.value) || 0;
inputField.value = currentValue - 0.01;
});
plusButton.addEventListener('click', event => {
event.preventDefault();
const currentValue = Number(inputField.value) || 0;
inputField.value = currentValue + 0.01;
});
// Returning 0 when clearing input
const numInputs = document.querySelectorAll('input[type=number]')
numInputs.forEach(function(input) {
input.addEventListener('change', function(e) {
if (e.target.value == '') {
e.target.value = 0
}
})
})
<button class="input-btn" id="minus">−</button>
<button class="input-btn" id="plus">+</button>
<input class="input" type="number" value="0" id="amount"/>

Your code is almost correct.
In the minusButton event handler logic, you can enforce that the value never gets set to anything lower than 0.
Edit the input event handler to check for values lower than 0, not equal to it.
Note: the event handler you add to input to fire upon 'change' only gets executed when the user manually makes the change to the value of input box, and NOT when it gets changed by code (as you're doing through minusButton and plusButton). Since, the user clicks the button (and never interact with the input directly), the event happens on the button, not the input box.
You can give below code a try.
// Button functions
const minusButton = document.getElementById("minus");
const plusButton = document.getElementById("plus");
const inputField = document.getElementById("amount");
minusButton.addEventListener("click", (event) => {
event.preventDefault();
const currentValue = Number(inputField.value) || 0;
// if less than 0, set to 0, else currentValue - 0.01
inputField.value = currentValue - 0.01 < 0 ? 0 : currentValue - 0.01;
});
plusButton.addEventListener("click", (event) => {
event.preventDefault();
const currentValue = Number(inputField.value) || 0;
inputField.value = currentValue + 0.01;
});
// Returning 0 when clearing input
const numInputs = document.querySelectorAll('input[type="number"]');
numInputs.forEach((input) => {
input.addEventListener("change", function (e) {
if (e.target.value === "" || e.target.value < 0) {
e.target.value = 0;
}
});
});
If you were using a submit button and the input box was in a form element, you could have used the min attribute
<input class="input" type="number" value="0" id="amount" min="0" />
This would be the ideal front-end way of doing it.
You could use JavaScript too, but it can be disabled by the user.
You should, however, check this value (validation) when it gets submitted, before you use it because even this can be bypassed.

let newValue = currentValue - 0.01
if(newValue < 0) {
newValue = 0
}
inputField.value = newValue

Related

Get a result when an option value selection is changed in javascript

I'm trying to get a different value when the value of an option is changed. I have this code, but when I change my selection, the result is not changing.
let cantidad1 = document.getElementById("cantidad");
let moneda1 = document.getElementById("cambio").value;
if (moneda1 === "cup") {
tipodemoneda = 97;
} else if (moneda1 === "mlc") {
tipodemoneda = 0.89;
}
let tasadecambio = tipodemoneda;
let resultado1 = document.getElementById("resultado")
cantidad1.addEventListener("change", () => {
resultado1.value = parseFloat(tasadecambio) * parseFloat(cantidad1.value)
})
Listen for input events instead of change events. Change events only fire for a text input or text area when the the element lose focus (1)
let cantidad1 = document.getElementById("cantidad");
let moneda1 = document.getElementById("cambio").value;
if (moneda1 === "cup") {
tipodemoneda = 97;
} else if (moneda1 === "mlc") {
tipodemoneda = 0.89;
}
let tasadecambio = tipodemoneda;
let resultado1 = document.getElementById("resultado")
cantidad1.addEventListener("input", () => {
resultado1.value = parseFloat(tasadecambio) * parseFloat(cantidad1.value)
})
<input id="cantidad">
<input id="cambio" value="cup">
<input id="resultado">
Also the way the code is right now, moneda1 only gets set once. You should move it into the event handler.
let cantidad1 = document.getElementById("cantidad");
let moneda1 = document.getElementById("cambio");
let resultado1 = document.getElementById("resultado")
let tipodemoneda; // Put this to stop it from being a global variable (window.tipodemoneda)
function updateResultado() { // Handler in its own function
if (moneda1.value === "cup") { // Check mondedal.value since it can change
tipodemoneda = 97;
} else if (moneda1.value === "mlc") {
tipodemoneda = 0.89;
}
let tasadecambio = tipodemoneda;
resultado1.value = parseFloat(tasadecambio) * parseFloat(cantidad1.value)
}
cantidad1.addEventListener("input", updateResultado)
moneda1.addEventListener("change", updateResultado)
<input id="cantidad">
<select id="cambio">
<option value="mlc">mlc</option>
<option value="cup">cup</option>
</select>
<input id="resultado">

HTML number input - how to increase step size w/ time held

For number inputs in HTML, is there any way to have it function such that the longer the user holds the stepper arrows, the larger the increment/step size becomes?
For example, we start out at step size=1, but after a few seconds of holding, it will ramp up to 5, 10, 20, ... etc.
Is this possible?
Thanks!
The step attribute controls the quantity added to the value of the input when the stepper is activated.
Using the setInterval method, we can change this value every X milliseconds.
Using a listener for the input's mousedown event, we can start/stop the interval and reset the current step when the mouse is released.
Here's a sample:
const input = document.getElementById('my-stepper');
const label = document.getElementById('my-label');
const defaultStep = 1;
const maxStep = 100000;
let interval;
input.addEventListener('mousedown', () => {
interval = setInterval(() => {
const currentStep = Number(input.step);
if (currentStep < maxStep) {
input.step = currentStep * 10;
label.innerText = `Current step is ${input.step}`;
}
}, 1000);
});
input.addEventListener('mouseup', () => {
clearInterval(interval);
input.step = defaultStep;
label.innerText = `Current step is ${input.step}`;
});
<input id="my-stepper" type="number" step="1" value="0">
<p id="my-label">Current step is 1</p>
Basic idea is below using mouse event listeners.
const elem = document.querySelector("#num");
let timer;
elem.addEventListener("mousedown", (evt) => {
const inp = evt.target;
inp.dataset.step = inp.step;
const initialValue = Number(inp.value);
timer = window.setInterval(()=>{
const dir = Number(inp.value) > initialValue ? 100 : -100;
console.log(Number(inp.step) + dir);
inp.step = Number(inp.step) + dir;
},2000);
});
elem.addEventListener("mouseup", (evt) => {
if (timer) window.clearTimeout(timer);
const inp = evt.target;
inp.setAttribute('step', inp.dataset.step);
});
<input type="number" step="1" id="num">

Can you use decrement/increment operator but skip 0 in JavaScript just like how continue works?

I have here a number counter code where it has increment and decrement buttons. Whenever you click a button, it does its job of incrementing and decrementing the value of the input.
// =number_counter
function decrement(e) {
const btn = e.target.parentNode.parentElement.querySelector(
'button[data-action="decrement"]'
);
const target = btn.nextElementSibling;
let value = Number(target.value);
value--;
target.value = value;
toggleRowClass(btn, value, ["bg-red-200", "item-returned"]);
}
function increment(e) {
const btn = e.target.parentNode.parentElement.querySelector(
'button[data-action="decrement"]'
);
const target = btn.nextElementSibling;
let value = Number(target.value);
value++;
target.value = value;
toggleRowClass(btn, value, ["bg-red-200", "item-returned"]);
}
const decrementButtons = document.querySelectorAll(
`button[data-action="decrement"]`
);
const incrementButtons = document.querySelectorAll(
`button[data-action="increment"]`
);
decrementButtons.forEach(btn => {
btn.addEventListener("click", decrement);
});
incrementButtons.forEach(btn => {
btn.addEventListener("click", increment);
});
This time, I wanted to skip 0 when clicking the buttons having the input value as either -1 or 1. Can I add a behavior such as continue; without the loop and just having increment/decrement operators?
Continue does't exist outside of the loops. The simplest solution for you is to add a condition inside increment/decrement where you would check if the current value is -1/1 and add additional logic in those cases :)
The solution was just to set the value = 1 or value = -1;
function decrement(e) {
const btn = e.target.parentNode.parentElement.querySelector(
'button[data-action="decrement"]'
);
const target = btn.nextElementSibling;
let value = Number(target.value);
value--;
if (value == 0) {
value = -1;
target.value = value;
} else {
target.value = value;
}
toggleRowClass(btn, value, ["bg-red-200", "item-returned"]);
}
function increment(e) {
const btn = e.target.parentNode.parentElement.querySelector(
'button[data-action="decrement"]'
);
const target = btn.nextElementSibling;
let value = Number(target.value);
value++;
if (value == 0) {
value = 1;
target.value = value;
} else {
target.value = value;
}
toggleRowClass(btn, value, ["bg-red-200", "item-returned"]);
}
Sorry I have missed it.

Code optimization in Reactjs for multiple events

The points are:
when I enter any number in input so % sign add after the digit.
when I delete all numbers, % sign remove and width reset according entering the value.
if number already come from the api so when i click then my focus before % sign .
number <=100
so my functionality is working fine, but the problem is i am using multiple events (onClick, KeyPress, keyUp, onBlur etc) , so how i manage this functionality
<div className={`form-control valbox1 dvPercValue`} disabled = {isDisabled ? true : false } onClick={event=>this.focusPerc(event, rowIndex)}>
<Textbox
onTextboxChange={e => this.onTextboxChange(e, rowIndex)}
name="percentage"
isDisabled={isDisabled}
value={(value) }
maxLength={4}
refData={(input) => {
this.myAllocat[rowIndex] = input
}}
className = "percValue"
onInputKeyPress= {event=> this.setWidth(event, rowIndex) }
onInputkeyUp={ event=> this.setInputValue(event, rowIndex)}
textBoxWidth= { textBoxWidth }
/>
{ value && <span className="percSign ">%</span> }
</div>
const textBoxWidth = {
width: (value && parseInt(value,10) < 101) ? ((value.length ) * 8) : 0
};
focusPerc =(e, rowIndex) => {
if (rowIndex >=0) {
let searchInput= null;
const allBox = document.querySelectorAll(".dvPercValue");
for (let i=0;i<allBox.length;i++) {
allBox[i].classList.remove("active");
}
if (e.target && e.target.tagName) {
if (e.target.tagName.toLowerCase() === 'span' || e.target.tagName.toLowerCase() === 'input') {
e.target.parent.classList.add("active");
searchInput= e.target.parent.children[0];
} else {
e.target.classList.add("active");
searchInput = e.target.children[0]
}
}
if (searchInput) {
const strLength = searchInput.value.length * 2;
searchInput.focus();
searchInput.setSelectionRange(strLength, strLength);
}
}
}
setInputValue = (e, rowIndex) => {
const inputvalue=e.target.value.trim();
if (e.keyCode ===8 && rowIndex >=0) {
if (parseInt(inputvalue,10) > 100) {
return;
}
e.target.style.width = ((inputvalue.length ) * 8) + 'px';
}
}
setWidth =(e, rowIndex) => {
const inputval=e.target.value.trim();
if (parseInt(inputval,10) > 100) {
return;
}
e.target.style.width = ((inputval.length + 1) * 8) + 'px';
}
const TextboxComponent = (props) => {
return (
<input type="text
value= {props.value}
name= {props.name}
maxLength= {props.maxLength}
className={props.className}
disabled= {props.isDisabled}
placeholder= {props.placeHolder}
onChange={props.onTextboxChange}
onKeyPress = {props.onInputKeyPress}
onBlur = {props.onTextBoxBlur}
ref={props.refData}
autoComplete="off"
onKeyUp = {props.onInputkeyUp}
style = { props.textBoxWidth }
/>
)
}
For optimizing your ReactJS code you can firstly divide it into clear components and subsequently work on their functionality
So say you want add/remove a class "active" to your element so that you can highlight the field that the user is currently focused on this can be done as following:
<input
type="text"
className="simple"
onFocus={e => (e.target.classList += " active")}
onBlur={e => (e.target.className = "simple")}
/>
Which will help you avoid the current approach (which I guess is like jQuery) where you first capture all the elements and then loop over them.
Similarly if you want to capture the whole input of the user and then replace % sign for the deleted characters you can use a state for your component updating it through onChange.
If it is simply about showing a % sign after your input you can continue with your own code value && <span className="percSign ">%</span>

updated values inside form do not transfer properly into new div

basically when you enter a value out of the specified range it gets updated to the minimum/maximum allowed, but the value of the var doesn't get updated to the max/min. (you can check by entering 1 into both forms and clicking on quote)
https://jsfiddle.net/epf4uyr6/
function cadCheck(input) {
if (input.value < 2) input.value = 2;
if (input.value >= 100) input.value = 99.99;
}
document.getElementById('cad').onkeyup = function() {
var cad = (this.value);
document.getElementById("cad-quote").innerHTML = "Market: $" +cad;
}
your values not updating properly because , keyup function executing first and then onchange(cadCheck) function execute.
your current logic is inside onchange function , thats why value not updating properly.
move this line in onkeyup function , and remove it from onchange.
document.getElementById('cad').onkeyup = function() {
if (this.value >= 100) this.value = 99.99;
var cad = (this.value);
document.getElementById("cad-quote").innerHTML = "Market: $" +cad;
}

Categories