Condtionally disable button by Radio and Checkbox - javascript

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.

Related

Issue with script being triggered by wrong checkbox

I'm trying to enable/disable a place order button based on whether or not the terms acceptance checkbox has been checked. The script I have been working on works fine for that, but it's also triggered when a different checkbox (with a different id) is checked. Although the other checkbox enables the button, it doesn't disable it again when un-checking it. So I think it's something wrong with the 'on change' part.
I've tried everything I could find and can't make it work only when the checkbox with id 'terms' is checked:
<script>
jQuery(window).on('load',function(){
setTimeout(function(){
jQuery('#payment #place_order').attr("disabled","disabled");
},1000);
});
jQuery(document).on('change','#terms',function() {
var ischecked = document.getElementById("terms");
if(ischecked.checked == false){
jQuery('#payment #place_order').attr("disabled","disabled");
}else{
jQuery('#payment #place_order').removeAttr("disabled");
}
});
</script>
The terms checkbox is as below:
<input type="checkbox" class="woocommerce-form__input woocommerce-form__input-checkbox input-checkbox ios-switch" name="terms" id="terms">
And the other one that triggers it is as below:
<input class="woocommerce-form__input woocommerce-form__input-checkbox input-checkbox" id="createaccount" type="checkbox" name="createaccount" value="1">
Your code is not clear.
Assuming the place order has the id of #place_order, there is no need to add the container
jQuery(function() { // on page load
jQuery('#place_order').attr("disabled", "disabled");
jQuery(document).on("change", "#terms", function() { // assuming the terms is dynamically inserted
if (!this.checked) {
jQuery('#place_order').attr("disabled", "disabled");
} else {
jQuery('#place_order').removeAttr("disabled");
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Terms <input type="checkbox" class="woocommerce-form__input woocommerce-form__input-checkbox input-checkbox ios-switch" name="terms" id="terms"><br/>
<button id="place_order">Place order</button>
<hr/>
Create account <input class="woocommerce-form__input woocommerce-form__input-checkbox input-checkbox" id="createaccount" type="checkbox" name="createaccount" value="1">

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.

changing checkboxes into animatable buttons with javascript

I'm building a practice app. I've got a working filter system using checkboxes and radio buttons. I need a way to replace them with buttons that I can animate. For my plunk I'll use buttons with text, but then offline I'll replace them with images. Here's a sample of my work:
HTML
<h2>Type</h2>
<label class="btns">
<input type="radio" name="vegMeat" value="" ng-model="type.searchVeg" ng-checked="true">All
</label>
<label class="btns">
<input type="radio" name="vegMeat" value="veg" ng-model="type.searchVeg">Vegetarian
</label>
<label class="btns">
<input type="radio" name="vegMeat" value="meat" ng-model="type.searchVeg">Meat
</label>
</div>
JavaScript
.filter('searchType', function() {
return function(foods, search) {
var filtered = [];
if (!search) {
return foods;
}
angular.forEach(foods, function(food) {
if (angular.lowercase(food.type).indexOf(angular.lowercase(search)) != -1) {
filtered.push(food);
}
});
return filtered;
};
sample plunk
https://plnkr.co/edit/xk1VcCfAsVknyahux4fw?p=preview
PS I know mine is not the most efficient way of doing it, but I'm still a beginner. The buttons are my main concern but if anyone does have suggestions on how to improve the code itself, please feel free to provide an example. This is just a sample of my plunk. My full one has another 5 sets of buttons and many more recipes.

copy label text to input

I have tried several ways to achieve this, but somehow nothing works for this.
How can I copy the "label text" of respective Radio Button, which is selected by user into the input field (Result Box) in real time?
HTML -
<ul class="gfield_radio" id="input_4_4">
Radio Buttons:
<br />
<li class="gchoice_4_0">
<input name="input_4" type="radio" value="2" id="choice_4_0" class="radio_s" tabindex="4">
<label for="choice_4_0">Hi</label>
</li>
<li class="gchoice_4_1">
<input name="input_4" type="radio" value="4" id="choice_4_1" class="radio_s" tabindex="5">
<label for="choice_4_1">Hello</label>
</li>
<li class="gchoice_4_2">
<input name="input_4" type="radio" value="3" id="choice_4_2" class="radio_s" tabindex="6">
<label for="choice_4_2">Aloha</label>
</li>
</ul>
<br />
<div class="ginput_container">
Result Box:
<br />
<input name="input_3" id="input_4_3" type="text" value="" class="medium" tabindex="3">
</div>
My attempts:
$('input').change(function() {
if (this.checked) {
var response = $('label[for="' + this.id + '"]').html();
alert(response);
}
// also this:
// if ($("input[type='radio'].radio_s").is(':checked')) {
// var card_type = $("input[type='radio'].radio_s:checked").val();
// alert('card_type');
// }
});
You need to traverse the DOM from the radio which was clicked to find the nearest label element.
$('.radio_s').change(function() {
$('#input_4_3').val($(this).closest('li').find('label').text());
});
Example fiddle
You could also use $(this).next('label') however, that relies on the position of the label element not changing. My first example means the label can be anywhere within the same li as the radio button and it will work.
Try this:
$('.radio_s').click(function() {
$("#input_4_3").val($("input:checked" ).next().text());
});
Demo: http://jsfiddle.net/WQyEw/3/
This is a slightly tricky question to answer well. The structure of your HTML implies that there may be more than one of these structures on the page. So you may have more than one set of radio buttons with a corresponding checkbox.
I have put some working code into a jsFiddle.
I made one change: all the code you had in your question is now in <div class="container">. You would need as many of these as you had groups of radio buttons and checkboxes.
You can then have jQuery code like this:
$('ul.gfield_radio').on('change', 'input[type="radio"]', function () {
var label = $('label[for="' + this.id + '"]');
$(this).closest('.container').find('input.medium').val(label.text());
});
This code is not tied to the id values in this particular bit of HTML, but would work as many times as necessary throughout the page.
Why to depend on third party library when you can achieve it with plain javascript:
<script>
document.addEventListener('DOMContentLoaded', function () {
var a = document.getElementsByName('input_4');
for (var i = 0; i < a.length; i++) {
document.getElementsByName('input_4')[i].addEventListener('change', function () {
showValue(this);
}, false);
}
}, false);
function showValue(element) {
alert(element.parentNode.getElementsByTagName('label')[0].innerHTML)
}
</script>

CheckAll/UncheckAll checkbox with jQuery

I have made a check-box checkall/uncheckall.
HTML
<div> Using Check all function </div>
<div id="selectCheckBox">
<input type="checkbox" class="all" onchange="checkAll('selectCheckBox','all','check','true');" />Select All
<input type="checkbox" class="check" onchange="checkAll('selectCheckBox','all','check','false');" />Check Box 1
<input type="checkbox" class="check" onchange="checkAll('selectCheckBox','all','check','false');" />Check Box 2
<input type="checkbox" class="check" onchange="checkAll('selectCheckBox','all','check','false');" />Check Box 3
<input type="checkbox" class="check" onchange="checkAll('selectCheckBox','all','check','false');" />Check Box 4
</div>
main.js
function checkAll(parentId,allClass,checkboxClass,allChecked){
checkboxAll = $('#'+parentId+' .'+allClass);
otherCheckBox = $('#'+parentId+' .'+checkboxClass);
checkedCheckBox = otherCheckBox.filter($('input[type=checkbox]:checked'));
if(allChecked=='false'){
if(otherCheckBox.size()==checkedCheckBox.size()){
checkboxAll.attr('checked',true);
}else{
checkboxAll.attr('checked',false);
}
}else{
if(checkboxAll.attr('checked')){
otherCheckBox.attr('checked',true);
}else{
otherCheckBox.attr('checked',false);
}
}
}
It works fine. But get bulky when I have whole lot of checkboxes. I want to do same work by using jQuery rather than putting onchange on each checkbox. I tried different sort of things but couldnot work. I tried following one:
$('.check input[type="checkbox"]').change(function(e){
checkAll('selectCheckBox','all','check','true');
});
to do same work as onchange event but didnot work. Where do I went wrong.
I think you just need this: You do not need to pass all the arguments and have the inline onchange event attached to it. You can simplify your code.
$(function () {
$('input[type="checkbox"]').change(function (e) {
if(this.className == 'all')
{
$('.check').prop('checked', this.checked); //Toggle all checkboxes based on `.all` check box check status
}
else
{
$('.all').prop('checked', $('.check:checked').length == $('.check').length); // toggle all check box based on whether all others are checked or not.
}
});
});
Demo
Your selector is wrong:
.check input[type="checkbox"]
Above selects any input of type checkbox that has the ancestor with class .check. It'll match this:
<div class="check">
<input type="checkbox".../>
</div>
it should be:
input.check[type="checkbox"]
You closed the string here $('.check input[type='checkbox']') instead, you should use double quotes $('.check input[type="checkbox"]')

Categories