What is the simplest way to check with jQuery if we have multiple input fields on the page with the same value?
Thank you all!
You can iterate all input elements, store their value in a hash table, and check if the value was already there:
var hash = Object.create(null),
result = [].some.call(document.getElementsByTagName('input'), function(inp) {
if(hash[inp.value]) return true;
hash[inp.value] = true;
});
Get all the input elements, sort and check if there are duplicates.
var elements = document.getElementsByTagName("input")
var values = [];
for (var i = 0; i < elements.length; i++) {
values.push(elements[i].value);
}
var sortedValues = values.sort();
for (var o = 0; o < values.length-1; o++) {
if (values[o] == values[o+1])
alert ('Duplicate!');
}
You can loop thru all inputs and generate a data structure like below.
var inputs = {};
$("input").each(function(i, elem) {
if (inputs.hasOwnProperty(elem.value)) {
inputs[elem.value] += 1;
} else {
inputs[elem.value] = 1;
}
});
alert (JSON.stringify(inputs, null, 4))
A Demo
The solution is to write a loop and iterate through each input field for a possible match. If you're using jQuery, then it's actually very simple.
Let's say we have a simple HTML page with 3 input fields.
HTML:
<input type="text" name="input1">
<input type="text" name="input2>
<input type="text" name="input3">
Then we use the jQuery each() method to iterate over the fields. Mainly saying, we iterate over all the input fields and get their values. Then we again iterate through all the input fields (so were actually creating a nested loop) and check if any of them match the currently iterating input value.
jQuery:
var currentInput;
$("input").each(function(index) {
currentInput = $(this);
$("input").each(function(index) {
if currentInput.val() === $(this).val() {
alert("Error: input fields match found");
}
});
});
I would like to provide a more efficient answer when it comes to checking for duplicate values in multiple input fields. When it comes to comparing values we need to,
Iterate and keep the current element somewhere temporarily
Re-iterate and check against the previously kept value whether its a duplicate
When performing the step 2, we need to make sure that we skip comparing the previously kept (step 1) value against itself.
If I am not wrong, I have seen step 1 and 2 in all above answers but not the step 3.
The following code will do all those 3 steps.
var eqArr = [];
var currentInput;
$("input").each(function(k1, v1) {
if($(v1).val() != ''){
currentInput = $(v1);
$("input").each(function(k2, v2) {
if(k1 !== k2 &&
currentInput.val() === $(v2).val() &&
$.inArray($(this).attr('id'), eqArr) === -1){
eqArr.push($(this).attr('id'));
}
});
}
});
In the above code I am collecting id's of those input fields of those duplicates (in array). After performing the above logic, doing following simple check will tell you whether you have duplicates or not.
if(eqArr.length > 0){
//It means we have duplicates
}
var eqArr = [];
var currentInput;
$("input").each(function(k1, v1) {
if ($(v1).val() != '') {
currentInput = $(v1);
$("input").each(function(k2, v2) {
if (k1 !== k2 &&
currentInput.val() === $(v2).val() &&
$.inArray($(this).attr('id'), eqArr) === -1) {
eqArr.push($(this).attr('id'));
}
});
}
});
console.log(eqArr);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>Input Field Duplicates</title>
</head>
<body>
<input type="text" name="input1" id="i1" value="bbb">
<input type="text" name="input2" id="i2" value="aaa">
<input type="text" name="input3" id="i3" value="aaa">
<input type="text" name="input3" id="i4" value="fff">
<input type="text" name="input3" id="i5" value="bbb">
<input type="text" name="input3" id="i6" value="ccc">
<input type="text" name="input3" id="i7" value="bbb">
<input type="text" name="input3" id="i8" value="bbb">
</body>
</html>
Related
I have 4 checkboxes. I add values of them to an array on check. It looks like this.
Here are the four checkboxes I have.
<input type="checkbox" value="degree">
<input type="checkbox" value="pgd">
<input type="checkbox" value="hnd">
<input type="checkbox" value="advdip">
Once I check all four of them, the array becomes,
["degree", "pgd", "hnd", "advdip"]
When I uncheck a checkbox, I need to remove the value of it from the array according to its correct index number. I used splice() but it always removes the first index which is degree. I need to remove the value from the array according to its index number no matter which checkbox I unselect. Hope someone helps. Below is the code. Thanks in advance!
<input type="checkbox" value="degree">
<input type="checkbox" value="pgd">
<input type="checkbox" value="hnd">
<input type="checkbox" value="advdip">
<script>
function getLevels() {
// get reference to container div of checkboxes
var con = document.getElementById('course-levels');
// get reference to input elements in course-levels container
var inp = document.getElementsByTagName('input');
// create array to hold checkbox values
var selectedValues = [];
// collect each input value on click
for (var i = 0; i < inp.length; i++) {
// if input is checkbox
if (inp[i].type === 'checkbox') {
// on each checkbox click
inp[i].onclick = function() {
if ($(this).prop("checked") == true) {
selectedValues.push(this.value);
console.log(selectedValues);
}
else if ($(this).prop("checked") == false) {
// get index number
var index = $(this).index();
selectedValues.splice(index, 1);
console.log(selectedValues);
}
}
}
}
}
getLevels();
</script>
You used the wrong way to find index in your code. If you used element index, it will avoid real index in your array and gives the wrong output. Check below code, it may be work for you requirement.
<input type="checkbox" value="degree">
<input type="checkbox" value="pgd">
<input type="checkbox" value="hnd">
<input type="checkbox" value="advdip">
<script src="https://code.jquery.com/jquery-3.5.0.min.js" integrity="sha256-xNzN2a4ltkB44Mc/Jz3pT4iU1cmeR0FkXs4pru/JxaQ=" crossorigin="anonymous"></script>
<script>
function getLevels() {
// get reference to container div of checkboxes
var con = document.getElementById('course-levels');
// get reference to input elements in course-levels container
var inp = document.getElementsByTagName('input');
// create array to hold checkbox values
var selectedValues = [];
// collect each input value on click
for (var i = 0; i < inp.length; i++) {
// if input is checkbox
if (inp[i].type === 'checkbox') {
// on each checkbox click
inp[i].onclick = function() {
if ($(this).prop("checked") == true) {
selectedValues.push(this.value);
console.log(selectedValues);
}
else if ($(this).prop("checked") == false) {
// get index number
var index = selectedValues.indexOf(this.value);
selectedValues.splice(index, 1);
console.log(selectedValues);
}
}
}
}
}
getLevels();
</script>
Add change handler to the inputs and use jQuery map to get the values of the checked inputs.
var levels
$('#checkArray input').on('change', function () {
levels = $('#checkArray input:checked').map(function () {
return this.value
}).get()
console.log(levels)
}).eq(0).change()
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<fieldset id="checkArray">
<input type="checkbox" value="degree" checked>
<input type="checkbox" value="pgd">
<input type="checkbox" value="hnd">
<input type="checkbox" value="advdip">
</fieldset>
my approach was to add an event handler that reads all checked values when any of those inputs is clicked and empty the array before loging the response. no need to add any dependencies with this one
Hope this is what you are looking for
function getLevels() {
let checkboxContainer = document.getElementById("checkboxContainer");
let inputs = checkboxContainer.querySelectorAll("input");
let checked = [];
inputs.forEach( (input) => {
checked = [];
input.addEventListener( 'click', () => {
checked = [];
inputs.forEach( (e) => {
e.checked ? checked.push(e.value) : null;
})
console.log(checked);
});
});
}
getLevels();
<div id="checkboxContainer">
<input type="checkbox" value="degree" >
<input type="checkbox" value="pgd">
<input type="checkbox" value="hnd">
<input type="checkbox" value="advdip">
</div>
I don't know if this is what you need, to show an array of the selected values, if you want you can call the function that calculates on the check.
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0/jquery.min.js"></script>
<fieldset id="checkArray">
<input type="checkbox" value="degree" checked>
<input type="checkbox" value="pgd">
<input type="checkbox" value="hnd">
<input type="checkbox" value="advdip">
</fieldset>
<button onclick="getLevels()">getLevels</button>
<script>
function getLevels() {
var levels = [];
$.each($("input:checked"), function() {
levels.push(($(this).val()));
});
console.log(levels);
}
getLevels();
</script>
I'm trying to check if the form inputs are all empty. It works fine when any input has value (returns true) but doesn't return false when input gets empty again.
var data;
$('form :input').on('input', function() {
data = $('form').serialize();
console.log(data.indexOf('=&') > -1)
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form>
<input type="text" name="in-1" />
<input type="text" name="in-2" />
<input type="text" name="in-3" />
<input type="text" name="in-4" />
<input type="text" name="in-5" />
<input type="text" name="in-6" />
<input type="text" name="in-7" />
<input type="text" name="in-8" />
</form>
(data.indexOf('=&') > -1
will return true when at least one of the fields is blank - you're checking for the existence of the =&, and as soon as one field is blank, this string will exist. However, relying on the serialised version of the data is a bit of a hack anyway IMHO. Much better to check the inputs directly:
$('form :input').on('input', function() {
var allBlank = true; //assume they're all blank until we discover otherwise
//loop through each of the inputs matched
$('form :input').each(function(index, el)
{
if ($(el).val().length != 0) allBlank = false; //they're not all blank anymore
});
console.log(allBlank);
});
var serialized = $(form).serialize();
if(serialized.indexOf('=&') > -1 || serialized.substr(serialized.length - 1) == '='){
//you've got empty values
}
Using jQuery, you can test it before serializing:
$(form).find('input').each(function(index, elem){
if($(elem).val().length == 0){
//this field is empty
}
});
data.split('&').every(e => { return e.indexOf('=') === (e.length - 1); })
let us say that there is 5 input field for page (A)
<form class="classesName" action="action.php" method="POST">
<input type="text" name="class1" placeholder="Class Name1?" required="">
<input type="text" name="class2" placeholder="Class Name2?" required="">
<input type="text" name="class3" placeholder="Class Name3?" required="">
<input type="text" name="class4" placeholder="Class Name4?" required="">
<input type="text" name="class5" placeholder="Class Name5?" required="">
</form>
I want the user to fill all the fields BUT it must be unique class name for each field
so he can't fill
class a
class b
class a < this one is duplicated so it should display an error message
class c
class d
I think I can make if statement in the action.php page to check is there a duplication in the submitted field or not
but I don't want all the other values to be lost when I reload this page again to display the error for him
is there like a property in html5 or anything like that ?
thanks
No, this cannot be done with HTML5 alone. You'll have to write some JavaScript to make this happen. The JavaScript code should check all the values and if any two are identical prevent the form from submitting successfully.
In this case you could use javascript to validate the fields every time the user fills out a textbox. Here is an example:
$('input[type=text]').on('change',function(){
var arr = [];
$siblings = $(this).siblings();
$.each($siblings, function (i, key) {
arr.push($(key).val());
});
if ($.inArray($(this).val(), arr) !== -1)
{
alert("duplicate has been found");
}
});
JSFiddle: http://jsfiddle.net/x66j3qw3/
var frm = document.querySelector('form.classesName');
var inputs = frm.querySelectorAll('input[type=text]');
frm.addEventListener('submit', function(e) {
e.preventDefault();
var classArr = [];
for(var i = 0; i < inputs.length; i++) {
if(classArr.indexOf(inputs[i].value) != -1) {
inputs[i].style.backgroundColor = "red";
return false;
}
else
classArr.push(inputs[i].value);
}
frm.submit();
});
jsfiddle DEMO
I am trying to perform this action like if user choose same value for two different box i have to show some errors.my textbox code as follows.
<input class="order form-control vnumber" type="text" maxlength="1" name="Orderbox[]" required="true">
<input class="order form-control vnumber" type="text" maxlength="1" name="Orderbox[]" required="true">
<input class="order form-control vnumber" type="text" maxlength="1" name="Orderbox[]" required="true">
<input class="order form-control vnumber" type="text" maxlength="1" name="Orderbox[]" required="true">
so the textbox values should be different like 1,2,3,4 it should not be 1,1,1,1 so i have tried real time update using jquery.
$('.order').keyup(function () {
// initialize the sum (total price) to zero
var val = 0;
var next_val=0;
// we use jQuery each() to loop through all the textbox with 'price' class
// and compute the sum for each loop
$('.order').each(function() {
val+=$(this).val();
});
alert(val);
if (next_val==val) {
alert("same value");
}
next_val=val;
});
But its not working as i expected can anybody tell is there any solutions for this.Any help would be appreciated.Thank you.
JFIDDLE:
jfiddle
Try this Demo Fiddle.
var valarr = [];
$('.order').keyup(function () {
var curr = $(this).val();
if (jQuery.inArray(curr, valarr) > -1) {
alert('exists');
} else {
valarr.push(curr);
}
});
You can use arrays to maintain values. To check the existence of value use inArray()
You need to put more of the code inside the .each() loop. Also, change val+= to just val=
$('.order').each(function() {
val=$(this).val();
alert(val);
if (next_val==val) {
alert("same value");
}
next_val=val;
});
And keep in mind next_val is actually the previous value...
fiddle http://jsfiddle.net/phZaL/8/
This will only work if all values entered till now have the same value
jQuery Code
var arr = [];
$('.order').change(function () {
arr.push($(this).val());
if (arr.length > 1) {
if (arr.AllValuesSame()) alert("Values are same");
}
var val = 0;
$.each(arr, function () {
val = parseInt(val) + parseInt(this);
});
$('.val').text(val);
});
Array.prototype.AllValuesSame = function () {
if (this.length > 0) {
for (var i = 1; i < this.length; i++) {
if (this[i] !== this[0]) return false;
}
}
return true;
}
Demo Fiddle
Made with great help from this answer by #Robert
If I have 50 pairs of input textboxes, i.e.
<input type="text" id="name_0" /><input type="text" id="name_1" />
<input type="text" id="dept_0" /><input type="text" id="dept_1" />
...
<input type="text" id="age_0" /><input type="text" id="age_1" />
<input type="text" id="weight_0" /><input type="text" id="weight_1" />
i.e 50 variables of these.
When the page loads, I populate each pair with identical data.
What is the best way to check if the _0 is different from the _1?
then returning a message showing which pair has changed.
The comparison should take place once the values have been changed and a button is clicked.
$("input[type=text]").each(function () {
var $this = $(this);
if ( /_0$/.test(this.id) ) {
if ( $this.val() != $this.next("input").val() ) {
$this.css("color", "red"); // or whatever
}
}
});
Tomalak's answer should work, but just in case your inputs are scattered or not necessarily beside each other, something like this should suffice.
$('input:text[id$="_0"]').each(function() {
var new_id = this.id.replace('_0','_1');
if ($(this).val() !== $('input#'+new_id).val()) {
// not the same
}
});
var changed = [];
$("[id$=_0]").each(function() {
var name = this.id.replace("_0", "");
if (this.value != $("#" + name + "_1").val()) {
changed.push(name);
}
});
console.log(changed);