I have a checkbox which add an id of his value in array when checked and I want to delete this value when I uncheck it
I tried to remove my id with and indexOf() + splice() but I can't use indexOf() because I'm using an object
Some one have an idea to how can I delete my id when I uncheck my checkbox,
or if there is a trick to use indexOf with an object?
there is my script :
$(document).ready(function() {
const formInputIds = $('form#export input[name="ids"]');
$('.exportCheckbox:checkbox').on('change', function() {
const announceId = $(this).data('id');
if (this.checked) {
formInputIds.push(announceId);
console.log(formInputIds);
} else {
const index = formInputIds.val().indexOf(announceId);
if (index > -1) {
formInputIds.val().splice(index, 1);
}
console.log(formInputIds);
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form id="export" action="exportAnnounces">
<input type="hidden" name="ids" value="[]" />
<button type="submit" class="btn btn-primary">Download</button>
</form>
<some data of product displayed>
<input type="checkbox" data-id="{{annonce._id}}" class="exportCheckbox"/>
there is the console.log of formInputIds with 3 ids :
Consider the following.
$(function() {
var formInputIds;
function getChecked(target) {
var results = [];
$("input[type='checkbox']", target).each(function(i, elem) {
if ($(elem).is(":checked")) {
results.push($(elem).data("id"));
}
});
return results;
}
$('.exportCheckbox').on('change', function(event) {
formInputIds = getChecked($(this).parent());
console.log(formInputIds);
});
$("#export").submit(function(event) {
event.preventDefault();
console.log(formInputIds);
$("[name='ids']", this).val("[" + formInputIds.toString() + "]");
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form id="export" action="exportAnnounces">
<input type="hidden" name="ids" value="[]" />
<button type="submit" class="btn btn-primary">Download</button>
</form>
<div class="some content">
<input type="checkbox" data-id="1001" class="exportCheckbox" />
<input type="checkbox" data-id="1002" class="exportCheckbox" />
<input type="checkbox" data-id="1003" class="exportCheckbox" />
<input type="checkbox" data-id="1004" class="exportCheckbox" />
<input type="checkbox" data-id="1005" class="exportCheckbox" />
<input type="checkbox" data-id="1006" class="exportCheckbox" />
</div>
This way, you build the Array based on just the checked items. No need to find and slice the exact item.
Related
how to find all duplicate ids when the page is relaod:
Let's say we have html like this:
<input type="radio" id="name" />
<input type="radio" id="name" />
<input type="radio" id="name" />
<input type="radio" id="last" />
<input type="radio" id="last" />
The idea is to find duplicate ids and add +1 or something like that:
What I want to achieve is:
<input type="radio" id="name1" />
<input type="radio" id="name2" />
<input type="radio" id="name3" />
<input type="radio" id="last1" />
<input type="radio" id="last2" />
JS
$('[id]').each(function(){
var ids = $('[id="'+this.id+'"]');
if(ids.length>1 && ids[0]==this)
$(this).attr('id', $(this).attr('id') + i);
});
Any ideas? Thank you all.
I would strongly recommend you serve valid HTML rather than manipulating Ids.
However, You are were close as attribute value selector may return multiple elements, You need to iterate the matching elements
var handled = [];
$('[id]').each(function() {
if (handled.includes(this.id)) {
return;
}
var elemets = $('[id="' + this.id + '"]');
if (elemets.length > 1) {
handled.push(elemets.attr('id'));
elemets.attr('id', function(index, v) {
return v + (index+1);
});
}
});
//For Readablity
$('[id]').each(function(){
console.log(this.outerHTML)
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="radio" id="name" />
<input type="radio" id="name" />
<input type="radio" id="name" />
<input type="radio" id="last" />
<input type="radio" id="last" />
Try like this.
var allId = [];
var data = [];
$('[id]').each(function(){
var ids = $('[id="'+this.id+'"]');
if(allId.indexOf(this.id) < 0){
data[this.id] = 1;
allId.push(this.id);
} else {
data[this.id]++;
}
$(this).attr('id', $(this).attr('id') + data[this.id]);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="radio" id="name" />
<input type="radio" id="name" />
<input type="radio" id="name" />
<input type="radio" id="last" />
<input type="radio" id="last" />
No need for jQuery:
const ids = {}
document.querySelectorAll('[id]').forEach(node => {
if (ids[node.id] !== undefined) {
ids[node.id] += 1
} else {
ids[node.id] = 1
}
node.id = `${node.id}${ids[node.id]}`
})
document.querySelectorAll('[id]').forEach(node => console.log(node))
<input type="radio" id="name" />
<input type="radio" id="name" />
<input type="radio" id="name" />
<input type="radio" id="last" />
<input type="radio" id="last" />
try this
var i = 0;
('[id]').each(function(){
var allIds = $('[id^="'+this.id+'"]').length
var ids = $('[id="'+this.id+'"]');
if(ids.length>1 && ids[0]==this)
var i = allIds - ids.length + 1
$(this).attr('id', $(this).attr('id') + i++);
})
var a = [];
var i =0;
jQuery('[id]').each(function(){
if(a.indexOf(this.id) !== -1){ //checks if id exists in array
i++;
}
else{
i = 1;
a.push(this.id);
}
jQuery(this).attr('id', jQuery(this).attr('id') + i);
});
Explaination : I am storing each new id in array. At each iteration it checks whether the id is repeated, if so then the attribute is incremented to 1.
Example code:
<form method="get">
<input type="checkbox" name="anythingOne[]" value='one'> <!-- checked -->
<input type="checkbox" name="anythingOne[]" value='two'>
<input type="checkbox" name="anythingOne[]" value='three'> <!-- checked -->
<input type="checkbox" name="otherThingTwo[]" value='Forty'>
<input type="checkbox" name="otherThingTwo[]" value='Fifty'> <!-- checked -->
</form>
On form submission the URL should look like:
http://some-website.tld/action?anythingOne=one,three&otherThingTwo=Fifty
What I am observing now is,
http://some-website.tld/action?anythingOne=one&anythingOne=three&otherThingTwo=Fifty
The serialize() or serializeArray() is not working in this case. Any ideas?
You could grab the result of .serializeArray and transform it into the desired format:
$(function() {
$('form').on('submit', function(e) {
e.preventDefault();
var data = $(this).serializeArray();
var dataByKey = data
.reduce((result, entry) => {
var name = entry.name.replace(/\[\]$/, '');
(result[name] || (result[name] = [])).push(entry.value);
return result;
}, {});
Object.keys(dataByKey)
.forEach((key, _) => dataByKey[key] = dataByKey[key].join(','));
console.log(dataByKey);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form method="get">
<fieldset>
<input type="checkbox" name="anythingOne[]" value='one'>1
<input type="checkbox" name="anythingOne[]" value='two'>2
<input type="checkbox" name="anythingOne[]" value='three'>3
</fieldset>
<fieldset>
<input type="checkbox" name="otherThingTwo[]" value='Forty'>40
<input type="checkbox" name="otherThingTwo[]" value='Fifty'>50
</fieldset>
<input type="submit" />
</form>
If you want, you can also use pure javascript without jQuery to get all the checked checkboxes' value, http://jsfiddle.net/jx76dpkh/1/
<form id="myForm" method="get">
<input type="checkbox" name="anythingOne[]" value='one'>1
<input type="checkbox" name="anythingOne[]" value='two'>2
<input type="checkbox" name="anythingOne[]" value='three'>3
<input type="checkbox" name="otherThingTwo[]" value='Forty'>40
<input type="checkbox" name="otherThingTwo[]" value='Fifty'>50
<input type="submit" />
</form>
JS:
const myForm = document.getElementById('myForm');
myForm.addEventListener('submit', (e) => {
e.preventDefault();
let checkboxes = Array.from(myForm.querySelectorAll('input[type="checkbox"]:checked');// build the array like element list to an array
let anythingOne = checkboxes.filter( box => box.name === 'anythingOne[]').map(item => item.value);
let otherThingTwo = checkboxes.filter( box => box.name === 'otherThingTwo[]').map(item => item.value);
});
In case, you are allowed to change html, here is a solution using hidden fields.
function updateChecks() {
$.each(['anythingOne', 'otherThingTwo'], function(i, field) {
var values = $('input[type=checkbox][data-for=' + field + ']:checked').map(function() {
return this.value;
}).get().join(',');
$('input[type=hidden][name=' + field + ']').val(values);
});
}
$(function() {
$('form').on('submit', function(e) {
updateChecks();
});
updateChecks();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form method="get">
<input type="hidden" name="anythingOne" value='' />
<input type="hidden" name="otherThingTwo" value='' />
<input type="checkbox" data-for="anythingOne" value='one' checked='' />
<input type="checkbox" data-for="anythingOne" value='two' />
<input type="checkbox" data-for="anythingOne" value='three' checked='' />
<input type="checkbox" data-for="otherThingTwo" value='Forty' />
<input type="checkbox" data-for="otherThingTwo" value='Fifty' checked='' />
</form>
You could get query string parameters using by serializeArray() method. Then use reduce() to group parameter values by name, and map() to get array of key-value pairs. Then it is possible to concatenate the pairs separated by & using join() method. For example the following snippet creates a target URL using actual value of the form action (current URL by default) and values of checked checkboxes:
$('form').submit(function() {
var queryString = $(this).serializeArray()
.reduce(function(transformed, current) {
var existing = transformed.find(function(param) {
return param.name === current.name;
});
if (existing)
existing.value += (',' + current.value);
else
transformed.push(current);
return transformed;
}, [])
.map(function(param) {
return param.name + '=' + param.value;
})
.join('&');
var action = $(this).prop('action');
var delimiter = (~action.indexOf('?')) ? '&' : '?';
$(this).prop('action', action + delimiter + queryString);
// Only for display result. Remove on real page.
var url = $(this).prop('action');
console.log(url);
return false;
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form method="GET">
<input type="checkbox" name="anythingOne" value='one'>
<input type="checkbox" name="anythingOne" value='two'>
<input type="checkbox" name="anythingOne" value='three'>
<input type="checkbox" name="otherThingTwo" value='Forty'>
<input type="checkbox" name="otherThingTwo" value='Fifty'>
<button type="submit">Show target URL</button>
</form>
The latest 3 lines are used only to prevent the form sending and display resulted URL.
Also it is possible to solve the question using only serialize() mathod and regular expressions, but it requires lookbehind assertion support in browsers.
You can collect all the checked boxer and join the different parts of the strings.This may not be the most neat or efficient solution, but it works. I used a button to trigger the concatenation. See my comments within the code.
$(document).ready(function(){
$("button").click(function(){
/* concatenate anythingOne form*/
//collect anythingOne input
var joined_serialized = []
var anythingOne = [];
$.each($("input[name='anythingOne[]']:checked"), function(){
anythingOne.push($(this).val());
});
//join otherThingTwo input
var anythingOne_serialized = "";
if(anythingOne.length > 0){ //only collect if checked
anythingOne_serialized = "anythingOne=" + anythingOne.join(",");
joined_serialized.push(anythingOne_serialized)
}
/* concatenate otherThingTwo form*/
//collect otherThingTwo input
var otherThingTwo = []
$.each($("input[name='otherThingTwo[]']:checked"), function(){
otherThingTwo.push($(this).val());
});
//join otherThingTwo input
var otherThingTwo_serialized = "";
if(otherThingTwo.length > 0){ //only collect if checked
otherThingTwo_serialized = "otherThingTwo=" + otherThingTwo.join(",");
joined_serialized.push(otherThingTwo_serialized)
}
/*join different form names*/
var joined_serialized = joined_serialized.join("&")
if(joined_serialized.length == 1){ //remove last & if only one form is checked
joined_serialized = joined_serialized.slice(0, -1)
}
/*concatenated forms with website*/
var result = "http://some-website.tld/action?"+joined_serialized
console.log(result) //E.g. when Two, Three and Forty are checked: http://some-website.tld/action?anythingOne=two,three&otherThingTwo=Forty
})
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form method="get">
<input type="checkbox" name="anythingOne[]" value='one'> <!-- checked -->
<input type="checkbox" name="anythingOne[]" value='two'>
<input type="checkbox" name="anythingOne[]" value='three'> <!-- checked -->
<input type="checkbox" name="otherThingTwo[]" value='Forty'>
<input type="checkbox" name="otherThingTwo[]" value='Fifty'> <!-- checked -->
</form>
<button>submit<button/>
I have a textbox that can be append.. and i want to get the values of each textbox
$('#entryData').append('<div><input type="text" id="quantity"></div>');
var total = $('#quantity').val();
console.log(total);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="entryData">
<input type="text" id="quantity">
<input type="button" value="+">
<input type="button" value="Total">
</div>
but I am only getting the first textbox value and not the other textbox
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.2/jquery.min.js"></script>
<div id='entryData' >
<input type="text" class='quantity'>
<input type="button" value="+" id='add'>
<input type="button" value="Total" id='total'>
</div>
<script>
$(document).ready(function(){
$('#add').click(function(){
$('#entryData').append('<div><input type="text" class="quantity"></div>');
});
$('#total').click(function(){
var total=0;
$('.quantity').each(function(index,quantity){
total=total+parseInt($(this).val());
});
alert(total);
});
});
</script>
I expect this is what you are trying to do?
Or make it like this:
<div id='entryData' >
<input type="number" class='quantity'>
<input type="button" value="+" id='add'>
<input type="button" value="Total" id='total'>
</div>
If you expect numbers - make the field number.
//this should come from helper method file/lib - for reusability
const sum = (accumulator, currentValue) => accumulator + currentValue;
const mapToInt = (idx,element) => { if (element.value !== "") { return parseInt(element.value, 10); } }
$(document).ready(() =>{
$('#add').click( () => {
$('#entryData').append('<div><input type="number" class="quantity" /></div>');
});
$('#total').click( () => {
let total = $(".quantity").map(mapToInt).get().reduce(sum);
console.log ( total );
});
});
Edit: sum (aggregation func) and mapToInt can be reused if you consider having more functional approach.
I have a checkboxs 3-4 of them, when the user checks the checkbox I want to add the value of the checkbox to the array, if they uncheck the box I want to remove the item from the array, this is what I got so far:
$('ul.dropdown-menu input[type=checkbox]').each(function () {
$(this).change(function () {
if ($(this).attr("id") == 'price') {
if (this.checked) {
priceArray.push($(this).val());
}
else {
priceArray = jQuery.grep(priceArray, function (value) {
return value != $(this).val();
});
}
}
});
});
Adding the value to the array works perfectly, however removing items results in this error:
Cannot read property 'toLowerCase' of undefined
on this line:
return value != $(this).val();
Run the code snippet and check
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script>
var priceArray=[];
$(document).ready(function(){
$('input[type=checkbox]').each(function () {
$(this).change(function () {
if (this.checked) {
priceArray.push($(this).val());
$("#displayarray").html("array=[" + priceArray+"]");
}
else {
var index = priceArray.indexOf($(this).val());
if (index > -1) {
priceArray.splice(index, 1);
}
$("#displayarray").html("array=[" + priceArray+"]");
}
});
});
});
</script>
<input type="checkbox" value="box1"/>box1
<input type="checkbox" value="box2"/>box2
<input type="checkbox" value="box3"/>box3
<input type="checkbox" value="box4"/>box4
<br/>
<div id="displayarray"></div>
Replace
priceArray = jQuery.grep(priceArray, function (value) {
return value != $(this).val();
});
By
val = $(this).val();
priceArray = jQuery.grep(priceArray, function (value) {
return value != val;
});
Don't forget the scope where your are in the callback function.
You can try using filter instead of $.grep:
var values = [];
$("input").on("change", function()
{
var $this = $(this);
if ($this.is(":checked"))
{
values.push($this.val());
}
else
{
values = values.filter(x => x != $this.val());
}
console.log(values);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="checkbox" value="1" />
<input type="checkbox" value="2" />
<input type="checkbox" value="3" />
<input type="checkbox" value="4" />
<input type="checkbox" value="5" />
<input type="checkbox" value="6" />
<input type="checkbox" value="7" />
filter() is a native function, I prefer using built-in function rather than 3rd party's, IMO. Also, avoid binding events within loops like this:
$('ul.dropdown-menu input[type=checkbox]').each(function () {
$(this).change(function () {
Use this method:
$('ul.dropdown-menu').on('change', 'input[type=checkbox]', function() { ...
This will work even if checkbox is dynamically added.
You could do this very cleanly with a functional style
<div class="checkboxes">
<input type="checkbox" value="1" />
<input type="checkbox" value="2" />
</div>
And
(function() {
$(".checkboxes input[type=checkbox]").on("click", function() {
var x = $(".checkboxes input[type=checkbox]:checked").map(function(a,b) {
return parseFloat(b.value);
}).toArray();
console.log(x)
});
})();
I had a similar situation and I was able to overcome it in the following way :
My jQuery :
$(document).ready(function(){
$("#dataFilterForm").on("input", function() {
var values = '';
var boxes = $('input[name=vehicle]:checked');
boxes.each(function(b){
values = values + boxes[b].id + ', ';
});
$('#filterResult').text(values.substring(0, values.length-2));
});
});
My HTML :
<form id="dataFilterForm">
<input type="checkbox" id="Filter1" name="vehicle" value="Bike">
<label for="Filter1">Filter1</label><br>
<input type="checkbox" id="Filter2" name="vehicle" value="Car">
<label for="Filter2">Filter2</label><br>
<input type="checkbox" id="Filter3" name="vehicle" value="Boat">
<label for="Filter3">Filter3</label><br>
</form>
<p>Result : </p>
<p id="filterResult"></p>
Here is my HTML
<script type="text/javascript" src="./The Desktop Calculator_files/calc.js"></script>
<style type="text/css"></style>
</head>
<body onLoad="checkBrowser()">
<form id="calcForm">
<div id="calc">
<input type='hidden' id='param1' value='0' />
<input type='hidden' id='operator' value='' />
<div id="display">
<input type="text" name="disp" id="disp" class="disp" size="36" value="0">
</div>
<div id="buttons">
<div class="row">
<input type="button" value="7" onclick="isNum();appendMe(this.value)">
<input type="button" value="8" onclick="isNum();appendMe(this.value)">
<input type="button" value="9" onclick="isNum();appendMe(this.value)">
<input type="button" value="/" onClick="isNum();setOp(this.value)">
<input type="button" value="CE">
</div>
<div class="row">
<input type="button" value="4" onclick="isNum();appendMe(this.value)">
<input type="button" value="5" onclick="isNum();appendMe(this.value)">
<input type="button" value="6" onclick="isNum();appendMe(this.value)">
<input type="button" value="*" onClick="isNum();setOp(this.value)">
<input type="button" value="C" onclick="clearAll()">
</div>
<div class="row">
<input type="button" value="1" onclick="isNum();appendMe(this.value)">
<input type="button" value="2" onclick="isNum();appendMe(this.value)">
<input type="button" value="3" onclick="isNum();appendMe(this.value)">
<input type="button" value="-" onClick="isNum();setOp(this.value)">
<input type="button" value="M" onClick="isNum();set_getMem()">
</div>
<div class="row">
<input type="button" value="0" onclick="isNum();appendMe(this.value)">
<input type="button" value="+/-" onclick="isNum();plusMinus()">
<input type="button" value="." onclick="isNum();appendMe(this.value)">
<input type="button" value="+" onClick="isNum();setOp(this.value)">
<input type="button" value="=" onClick="isNum();calcMe()">
</div>
</div>
<div id='warning'>Your Browser Can't Handle The Truth!</div>
</div>
</form>
</body></html>
Here is my JavaScript
function appendMe(val)
{
//alert(val);
//document.getElementById("disp").value+=val;
//alert(val);
if(document.getElementById("disp").value=='0')
{
document.getElementById("disp").value=val;
}
else if(val=='.' && document.getElementById("disp").value.indexOf('.')>-1) //do nothing, because we already have a decimal point
{
}
else //in any other case, we just append
{
document.getElementById("disp").value+=val;
}
}
function clearAll()
{
//alert(val);
document.getElementById("disp").value=0;
}
function checkBrowser()
{
alert("checking");
document.getElementById("warning").style.display="none";
}
function plusMinus()
{
document.getElementById("disp").value=(document.getElementById("disp").value*-1);
}
function setOp(val)
{
//first, set aside the initial value as entered
document.getElementById("param1").value=document.getElementById("disp").value;
//next, clear out that first number entered
document.getElementById("disp").value=0;
//finally, store the operation
document.getElementById("operator").value=val;
}
function calcMe()
{
var param1 = document.getElementById("param1").value;
var operator = document.getElementById("operator").value;
var param2 = document.getElementById("disp").value;
document.getElementById("disp").value = eval(param1+operator+param2);
}
function isNum()
{
//start as true
var isN = true;
if(isNaN(document.getElementById("disp").value))
{
isN=false;
alert("Non-numeric Data!");
}
return isN;
}
function set_getMem()
{
var memvalue;
//{
//isNum()
//}
if(memvalue == null ) //nothing in there, so set it
{
memvalue = document.getElementById("disp").value;
}
else //something in there, so display it
{
document.getElementById("disp").value = memvalue;
}
}
The part I am having problems with is getting the M button to function properly. What I want to happen is that I can click M and it will save whatever is in the display except when there is already a number stored I want it to display that number.
Currently I click the M button and it doesn't appear to save a number or display a number.
Edited: Based on feedback I got the Memory function to work but now I need a function that can clear the value of the global variable.
function clear_All()
{
var memvalue=0;
document.getElementById("disp").value=0;
var param1=0;
var param2=0;
}
When I put the memvalue to 0 in the function it doesnt clear it from memvalue. When I put it outside the function it just breaks the storing capabilities of the memvalue.
Here might be the problem:
function set_getMem()
{
var memvalue;
You define memvalue as a local variable inside set_memGet(), therefore this variable is gone once the function returns.
Define this variable out of the function.