Javascript loop array for form validation - javascript

I have a table form with some rows, that are controlled by user. Meaning they can add as more as they want. Let's pretend user requested 5 rows and i need to check if they all have values.
function validateForm() {
var lastRowInserted = $("#packageAdd tr:last input").attr("name"); // gives me "packageItemName5"
var lastCharRow = lastRowInserted.substr(lastRowInserted.length - 1); // gives me 5
var i;
for (i = 1; i <= lastCharRow; i++) {
var nameValidate[] = document.forms["packageForm"]["packageItemName"].value;
if(nameValidate[i].length<1){
alert('Please fill: '+nameValidate[i]);
return false;
}
}
}
How can i receive packageItemName1 to 5 values in a loop so then I can use to validate them. Want the loop to process this code
var nameValidate[] = document.forms["packageForm"]["packageItemName1"].value;
var nameValidate[] = document.forms["packageForm"]["packageItemName2"].value;
var nameValidate[] = document.forms["packageForm"]["packageItemName3"].value;
var nameValidate[] = document.forms["packageForm"]["packageItemName4"].value;
var nameValidate[] = document.forms["packageForm"]["packageItemName5"].value;

Like this
const validatePackageItems = () => {
const nameValidate = $("form[name=packageForm] input[name^=packageItemName]"); // all fields with name starting with packageItemName
const vals = nameValidate.map(function() { return this.value }).get(); // all values
const filled = vals.filter(val => val.trim() !== ""); // all values not empty
console.log("Filled", filled, "= ", filled.length, "filled of", vals.length)
return filled.length === vals.length
};
$("[name=packageForm]").on("submit",(e) => {
if (!validatePackageItems()) {
alert("not valid");
e.preventDefault();
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form name="packageForm">
<input type="text" name="packageItemName1" value="one" /><br/>
<input type="text" name="packageItemName2" value="two" /><br/>
<input type="text" name="packageItemName3" value="" /><br/>
<input type="text" name="packageItemName4" value="four" /><br/>
<input type="submit">
</form>

You can use string interpolation to get the key dynamically:
for (let i = 1; i < 6; i++) {
const currentValue = document.forms.packageForm[`packageItemName${i}`]
console.log('current value:', currentValue)
}

Related

Check two arrays and its respective index as pair and find if a similar pair exist

I have a simple html code as below
<input type="text" id="key" name="key">
<input type="text" id="value" name="value">
<button id="check">Check</button>
and I have related jQuery code as well
var keyArray = [];
var valueArray = [];
$("#check").click(function() {
var keyVal = $("#key").val();
var valueVal = $("#value").val();
keyArray.push(keyVal);
valueArray.push(valueVal);
console.log(keyArray);
console.log(valueArray);
for ($i = 0; $i < keyVal.length; $i++) {
//Need to add some code here to check
}
});
What I want is, whenever if someone click the Check button, it has to check if there is a similar item added before into the respective index of keyArray and valueArray. Eg: First I add 1 into the id key and 2 into the id value. If I add 1 and 2 into key and value fields a second time, it should prompt me such a pair already added.
How can I achieve this with JavaScript or jQuery?
var keyArray = [];
var valueArray = [];
$("#check").click(function() {
var keyVal = $("#key").val();
var valueVal = $("#value").val();
var exist=false;
if(keyArray.length>0){
for (i = 0; i < keyArray.length; i++) {
if(keyArray[i]==keyVal && valueArray[i]==valueVal)
{
console.log("pair exist");
exist=true;
break;
}
}
}
if(!exist)
{
keyArray.push(keyVal);
valueArray.push(valueVal);
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="text" id="key" name="key">
<input type="text" id="value" name="value">
<button id="check">Check</button>
If you want, you can introduce a third array and store data in it, and compare it with your value.
var keyArray = [];
var valueArray = [];
var newArray = [];
$("#check").click(function() {
var keyVal = $("#key").val();
var valueVal = $("#value").val();
var isExist = false;
for (i = 0; i < newArray.length; i++) {
if(newArray[i].key == keyVal && newArray[i].value == valueVal ){
isExist = true;
break;
}
else{
isExist = false;
}
}
if (isExist){
alert("such a pair already added");
}
else{
keyArray.push(keyVal);
valueArray.push(valueVal);
newArray.push({ key : keyVal, value : valueVal });
}
console.log(keyVal);
console.log(valueVal);
console.log(newArray);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="text" id="key" name="key">
<input type="text" id="value" name="value">
<button id="check">Check</button>

Repeating a div based on user input (JavaScript solution preferred)

Looking for the simplest implementation of the following problem:
I have a user input number field like:
<input type="number" id="numInput" name="numInput" value="1" onchange="myFunc()">
<div id="demo">*** TEST ***</div>
I want to replicate the #demo div based on the #numInput value entered by the user, e.g. if the user enters '5', there would be five #demo divs displayed on the page. At the moment, I'm using the following function:
function myFunc() {
var newArray = [];
var numInput = document.getElementById('numInput').value;
var x = document.getElementById('demo').innerHTML;
for(var i=0; i<numInput; i++) {
newArray.push(x);
}
document.getElementById('demo').innerHTML = newArray;
}
but this is adding to the existing array rather than outputting the exact number of divs based on user input. Please advise. Thanks.
There should not be multiple same id values.
function myFunc() {
let numInput = document.getElementById("numInput");
while (numInput.nextSibling) {
numInput.nextSibling.remove();
}
let numInputval = document.getElementById('numInput').value;
for(var i=numInputval; i>0; i--) {
var newDiv = document.createElement('div');
newDiv.setAttribute('id', 'demo' + i);
newDiv.innerHTML = '*** TEST ***';
numInput.parentNode.insertBefore(newDiv, numInput.nextSibling);
}
}
<input type="number" id="numInput" name="numInput" onchange="myFunc()">
+Edit
You can also manipulate <form> with javascript.
function myFunc() {
let numInput = document.getElementById("numInput");
while (numInput.nextSibling) {
numInput.nextSibling.remove();
}
let numInputval = document.getElementById('numInput').value;
for(var i=numInputval; i>0; i--) {
var newInput = document.createElement('input');
newInput.setAttribute('id', 'demoInput' + i);
newInput.setAttribute('type', 'text');
newInput.setAttribute('name', 'demoInputName' + i);
newInput.setAttribute('onchange', 'myFormChangeListener(this)');
numInput.parentNode.insertBefore(newInput, numInput.nextSibling);
numInput.parentNode.insertBefore(document.createElement('br'), numInput.nextSibling);
}
}
function myFormChangeListener(element) {
console.log(element);
console.log(element.value);
myForm.action = 'http://the.url/';
myForm.method = 'post';
console.log(myForm);
//myForm.submit;
}
<form id="myForm">
<input type="number" id="numInput" name="numInput" onchange="myFunc()">
</form>

Create an array of selected radio button values

I have few radio buttons:
<input type="radio" value="####.###/resources/videos/7.mp4">
<input type="radio" value="####.###/resources/videos/8.mp4">
<input type="radio" value="####.###/resources/videos/9.mp4">
How can I make an array containing the selected values like following:
var videos = ["./resources/videos/7.mp4",
"./resources/videos/1.mp4",
"./resources/videos/2.mp4",
"./resources/videos/3.mp4"];
Onclick push the value of radio in array
var arr=[];
$('input').click(function(){
arr.push("."+$(this).val().split('####.###')[1])
console.log(arr);
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="radio" value="####.###/resources/videos/7.mp4">Video1
<input type="radio" value="####.###/resources/videos/8.mp4">Video2
<input type="radio" value="####.###/resources/videos/9.mp4">Video3
I would add a change event listener, that checks if the input got checked or unchecked and would add it or remove it from the list.
var originalVideoList = ["./resources/videos/7.mp4",
"./resources/videos/1.mp4",
"./resources/videos/2.mp4",
"./resources/videos/3.mp4"
];
var videos = document.querySelector("#videos");
var result = document.querySelector("#result");
var template = "<li><label for='{0}'>Video {1}</label><input id='{0}' type='checkbox' onchange='onChange()'/></li>";
var selectedArray = [];
// Set up html
videos.innerHTML = originalVideoList.map(function(video) {
return template.replace(/\{0\}/g, video).replace(/\{1\}/g, video.split("/").pop());
}).join("");
// triggered on input change
function onChange() {
selectedArray = toArray(document.querySelectorAll("li>input:checked")).map(function(item) {
return item.id.replace("####.###", ".");
});
result.innerHTML = selectedArray.map(function(video) {
return "<li>" + video + "</li>";
}).join("");
}
// Same as [...input]
function toArray(input) {
var result = [];
for (var index = 0; index < input.length; index++) result[index] = input[index];
return result;
}
<ul id="videos"></ul>
<ul id="result"></ul>

Deactivate a button until all javascript conditions have been checked

I´m trying to do different javascript validations before sending a form, the problem is that I haven´t been able to prevent the form from submit, it checks the conditions and sends alerts when a conditions hasn´t been satisfied but it sends the form anyways. I want the button to either be disabled until everything is right or send a message telling user, to check the cuenta.
Thanks in advance. This is my code:
<form action="<?php echo base_url();?>index.php/Datos/agregar" method="post">
Enter CLABE account:
<input name="clabe" id="clabe" type = "text" pattern=".{17,17}" maxlength="17" required title="17 números exactamente"/>
<input type="text" name="control" id="control" maxlength="1" size="2" required >
Again:
<input name="clabe2" id="clabe2" type = "text" pattern=".{17,17}" maxlength="17" required title="17 números exactamente"/>
<input type="text" name="control2" id="control2" maxlength="1" size="2" required>
<hr>
Bank: <input type="text" name="Banco" id="Banco" readonly required onmousemove="comparaclabe();" >
<hr>
Observations: <input type="text" name="Observaciones" id="Observaciones" required>
<hr>
<input type="submit" id="myBtn" value="Guardar Cambios" onclick ="return compareclabe();" ><span id="msg"></span>
<hr>
<input type="hidden" id="cve_banco" name="cve_banco">
</form>
<hr>
<script>
function compareclabe(){
document.getElementById("myBtn").disabled = true;
var x1 = document.getElementById("clabe").value;
var x2 = document.getElementById("control").value;
var x3 = x1 + x2;
var z1 = document.getElementById("clabe2").value;
var z2 = document.getElementById("control2").value;
var z3 = z1 + z2;
if( x3 != z3){
alert("keys are not equal");
return false;
}else if (x3 == z3){
this.someFunc(); //I want to call function someFunc and then
if the result is true, execute the next code
if (true){
var cBanco = String(x3).charAt(0) + String(x3).charAt(1) + String(x3).charAt(2);
var x = cBanco;
switch (x) {
case "012":
text = "BBVA BANCOMER";
break;
case "014":
text = "SANTANDER";
break;
case "032":
text = "IXE";
break;
default:
text = "No value found";
}
document.getElementById("Banco").value = text;
document.getElementById("myBtn").disabled = false;
return true;
}
}else{
return false;
}
}
function someFunc() {
//myFunction2();
var x = document.getElementById("clabe2").value;
f2(x,'37137137137137137');
//return true;
}
function f2(a, b) {
var cad = Array.from(a, (v, i) => v * b[i] % 10).join('');
//se suman todos los digitos del array
var value = cad,
sum = value
.toString()
.split('')
.map(Number)
.reduce(function (a, b) {
return a + b;
}, 0);
//separate last digit from result
var number = sum;
// convert number to a string, then extract the first digit
var one = String(number).charAt(1);
// convert the first digit back to an integer
var one_as_number = Number(one);
var digito_control = (10 - one_as_number);
if (digito_control === 10 ) {
digito_control = 0;
var dg = digito_control;
}else{
dg = digito_control;
}
var z = document.getElementById("control2").value;
if (dg != z){
alert("checkig digit is not equal");
return false;
}
else if (dg == z){
alert("checkig digit is equal");
return true;
}
}
</script>
I changed form submit button type to "button" and if all the validations are passed, then submit form from javascript. See below code
function compareclabe() {
document.getElementById("myBtn").disabled = true;
var x1 = document.getElementById("clabe").value;
var x2 = document.getElementById("control").value;
var x3 = x1 + x2;
var z1 = document.getElementById("clabe2").value;
var z2 = document.getElementById("control2").value;
var z3 = z1 + z2;
if (x3 != z3) {
alert("keys are not equal");
return false;
} else if (x3 == z3) {
this.someFunc(); //I want to call function someFunc and then if the result is true, execute the next code
if (true) {
var cBanco = String(x3).charAt(0) + String(x3).charAt(1) + String(x3).charAt(2);
var x = cBanco;
switch (x) {
case "012":
text = "BBVA BANCOMER";
break;
case "014":
text = "SANTANDER";
break;
case "032":
text = "IXE";
break;
default:
text = "No value found";
}
document.getElementById("Banco").value = text;
document.getElementById("myBtn").disabled = false;
$('#form').submit(); //submit form if all validation succeeds
}
} else {
return false;
}
}
function someFunc() {
//myFunction2();
var x = document.getElementById("clabe2").value;
f2(x, '37137137137137137');
//return true;
}
function f2(a, b) {
var cad = Array.from(a, (v, i) => v * b[i] % 10).join('');
//se suman todos los digitos del array
var value = cad,
sum = value
.toString()
.split('')
.map(Number)
.reduce(function(a, b) {
return a + b;
}, 0);
//separate last digit from result
var number = sum;
// convert number to a string, then extract the first digit
var one = String(number).charAt(1);
// convert the first digit back to an integer
var one_as_number = Number(one);
var digito_control = (10 - one_as_number);
if (digito_control === 10) {
digito_control = 0;
var dg = digito_control;
} else {
dg = digito_control;
}
var z = document.getElementById("control2").value;
if (dg != z) {
alert("checkig digit is not equal");
return false;
} else if (dg == z) {
alert("checkig digit is equal");
return true;
}
}
<form action="<?php echo base_url();?>index.php/Datos/agregar" method="post" id="form"> <!-- I included an id to form -->
Enter CLABE account:
<input name="clabe" id="clabe" type="text" pattern=".{17,17}" maxlength="17" required title="17 números exactamente" />
<input type="text" name="control" id="control" maxlength="1" size="2" required> Again:
<input name="clabe2" id="clabe2" type="text" pattern=".{17,17}" maxlength="17" required title="17 números exactamente" />
<input type="text" name="control2" id="control2" maxlength="1" size="2" required>
<hr> Bank: <input type="text" name="Banco" id="Banco" readonly required onmousemove="comparaclabe();">
<hr> Observations: <input type="text" name="Observaciones" id="Observaciones" required>
<hr>
<input type="button" id="myBtn" value="Guardar Cambios" onclick="return compareclabe();"><span id="msg"></span>
<hr>
<input type="hidden" id="cve_banco" name="cve_banco">
</form>
<hr>
But there are many validation plugins where you can easily implement. No need to code from begining. Refer this for an example -> https://jqueryvalidation.org/
You can disable the button by default, and add event listeners to all the inputs in your form. But be weary of other ways to submit the form, like the enter key. I would add an onsubmit function just to prevent all ways the event can happen when you don't want it to.
const form = document.querySelector('form')
const inputs = [...form.querySelectorAll('input')] // convert node list to array
const isValid = () => {
let valid = false
disableButton()
// handle your conditions here
if (valid) enableButton()
return valid;
}
inputs.forEach( input => input.addEventListener('input', isValid))
form.onsubmit = event => if (!isValid()) event.preventDefault()
Or ES5 if you prefer:
var form = document.querySelector('form');
var inputNodes = form.querySelectorAll('input');
var inputs = Array.prototype.call.slice(inputNodes); // convert node list to array
var isValid = function() {
var valid = false;
disableButton();
// handle your conditions here
if (valid) enableButton();
return valid
}
inputs.forEach( function(input) {
input.addEventListener('input', isValid);
});
form.onsubmit = function(event) {
if (!isValid()) event.preventDefault();
};
It's also worth noting that HTML5 has a lot of built-in validation you can take advantage of.

jquery bunch of input values multiply by dynamic (another input)

I have a grouped product and that all group can buy within a page. Page has multiple quantity inputs (like 6). And another bulk quantity input.
What it must do is,
After setting the normal product quantities, those values must multiply by the bulk input value.
my code does the multiplication, but not as i expect. It just multiply by the current input value. I want to do as follows.
(1st attempt)
Eg : Input 1 Value = 5, Input 2 value = 2, Input 3 Value = 8. Bulk Value = 10
Results should be : Input 1 = 50, Input 2 = 20, Input 3 = 80
If we gain the bulk value by 1 (2nd attempt)
current Input 1 Value = 50, current Input 2 value = 20, current Input 3 Value = 80. new gained Bulk Value = 11
Results should be : Input 1 = 55, Input 2 = 22, Input 3 = 88
$('#multiply-value').change(function() {
var multiplied = $('#multiply-value').val();
var milti = 0;
var value_of = 0;
var test = 0;
if (this.getAttribute('value') === this.value) {
$(this).data('lastvalue', this.value);
} else {
if(this.value < $(this).data('lastvalue')){
var old = $(this).data('lastvalue');
console.log('decrement');
$('.input-text.qty').each(function() {
var i = 1;
var qty_vals = $(this);
var old_v = $(this).data('lastvalue');
old_test = old_v.val();
test = qty_vals.val();
var cals = 0;
while(i < multiplied ){
cals = +old_test + +cals;
console.log(cals);
i++
}
$(this).val(cals);
test = 0;
});
}
else{
console.log('increment');
$('.input-text.qty').each(function() {
var i = 1;
var qty_vals = $(this);
test = qty_vals.val();
var cals = 0;
while(i <= multiplied ){
cals = +test + +cals;
console.log(cals);
i++
}
$(this).val(cals);
test = 0;
});
}
// console.log(this.value < $(this).data('lastvalue') ? 'decrement' : 'increment');
$(this).data('lastvalue', this.value);
}
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<div class=""bunch-of-inputs">
<input type="text" name="super_group[50]" maxlength="12" value="0" title="Qty" class="input-text qty">
<input type="text" name="super_group[50]" maxlength="12" value="0" title="Qty" class="input-text qty">
<input type="text" name="super_group[50]" maxlength="12" value="0" title="Qty" class="input-text qty">
</div>
<input id="multiply-value" type="number" value="1">
</div>
why not to store the original value of each field at another field rather than the value field ?
so the html will be :
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<div class=""bunch-of-inputs">
<input type="text" name="super_group[50]" maxlength="12" value="5" title="Qty" class="input-text qty" data-default="5">
<input type="text" name="super_group[50]" maxlength="12" value="2" title="Qty" class="input-text qty" data-default="2">
<input type="text" name="super_group[50]" maxlength="12" value="8" title="Qty" class="input-text qty" data-default="8">
</div>
<input id="multiply-value" type="number" value="1" >
</div>
And the js will be:
$('#multiply-value').on('input',function() {
var multiplied = $('#multiply-value').val();
$('.input-text.qty').each(function() {
$(this).val($(this).data('default') * multiplied);
});
})
this way we don't need to store the previous value, we have the default value any time
/* modification start */
firsttime = true;
zero = true;
$('#multiply-value').change(function() {
if (firsttime && zero) {
$('.input-text.qty').each(function() {
this.setAttribute('value', $(this).val());
firsttime = false;
if($(this).val() != 0) {
zero = false;
}
});
}
/* modification end */
var multiplied = $('#multiply-value').val();
var milti = 0;
var value_of = 0;
var test = 0;
if (this.getAttribute('value') === this.value) {
$(this).data('lastvalue', this.value);
} else {
if (this.value < $(this).data('lastvalue')) {
var old = $(this).data('lastvalue');
console.log('decrement');
$('.input-text.qty').each(function() {
var i = 1;
var qty_vals = $(this);
var old_v = $(this).data('lastvalue');
old_test = old_v.val();
test = qty_vals.val();
var cals = 0;
while (i < multiplied) {
cals = +old_test + +cals;
console.log(cals);
i++
}
$(this).val(cals);
test = 0;
});
}
else {
console.log('increment');
$('.input-text.qty').each(function() {
var i = 1;
var qty_vals = this; // modified, write this instead of $(this)
test = qty_vals.getAttribute('value'); // modification here
var cals = 0;
while (i <= multiplied) {
cals = +test + +cals;
console.log(cals);
i++
}
$(this).val(cals);
test = 0;
});
}
// console.log(this.value < $(this).data('lastvalue') ? 'decrement' : 'increment');
$(this).data('lastvalue', this.value);
}
})
The first inputs are set to respective value attributes. If all of the inputs are zero, then the second inputs will act as first inputs and so on. Instead of test = qty_vals.value; write, test = qty_vals.getAttribute('value'); to get original non-zero values.

Categories

Resources