Not able to remove first 3 digit of phone number in react - javascript

In the phone number Text-field if you type any number like 919002007805 in the console its print normally but if you want to remove number one by one then up to 9 digits its working fine(919*********) then if you want to remove first 3 digits from input(919) you observe in console its not reflecting ,but in Input its removed ,so when I want to update the phone number the flag give some unwanted symbol. so how to resolved that one so that in console its working fine at the time of inserting as well deleting time.
import React from "react";
import PhoneInput from "react-phone-number-input";
export default function App() {
const [fields, setFields] = React.useState([{ value: null }]);
function handleChange(i, event) {
if (event) {
let values = [...fields];
values[i].value = event;
setFields((v) => values);
console.log(`values`, values[0]);
}
}
return (
<div className="App">
{fields.map((field, idx) => (
<PhoneInput
key={idx}
id="phoneNumbers1"
type="text"
placeholder="Enter phone number "
value={field.value || ""}
defaultCountry="IN"
international
name="phoneNumbers"
autoComplete="off"
onChange={(e) => handleChange(idx, e)}
/>
))}
</div>
);
}

Related

React hook form only allow numbers greater than 0

I'm using React Hook Form to make an input for height, weight and length. The value cannot be 0 - it has to be at least 1 or more. I tried different ways such as: pattern with regex, validate and more. But I am unable to figure out how to prevent the input field from letting the user type in '0' ( only as the first character ). I also tried type="number" and min="1" however it's not changing anything. Any ideas would be greatly appreciated.
<Input
{...form.register(`pallets.${index}.weight`, {
required: t('errors.emptyInput'),
pattern: {
value: /^[^1-9]/,
message: 'hello',
},
validate: (value) => {
return [/^[^1-9]/].every((pattern) => pattern.test(value))
},
})}
type='number'
/>
It appears to me that pattern does not change anything. Only type= 'number' actually affects the way the input field works.
<input
type="number"
{...register("test", {
min: 1
})}
/>
You can check the detailed usage from the documentation.
You can take advantage of react useState hook to implement this functionality.
export default function App() {
const [x, setX] = useState(null);
const handleChange = e => {
const value = e.target.value;
if (!value || /^[1-9]\d*/.test(value))
setX(e.target.value)
}
return (
<div className="App">
<input type="number" value={x} onChange={handleChange} />
</div>
);
}

two way binding string separated by commas

This is my object:
const [opportunity, setOpportunity] = useState({
name: '',
description: '',
experience: '',
});
I want to store it in the opportunity experience property like a string separated by commas. Like this for example: 'experience_1,experience_2,experience_3'.
But when i type in the input field i want to be able to have space between the words. Like this for example: experience_1 experience_2 experience_3
this is my code for the input field:
<InputField
type='text'
value={opportunity.experience.split(',').join(' ')} // i think i need changes here
onChange={(e) => setOpportunity({ ...opportunity, experience: e.currentTarget.value.split(" ").filter(x => x !== '').toString() })} // i think this works
label={"Experiences"}
/>
Any Help Guys?
Replace .filter(x => x !== '') with .replace(/\s+/g, " ") and place it before you call the .split() method. This will replace multiple spaces with a single space, and prevent the user from entering in more than one space at a time, while letting them change the contents of your InputField component. Remember, .filter() works on a cloned copy of the string while .replace() works on the string itself, which in this case is the event current target value.
Now it should work as intended.
Like so:
<InputField
type="text"
value={opportunity.experience
.split(",")
.map((x) => x.trim()) // Added .trim() to keep consistent spacing...
.join(" ")} // ...before joining
onChange={(e) => {
setOpportunity({
...opportunity,
experience: e.currentTarget.value
.replace(/\s+/g, " ") // If you try to use .filter() here, it won't work
.split(" ")
.toString(),
});
}}
label={"Experiences"}
/>
I've also chained a trim operation on each value from the state property with .map() to keep the spacing consistent during presentation, in the event that the state property was initialized with lots of spaces in between each experience value.
Here's an updated example of my previous answer using useEffect to update the state based on the input value. This keeps the input value and the state value separate.
working code sandbox
import React from "react";
export default function App() {
return (
<div className="App">
<MyComponent />
</div>
);
}
const MyComponent = () => {
const [opportunity, setOpportunity] = React.useState({
name: "",
description: "",
experience: []
});
const [experienceValue, setExperienceValue] = React.useState("");
React.useEffect(() => {
const experience = experienceValue.split(" ").filter((x) => x !== "");
setOpportunity({ ...opportunity, experience });
}, [experienceValue, opportunity]);
const handleInput = (e) => {
setExperienceValue(e.currentTarget.value);
};
return (
<>
<input type="text" value={experienceValue} onChange={handleInput} />
<br />
{JSON.stringify(opportunity.experience)}
</>
);
};

how to reset the phone number text field when you change the country code

in react phone input one property is there international that helps but in react phone input 2 this property is not working. In the react phone input 2 if you want to change the country code after filling the all digit then country code is changed but remaining digit are not removed automatically, in react phone number its was happening automatically. as for example if you given 91-9787890000 then if you change the code 91(India) to 852(Hong Kong) then its should look like 852 in phone text field but now its give 85297878900 how to reset those digit
now i get
import React, { useState } from "react";
import PhoneInput from "react-phone-input-2";
import "react-phone-input-2/lib/material.css";
export default function DropDown() {
const [fields1, setFields1] = useState([{ value: null }]);
function handleChange(i, event) {
if (event) {
let values = [...fields1];
values[i].value = event;
setFields1((v) => values);
}
}
return (
<div className="App">
{fields1.map((field, idx) => (
<PhoneInput
country={"in"}
key={idx}
localization={'in'}
enableSearch
disableSearchIcon={false}
specialLabel=""
autoComplete="off"
value={field.value || ""}
onChange={(e) => {handleChange(idx, e);}}
/>
))}
</div>
);
}

React: Bind number input to state (handle intermediate values)

I have a number stored in my React state, and I want to edit it using an <input type="number" />. Here's my attempt:
function MyNumberInput() {
const [number, setNumber] = useState(42);
return (
<input
type="number"
value={number}
onChange={event => {
setNumber(parseFloat(event.target.value)); // Convert string value to a number!
}}
/>
);
}
Try it on JSFiddle.
The problem is that this code fails during intermediate, non-number states. If I want to enter -12, I begin by typing the negative sign. When I do, the onChange handler fires, parseFloat("-") returns NaN, and the input remains empty. As a user, it feels like my input was completely ignored.
just use unary plus operator to convert a string into a number like this:
function MyNumberInput() {
const [number, setNumber] = useState(42);
return (
<input
type="number"
value={number}
onChange={event => {
setNumber(+(event.target.value)); // Convert string value to a number!
}}
/>
);
}
Use RegEx
The problem is the input get NaN is because the input type="number" and - or . is not a number.
I suggest to use RegEx:
function MyNumberInput() {
const [number, setNumber] = useState(42);
const updateNumber = ({ target }) => {
const reg = new RegExp('^[0-9+-/]+$|^$');
if (reg.test(target.value)) setNumber(target.value);
};
return (
<input type="text" value={number} onChange={updateNumber} />
);
}
You may want to remove the below props to enable non-number content input.
type="number"
And remove the parseFloat to store the string like - or .0
import React, { useState } from "react";
import "./styles.css";
export default function App() {
const [number, setNumber] = useState('');
return (
<div className="App">
<input
value={number}
onChange={event => {
// console.log(event.currentTarget.value);
setNumber(event.target.value);
}}
/>
</div>
);
}
Try it online:

Mobile number masking in React

Hi need to masked mobile number when user enter the mobile number in input box it should be 021 121 4544 in this format.
means there should be 021{auto space}121{auto space}4544
how can i build in react this functionality?
class NumberCheck extends Component {
state = {
disabled: true,
errorBlock: 'none',
mobileNumber: '',
error: ''
};
handleOnChange = (event) => {
let disabled = event.target.value ? disabled = false : disabled = true;
this.setState({
disabled: disabled,
mobileNumber: event.target.value
})
}
submit = (e) => {
e.preventDefault();
if (this.state.mobileNumber.match(/^02[0-9]{6,11}$/)) {
this.setState({
errorBlock: 'none'
})
const payload = {
msisdn: this.state.mobileNumber
}
this.props.checkNumber(payload);
} else {
this.setState({
error: ' Please enter valid mobile no',
errorBlock: 'block'
})
}
}
render() {
const { isLoading, isError } = this.props;
if (isLoading) {
return <Spinner />
}
if (isError) {
return <ChangePlanError />
}
return (
<form className="spring spring--sm">
<p className="heading heading--3 heading--center no-gutter--top">{"Already with Vodafone?"}</p>
<p className="heading--center">{"Sign in using a TXT code to check if you are eligible to upgrade or change your plan"}</p>
<div className="alert alert--light alert--warning alert--arrow validation__warning" style={{ display: this.state.errorBlock }}>
<div className="caption">
< div className="caption__media caption__media--top alert__media" >
<svg className="icon icon--extra-small icon--inherited" data-vft="icon-modifiers">
<use xmlnsXlink="http://www.w3.org/1999/xlink" xlinkHref="#icon-block" />
</svg>
</div>
<div className="caption__text caption__text--top alert__text">
{this.state.error}
</div>
</div>
</div>
<input
type="text"
onChange={this.handleOnChange}
className="form__input form__input--dark"
name="mobileno"
placeholder="021 1234567"
mask="000 000 0000" />
<div id="submit" className="form__row form__row--medium gutter--bottom">
<input
type="submit"
className={`button button--primary button--primary--grey button--full-width ${this.state.disabled ? 'button--disabled' : ''}`}
value=" Continue"
onClick={this.submit} />
</div>
</form >
);
}
}
You can create a new string with previous string and replace it in the input.
const number = '0211214544';
const num = `${number.substring(0, 3)} ${number.substring(3, 6)} ${number.substring(6, number.length)}`;
console.log(num);
Created a working example in React.
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
class App extends Component {
constructor(props) {
super(props);
this.state = {
name: ''
};
}
change = (event) => {
let val = event.target.value;
val = val.replace(/ /gm, '');
console.log(val);
let num = `${val.substring(0, 3)} ${val.substring(3, 6)} ${val.substring(6, val.length)}`;
num = num.trim();
this.setState({
name: num
});
};
render() {
return (
<div className="App">
<input
ref="inputName"
value={this.state.name}
onChange={this.change}
/>
</div>
);
}
}
export default App;
The below function will mask the phone number , the basic operation to perform such functions is slicing/sub string and string concatenation
maskingFunction= (phoneNumber)=>{
let subNum = phoneNumber.toString().substring(0,3)
subNum = subNum + "XXXXXXXXXXXX"
return subNum
}
I created a package that exposes an input component that displays a masked value according to the mask it receives.
The mask will change keeping the cursor at the correct position (even if you change part of the value in the middle of the input, paste some characters, or delete a part of it, and even if the mask changes).
You can see a Demo with examples at:
https://lucasbasquerotto.github.io/react-masked-input
(The first example has an input with the mask asked in this SO question: 999 999 9999).
To install the package: npm i react-hook-mask
Use it:
import { MaskedInput, createDefaultMaskGenerator } from 'react-hook-mask';
const maskGenerator = createDefaultMaskGenerator('999 999 9999');
const MobileNumberMaskedInput = () => {
const [value, setValue] = React.useState('');
return (
<MaskedInput
maskGenerator={maskGenerator}
value={value}
onChange={setValue}
/>
);
};
This component wraps a default input, but the package also expose hooks to make you able to use it with any kind of component.
The function createDefaultMaskGenerator that always return a static string mask. You can also use dynamic masks that change according to the value, and even transforming the value (for example, making the characters uppercase).
The hook useMask is a generic hook that can be used with any component (even native components) as long as the component has a way to retrieve and to modify the cursor position.
The hook useRefMask wraps useMask and provides an easy way to forward a ref to the component, as well as using the ref element in the functions that manage the cursor position (Example).
The (more specific) hook useWebMask wraps useRefMask and can be used with any custom react-dom component that wraps an input and whose ref is an HTMLInputElement, without having to define a getter and a setter for the cursor position, and with an onChange function that sets the value received from the event object (Example).

Categories