I'm working on a project with Java as the backend tech, JSPs and JS with jQuery on the frontend. I'm new to JS and jQuery or at least I'm no pro so I'm trying to do my best here.
So the thing is: I have this screen I'm working on, it shows two users or more and some information related to them. Each user (and its information) is on a different tab. Each user/tab has a checkbox that MUST be checked in order to go to the next screen. So if we have two users, both checkboxes MUST be checked. If we have five, all five of them. The screen is something like this (keeping in mind that the pink one is the selected user):
So the thing is, sometimes, my logic works well and I can move on to the next screen after checking all the checkboxes. But other times after refreshing the page, as I discovered using some console.logs, the checkbox on the first user is executing the code for all the checkboxes while the rest of the checkboxes are not doing anything. So I can't go on to the next screen unless I check the box in all the users and the first one last. The same happens if I uncheck a checkbox on the second user, it's not doing anything because its code is not executing.
I have a JS function on change that checks if all the checkboxes are checked in order to show the arrow to the next screen. Like this:
$("#demPricesCheckbox").change(function () {
var checkboxes = document.querySelectorAll("[id='demPricesCheckbox']");
var show = true;
for (var i = 0; i < checkboxes.length && show; i++) {
if (!checkboxes[i].checked) show = false;
}
if (show) {
ContractPrices.showForwardButton();
} else {
ContractPrices.hideForwardButton();
}
});
And my checkbox HTML reads as follows:
<label class="sub-checkbox" style="margin-left: 100px; margin-top: 5px">
<input
type="checkbox"
id="demPricesCheckbox"
name="demPricesCheckbox"
value="1"
/>
<branches:message code="NAME_OF_CHECKBOX" />
</label>
Any hints? I would appreciate any ideas or explanations on why this could be happening. If you need more info just ask me.
Thank you for your time! And pardon my bad English!
Your logic is close, but there are a few things to keep in mind.
HTML elements should have unique id attributes, meaning that you should never have more than 1 element with the same id on any page.
You should check the "state" of your user interface on every interaction – this is the foundation of reactive programming, and something that jQuery/React/Vue makes easy.
I've written and annotated some code that should help clarify.
// You have jQuery installed, so let's use that instead of vanilla
// This is a CSS selector for "all checkboxes in the DOM".
$("input[type='checkbox']").change(() => {
// Count how many checkboxes you have on the page
// You can use a different method
const totalNumberOfCheckboxes = $("input[type='checkbox']").length;
let countChecked = 0;
// Now, let's loop through them all and see if they are all checked
$("input[type='checkbox']").each((index, element) => {
// Increase the counter only if the checkbox is checked
if (element.checked) {
countChecked += 1;
}
});
// Now, let's check if they are all checked!
if (totalNumberOfCheckboxes === countChecked) {
// Enable your button
console.log("Enabling the next button");
$(".btn.next").removeAttr("disabled");
} else {
// Disable the button
console.log("Disabling the next button because all the checkboxes are not checked.");
$(".btn.next").attr("disabled", "disabled");
}
});
// Next button click listener
// This will only trigger when clicked, and the button is "enabled" – i.e.: not "disabled"
$(".btn.next").click(() => {
console.log('Go to the next page :)')
// This is just for the example – it disables all the checkboxes again
$("input[type='checkbox']").each((index, element) => {
element.checked = false;
});
});
// Setup
// This is not waiting for events, so it will run
// when the page is loaded
console.log("Disabling the next button because the page has just been loaded");
$(".btn.next").attr("disabled", "disabled");
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<input id="user1" type="checkbox" />
<label for="user1">User 1</label>
</div>
<div>
<input id="user2" type="checkbox" />
<label for="user2">User 2</label>
</div>
<div>
<input id="user3" type="checkbox" />
<label for="user3">User 3</label>
</div>
<button class="btn next">Next</button>
Related
New to Javascript, teaching myself for fun. I have a basic function, and what I am attempting to do is make a checkbox (if checked) do more than one thing. In this example, I want to make a form become visible and also make the inputs required.
What I am noticing is that the first line works, I can make the form appear. However, the first input in that form does not become required.
Here is the Function.
When the checkbox is checked, the function does work. It makes the form "kForm2" become visible and hides it if not checked. But it seems it doesnt want to run the second line, where i require the first input of that form. There is also about 10 more inputs that I want to make required if that checkbox is checked. I know im writing this wrong, but I cant find the information online. Thanks
<input type="checkbox" id="k2Check" onclick="k2()">
<div id="kForm2" style="display:none">
<label for="kfirstname2">First Name:</label>
<input type="text" name="kfirstname2" id="kfirstname2"
minlength="3" maxlength="20">
</div>
<script>
function k2() {
var checkBox = document.getElementById("k2Check");
var kForm2 = document.getElementById("kForm2");
if (checkBox.checked == true){
kForm2.style.display = "block";
this.getField(kfirstname2).required=true;
}
else {
kForm2.style.display = "none";
this.getField(kfirstname2).required=false;
}
}
</script>
I was using the wrong code, after further research.
INCORRECT
this.getField(kfirstname2).required=true;
CORRECT
document.getElementById("kfirstname2").required = true;
This is working now thanks for your help guys.
This section uses a checkbox to select your extras, once selected you move onto the next step and it will display your choice in a header called checkout[itemname]. When a check box is selected it changes a variable from false to true however my code doesn't seem to be doing that.
I will show an example section of the user selecting "Neck Tie" from the list of extras.
var hasNeckTie = false;
if (hasNeckTie = true) {
document.getElementById("checkoutnecktie").innerHTML = "Neck Tie";
}
<div class="three columns bear">
<h3>Matching Tartan Scarf (£2.50)</h3>
<label>
<input type="checkbox" autocomplete="off" name="scarf" id="scarf" value="2.5" />
<img src="Images/Scarft.png">
</label>
<p>Personalise your bear with a matching tartan scarf. It gets cold up here in Scotland, and this is the best way to keep your bear warm.</p>
</div>
<div id="checkoutnecktie"></div>
Any ideas why this code isn't running properly?
Your problem starts where you are using = instead of == in your if statement.
You are also trying to set the HTML value of an element which does not exist.
document.getElementById("checkoutnecktie").innerHTML = "Neck Tie";
You need to change "checkoutnecktie" to an element ID which exists.
You would need to hook an event to the checkbox.
You can do this with jQuery like so
$('#scarf').change(function(){
if($(this).is(":checked")) {
$('#checkoutnecktie').text('Neck tie');
}
}
Also like the other answer states, set the text to an element that exists.
I have several checkboxs on site. This checkboxs can be check by div too, but only one checkbox can be check at a time. That is the problem. When I want click on checbox by div - it works.
When I want only one checbox checked at a time - it works. But when I want both functions at once - it doesn't.
So here is code (for example):
<div class="sth">
<input type="checkbox" class="myCheck"><label>blabla</label>
</div>
<div class="sth">
<input type="checkbox" class="myCheck"><label>blabla</label>
</div>
<div class="sth">
<input type="checkbox" class="myCheck"><label>blabla</label>
</div>
And jQuery:
$("div.sth").on("click",function(event) {
var target = $(event.target);
if (target.is('input:checkbox')) return;
var checkbox = $(this).find("input[type='checkbox']");
if( !checkbox.prop("checked") ){
checkbox.prop("checked",true);
} else {
checkbox.prop("checked",false);
}
});
$('input:checkbox').on('change', function() {
$('input:checkbox').not(this).prop('checked', false);
});
Updated fiddle.
You should add the following line :
$('input:checkbox').not(this).prop('checked', false);
In your "div.sth" click event to uncheck the other checkboxes first then select the one related with clicked div.
Hope this helps.
Have you considered using radio buttons instead and just styling them with CSS to look however you want?
Otherwise use the other answer, mine second portion of this was me misunderstanding the goal.
Well, I'm stuck and have been banging my head for a little while now to try to figure what I'm doing wrong.
Scenario:
I have a question with a Yes/No answer (ie 2 radio buttons). When a user selects the either Yes or No, I call a function to .toggle() a hidden div to show a link. That works great. And if they go back and check that Yes/No again it disappears again due to the .toggle()
My issue is that if a user clicks the No (and the link is shown) but then clicks the Yes I want the link that is showing due to the No result to disappear and vice-versa.
So basically only show 1 link at a time.
I figured that maybe an If statement would work but I can't seem to get it right.
My code:
<div id="Question1">
<div>Do you kazoo?</div>
<input type="radio" ID="Q1RB1" runat="server" value="Yes" text="Yes" name="RadioGroup1"/>Yes<br />
<input type="radio" ID="Q1RB2" runat="server" value="No" text="No" name="RadioGroup1"/> No
<span id="Q1RB1Results" style="display:none"> <a href=#>Click here</a></span>
<span id="Q1RB2Results" style="display:none"> <a href=#>Click here</a></span>
</div>
My jQuery code that works for each individual radio button:
$("input[id$=Q1RB1]:radio").change(function () {
$("[id$=Q1RB1Results]").toggle();
});
$("input[id$=Q1RB2]:radio").change(function () {
$("[id$=Q1RB2Results]").toggle();
});
This is the If statement I'm trying to get to work. Amy I going about this the wrong way?
if ($("input[id$=Q1RB2]").is(":checked")) {
$("input[id$=Q1RB2]:radio").change(function () {
$("[id$=Q1RB2Results]").toggle();
});
});
Thanks for any thoughts/advice. I've tried a multitude of answers here in Stackoverflow and the 'net but can't seem to figure out what I'm doing wrong. :(
~V
Update: I put a sample form and the dialogue up on JSFiddle. http://jsfiddle.net/Valien/7uN6z/4/ I tried some of the solutions mentioned here and couldn't get them working so not sure what I'm doing wrong.
When you register an event listener in JQuery (.change, .click, .blur, etc.), the Javascript engine matches the selector and applies them at that point. With that in mind, you can rearrange your code (which is close to being right) to this, which should do the trick:
/* The function you're about to define applies to all radio button
inputs whose ID ends with Q1RB2 */
$("input[id$=Q1RB2]:radio").change(function()
{
/* Inside the change function, $(this) refers to the instance that
was changed. So, this checks to see if the instance that was just
changed is currently checked, after being changed. */
if ($(this).is(":checked"))
{
// If that was the case, then toggle the item
$("[id$=Q1RB2Results]").toggle();
}
});
Try this:
$('input:radio[name=RadioGroup1]').change(function(){
var show = "#" + $(this).attr('id') + 'Results';
$('#Question1 span').hide();
$(show).show();
});
I believe this is what you need:
// declare common variables so it's easier to target
var question = $("#Question1"),
group = question.find("input[name='RadioGroup1']"),
span = question.find("span");
// change listener for each radio button group
group.click(function(){
var id = $(this).attr("id"); // get the radio button id for reference
span.each(function(){ // loop through each span and check which one to hide/show
var item = $(this);
if (item.attr("id")===id+"Results") { item.show(); } else { item.hide(); }
});
});
My first question is this although I doubt if it is possible. However, if it is, it will make my life much easier.
Can you have a radio button group with 2 forms? What I mean is that the same radio button group is found in both form1 and form2.
The reason why I need this is to that if I click on the first 2 radio buttons, the form action will be to one page, while if I click on the last 2 radio buttons, the action will be to another page.
If this is not possible, I would use one form and will have to change the form action depending on which radio button I select. I will give a class to the first two radio buttons and another class to the other 2 radio buttons.
If anyone can let me know which method is better and how to implement it in jQuery, that would be great.
Many thanks in advance
You cannot have a single group of form elements be part of two separate forms. It's just not possible to construct a valid document like that.
Javascript that dynamically updates the URL in the "action" property of the parent <form> should not be too hard to do. As you suggested, the "class" attribute of the radio button elements can be used to guide the code, making it pretty flexible if you need to add one or more buttons later on.
Since you included the jQuery tag:
$(function() {
var actionMap = {
key1: 'http://yoursite.com/some/action/1',
key2: 'http://yoursite.com/some/action/2',
/* ... */
};
$('input:radio').click(function() {
var $rb = $(this);
for (var key in actionMap) {
if ($rb.hasClass(key))
$rb.closest('form').attr('action', actionMap[key]);
}
});
});
or something. You could also use an HTML5-style "data-" attribute to store the URLs directly on the radio button elements, or a key fragment of the URL. (Also might want to handle the "change" event the same way, etc.)
The one form, alternate action pages seems to be the way to go. If you're going to use classes for the radio buttons then something like this would work.
Live example
JavaScript
// override the action page based on which radio button is checked
$('#someForm').submit( function(e) {
if($('.useDefault:checked').length == 1) this.action = 'http://www.google.com';
else this.action = 'http://wikipedia.org';
});
HTML
<form id="someForm" action="#">
<input name="rad" type="radio" value="default0" class="useDefault" /><label>default0</label>
<br />
<input name="rad" type="radio" value="default1" class="useDefault" /><label>default1</label>
<br />
<input name="rad" type="radio" value="alternate0" class="useAlternate" /><label>useAlternate0</label>
<br />
<input name="rad" type="radio" value="alternate1" class="useAlternate" /><label>useAlternate1</label>
<br />
<input type="submit" value="submit"/>
</form>
I have implemented the right solution with some help from Pointy. Here is my code:
$(function() {
$('input:radio').click(function() {
var $rb = $(this);
if ($rb.hasClass('class1')){
$("#myForm").attr("action", "link1.php");
}else if($rb.hasClass('class2')){
$rb.closest('form').attr("action", "link2.php");
}
});
$('#btnProceed').click(function(){
$('#myForm').submit();
});
});