how do i adjust this slice and replace React - javascript

I am trying to set the maximum length of an input through js because I need to do it like this, and in part it already works, I need it to print with commas but not to count them, this is my code:
<input onInput={ (evt) => this.handleChange(evt)} />
if the maxlenght is 8 then until I press 8 numbers it prints me like this:
12,222,222
but if I press one more number, 8 are still preserved but the format is damaged and it prints like this:
12222222
private handleChange(evt) {
evt.target.value=evt.target.value.replace(/,/g,"").slice(0, this.maxLength)
const element = evt.target ? evt.target.value : '';
if (this.type == 'decimal') {
const value= this.formatDecimal(element,this.maxLength, this.maxDecimals, this._separatorDecimal, this.separator);
}
}
formatDecimal(input, maxLength, maxDecimals, separator, separatordigit) {
var input_val = input;
if (input_val === separator) {
input_val = '';
}
input_val = this.formatNumber(input_val, maxLength, separatordigit);
input_val = "" + input_val;
}
return input_val;
}
I hope you can help me, thanks

The logic seems to be working when I made the input controlled and made value part of the state of the component.
Main things to note are:
You shouldn't mutate the input's value directly. That could cause some issues.
You should make value changes that you expect to be related to the DOM in component state rather than component properties. Properties won't cause the component to re-render and sync to the dom.
class Example extends React.Component {
maxLength = 14;
type = 'decimal';
state = { value: '' };
separator = ','
handleChange = (ev) => {
const element = ev.target.value.replace(/,/g,'').slice(0,this.maxLength);
if (this.type == 'decimal') {
this.setState({value:this.formatDecimal(
element,
this.maxLength,
this.maxDecimals,
this._separatorDecimal,
this.separator
)});
}
};
formatDecimal(input, maxLength, maxDecimals, separator, separatordigit) {
var input_val = input;
if (input_val === separator) {
input_val = '';
}
input_val = this.formatNumber(input_val, maxLength, separatordigit);
input_val = '' + input_val;
return input_val;
}
formatNumber(n, maxLength, separator) {
n = n.replace(/\D+/g, '');
n = n.substring(0, maxLength);
// format number 1000000 to 1,234,567
return n.replace(/\D+/g, '').replace(/\B(?=(\d{3})+(?!\d))/g, separator);
}
render() {
return (
<div>
<input value={this.state.value} onChange={this.handleChange} />
</div>
);
}
}
ReactDOM.render(<Example />, document.getElementById('root'));
<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>
<div id="root"/>

Related

Button adding user input to the array. Then typing out the data in array to a <div>

I'm fairly new to coding so please ignore any unwritten rules I might be missing.
Any feedback is appreciated.
Basically, I have three text inputs, Name:, Age:, and Password:
If not all fields are filled and error message will occur, but if everything is filled in and the user presses the button I need the information to be saved to an array, and for the information (only Name: & Age:) to be typed out below, along with two other "personas" that are to be added via (Push) method.
However, I'm not getting these different stages to work together. I am receiving different errors each time I change something. As previously stated I am a novice within coding and will take any help I can get.
function buttonclick() {
validate();
addToArray();
}
function validate() {
var name = document.getElementById("NameInput");
var age = document.getElementById("AgeInput");
var password = document.getElementById("PasswordInput");
if (name.value == "" || password.value == "" || age.value == "") {
alert("Field is required");
return false;
} else {
true;
}
if (password.value == "IHM") {
true;
} else {
alert("Not a valid password")
return false;
}
}
function addToArray() {
let persons = [];
let person1 = {
Uname: "Marcus",
Uage: 34
}
let person2 = {
Uname: "Cihan",
Uage: 35
}
// Gets name from the input
let Uname = document.getElementById("NameInput").value;
// Gets age from the input
let Uage = document.getElementById("AgeInput").value;
// Adds antoher name to the array?
persons.push(person1, person2);
// Sorts the array
persons.sort();
/* Is this needed?
const write = () => {
NameInput.forEach()
AgeInput.forEach()
}*
<div>
<input type="text" placeholder="Name" id="NameInput">
</div>
<div>
<input type="number" placeholder="Age" id="AgeInput">
</div>
<div>
<input type="password" placeholder="Password" id="PasswordInput">
</div>
<button onclick="buttonclick()" type="button">Submit</button>
<div id="output"></div>
I see your code in the vsCode, and your array gets the two objects if you check in the console, I add an object of user name and age- from inputs. I hope that im understand.. that my code:
enter code here function buttonclick() {
validate(addToArray);
}
var uname = document.getElementById("NameInput");
var age = document.getElementById("AgeInput");
function validate(cb) {
var password = document.getElementById("PasswordInput");
if (name.value == "" || password.value == "" || age.value == "") {
alert("Field is required");
return false;
} else {
true;
}
if (password.value == "IHM") {
true;
} else {
alert("Not a valid password")
return false;
}
cb();
}
function addToArray() {
let persons = [];
let person1 = {
Uname: "Marcus",
Uage: 34
}
let person2 = {
Uname: "Cihan",
Uage: 35
}
// Gets name from the input
let objOfUserInputs = {};
objOfUserInputs.uname = uname.value;
objOfUserInputs.uage = age.value;
// Gets age from the input
let Uage = document.getElementById("AgeInput").value;
// Adds antoher name to the array?
persons.push(person1, person2, objOfUserInputs);
// Sorts the array
persons.sort();
console.log(persons);
}
First step: You don't need to write true in the conditionals, you could just return if you don't need to check the returned value
eg.:
For the first conditional, you don't even need the else part
if (name.value == "" || password.value == "" || age.value == "") {
alert("Field is required");
return
}
For the second conditional
if (password.value == "IHM"){
return true
} else {
alert ('Wrong password')
}
You could even write it like this, since if the condition is met, the function will return and the alert won't trigger
if (password.value == "IHM"){
return true
}
alert ('Wrong password')
Try it out.
Then you want to append those values to the array (if i understood correctly) and you want them to be displayed, alongside with the others.
I suggest you create a similar object and then push that object to the array, then you can sort it
So, create the object from the user input:
let Uname = document.getElementById("NameInput").value;
let Uage = parseInt(document.getElementById("AgeInput").value);
//You need to use parseInt() if you want that item to be an integer
let person3 = {
Uname: Uname,
Uage: Uage
}
And then push every object to the array
persons.push(person1, person2, person3);
//return the array
return persons
to sort the array, by name i imagine, just using sort would not suffice, as you want to sort on the 'name' property, so you have to pass a function to sort that orders the items by their name.
You can check it here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort
persons.sort(function (a, b) {
var nameA = a.name.toUpperCase(); // ignore upper and lowercase
var nameB = b.name.toUpperCase(); // ignore upper and lowercase
if (nameA < nameB) {
return -1;
}
if (nameA > nameB) {
return 1;
}
// names must be equal
return 0;
});
The last step, if i understand correctly, is placing all the items, in the ordered array, inside the output div, so let's keep the write() function.
You have to iterate through each element, and then you need to insert the HTML that you have created inside the 'output' div.
There are a few ways to to this, you can create elements in the js, or you can append the HTML directly to the div.
Let's say you want to place them in an unordered list.
//pass the result from the addToArray() funtion to the write() function
function write(persons){
let output = document.getElementById('output')
//clean output div otherwise everytime it will append new content
output.innerHTML = ""
let ul = document.createElement('ul')
//Iterate
for( let i of persons){
let li = document.createElement('li')
li.innerHTML = `${i.Uname} - ${i.Uage}`
ul.appendChild(li)
}
output.appendChild(ul)
}
and finally the onclick function, you need to make sure that everything is as you want before adding it to the output div, so check if the verify function has returned true(or whatever you prefer), and the create the array and write it to the div
function buttonclick() {
if (validate() === true){
write(addToArray())
}
}
here is it in full
<body>
<div>
<input type="text" placeholder="Name" id="NameInput">
</div>
<div>
<input type="number" placeholder="Age" id="AgeInput">
</div>
<div>
<input type="password" placeholder="Password" id="PasswordInput">
</div>
<button onclick="buttonclick()" type ="button">Submit</button>
<div id="output"></div>
<script>
function buttonclick() {
if (validate() === true){
write(addToArray())
}
}
function validate() {
var name = document.getElementById("NameInput");
var age = document.getElementById("AgeInput");
var password = document.getElementById("PasswordInput");
if (name.value == "" || password.value == "" || age.value == "") {
alert("Field is required");
return
}
if (password.value == "IHM") {
return true
}
alert("Not a valid password")
}
function addToArray() {
let persons = [];
let person1 = {
Uname: "Marcus",
Uage: 34
}
let person2 = {
Uname: "Cihan",
Uage: 35
}
// Gets name from the input
let Uname = document.getElementById("NameInput").value;
// Gets age from the input
let Uage = parseInt(document.getElementById("AgeInput").value);
//Create the object
let person3 = {
Uname: Uname,
Uage: Uage
}
// Adds antoher name to the array?
persons.push(person1, person2, person3);
// Sorts the array
persons.sort(function (a, b) {
var nameA = a.Uname.toUpperCase(); // ignore upper and lowercase
var nameB = b.Uname.toUpperCase(); // ignore upper and lowercase
if (nameA < nameB) {
return -1;
}
if (nameA > nameB) {
return 1;
}
// names must be equal
return 0;
});
return persons
}
function write(persons) {
let output = document.getElementById('output')
//clean output div otherwise everytime it will append new content
output.innerHTML = ""
let ul = document.createElement('ul')
//Iterate
for (let i of persons) {
let li = document.createElement('li')
li.innerHTML = `${i.Uname} - ${i.Uage}`
//Append items to ul
ul.appendChild(li)
}
//Append ul to the 'output' div
output.appendChild(ul)
}
</script>
</body>
There are many ways you can accomplish this, i have tried to stay as close as possible to your example so you can understand better, i hope it'll help you, have a good day.

SyntaxError: invalid increment/decrement operand

am trying to create a calculator in react but when i do the calulaculations it gives me that syntax Error. For example when calaculate different numbers day (30 + 23423 - 3428 *5235) it gives me that error. also i cant get my Reset and backspace and decimal to work. Can someone please help
here is my code
import React, { Component } from 'react'
import Button from "./components/Button";
import Input from "./components/Input";
import {buttonData} from "./components/Data"
class App extends Component {
constructor(props) {
super(props)
this.state = {
input: [],
result: 0,
operator: "+"
}
}
calculate = (num1, operator, num2) => {
let result;
// console.log("math");
if(!isNaN(num2)) {
result = eval(num1 + operator + num2)
this.setState({result})
}
}
handleClick = (button) => {
let input = [...this.state.input]
let result = this.state.result;
let operator = this.state.operator;
const num = parseFloat(input.join(''))
switch(true) {
case /[+-\/\*]/.test(button):
// console.log(operator);
this.calculate(result, operator, num)
operator = button;
input = operator;
break
case/\d/.test(button):
// console.log(button);
if(/[+-\/\*]/.test(button)){
input = []
}
input.push(button)
break
}
if(button === "="){
this.calculate(result, operator, num)
}
else if(button === "C"){
this.reset()
}
else if(button === "CE"){
this.backspace()
}
else if(button === "."){
this.handleDecimal()
}
this.setState({input, operator})
};
reset = () => {
this.setState({
input: "0",
reset: []
})
};
backspace = () => {
this.setState({
input: this.state.input.slice(0, -1)
})
};
handleDecimal = () => {
const { input } = this.state;
// ! add the point only if no point is already included
if(!/\./.test(input)) {
this.setState({input: `${input}.`})
}
}
render() {
return (
<div className="app">
<div className="calc-wrapper">
<h2>Tony's Calculator</h2>
<div id="display" >
<Input input={this.state.input}
result={this.state.result}
/>
</div>
{buttonData.map((item) => {
let name = item.button;
let id = item.id;
return <Button
key={id}
name={name}
id={id}
value={name}
handleClick={this.handleClick}
/>
} )
}
</div>
</div>
)
}
}
export default App;
<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>
enter link description here
The error happens when you try to use eval() or alert() with a mathematical expression that contains -- or ++
Ex:
alert(-50--30.25*32)
will throw: Uncaught SyntaxError: invalid increment/decrement operand
So, you need to surround your value by parenthesis or replace your signs with a single sign.
Ex:
alert(-50-(-30.25)*32)
Or:
str.replace(/[-]{2}|[+]{2}/g, '+')
I would use parenthesis if I was constructing a string and regex if I was reading a string.

How to keep a specific type of element from being stored in an array?

I have code that has a user input numbers that are stored in an array. I would like to know how to prevent a user from entering a negative number in the array and showing in red (preferably red text below input) that they can't enter a negative number
I was able to get the array to identify what type of integer is put into an array with an if... else statement, but I can't seem to get the array to pop off the negative number.
<input type="number" id="user_input">
<button type="button" id="myBtn">Click to store</button>
<script>
const myArray = [];
const addData = () => {
let inputData = document.getElementById('user_input');
myArray.push(parseInt(inputData.value));
console.log(myArray);
if (inputData.value <= 0) {
console.log("negative int")
} else if (inputData.value == 0) {
console.log('nothing entered')
} else {
console.log("positive int")
}
inputData.value = "";
}
document.getElementById('myBtn').addEventListener('click', addData);
</script>
You could take the numerical value and check if the string is given or if this value is an integer value, or negative. Then you need function for showing a wanted message with a certain color.
This solution features an exit early, exit often paradigm, where the function takes a condition and exits if the condition is met, to prevent to go to the natural end of the function by using a chained else ... if ... else structure.
In short, this approach works without else parts, which is here possible.
const
myArray = [],
addData = () => {
const setMessage = (string, color = '#000000') => {
message.style.color = color;
message.innerHTML = string;
}
let inputData = document.getElementById('user_input'),
message = document.getElementById('message'),
value = +inputData.value;
if (inputData.value === '') {
setMessage('nothing entered', '#bb0000');
return;
}
inputData.value = "";
if (value !== Math.floor(value)) {
setMessage('no int', '#bb0000');
return;
}
if (value <= 0) {
setMessage('negative int', '#bb0000');
return;
}
myArray.push(value);
console.log(myArray);
setMessage('positive int');
}
document.getElementById('myBtn').addEventListener('click', addData);
<input type="number" id="user_input">
<button type="button" id="myBtn">Click to store</button>
<p id="message"></p>
The issue here is that you're pushing the value in the array before checking for its type. You just have to do it like this to prevent negative numbers to get inside the array :
const myArray = [];
const addData = () => {
let inputData = document.getElementById('user_input');
console.log(myArray);
if (inputData.value <= 0) {
console.log("negative int")
} else if (inputData.value == 0) {
console.log('nothing entered')
} else {
console.log("positive int")
myArray.push(parseInt(inputData.value));
}
inputData.value = "";
}
document.getElementById('myBtn').addEventListener('click', addData);
Or, very simply <input type="number" id="user_input" min="0">

how to replace input numbers with commas after key presses

I want to replace a number over 100 with commas. Like 1000 to 1,000 and 1000000 to 1,000,000 etc. in HTML. I have found the code on here to do so but it only works with predetermined numbers being passed. I don't want it to work for a predetermined number but for any number typed into the box.
<label for="turnover">Estimated Monthly Card Turnover:</label><br />
<span>£ </span><input type="text" id="turnover" maxlength="11"
name="turnover" size="10" required>*
<br /><br />
<script type="text/javascript">
$('#turnover').keydown(function(){
var str = $(this).val();
str = str.replace(/\D+/g, '');
$(this).val(str.replace(/\B(?=(\d{3})+(?!\d))/g, ","));});
</script>
I created a solution using pure javascript.
function onChange(el) {
var newValue = el.value.replace(/,/g, '');
var count = 0;
const last = newValue.substring(newValue.length - 1, newValue.length); // last input value
// check if last input value is real a number
if (!isNumber(last)) {
el.value = el.value.substring(0, el.value.length - 1);
return;
}
newValue = newValue.split('')
.reverse().map((it) => {
var n = it;
if (count > 0 && count % 3 == 0) n = n + ',';
count++;
return n;
})
.reverse().join('')
el.value = newValue
// document.getElementById('value').innerHTML = newValue
}
function isNumber(input) {
return input.match(/\D/g) == undefined;
}
<label>Number</label>
<input id="numbers" onkeyup="onChange(this)">
There are a couple of issues with your code:
It runs once when the page loads, not after that. I added a button to fix that.
The id used in your code does not match the actual id of the input field.
Input fields must be read and written using .val(). .text() works only for divs, spans etc.
Note that the conversion now works one time, after that it fails to properly parse the new text which now contains the comma(s).
function numberWithCommas(x) {
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
function ShowComma() {
console.clear();
var val = parseInt($("#comma").val());
console.log(val);
val = numberWithCommas(val);
console.log(val);
$("#comma").val(val);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<label for="turnover">Estimated Monthly Card Turnover:</label><br />
<span>£ </span><input type="value" id="comma" maxlength="30" name="turnover" size="10" required>*
<button onclick="ShowComma()">Show Comma</button>
To finalise this I have putgetElementById functions in so that this will work with a wordpress contact form 7. This must be with a text field though as it will not work with the number field as it will now accept commas:
<script>
document.getElementById("averagetrans").onkeyup = function() {onChange(this)};
document.getElementById("Turnover").onkeyup = function() {onChange(this)};
</script>
<script type="text/javascript">
function onChange(el) {
var newValue = el.value.replace(/,/g, '');
var count = 0;
const last = newValue.substring(newValue.length - 1, newValue.length); // last input value
// check if last input value is real a number
if (!isNumber(last)) {
el.value = el.value.substring(0, el.value.length - 1);
return;
}
newValue = newValue.split('')
.reverse().map((it) => {
var n = it;
if (count > 0 && count % 3 == 0) n = n + ','; // put commas into numbers 1000 and over
count++;
return n;
})
.reverse().join('')
el.value = newValue
// document.getElementById('value').innerHTML = newValue
}
function isNumber(input) {
return input.match(/\D/g) == undefined;
}
</script>

jquery does not support mask,any altenative? [duplicate]

I want to mask the text in an input box without changing the actual value. I can not use any plugins.
I am currently doing this - but as you can see the issue is that the actual value is changed on submit. How can I just change the display value?
$("input[name='number']").focusout(function(){
var number = this.value.replace(/(\d{2})(\d{3})(\d{2})/,"$1-$2-$3");
this.value = number;
}
You need two inputs
Two inputs should get the job done. One input will contain the masked text and the other will be a hidden input that contains the real data.
<input type="text" name="masknumber">
<input type="text" name="number" style="display:none;">
The way I approached the masking is to build a function for both masking and unmasking the content so everything stays uniform.
$("input[name='masknumber']").on("keyup change", function(){
$("input[name='number']").val(destroyMask(this.value));
this.value = createMask($("input[name='number']").val());
})
function createMask(string){
return string.replace(/(\d{2})(\d{3})(\d{2})/,"$1-$2-$3");
}
function destroyMask(string){
return string.replace(/\D/g,'').substring(0,8);
}
Working JSFiddle
or also
<input type="text" onkeypress="handleMask(event, 'data: 99/99/9999 99:99 999 ok')" placeholder="data: ok" size=40>
with
function handleMask(event, mask) {
with (event) {
stopPropagation()
preventDefault()
if (!charCode) return
var c = String.fromCharCode(charCode)
if (c.match(/\D/)) return
with (target) {
var val = value.substring(0, selectionStart) + c + value.substr(selectionEnd)
var pos = selectionStart + 1
}
}
var nan = count(val, /\D/, pos) // nan va calcolato prima di eliminare i separatori
val = val.replace(/\D/g,'')
var mask = mask.match(/^(\D*)(.+9)(\D*)$/)
if (!mask) return // meglio exception?
if (val.length > count(mask[2], /9/)) return
for (var txt='', im=0, iv=0; im<mask[2].length && iv<val.length; im+=1) {
var c = mask[2].charAt(im)
txt += c.match(/\D/) ? c : val.charAt(iv++)
}
with (event.target) {
value = mask[1] + txt + mask[3]
selectionStart = selectionEnd = pos + (pos==1 ? mask[1].length : count(value, /\D/, pos) - nan)
}
function count(str, c, e) {
e = e || str.length
for (var n=0, i=0; i<e; i+=1) if (str.charAt(i).match(c)) n+=1
return n
}
}
A more robost version of accepted answer without having two input's which may pollute transmitted form fields and also being aware of key-repetitions and other quirks when pressing a key too long:
<input type="text" name="masknumber" data-normalized="">
and
$("input[name='masknumber']").on("input", function(){ // input event!
let n = destroyMask(this.value);
this.setAttribute("data-normalized", n); // saved as attribute instead
this.value = createMask(n);
})
function createMask(string){
return string.replace(/(\d{2})(\d{3})(\d{2})/,"$1-$2-$3");
}
function destroyMask(string){
return string.replace(/\D/g,'').substring(0, 7); // 7 instead of 8!
}
JSFiddle

Categories