I am trying to validate my input field in a redux form based on a formula.
There are 4 terms in my formula. I would like to restrict the user to type/enter only these 4 terms and make a formula.
TERM1, TERM2, TERM3, TERM4
User can write something in the formula including these 4 terms
TERM1*5,
TERM2/0.2 etc
You can do something like the following.
handleValidate = (text) => {
const re = /(TERM\[1-4])/
return re.test(text)
}
The above function will return true if the text sent to it matches the pattern you specified
Related
I'm trying to format the value of the input of this MUI component to show a maximum of 3 numbers following with a maximum of 2 decimals separated by a dot, e.g. 233.99, I want to store this value in a react state called value (const [value, setValue] = useState(0)).
I'm having trouble since I see a lot of approachs to achieve this, but I find it complicated to also keep track if the user already entered the first 3 numbers and not let him enter more while also keeping tack of the decimal values too, since as I said, there should be a maximum of 2 decimals.
I tried regex functions, toFixed js function, and more, but I can't make this work smoothly.
If I understood this correctly, you can achieve this with:
let inp = document.getElementById("input");
inp.addEventListener("keypress", ev => {
ev.preventDefault();
if (!/\d|\./.test(ev.key)) return;
inp.value = /^\d{0,3}(\.\d{0,2})?$/.test(inp.value + ev.key) ? inp.value + ev.key : inp.value;
// update state when value has changed
// if (inp.value != value) setValue(inp.value);
})
<input type="text" id="input">
Alternatively, you can use <input type="text" pattern="^\d{0,3}(\.\d{0,2})?$"> and input.checkValidity() to notify the user on submit.
I need to compare two number fields. AreaTo must be bigger than AreaFrom. It works this way:
area_to: Yup.number().min(
Yup.ref("area_from"),
`AreaTo should be bigger than AreaFrom`
),
The problem is I also use custom number formatting in this fields, that returns string, so the field type should be not number but string. But min() is not usable with the strings. I have a function parseNumber(str) that parse number from that string. So I need something like:
area_to: parseNumber(Yup.string()).min(
Yup.ref("area_from"),
`AreaTo should be bigger than AreaFrom`
),
But obviously it don’t work that way. Please help me to implement it properly.
I think you'd want to use test(), and pass in testContext, to reference the other field's value via testContext.parent:
const validationSchema = Yup.object().shape({
area_from: Yup.number().isRequired('Required'),
area_to: Yup.mixed().test('isLarger', 'area_to must be larger than area_from', (value, testContext) => {
if (testContext.parent.area_from > value) return false
return true
})
})
You can read the documentation on this feature here.
At the end this solution worked as expected:
area_to: Yup.string().test(
"area_compare",
`area_to must be bigger then area_from`,
function (area_to: string | undefined): boolean {
return area_to
? parseNumber(area_to) > parseNumber(this.parent.area_from)
: true;
}
),
Need to store the text field data and store and then sumI am creating multiples sub category Just like to-do on button click it creates a field where user can put his/her input.
The Input is product Price Now I wanna store this all data in similar list As it's subcategories for some product and wanna display their total sum along side all values.
Consider using fold function
arrayName.fold(0, (result, eachItem) => result+eachItem)
it will add current item to result(which is 0 initially) and return it
eg: given your data of List< String > items
here is your a function that will parse the items to int and return the sum
int getTotal()=> items.fold(0,(total, item) {
int? price = int.tryParse(item);
if(price!=null) return total+price;
else return total;
});
Although according to your existing code you have on bug, which is the price is not being updated form the text field
Therefore you must add onChanged to your text field
onChanged:(value) => items[index]=value,
Then you can display it like this
Text("Total price: ${getTotal()}"),
i have a form where i show previous field value in input tag. But, as i put type=number. then my .toLocaleString("en-IN") would'nt work.Also, i want to show comma in INR currency styles. i.e 12,25,789
Following is my code:
<Col lg="2">
<Form.Control
size="sm"
// type="number"
value={temp.originalAmount.toLocaleString("en-IN")}
onChange={this.handlechangevalue.bind(
this,
item,
keys,
index
)}
/>
</Col>
P.S been using react-bootstrap
It's not clear for me where you want to use the comma separated values but you can change between styles with the help of regexp and replace. Something like this:
// 1234567 => 12,34,567
const encode = string => string.match(/(\d{2})(\d{2})(\d{3})/).slice(1).join(',');
// 12,34,567 => 1234567
const decode = string => string.replace(/,/g, '');
(If your input is looks like two digits / comma / two digits / comma / three digits but this can be changed easly ofc.)
Then you can convert the result to number before save into the state and the back to the comma version to display the user.
Also, I would use a text type on the input field an a regexp based validator.
I'm using similar in case of dates.
I've come across this before. What you can do is restrict the type of input in your handlechangevalue function to numbers only. If any other character appears then discard/ignore it.
Something like this:
handlechangevalue(e) {
if( parseInt(e.target.value) !== NaN ) {
this.setState({val: e.target.value});
}
}
I have a table that displays several entries, each has an <input>. The user can dynamically add additional inputs by clicking an "add entry" button. I need to iterate over them before saving and validate each one. I simplified my example to check that the value of each input is greater than 100 (ultimately I will use a pattern-match to validate MAC and IP addresses).
I can probably handle it if I could select all <input>s, but I would really like to select a specific <input> using an index I already have in my scope. I read that angular.element is a way, but I need to select something that was dynamically created, and thus not named something easy like id="myInput". Unless I use an id of "input" and append a unique number with Angular's $index in the id attribute?
Here is my Fiddle that shows what I'm doing. Line 44 is an if() that should check if any <input> is greater than 100. The "Save Row" button validates that the input is greater than 100, but if you edit a line, I need the "Save" button to validate any that the user has edited (by clicking Edit next to it).
tl;dr:
How can I use Angular to select an <input> that has been created dynamically?
I have updated your fiddle in a clean way so that you can maintain the validation in a generic method for both add & edit.
function validateBinding(binding) {
// Have your pattern-match validation here to validate MAC and IP addresses
return binding.ip > 100;
}
Updated fiddle:
https://jsfiddle.net/balasuar/by0tg92m/27/
Also, I have fixed the current issue with editing you have to allow multiple editing without save the first row when clicking the next edit on next row.
The validation of 'save everything' is now cleaner in angular way as below.
$scope.changeEdit = function(binding) {
binding.onEdit = true;
//$scope.editNum = newNum;
$scope.showSave = true;
};
$scope.saveEverything = function() {
var error = false;
angular.forEach($scope.macbindings, function(binding) {
if(binding.onEdit) {
if (validateBinding(binding)) {
binding.onEdit = false;
} else {
error = true;
}
}
});
if (error) {
alert("One/some of the value you are editing need to be greater than 100");
} else {
$scope.showSave = false;
}
}
You can check the updated fiddle for the same,
https://jsfiddle.net/balasuar/by0tg92m/27/
Note: As you are using angular, you can validate the model as above and no need to retrieve and loop the input elements for the validation. Also for your case, validating the model is sufficient.
If you need some advanced validation, you should create a custom
directive. Since, playing around with the elements inside the
controller is not recommended in AngularJS.
You can use a custom class for those inputs you want to validate. Then you can select all those inputs with that class and validate them. See this Fiddle https://jsfiddle.net/lealceldeiro/L38f686s/5/
$scope.saveEverything = function() {
var inputs = document.getElementsByClassName('inputCtrl'); //inputCtrl is the class you use to select those input s you want to validate
$scope.totalInputs = inputs.length;
$scope.invalidCount = 0;
for (var i = 0; i < inputs.length; i++){
if(inputs[i].value.length < 100){
$scope.invalidCount++;
}
}
//do your stuff here
}
On line 46 a get all the inputs with class "classCtrl" and then I go through the input s array in order to check their length.
There you can check if any of them is actually invalid (by length or any other restriction)