Having trouble getting inside an .each function that finds checkboxes - javascript

I've used similar code earlier in the application and it works, but for some reason, I cannot get anything inside the .each function here to fire.
I have an application where you can check a membership checkbox to apply a 10% credit to the premium of a premise. The number of premises is dynamic, so when you check the membership box, the javascript creates a premise checkbox for each user-created premise on the page. No problem there.
But, I need to find the label for each premise that is checked under the membership box, and my code is failing. The alerts inside that .each do not fire. I've rewritten it to go Div by Div to reach those checkboxes, but I still cannot reach it.
HTML
<div class="form-check creditChecks">
<input class="form-check-input creditCheckInput" type="checkbox" value='4' id="Membership">
<label class="form-check-label" for="Membership">Association Membership</label>
<div class="creditPremiseSelect">
<div class="form-check">
<input class="form-check-input creditPremiseInput" type="checkbox" value='1' id="MembershipcreditPrem1">
<label class="form-check-label" for="MembershipcreditPrem1">Premise #1</label>
</div>
</div>
Javascript to append more premise checkboxes:
//Populate Credit/Debit Premise Selector
function loadSelectPrems(ele){
var firedInput = ele;
var inputID = ele.attr('id');
var thisDiv = firedInput.closest('.creditChecks');
var selector = thisDiv.find('.creditPremiseSelect');
//Empty selector
selector.empty();
//Find all Premises on Policy
$('.premiseList').find('.premise').each(function(index){
var premiseID = $(this).find('.premiseNum').text();
var premNum = index+1;
selector.append($(`
<div class='form-check'>
<input class='form-check-input creditPremiseInput' type='checkbox' value='`+premNum+`' id='`+inputID+`creditPrem`+premNum+`'>
<label class='form-check-label' for='`+inputID+`creditPrem`+premNum+`'>`+premiseID+`</label>
</div>
`))
});
}
JQuery that isn't working as expected:
if($('#Membership').is(':checked')){
doc.text(25, lineCount, 'Association Membership Credit 10% applied to:');
updateLine('s');
alert("Membership checked"); //This alert fires
$(this).closest('.creditChecks').find('.creditPremiseInput').each(function(){
alert("Looking at premises"); //This alert does not fire
if($(this).is(':checked')){
alert("Found checked premise");
var labeltxt = $(this).closest('.creditPremiseSelect').find('.form-check-label').text();
doc.text(30, lineCount, labeltxt);
updateLine('s');
}
});
updateLine('n');
}

I'm going to go out on a limb and say the error is on this line:
$(this).closest('.creditChecks').find('.creditPremiseInput').each...
It appears you are referencing $(this) as being $('#Membership'), but it isn't. Also, as you've assigned a singular ID $('#Membership'), I think you probably just need to access $('.creditChecks') directly in that line.
if ($('#Membership').is(':checked')) {
doc.text(25, lineCount, 'Association Membership Credit 10% applied to:');
updateLine('s');
alert("Membership checked"); //This alert fires
$('.creditChecks').find('.creditPremiseInput').each(function() {
alert("Looking at premises"); //This alert does not fire
if ($(this).is(':checked')) {
alert("Found checked premise");
var labeltxt = $(this).closest('.creditPremiseSelect').find('.form-check-label').text();
doc.text(30, lineCount, labeltxt);
updateLine('s');
}
});
updateLine('n');
}

Related

How to code a proper checkbox that saves changes after refreshing page

I’m trying to do a simple personal website with checkboxes implemented into it, I’ve never done anything to do with coding ever so I’m super confused on how to put it all together. So far I have a checkbox labeled as purchased, but after I check the box and refresh the page it’s like I never checked the box. I was reading that I need local storage implemented into the code for my changes to save even after refreshing the page. But I have no idea how it should be done and what exactly I need to type in, if anyone could leave what it’s supposed to look like that would be great, thank you genuinely! What I have so far:
<label class="form-control">
<input type="checkbox" name="purchased" />
Purchased
</label>
You can implement a persistent checkbox using local storage like this:
const cb = document.getElementById('checkbox');
//run every time the checkbox is set
cb.addEventListener('input', (e) => {
console.log('changed');
localStorage.setItem('purchased', e.target.checked);
});
//run once on page load, check if it is set in LS if yes then check it
const localPurchasedValue = localStorage.getItem('purchased');
if (localPurchasedValue === 'true') {
cb.checked = true;
}
<label class="form-control">
<input id="checkbox" type="checkbox" name="purchased" />
Purchased
</label>
Note this little preview will not work due to iframe restrictions on this site, but if you copy this into your own file and run with a dev server or some kind you can see it working.
"... but after I check the box and refresh the page it’s like I never checked the box..."
Hi, according comments is necessary to save into some type storage.
Look like this:
let boxes = document.getElementsByClassName('box').length;
function save() {
for(let i = 1; i <= boxes; i++){
var checkbox = document.getElementById(String(i));
localStorage.setItem("checkbox" + String(i), checkbox.checked);
}
}
//for loading
for(let i = 1; i <= boxes; i++){
if(localStorage.length > 0){
var checked = JSON.parse(localStorage.getItem("checkbox" + String(i)));
document.getElementById(String(i)).checked = checked;
}
}
window.addEventListener('change', save);
<input type="checkbox" id="1" class="box">checkbox1</input><br>
<input type="checkbox" id="2" class="box">checkbox2</input><br>
<input type="checkbox" id="3" class="box">checkbox3</input><br>
<input type="checkbox" id="4" class="box">checkbox4</input><br>
<input type="checkbox" id="5" class="box">checkbox5</input><br>
<input type="checkbox" id="6" class="box">checkbox6</input><br>

Bootstrap checkbox value passed correctly but not showed in the box

I have a frustrating issue since last week. I am using a bootstrap checkbox inside a modal that I want to prefill with either true or false depending on the user selection for that boolean field. Even though I can get the value correctly, I can not get the tick on the checkbox working.
modal.html
<div class="input-group">
<label class="form-check-label" for="active">
Active
<span>
<input class="form-check-input" name="activeCheckbox" type="checkbox" id="active" onclick="handleCheckboxClick()">
</span>
</label>
</div>
handleCheckboxClick.js
$('.form-check-input').change(function () {
var check = $(this).prop('checked');
if(check === true) {
$('#active').prop('checked', true);
} else {
$('#active').prop('checked', false);
}
});
jQuery that prefills the modal
$('#modal-edit-config').on('shown.bs.modal', function() {
$('#classname').focus();
var selectedId = confId;
$.ajax({
url: 'getConfig',
data: {configId: selectedId},
success: function(data){
var config = data;
if(config != null) {
$('#id').val(config.id);
$('#className').val(config.className);
console.log(config.active);
config.active ? $('#active').attr('checked', true).change() : $('#active').attr('checked', false).change();
}
},
error: function(result) {
alert("Error getting the audit configId");
}
});
});
I tried both with prop() and attr() but, it doesn't work.
The js function works perfectly fine but when the modal pops up the prefilled value of the checkbox even though it is correct, it is not corresponding to the tick or untick in the UI.
Checkboxes change their visual "checked" status based on the existence of the attribute name itself, not its setting -- according to dev.mozilla.org: checked, Boolean; if present, the checkbox is toggled on by default
<p>Checkbox checked="true"</p>
<input type="checkbox" checked="true">
<p>Checkbox checked="false"</p>
<input type="checkbox" checked="false">
<p>Checkbox (no checked attr)</p>
<input type="checkbox">
You should update your checkbox generation JS to leave out the attribute itself: $('#active').attr('checked', false) will show a checked checkbox.
For regular checkboxes
You should use the proper HTML semantics with .form-check wrapper as described in Forms > Checkboxes & Radios:
<div class="form-check">
<input class="form-check-input" type="checkbox" id="gridCheck">
<label class="form-check-label" for="gridCheck">
Check me out
</label>
</div>
As such, our <input>'s and <label>'s are sibling elements as opposed to an <input> within a <label>. This is slightly more verbose as you must specify id and for attributes to relate the <input> and <label>.
For custom checkboxes
To point you in the right direction you should read the section Custom forms > checkboxes.
Please note a label and input pairing wrapped in a div comes with a specific order.
The input goes first and is not wrapped by the label.
The reason is simple once you realize an input is an HTML element and they do not support "pseudo elements" :before and :after. These "pseudo class selectors" are required to introduce custom design on checkboxes/radios and so on.
Trivial and simplified CSS selector:
input[type="checkbox"]:checked ~ label:before { content: '✓' }
Otherwise there's no direct solution to reverse this selector like label input[type="checkbox"]:checked.
With that said, HTML is capable of handling your states by itself. No need for the handleCheckboxClick.js. You can then use .prop() to select by default in the ajax handler.
If you need to change the order visualy, you can introduce something like .custom-checkbox-reverse.
.custom-checkbox-reverse .custom-control-label::before,
.custom-checkbox-reverse .custom-control-label::after {
left: auto;
right: -1.5rem;
}
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.css" rel="stylesheet"/>
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="customCheck1">
<label class="custom-control-label" for="customCheck1">Label after the checkbox</label>
</div>
<div class="custom-control custom-checkbox custom-checkbox-reverse">
<input type="checkbox" class="custom-control-input" id="customCheck2">
<label class="custom-control-label" for="customCheck2">Label before the checkbox</label>
</div>
FIDDLE to play around and enhance the padding for example as well.
A revision on the JavaScript part:
// what to expect here?
// should be sufficient to check if it has an id
// perhaps something else we can check? like config.status? Only you know at this point
// in fact it should always return the object or enter the error function
var checkboxState = false; // default
if(config && config.hasOwnProperty('id')) {
$('#id').val(config.id);
$('#className').val(config.className);
console.log(config.active); // expecting a boolean value
checkboxState = !!config.active; // double bang operator to make sure it's a boolean value
}
$('#active').prop('checked', checkboxState);

Jquery how to use variable as identifier for .change() function?

right now I am a beginner in Javascript/Jquery.
I want to create a dynamic code, so that it will work when there comes some new features to the website without need to edit code.
Now i just read in some posts how to use a variable as identifier for id, but it is not working for me. So below is an example:
var category;
$('#mainCategory').change(function (event) {
checkboxID = event.target.id;
category="category"+checkboxID;
...some code...
});
$("#"+category).change(function (event) {
$('#category'+checkboxID+' :input').attr('class','' );
console.log("var: "+category);
});
So the function mainCategory always runs before the other one and category got written correct in the 2nd function, when i am using the whole expression instead of using a variable.
I hope you can help me.
the part of html code:
<form method="post" action="../php/saveTraining.php">
<section id="mainCategory" class="hidden">
<label><input type="checkbox" id="Krafttraining">Krafttraining</label>
<label><input type="checkbox" id="Joggen">Joggen</label>
</section>
<section id="categoryKrafttraining" class="hidden">
<label><input type="checkbox">Kurzhantel</label>
<label><input type="checkbox">Bankdrücken</label>
<label class="hidden"><input type="number" id="saetze">Sätze</label>
<label class="hidden"><input type="number" id="wiederholungen">Wiederholungen</label>
</section>
<input type="hidden" id="saveTraining" name="sent" value="save" class="hidden"/>
</form>
So what actually happens is that when checking a checkbox of mainCategory the checkboxes of the second section appearing.
But when I check a checkbox of the second section nothing happens.
I thought I had the solution before but I see I was wrong. I believe this should work, where you re-add the listener as the value for the var category change:
var category;
$('#mainCategory input[type="checkbox"]').change(function (event) {
checkboxID = event.target.id;
category="category"+checkboxID;
$('#' + category).find('input[type="checkbox"]').off("change").on("change", function (event) {
$('#category'+checkboxID+' :input').attr('class','' );
console.log("var: "+category);
});
});
You need to re-add the listener because new elements will be targeted as var category changes.

Checkbox always cheked if property specified?

This is driving me completely nuts. I can't figure out how to check/uncheck a checkbox through JavaScript.
I have the following in my HTML file:
<div class="form-group">
<label class="col-sm-3 control-label"></label>
<div class="col-sm-9">
<div class="checkbox">
<input id="hardhat" type="checkbox" name="hardhat" checked="false" class="flat"/> Does the employee need his own hardhat?
</div>
</div>
</div>
Which translates to this in Jade:
.form-group
label.col-sm-3.control-label
.col-sm-9
.checkbox
input#hardhat(type='checkbox', name='hardhat', class='flat', checked='false')
| Does the employee need his own hardhat?
Having the checked property in HTML will ALWAYS open the window with the checkbox checked. The only way to uncheck the checkbox is to remove the checked property. What am I missing?
Because of this, nothing I do in JavaScript to check/uncheck the checkbox works :(. I was trying this:
var $modal = $('#editJob');
$modal.find('input#hardhat')['checked']=true;
Any help would be greatly appreciated!
EDIT:
function showJobInfo(event) {
document.getElementById('editJob').style.display = "block";
document.getElementById('editJob').style.visibility = "visible";
// Prevent Link from Firing
event.preventDefault();
// Retrieve job title from link rel attribute
var thisJobTitle = $(this).attr('rel');
// Get Index of object based on id value
var arrayPosition = userJoblistData.map(function(arrayItem) { return arrayItem.title; }).indexOf(thisJobTitle);
// Get our Job Object
var thisJobObject = userJoblistData[arrayPosition];
// Populate the edit job popup window
var $modal = $('#editJob');
$modal.find('input#jobTitle').val(thisJobObject.title);
$modal.find('input#payRate').val(thisJobObject.payrate);
$modal.find('input#startDate').val(thisJobObject.durationstart);
$modal.find('input#endDate').val(thisJobObject.durationend);
$modal.find('input#workingHours').val(thisJobObject.workinghrs);
$modal.find('input#location').val(thisJobObject.location);
$('#hardhat').prop('checked', false);
}
I do not understand what is the problem. If you want always checked, add checked="true" html attribute.
https://jsfiddle.net/yw3obrrt/
<input id="hardhat" type="checkbox" name="hardhat" checked="true" class="flat"/>
Check in jade that checked='true'
input#hardhat(type='checkbox', name='hardhat', class='flat', checked='true')
| Does the employee need his own hardhat?
For test, not use F5 because remember your selection.
If not works.. try with jquery and use
$(document).ready(function (){
$("#hardhat").attr("checked",true);
});
https://jsfiddle.net/yw3obrrt/1/
In your example!!
$('#hardhat').prop('checked', false);
This line, unchecked checkbox!
Change to
$('#hardhat').attr('checked', true); // attr or prop
or comment this and add checked="true" in the html input!

Condtionally disable button by Radio and Checkbox

I would like to conditionally disable a button based on a radio and checkbox combination. The radio will have two options, the first is checked by default. If the user selects the second option then I would like to disable a button until at least one checkbox has been checked.
I have searched at length on CodePen and Stack Overflow but cannot find a solution that works with my conditionals. The results I did find were close but I couldn't adapt them to my needs as I am a Javascript novice.
I am using JQuery, if that helps.
If needed:
http://codepen.io/traceofwind/pen/EVNxZj
<form>
<div id="input-option1">First option: (required)
<input type="radio" name="required" id="required" value="1" checked="checked">Yes
<input type="radio" name="required" id="required" value="2">No
<div>
<div id="input-option2">Optionals:
<input type="checkbox" name="optionals" id="optionals" value="2a">Optional 1
<input type="checkbox" name="optionals" id="optionals" value="2b">Optional 2
<div>
<div id="input-option3">Extras:
<input type="checkbox" name="extra" id="extra" value="3">Extra 1
<div>
<button type="button" id="btn">Add to Cart</button>
</form>
(Please excuse the code, it is in short hand for example!)
The form element IDs are somewhat fixed. The IDs are generated by OpenCart so I believe the naming convention is set by group, rather than unique. I cannot use IDs such as radio_ID_1 and radio_ID_2, for example; this is an OpenCart framework facet and not a personal choice.
Finally, in pseudo code I am hoping someone can suggest a JQuery / javascript solution along the lines of:
if radio = '2' then
if checkboxes = unchecked then
btn = disabled
else
btn = enabled
end if
end if
Here is a quick solution and I hope that's what you were after.
$(function() {
var $form = $("#form1");
var $btn = $form.find("#btn");
var $radios = $form.find(":radio");
var $checks = $form.find(":checkbox[name='optionals']");
$radios.add($checks).on("change", function() {
var radioVal = $radios.filter(":checked").val();
$btn.prop("disabled", true);
if (radioVal == 2) {
$btn.prop("disabled", !$checks.filter(":checked").length >= 1);
} else {
$btn.prop("disabled", !radioVal);
}
});
});
Here is a demo with the above + your HTML.
Note: Remove all the IDs except the form ID, button ID (since they're used in the demo) as you can't have duplicate IDs in an HTML document. an ID is meant to identify a unique piece of content. If the idea is to style those elements, then use classes.
If you foresee a lot of JavaScript development in your future, then I would highly recommend the JavaScript courses made available by Udacity. Although the full course content is only available for a fee, the most important part of the course materials--the videos and integrated questions--are free.
However, if you don't plan to do a lot of JavaScript development in the future and just need a quick solution so you can move on, here's how to accomplish what you are trying to accomplish:
$(document).ready(function(){
$('form').on('click', 'input[type="radio"]', function(){
conditionallyToggleButton();
});
$('form').on('click', 'input[type="checkbox"]', function(){
conditionallyToggleButton();
});
});
function conditionallyToggleButton()
{
if (shouldDisableButton())
{
disableButton();
}
else
{
enableButton();
}
}
function shouldDisableButton()
{
if ($('div#input-option1 input:checked').val() == 2
&& !$('form input[type="checkbox"]:checked').length)
{
return true;
}
return false;
}
function disableButton()
{
$('button').prop('disabled', true);
}
function enableButton()
{
$('button').prop('disabled', false);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form>
<div id="input-option1">First option: (required)
<input type="radio" name="required" id="required" value="1" checked="checked">Yes
<input type="radio" name="required" id="required" value="2">No
<div>
<div id="input-option2">Optionals:
<input type="checkbox" name="optionals" id="optionals" value="2a">Optional 1
<input type="checkbox" name="optionals" id="optionals" value="2b">Optional 2
<div>
<div id="input-option3">Extras:
<input type="checkbox" name="extra" id="extra" value="3">Extra 1
<div>
<button type="button" id="btn">Add to Cart</button>
</form>
Note that the JavaScript code above is a quick-and-dirty solution. To do it right, you would probably want to create a JavaScript class representing the add to cart form that manages the behavior of the form elements and which caches the jQuery-wrapped form elements in properties.

Categories