Remove specific array from multiple array set using jquery - javascript

I have two checkboxes. When I check one, the code will get status and id of that checkbox and push into array, if that value is not present already
The array set become like this
[8,0] [10,0]
Requirements:
It is inserting [8,0] [8,0] twice if I check and then uncheck and again check it so this should not insert multiple times same values
Remove specific array from set of array so if I uncheck chkecbox then remove only [8,0] but keep [10,0]
var positions = [];
$("body").on('click', '.check_box', function() {
var id = $(this).attr('data-id');
var status = $(this).attr('data-status');
if ($(this).prop("checked") == true) { // if click on check
if (!$.inArray(id, positions)) positions.push(id); // if id and status not in array then only push
positions.push([id, status]); // it will insert like [8,10] but geting duplicate [8,10] [8,10]
console.log(positions);
} else {
// if uncheck checkbox
// remove specific value like [8,0] or if value present [10,0] then remove this
console.log(positions);
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="checkbox" class="check_box" data-id="8" data-status="0">
<input type="checkbox" class="check_box" data-id="10" data-status="0">

You can use indexOf to check if object is present in array & add only if it doesn't exist
For removing, you can use filter & select only those objects in array which are not exactly as you specify
var positions = [];
$("body").on('click', '.check_box', function() {
var id = $(this).attr('data-id');
var status = $(this).attr('data-status');
if ($(this).prop("checked") == true) {
var exists = false;
positions.forEach((p) => {
if (id == p[0] && status == p[1]);
exists = true;
});
if (!exists) {
positions.push([id, status]);
}
} else {
positions = positions.filter(function(a) {
return !(a[0] == id && a[1] == status);
});
}
console.log(positions);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="checkbox" class="check_box" data-id="8" data-status="0">
<input type="checkbox" class="check_box" data-id="10" data-status="0">
Explanation
In The first loop .each we iterate through each existing values in array & set exist to true when we find an element which has id & status same as the one we selected
If after loop we have exist as true, we know it already exists & we won't push it to array, otherwise we will push it to the array
In else condition we have used filter function of array, this fuction filters the array & only keep the elements for which we returned true, for elements we return false, it gets removed from resulting array
So we did check every element of array for exact match of id & status & if its matched we return false, so it gets removed from the resulting array

I will use findIndex and splice to handle it, hope this can help you :)
$(function() {
let positions = [];
$("body").on('click', 'input:checkbox', function() {
let id = $(this).attr('data-id');
let status = $(this).attr('data-status');
let data = [id, status];
if ($(this).is(':checked')) {
positions.push(data);
} else {
let index = positions.findIndex(c => c[0] === id);
if (index != -1)
positions.splice(index, 1);
}
$('#result').html(positions.toString());
});
});
#result{
width: 20rem;
height: 1rem;
margin-top: 2rem;
border-width:3px;
border-style:dashed;
border-color:#FFAC55;
padding: 15px 20px;
}
<!DOCTYPE html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>
<body>
<input type="checkbox" data-id="A" data-status="0">A</button>
<input type="checkbox" data-id="B" data-status="0">B</button>
<div id="result"></div>
</body>
</html>

If the array is small, just recreate it each time
let positions;
$("body").on('click', '.check_box', function() {
positions = [];
$(".check_box:checked").each(function() {
positions.push([
$(this).data('id'), $(this).data('status')
]);
});
console.log(positions);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="checkbox" class="check_box" data-id="8" data-status="0">
<input type="checkbox" class="check_box" data-id="10" data-status="0">

Related

Removing value from array according to index using splice()

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>

check two input element's names are different or not using javascript

I have an array in which the values of check boxes gets stored on user click. Now I need to use an if loop for a particular logic in my code to give a condition whether the elements inside the array have same name (group check box name) or different names. How can I do it in javascript or jquery?
var Array = ['bob','bob','smith','smith','john','john'];
var UniqueArray = new Array();
var obj = {};
$.each(Array , function(i,value) {
if(!obj[value]) {
obj[value] = true;
UniqueArray.push(value)
}
})
Are you expecting something like this.
$(function() {
// create an array.
var elements = [];
// click event for all input of type checkbox.
$('[type="checkbox"]').on("click", function() {
// restrict no. of items to be inserted into the array to 2
if (elements.length <= 2) {
// push each element to array.
elements.push($(this));
}
// compare name attribute of 1st and 2nd element in array.
if (elements.length == 2) {
if (elements[0].attr('name') == elements[1].attr('name')) {
alert('elements with same name');
} else {
alert('elements with differnt name');
}
//clear all elements from array.
elements = [];
//clear all checkbox.
$('input:checkbox').removeAttr('checked');
}
// if you want to iterate through array use $.each
/*$.each(elements,function(index,data){
alert(data.attr('name'));
});
*/
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
first checkbox - :"myCheckBox":
<input type="checkbox" name=myCheckBox id="cbxCustom1" />
<br>second checkbox - :"myCheckBox":
<input type="checkbox" name=myCheckBox id="cbxCustom2" />
<br>third checkbox - :"myCheckBoxNew":
<input type="checkbox" name=myCheckBoxNew id="cbxCustom3" />

Check if there are multiple input fields with the same value

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>

compare two arrays based on length: skip empty values

I have a form with 4 input (can be even many more) where the user can put a number or nothing. The only rule is that if you put a number in a input you cannot submit if the same number is in another input (no duplicates). You can submit with as many empty input as you want.
To validate the input I compare the length of the array of all the inputs with the same array with only unique values. If they have the same length it's ok.
I need to improve my code because now it works only if the user enters all the input fields. If some inputs are empty they are considered in the array with unique value as they all have "" as a value. So, if the user enters just one number I will get that array length is 4 and array unique is 2 but it should be 1 and 1 (skipping the blank items).
I was thinking about using splice() on arr, but is this the best way to do this validation?
**EDIT: I applied splice BUT if the array is ('1','','') my code gives me ('1','') instead of just (1) as I'd expect... ** This is because splice remove the item and change array length so that the for loop point to the wrong index.
Any idea?
HTML:
<div class="sez-form">
<fieldset>
<legend>Messaggi inclusi</legend>
<div class="percheckbox">
<input class="checkseq" type="checkbox" value="1" name="messaggio[0]">
Prova di messaggio che scorre<br>
<label>Ordine: </label>
<input class="seq" type="text" name="ordine[0]" maxlength="2" size="2">
</div>
<div class="percheckbox">
<input class="checkseq" type="checkbox" value="3" name="messaggio[1]">
Titoli di film<br>
<label>Ordine: </label>
<input class="seq" type="text" name="ordine[1]" maxlength="2" size="2">
</div>
<div class="percheckbox">
<input class="checkseq" type="checkbox" value="6" name="messaggio[2]">
Prova a testo fisso<br>
<label>Ordine: </label>
<input class="seq" type="text" name="ordine[2]" maxlength="2" size="2">
</div>
<br style="clear: both;">
</fieldset>
</div>
JAVASCRIPT:
function uniqueArray(arr) {
return $.grep(arr,function(v,k) {
return $.inArray(v,arr) === k;
});
}
$(document).ready(function() {
$('#invia').click(function(e) {
e.preventDefault();
var arr = $(".seq").map(function(){ return $(this).val(); }).toArray();
var empty = $(".seq").filter(function() {
return this.value == "";
})
for (index = 0; index < arr.length; ++index) {
if (arr[index]=='') {
new_arr = arr.splice([index],1);
}
console.log(arr);
}
if(empty.length == $('.seq').length) {
alert('Non hai scelto alcun messaggio per il workflow. Correggi per procedere.');
}
else if(uniqueArray(arr).length != $('.seq').length) {
console.log(uniqueArray(arr));
alert('Ci sono voci duplicate nella sequenza. Correggi per procedere.');
}
else if($('#dt_from').val()=='__/__/____ __:__') {
alert('Scegli data e ora di inizio validit\u00E0 per il workflow');
}
else if($('#dt_to').val()=='__/__/____ __:__') {
alert('Scegli data e ora di fine validit\u00E0 per il workflow');
}
else {
ajaxSubmit();
}
});
});
Here is another possible way to handle it. Here is the working JSFiddle. And here is the code:
$(function() {
$("#submit").click(function() {
//build a profile of the inputs
var inputs = [];
var values = [];
var dups = false; //track duplicates on pass 1
$(".seq").each(function(i, el) {
var empty = (el.value == ""); //check if empty
var exists = (!empty && $.grep(inputs, function(item, index) {
return (item.Value === el.value);
}).length > 0); //check if exists
dups = (dups || exists); //track dups
//add the new input item
var obj = {
Element: el,
Value: el.value,
Empty: empty,
Exists: exists
};
inputs.push(obj);
//conditionally add the sorting value
if (!empty && !exists)
values.push(el.value);
});
//Validate the inputs. If there are duplicates, don't submit
$(".seq").css("background-color", "white"); //clear errors
if (dups) {
$(inputs).each(function(i, el) {
if (el.Exists)
el.Element.style.backgroundColor = "red";
});
} else {
values = values.sort();
alert(values);
}
});
});
With this method, at the end you have an array - inputs - of all of the elements with their statuses so that you can provide error handling on specific fields. In my example, the error fields turn red.
At the alert, you have a sorted array of the valid values.
Maybe I don't understand what you are trying to do, but why can't you do it very simply with something like:
$('#invia').click(function(e) {
e.preventDefault();
var unique = [], nonunique = [];
$(".seq").each(function(index){
var val = $(this).val();
if (val !== "") {
if ($.inArray(val, unique) !== -1) {
nonunique.push(val);
} else {
unique.push(val);
}
}
});
// If unique and nonunique are empty, all inputs were blank
// else if nonunique is empty, inputs are valid and in unique
});
Use a hash to track values as you iterate. This example simply returns true or false, but you could also scan the entire array and return the repeated values.
function uniquifyArray(ary) {
var seen = {};
var isUnique = true;
/* iterate backwards since the array length will change as elements are removed */
for (var i=ary.length; i--;) {
/* remove blank/undefined */
if (typeof ary[i] === 'undefined' || ary[i] === '') {
ary.splice(i,1);
} else {
/* check if this value has already been seen */
if (ary[i] in seen) {
isUnique = false;
ary.splice(i,1);
} else {
seen[ary[i]]=true;
}
}
}
ary = ary.sort();
return isUnique;
}
var test = [ '1','2','','','3','4','1' ];
uniquifyArray(test); // returns false, test = [ '1','2','3','4' ]
test = [ '1','2','','' ]
uniquifyArray(test); //true, test = ['1','2']

Javascript checkbox onChange

I have a checkbox in a form and I'd like it to work according to following scenario:
if someone checks it, the value of a textfield (totalCost) should be set to 10.
then, if I go back and uncheck it, a function calculate() sets the value of totalCost according to other parameters in the form.
So basically, I need the part where, when I check the checkbox I do one thing and when I uncheck it, I do another.
Pure javascript:
const checkbox = document.getElementById('myCheckbox')
checkbox.addEventListener('change', (event) => {
if (event.currentTarget.checked) {
alert('checked');
} else {
alert('not checked');
}
})
My Checkbox: <input id="myCheckbox" type="checkbox" />
function calc()
{
if (document.getElementById('xxx').checked)
{
document.getElementById('totalCost').value = 10;
} else {
calculate();
}
}
HTML
<input type="checkbox" id="xxx" name="xxx" onclick="calc();"/>
If you are using jQuery.. then I can suggest the following:
NOTE: I made some assumption here
$('#my_checkbox').click(function(){
if($(this).is(':checked')){
$('input[name="totalCost"]').val(10);
} else {
calculate();
}
});
Use an onclick event, because every click on a checkbox actually changes it.
The following solution makes use of jquery. Let's assume you have a checkbox with id of checkboxId.
const checkbox = $("#checkboxId");
checkbox.change(function(event) {
var checkbox = event.target;
if (checkbox.checked) {
//Checkbox has been checked
} else {
//Checkbox has been unchecked
}
});
HTML:
<input type="checkbox" onchange="handleChange(event)">
JS:
function handleChange(e) {
const {checked} = e.target;
}
Reference the checkbox by it's id and not with the #
Assign the function to the onclick attribute rather than using the change attribute
var checkbox = $("save_" + fieldName);
checkbox.onclick = function(event) {
var checkbox = event.target;
if (checkbox.checked) {
//Checkbox has been checked
} else {
//Checkbox has been unchecked
}
};
Javascript
// on toggle method
// to check status of checkbox
function onToggle() {
// check if checkbox is checked
if (document.querySelector('#my-checkbox').checked) {
// if checked
console.log('checked');
} else {
// if unchecked
console.log('unchecked');
}
}
HTML
<input id="my-checkbox" type="checkbox" onclick="onToggle()">
try
totalCost.value = checkbox.checked ? 10 : calculate();
function change(checkbox) {
totalCost.value = checkbox.checked ? 10 : calculate();
}
function calculate() {
return other.value*2;
}
input { display: block}
Checkbox: <input type="checkbox" onclick="change(this)"/>
Total cost: <input id="totalCost" type="number" value=5 />
Other: <input id="other" type="number" value=7 />
I know this seems like noob answer but I'm putting it here so that it can help others in the future.
Suppose you are building a table with a foreach loop. And at the same time adding checkboxes at the end.
<!-- Begin Loop-->
<tr>
<td><?=$criteria?></td>
<td><?=$indicator?></td>
<td><?=$target?></td>
<td>
<div class="form-check">
<input type="checkbox" class="form-check-input" name="active" value="<?=$id?>" <?=$status?'checked':''?>>
<!-- mark as 'checked' if checkbox was selected on a previous save -->
</div>
</td>
</tr>
<!-- End of Loop -->
You place a button below the table with a hidden input:
<form method="post" action="/goalobj-review" id="goalobj">
<!-- we retrieve saved checkboxes & concatenate them into a string separated by commas.i.e. $saved_data = "1,2,3"; -->
<input type="hidden" name="result" id="selected" value="<?= $saved_data ?>>
<button type="submit" class="btn btn-info" form="goalobj">Submit Changes</button>
</form>
You can write your script like so:
<script type="text/javascript">
var checkboxes = document.getElementsByClassName('form-check-input');
var i;
var tid = setInterval(function () {
if (document.readyState !== "complete") {
return;
}
clearInterval(tid);
for(i=0;i<checkboxes.length;i++){
checkboxes[i].addEventListener('click',checkBoxValue);
}
},100);
function checkBoxValue(event) {
var selected = document.querySelector("input[id=selected]");
var result = 0;
if(this.checked) {
if(selected.value.length > 0) {
result = selected.value + "," + this.value;
document.querySelector("input[id=selected]").value = result;
} else {
result = this.value;
document.querySelector("input[id=selected]").value = result;
}
}
if(! this.checked) {
// trigger if unchecked. if checkbox is marked as 'checked' from a previous saved is deselected, this will also remove its corresponding value from our hidden input.
var compact = selected.value.split(","); // split string into array
var index = compact.indexOf(this.value); // return index of our selected checkbox
compact.splice(index,1); // removes 1 item at specified index
var newValue = compact.join(",") // returns a new string
document.querySelector("input[id=selected]").value = newValue;
}
}
</script>
The ids of your checkboxes will be submitted as a string "1,2" within the result variable. You can then break it up at the controller level however you want.

Categories