Javascript replace method not functioning in checkbox if/else toggle - javascript

I have a bit of Javascript I'm playing with, which is called by a number of checkboxes and will ideally perform an action (adding and removing &attributeValue=attribID to the URL cumulatively) upon the checkbox being checked/unchecked.
Here's the Javascript:
var filterBaseURL = <?="\"".$url."\""?>; /*This is just copying a php variable that contains the base URL defined earlier - all of this works fine*/
var filterFullURL = filterBaseURL;
function filterToggle(attribID)
{
var elementII = document.getElementById(attribID);
if(elementII.checked){
filterFullURL = filterFullURL+"&attributeValue="+attribID;
}
else {
filterFullURL.replace("&attributeValue="+attribID, "");
alert(filterFullURL);
}
}
So what I'm doing here is attempting to on check of a checkbox add that checkbox's attributeValue to the URL, and on uncheck of a checkbox, remove that checkbox's attributeValue from the URL. I am using the filterFullURL = filterFullURL+"..." because there are multiple checkboxes and I want all their attributeValues to cumulatively be added to the URL.
All of this is working fine - the only thing that isn't working fine is the else statement action -
filterFullURL.replace("&attributeValue="+attribID, "");
Here are some example checkboxes:
<input type="checkbox" onclick="filterToggle('price_range_0_20')" name="Price_Range" value="Below_$20" id="price_range_0_20" /> Below $20
<input type="checkbox" onclick="filterToggle('price_range_20_40')" name="Price_Range" value="$20_-_$40" id="price_range_20_40" /> $20 - $40
<input type="checkbox" onclick="filterToggle('price_range_40_70')" name="Price_Range" value="$40_-_$70" id="price_range_40_70" /> $40 - $70
So to recap - I can add the attributeValues of all the checkboxes together, but I can't delete any of them. Any help here? Thanks!

Do you not need to save the output of filterFullURL.replace like filterFullURL = filterFullURL.replace("&attributeValue="+attribID, "")?

There was also an alert missing from the if statement - not sure if that's intentional, but this should operate well for you:
var filterBaseURL = <?="\"".$url."\""?>; /*This is just copying a php variable that contains the base URL defined earlier - all of this works fine*/
var filterFullURL = filterBaseURL;
function filterToggle(attribID)
{
var elementII = document.getElementById(attribID);
if(elementII.checked){
filterFullURL = filterFullURL+"&attributeValue="+attribID;
alert(filterFullURL);
}
else {
filterFullURL = filterFullURL.replace("&attributeValue="+attribID, "");
alert(filterFullURL);
}
}

Related

How do I retrieve values from checkboxes in JavaScript, using onchange to trigger a function?

I'm a High School student who takes a programming course (JavaScript) at school. We just had a test (which I miserably failed), but we are allowed to try again.
I have a couple of checkboxes. They all have an onchange which triggers a function later. I want to retrieve their values when I click on the checkboxes.
I've browsed around here a bit and seen something called jQuery. I have no idea what that is, so I would highly appreciate to get my help in pure JavaScript.
Okay, here is what I have of code. Note: Some variables and such are in Norwegian. I don't think it should be a problem, since I show the references to all.
My inputs (checkboxes):
<input type="checkbox" class="tur" value="0" onchange="funcSjekkBoks(this)">
<input type="checkbox" class="tur" value="1" onchange="funcSjekkBoks(this)">
<input type="checkbox" class="tur" value="2" onchange="funcSjekkBoks(this)">
<input type="checkbox" class="tur" value="3" onchange="funcSjekkBoks(this)">
<input type="checkbox" class="tur" value="4" onchange="funcSjekkBoks(this)">
I only need their value to be numbers, since I will use those in reference to an array list I have later.
Here is my function:
var inputTur = document.getElementsByClassName("tur");
console.log(inputTur);
function funcSjekkBoks(checkboxEl) {
var resultatListe = [];
if (checkboxEl.checked) {
resultatListe.push(inputTur.value);
console.log(resultatListe);
}
else {
console.log("usant")
}
}
What I would like to happen (if all checkboxes are checked from top to bottom):
resultatListe = [0, 1, 2, 3, 4]
When I uncheck a checkbox, it's value will be removed from the array.
Here is what currently happens:
When I check a checkbox I get [undefined] in my console, when I uncheck a checkbox I get usant (although that is the expected response, I haven't worked with the else part of my if-sentence yet.)
Below code will work for you:
var resultatListe = [];
function funcSjekkBoks(checkboxEl) {
var value = parseInt(checkboxEl.value);
if (checkboxEl.checked) {
resultatListe.push(value);
console.log(resultatListe);
}
else {
console.log("usant");
var indexToRemove = resultatListe.indexOf(value);
resultatListe.splice(indexToRemove,1);
}
}
You need to keep the array resultatListe outside the function other it will be initialized to empty everytime a checkbox is checked/un-checked, triggering the onchange handler. You were getting undefined as you were accessing 'value' property on HTMLCollection object which does not contain that property. Read more about it on MDN
var inputTur = document.getElementsByClassName("tur");
var resultatListe = [];
console.log(inputTur);
function funcSjekkBoks(checkboxEl) {
if (checkboxEl.checked) {
resultatListe.push(parseInt(checkboxEl.value));
}
else {
resultatListe = resultatListe.filter(d => d != checkboxEl.value)
}
console.log(resultatListe);
}
There were 2 mistakes in your logic:
1) You need to define resultatListe outside the function so that it won't get initialized to an empty array everytime
2) In you code resultatListe.push(inputTur.value); inputTur is the HTMLCollection of checkboxes whereas you need the single checkbox.
For the else logic, if the value of each checkbox is going to be unique you can use array.prototype.filter method to filter out the value of checkbox from resultatListe

Toggling a group of checkboxes from a master checkbox

I have the following JS which is actually working and checks all my boxes if the one of the top is checked (currently works) therefore I am unable to UNCHECK them by repeating the same process (unchecking the first box is not uncheckable)
I have the following code which actually call my function each time the checkbox is unchecked or checked:
function refresh_checkbox_list(){
// document.getElementById('gdr_select_users').setAttribute("checked");
(function() {
var aa = document.querySelectorAll("input[type=checkbox]");
for (var i = 0; i < aa.length; i++){
aa[i].checked = true;
}
})()
}
<input type="checkbox" name="gdr_select_all_users" id="gdr_select_all_users" onchange="refresh_checkbox_list()">
<input type="checkbox" name="gdr_select_users" id="gdr_select_users">
Just to say: I am a truly noob of JavaScript, I know how I would process it in PHP so it does check and uncheck, but I don't know how does "if" statements work in JS, this is my actual problem..
I was thinking about an if statement that checks if my 1st box is checked then check all others boxes, then another statement which do the exact reverse. Right?
I must admit that I have also found that JS on this website (an user which had a similar case)
Instead of using true use the checked state of #gdr_select_all_users.
Also need to exclude #gdr_select_all_users from the loop. Can use not() in the query selector or better yet apply a common class to the user checkboxes
function refresh_checkbox_list(){
// get checked state of the "check all" box
let allChecked = document.getElementById('gdr_select_all_users').checked;
(function() {
var aa = document.querySelectorAll("input[type=checkbox]:not(#gdr_select_all_users)");
for (var i = 0; i < aa.length; i++){
// set other checkboxes to same state as the "check all"
aa[i].checked = allChecked;
}
})()
}
Check all:<input type="checkbox" name="gdr_select_all_users" id="gdr_select_all_users" onchange="refresh_checkbox_list()">
<br>
User 1<input type="checkbox" name="gdr_select_users_1" >
<br>
User 2<input type="checkbox" name="gdr_select_users_2" >

Javascript onchange checkbox cancel

My first question here and really hope to learn a lot. I'm actually not the technical guy at my startup but cause of the lack of it trying to do things by myself :-)
I made an onchange event for my module order system. When i click on the checkbox, the selected module appears in the summary. This works. But when i deselect the checkbox, i want the module to dissapear from the summary. That doesn't work now. What do i have to change in the JS to do that?
The checkbox
<input type="checkbox" class="custom-control-input"
onchange="modulecontractsSelect(this, event)">
The summary
<p id="module-contracts-summary"> </p>
<p id="module-contracts-summary-price"> </p>
The Javascript
function modulecontractsSelect() {
document.getElementById("module-contracts-summary").innerHTML = "Module contractbeheer"
document.getElementById("module-contracts-summary-price").innerHTML = "€5 / mnd";
}
Thanks in advance!
First, change your checkbox's onchange event to pass only itlsef (as this) as a parameter. You don't really need to pass the event as a parameter:
<input type="checkbox" class="custom-control-input" onchange="modulecontractsSelect(this);">
Then, change your modulecontractsSelect function to receive the checkbox (this) as a parameter (I highlighted it for you with an arrow below). If the checkbox is checked, set the innerHTML values. If it's not checked, set them to an empty string:
▼
function modulecontractsSelect(checkbox) {
if (checkbox.checked) {
document.getElementById("module-contracts-summary").innerHTML = "Module contractbeheer"
document.getElementById("module-contracts-summary-price").innerHTML = "€5 / mnd";
}
else {
document.getElementById("module-contracts-summary").innerHTML = "";
document.getElementById("module-contracts-summary-price").innerHTML = "";
}
}
Change your checkbox code to something like:
<input type="checkbox" class="custom-control-input" onchange="modulecontractsSelect(this.checked)">
Then change your modulecontractsSelect function to something like:
function modulecontractsSelect(is_checked) {
if( is_checked ) {
document.getElementById("module-contracts-summary").innerHTML = "Module contractbeheer"
document.getElementById("module-contracts-summary-price").innerHTML = "€5 / mnd";
} else {
document.getElementById("module-contracts-summary").innerHTML = "";
document.getElementById("module-contracts-summary-price").innerHTML = "";
}
}
Please note I haven't tested this code, but you should get the idea.

Sending Checkbox and Text Input Values to URL String with Javascript

I have a list of products, each individual product has a checkbox value with the products id e.g. "321". When the products checkbox is checked (can be more than 1 selected) i require the value to be collected. Each product will also have a input text field for defining the Qty e.g "23" and i also require this Qty value to be collected. The Qty text input should only be collected if the checkbox is checked and the qty text value is greater than 1. The plan is to collect all these objects, put them in to a loop and finally turn them in to a string where i can then display the results.
So far i have managed to collect the checkbox values and put these into a string but i'm not sure how to collect the additional text Qty input values without breaking it. My understanding is that document.getElementsByTagName('input') is capable of collecting both input types as its basically looking for input tags, so i just need to work out how to collect and loop through both the checkboxes and the text inputs.
It was suggested that i use 2 if statements to accomplish this but i'm new to learning javascript so i'm not entirely sure how to go about it. I did try adding the if statement directly below the first (like you would in php) but this just seemed to break it completely so i assume that is wrong.
Here is my working code so far that collects the checkbox values and puts them in a string. If you select the checkbox and press the button the values are returned as a string. Please note nothing is currently appended to qty= because i dont know how to collect and loop the text input (this is what i need help with).
How can i collect the additional qty input value and append this number to qty=
// function will loop through all input tags and create
// url string from checked checkboxes
function checkbox_test() {
var counter = 0, // counter for checked checkboxes
i = 0, // loop variable
url = '/urlcheckout/add?product=', // final url string
// get a collection of objects with the specified 'input' TAGNAME
input_obj = document.getElementsByTagName('input');
// loop through all collected objects
for (i = 0; i < input_obj.length; i++) {
// if input object is checkbox and checkbox is checked then ...
if (input_obj[i].type === 'checkbox' && input_obj[i].checked) {
// ... increase counter and concatenate checkbox value to the url string
counter++;
url = url + input_obj[i].value + '&qty=' + '|';
}
}
// display url string or message if there is no checked checkboxes
if (counter > 0) {
// remove first "&" from the generated url string
url = url.substr(1);
// display final url string
alert(url);
}
else {
alert('There is no checked checkbox');
}
}
<ul>
<li>
<form>
<input type="checkbox" id="checked-product" name="checked-product" value="311">Add To Cart
<div class="quantity">
<input type="text" name="qty" id="qty" maxlength="12" value="1" class="input-text qty"/>
</div>
</form>
</li>
<li>
<form>
<input type="checkbox" id="checked-product" name="checked-product" value="321">Add To Cart
<div class="quantity">
<input type="text" name="qty" id="qty" maxlength="12" value="10" class="input-text qty"/>
</div>
</form>
</li>
<li>
<form>
<input type="checkbox" id="checked-product" name="checked-product" value="98">Add To Cart
<div class="quantity">
<input type="text" name="qty" id="qty" maxlength="12" value="5" class="input-text qty"/>
</div>
</form>
</li>
</ul>
<button type="button" onclick="javascript:checkbox_test()">Add selected to cart</button>
My answer has two parts: Part 1 is a fairly direct answer to your question, and Part 2 is a recommendation for a better way to do this that's maybe more robust and reliable.
Part 1 - Fairly Direct Answer
Instead of a second if to check for the text inputs, you can use a switch, like so:
var boxWasChecked = false;
// loop through all collected objects
for (i = 0; i < input_obj.length; i++) {
// if input object is checkbox and checkbox is checked then ...
switch(input_obj[i].type) {
case 'checkbox':
if (input_obj[i].checked) {
// ... increase counter and concatenate checkbox value to the url string
counter++;
boxWasChecked = true;
url = url + input_obj[i].value + ',qty=';
} else {
boxWasChecked = false;
}
break;
case 'text':
if (boxWasChecked) {
url = url + input_obj[i].value + '|';
boxWasChecked = false;
}
break;
}
}
Here's a fiddle showing it working that way.
Note that I added variable boxWasChecked so you know whether a Qty textbox's corresponding checkbox has been checked.
Also, I wasn't sure exactly how you wanted the final query string formatted, so I set it up as one parameter named product whose value is a pipe- and comma-separated string that you can parse to extract the values. So the url will look like this:
urlcheckout/add?product=321,qty=10|98,qty=5
That seemed better than having a bunch of parameters with the same names, although you can tweak the string building code as you see fit, obviously.
Part 2 - Recommendation for Better Way
All of that isn't a great way to do this, though, as it's highly dependent on the element positions in the DOM, so adding elements or moving them around could break things. A more robust way would be to establish a definitive link between each checkbox and its corresponding Qty textbox--for example, adding an attribute like data-product-id to each Qty textbox and setting its value to the corresponding checkbox's value.
Here's a fiddle showing that more robust way.
You'll see in there that I used getElementsByName() rather than getElementsByTagName(), using the name attributes that you had already included on the inputs:
checkboxes = document.getElementsByName('checked-product'),
qtyBoxes = document.getElementsByName('qty'),
First, I gather the checkboxes and use an object to keep track of which ones have been checked:
var checkedBoxes = {};
// loop through the checkboxes and find the checked ones
for (i = 0; i < checkboxes.length; i++) {
if (checkboxes[i].checked) {
counter++;
checkedBoxes[checkboxes[i].value] = 1; // update later w/ real qty
}
}
Then I gather the Qty textboxes and, using the value of each one's data-product-id attribute (which I had to add to the markup), determine if its checkbox is checked:
// now get the entered Qtys for each checked box
for (i = 0; i < qtyBoxes.length; i++) {
pid = qtyBoxes[i].getAttribute('data-product-id');
if (checkedBoxes.hasOwnProperty(pid)) {
checkedBoxes[pid] = qtyBoxes[i].value;
}
}
Finally, I build the url using the checkedBoxes object:
// now build our url
Object.keys(checkedBoxes).forEach(function(k) {
url += [
k,
',qty=',
checkedBoxes[k],
'|'
].join('');
});
(Note that this way does not preserve the order of the items, though, so if your query string needs to list the items in the order in which they're displayed on the page, you'll need to use an array rather than an object.)
There are lots of ways to achieve what you're trying to do. Your original way will work, but hopefully this alternative way gives you an idea of how you might be able to achieve it more cleanly and reliably.
Check the below simplified version.
document.querySelector("#submitOrder").addEventListener('click', function(){
var checkStatus = document.querySelectorAll('#basket li'),
urls = [];
Array.prototype.forEach.call(checkStatus, function(item){
var details = item.childNodes,
urlTemplate = '/urlcheckout/add?product=',
url = urlTemplate += details[0].value + '&qty=' + details[1].value;
urls.push(url)
});
console.log(urls);
})
ul{ margin:0; padding:0}
<ul id="basket">
<li class="products"><input type="checkbox" value = "311" name="item"><input type="text"></li>
<li><input type="checkbox" value = "312" name="item"><input type="text"></li>
<li><input type="checkbox" value = "313" name="item"><input type="text"></li>
</ul>
<button id="submitOrder">Submit</button>

Unable to remove form elements while using element.parentNode.removeChild(element)

I have a form that will submit to a Google search appliance, forming a query string "q".
In the form I have radio buttons and a hidden element; the radio buttons contain options for sites to select; the hidden element contains multiple sites that will allow the user to select multiple site searches.
<input type="radio" id="site_search" name="as_sitesearch" value="www.mycompany.com" checked>Current site<br />
<input type="radio" id="site_search" name="as_sitesearch" value="archive.mycompany.com">Archive site<br />
<input type="radio" id="site_search" name="as_sitesearch" value="">Both sites<br />
<input type="hidden" id="as_oqOption" name="as_oq" value="www.mycompany.com archive.mycompany.com">
This is the Javascript I wrote that will remove the radio element or the hidden element exclusively (one of them can exist in the form submittal):
// IF THE USER CHECKED "BOTH SITES", YOU WILL HAVE TO WIPE OUT THE VALUE OF as_sitesearch TO ALLOW FOR PASSING OF as_oq FOR GOOGLE ENGINE
if (form.elements['as_sitesearch'][0].value.length == 0) {
var goodbyeElement = document.getElementById('site_search');
goodbyeElement.parentNode.removeChild(goodbyeElement);
} else {
var goodbyeElement = document.getElementById('as_oqOption');
goodbyeElement.parentNode.removeChild(goodbyeElement);
}
However, when the form is submitted, "q" winds up obtaining both radio and hidden elements no matter what radio option I click.
Not sure why this is happening as I followed the guides in the DOM tutorial sites I have read on how to remove a form element prior to submittal. Any ideas?
Thanks
Following code may help you:
(form.as_sitesearch[2].checked){
for(var k=0; k<form.as_sitesearch.length;k++){
form.as_sitesearch[k].parentNode.removeChild(form.as_sitesearch[k])
}
}
else{
var goodbyeElement = document.getElementById('as_oqOption');
goodbyeElement.parentNode.removeChild(goodbyeElement);
}
You should call it on form submit. here form is document.form[index];
Got it! Apparently form.elements will always fail because of the grouping, so don't use it..
// IF THE USER CHECKED "BOTH SITES", YOU WILL HAVE TO WIPE OUT THE VALUE OF as_sitesearch TO ALLOW FOR PASSING OF as_oq FOR GOOGLE ENGINE
if (document.getElementById('site_search3').checked) {
for (var i = 1; i <= 3; i++) {
eval('var goodbyeElement = document.getElementById("site_search' + i + '");');
goodbyeElement.parentNode.removeChild(goodbyeElement);
}
} else {
var goodbyeElement = document.getElementById('as_oqOption');
goodbyeElement.parentNode.removeChild(goodbyeElement);
}

Categories

Resources