I have two separate radio button arrays that should behave as if they are one. Currently, I have it only working one way. I have a YouTube video showing my problem.
I have two mutually exclusive arrays that I want them working together as one array to the user. E.g., If one radio button is checked" in one array, I do not want the other array's radio button checked, but unchecked. JavaScript should deselect the radio button in the other array, making the functionality to look like the user is working with one set of radio buttons. The two separate radio arrays have different name=pair values.
YouTube Video Showing Problem
https://www.youtube.com/watch?v=nlvzgu3pJ8A
<!DOCTYPE html>
<html lang="en-US">
<head>
<style>
body{font-family:sans-serif, arial;}
th{text-align:left;}
h3,h4{margin-top:.15em; padding:0;}
</style>
<script>
function monthlyPlan(){
for(var i=0; i<document.deliveryForm.monthly.length;++i)
{
if(document.deliveryForm.monthly[i].checked== true )
document.deliveryForm.weekly.checked = false;
}
}
function weeklyPlan(){
for(var i=0; i<document.deliveryForm.weekly.length;++i)
{
if(document.deliveryForm.weekly[i].checked == true)
document.deliveryForm.monthly.checked = false;
}
}
</script>
</head>
<body>
<form name="deliveryForm" action="FormProcessor.html" method="get">
<h3>Delivery Rates</h3>
<h4>Allow users to select their desired delivery option.</h4>
<ul>
<li>Bill weekly or monthly</li>
<li>Devlivered Mon-Sat or Everyday</li>
</ul>
<p>
<strong>Billed continuously $3.50 by the Month?</strong>
<input type="radio" name="monthly" value="yes" onclick="monthlyPlan();" /> Yes
</p>
<strong>Billed by a Weekly Plan?</strong>
<table border=1 cellpadding=6>
<tr>
<th></th>
<th>4 weeks</th>
<th>13 weeks</th>
<th>26 weeks</th>
<th>52 weeks</th>
</tr>
<tr>
<th>Devlivered Mon-Sat</th>
<td><input type="radio" name="weekly" value="12.60" onclick="weeklyPlan();" />12.60</td>
<td><input type="radio" name="weekly" value="40.95" onclick="weeklyPlan();" />40.95</td>
<td><input type="radio" name="weekly" value="81.90" onclick="weeklyPlan();" />81.90</td>
<td><input type="radio" name="weekly" value="156.00" onclick="weeklyPlan();" />156.00</td>
</tr>
<th>Devlivered Everyday</th>
<td><input type="radio" name="weekly" value="13.56" onclick="weeklyPlan();" />13.56</td>
<td><input type="radio" name="weekly" value="44.07" onclick="weeklyPlan();" />44.07</td>
<td><input type="radio" name="weekly" value="88.14" onclick="weeklyPlan();" />88.14</td>
<td><input type="radio" name="weekly" value="159.74" onclick="weeklyPlan();" />159.74</td>
</tr>
</table>
</form>
</body>
</html>
Try this:
function monthlyPlan() {
for (var i = 0; i < document.deliveryForm.weekly.length; ++i) {
document.deliveryForm.weekly[i].checked = false;
}
}
function weeklyPlan() {
document.deliveryForm.monthly.checked = false;
}
Demo: http://jsfiddle.net/DpbMB/
You don't need to test whether the radio that was just clicked is checked, because for radio buttons you know they will be checked when the click event occurs (there's no way to uncheck them by clicking except by clicking on another in the group, and then it is the other that gets the event).
When the monthly radio button is clicked, loop over all of the weekly radio buttons and set them to not be checked. When any weekly radio is clicked simply uncheck the monthly one.
The array-style access is only applicable when there is more than one element with the same name, so to access the monthly button don't use [i].
It seems to me though that it would be easier to just make the monthly button part of the same group, and give it an appropriate value that you can test server-side.
Try the following for your monthlyPlan() function:
function monthlyPlan(){
/*for(var i=0; i<document.deliveryForm.monthly.length;++i)
{
if(document.deliveryForm.monthly.checked== true )
document.deliveryForm.weekly.checked = false;
}
*/
alert(document.deliveryForm.monthly.length); // will say undefined
if (document.deliveryForm.monthly.checked)
{
for (var k = 0; k < document.deliveryForm.weekly.length; ++k)
{
document.deliveryForm.weekly[k].checked = false;
}
}
}
It appears that when you only have one radio button in the group, the DOM doesn't treat it as an array.
EDIT: Actually, nnnnnn's answer is better. No point keeping the redundant if statements.
Related
I am having some problems regarding the jquery event handler function. I couldn't understand how can I set it in the correct way.
I will explain my problem, I have three checkboxes: 3D, TRI-Planar, and MPR. And when users check the 3D option the following two checkboxes appear Volume and Sur. Furthermore, when the user clicks the vol checkbox, some options toggle. And when the user unclicks the vol disappear and again if they click them then there will be two options of same. How can I solve it?
Below I have provided a minimal example which I used first without using a class like desire_viewer and method_selection. If you click 3D then vol and sur options toggle and if you click vol options then another options toggle but when u unclick it then it disappears and then click it again then two same options appear. I think there is something wrong with the code.
I expect the output to be like this: If the user clicks 3D options then it should toggle Volume and Surface options and again if the user clicks on the volume checkbox then volume options should toggle vice-verse with the surface. When the user unchecks any checkbox then its process should stop. For example, at first, the user clicked 3D > VOL and then 3D > sur, in this case, the first step should be stopped when the sur checkbox is clicked. I mean like logic 0 and 1. If the user clicks Tri-Planar then it's 1 and its option should toggle and again if the user unchecks it which is 0 then it's processed and should be stopped. So, in the next step user can play with MPR or other checkboxes.
ID_3D_render_selection = "#v1"
ID_tri_planar = "#v2"
ID_mpr_selection = "#v3"
ID_vol_selection = "#r1"
ID_sur_selection = "#r2"
$(ID_3D_render_selection).change(function() {
$('#select_render_method').slideToggle("slow");
$(ID_vol_selection).change(function() {
$('#VOL_OPTIONS').slideToggle("slow");
var vol_arr = []
var vol_arr2 = []
$( "#btn1" ).change(function() {
var vol_myFile = $('#btn1').prop('files');
vol_arr.push(vol_myFile)
});
<!--//////////////////////////////////////-->
$(document).ready(function() {
var vol_opacity = $('<input class=vol_set_opacity id="setScalarOpacityUnitDistance0" type="range" min="0" max="100" step="0.5" value="3">').appendTo('#set_opacity_distance_bm_Color');
var vol_distance = $('<input class=vol_set_distance id="setSampleDistance0" type="range" min="0.1" max="10" step="0.1" value="0.4">').appendTo('#set_opacity_distance_bm_Color');
var vol_blending = $('<select class=vol_blending_mode id=blendMode0 >').appendTo('#set_opacity_distance_bm_Color');
vol_blending.append($("<option>").attr('value',"0").text("Composite"));
var sel = $('<select class=colors_channels >').appendTo('#set_opacity_distance_bm_Color');
sel.append($("<option>").attr('value',"Reds").text("Reds"));
sel.append($("<option>").attr('value',"Blues").text("Blues"));
sel.append($("<option>").attr('value',"Greens").text("Greens"));
$( "#f" ).change(function() {
$('.vol_set_opacity').remove();
$('.vol_set_distance').remove();
$('.vol_blending_mode').remove();
$('.colors_channels').remove();
for(i=0; i<$('#f').val(); i++) {
var vol_opacity = $('<input class=vol_set_opacity id="setScalarOpacityUnitDistance'+ i +'"'+ ' type="range" min="0" max="100" step="0.5" value="3">').appendTo('#set_opacity_distance_bm_Color');
var vol_distance = $('<input class=vol_set_distance id="setSampleDistance'+ i + '"' + 'type="range" min="0.1" max="10" step="0.1" value="0.4">').appendTo('#set_opacity_distance_bm_Color');
var vol_blending = $('<select class=vol_blending_mode id="blendMode'+ i +'"'+ ' >').appendTo('#set_opacity_distance_bm_Color');
vol_blending.append($("<option>").attr('value',"0").text("Composite"));
var sel = $('<select class=colors_channels >').appendTo('#set_opacity_distance_bm_Color');
sel.append($("<option>").attr('value',"Reds").text("Reds"));
sel.append($("<option>").attr('value',"Blues").text("Blues"));
sel.append($("<option>").attr('value',"Greens").text("Greens"));
}
})
});
<!--//////////////////////////////////////-->
$( "#btn2" ).click(function() {
var vol_Picked_color = $(".colors_channels");
for(var i = 0; i < vol_Picked_color.length; i++){
vol_arr2.push($(vol_Picked_color[i]).val() );
}
console.log(vol_arr2)
if (vol_arr.length==vol_arr2.length){
vol_processFile(vol_arr, vol_arr2)
} else {
alert("Please check the number of input vs the number of channels ")
}
});
});
});
var tri_arr =[]
$(ID_tri_planar).click(function() {
$('#TRI_PLANAR_OPTIONS').slideToggle("slow");
});
$( "#btn1" ).change(function() {
var tri_myFile = $('#btn1').prop('files');
tri_arr.push(tri_myFile)
});
$( "#btn2" ).click(function() {
tri_processFile(tri_arr)
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script type="text/javascript" src="{% static '/js/jquery-3.6.0.min.js' %}"></script>
<div >
<input class="desire_viewer" type="checkbox" name="Viewers" id="v1" value="3D"><label for="v1">3D</label>
<input class="desire_viewer" type="checkbox" name="Viewers" id="v2" value="TRI-Planar"><label for="v2">TRI-Planar</label>
<input class="desire_viewer" type="checkbox" name="Viewers" id="v3" value="MPR"><label for="v3">MPR</label>
</div>
<div id="select_render_method" class="section_header_2" style="display:none;">
<input class="method_selection" type="checkbox" name="Render" id="r1" value="Vol" ><label for="r1">Vol</label>
<input class="method_selection" type="checkbox" name="Render" id="r2" value="Sur" ><label for="r2">Sur</label>
</div>
<div id="divInput" class="section_internal_layout_card_middle_body_title_4" >
<table>
<tbody>
<td>Select the number of inputs:</td>
<td>
<input min=1 max=10 type="number" id="f" value="1" style="width: 43px; height: 25px;">
</td>
</tbody>
</table>
<div>
<input name="inputFile" type="file" multiple id="btn1" style="margin-left: 1px; margin-top: 30px; padding: 0px; border: none; z-index: 1;">
</div>
<div>
<button name="render" id="btn2" style="margin-top: 0px; margin-left:304px; width: 96px; font-size: 14pt; border: none; z-index: 1; margin-bottom: 7px;"> Render </button>
</div>
</div>
<div id="VOL_OPTIONS" class="section_header_5" style="display:none;">
<div id="set_opacity_distance_bm_Color" class="section_internal_layout_card_middle_body_title_5">
<p><b>Scalar Opacity</b>&ensp<b>SampleDistance</b><b>Blending</b><b>Color</b></p>
</div>
</div>
<div id="SUR_OPTIONS" class="section_header_6" style="display:none;">
<div id="set_iso_Color" class="section_internal_layout_card_middle_body_title_55">
<p><b>Scalar Opacity</b><b>Iso value</b><b>Color</b> </p>
</div>
</div>
<div id="TRI_PLANAR_OPTIONS" class="section_header_7" style="display:none;">
<table>
<tbody>
<tr>
<td>XY</td>
<td>
<input class="XY" type="range" min="0" max="119" step="1" value="0"> <!-- sliceI -->
</td>
</tr>
<tr>
<td>XZ</td>
<td>
<input class="XZ" type="range" min="0" max="119" step="1" value="0"> <!-- sliceJ -->
</td>
</tr>
<tr>
<td>YZ</td>
<td>
<input class="YZ" type="range" min="0" max="119" step="1" value="0"> <!-- sliceK -->
</td>
</tr>
<tr>
<td>Color level</td>
<td>
<input class="colorLevel" type="range" min="0" max="255" step="1" value="0">
</td>
</tr>
<tr>
<td>ColorWindow</td>
<td>
<input class="colorWindow" type="range" min="0" max="255" step="1" value="0">
</td>
</tr>
</tbody>
</table>
</div>
<div id="MPR_OPTIONS" class="section_header_8" style="height:412px; display:none;">
<table><tbody><tr> // do some stuff </tr></tbody></table>
</div>
UPDATE:
OP has edited their question significantly and much of my original answer now makes no sense. Here's a new answer for the current code.
Leaving my original answer below for reference.
The main problem in the new code is that your volume toggle actions are not balanced - the untick action does not do the reverse of the tick action.
When you tick the volume checkbox, you add some HTML to the page, display it, and set up some new change handlers;
When you untick that same checkbox, you add the same HTML again, hide it, and add another set of identical change handlers on top of the first set;
So you can see that if you tick to volume checkbox, untick it, and then tick it again, you will see 2x your HTML on the page.
The other major problem is what I described in my original answer below as "problem 2" - you are adding event handlers inside event handlers. In the example tick/untick/tick example of the volume checkbox above, you will end up with 2x handlers for #f, and 2x handlers for #btn1. If, for eg, you click #btn1, that code will now run 2x, simultaneously. This gets very messy very quickly, and will cause all kinds of problems.
Here's updated, working code, with comments.
Note I have simplified the code a lot by removing lots of stuff which is not relevant to the current problem. Your question summaries the key problem:
... and when the user unclicks the vol disappear and again if they click them then there will be two options of same. How can I solve it?
Ticking and unticking the volume checkbox shows 2x duplicate options. That's the problem we're tying to solve. Everything else here is not relevant, and we can remove it. It is much simpler - for you too! - to find and fix the problem when you focus on just the part that is not working. This is what the minimal in MVCE refers to.
// Document ready event handler should never be nested inside other handlers.
$(document).ready(function() {
// Volume-related variables we need to be able to access later
var vol_opacity, vol_distance, vol_blending, sel;
// Click and change events are technically the same for checkboxes, but still be,
// consistent - use change here, not a mix of change and click as your code had.
// https://stackoverflow.com/questions/11205957/jquery-difference-between-change-and-click-event-of-checkbox
$('#v1').change(function() {
$('#select_render_method').slideToggle("slow");
});
$("#v2").change(function() {
$('#TRI_PLANAR_OPTIONS').slideToggle("slow");
});
// Do not nest event handlers inside each other - move this handler outside other
// change handlers
$('#r1').change(function() {
// We are toggling elements on and off here. If you are ADDing the HTML when
// the checkbox is ticked, it means you have to REMOVE that HTML when it is
// unticked. Is it really necessary? Modifying the DOM like this is slow and
// inefficient, what about just toggling visibility, like you do with
// slideToggle() for other options?
// Anyway - assuming you want to add/remove it, let's do it like this:
if ($(this).is(':checked')) {
addVolumeStuff();
} else {
deleteVolumeStuff();
}
// I moved this toggle below the code above - .appendTo is synchronous, so
// wait until the HTML updates are done before displaying them.
$('#VOL_OPTIONS').slideToggle("slow");
});
/**
* Add some HTML when the vol checkbox is ticked
*/
function addVolumeStuff() {
vol_opacity = $('<input class=vol_set_opacity id="setScalarOpacityUnitDistance0" type="range" min="0" max="100" step="0.5" value="3">').appendTo('#set_opacity_distance_bm_Color');
vol_distance = $('<input class=vol_set_distance id="setSampleDistance0" type="range" min="0.1" max="10" step="0.1" value="0.4">').appendTo('#set_opacity_distance_bm_Color');
vol_blending = $('<select class=vol_blending_mode id=blendMode0 >').appendTo('#set_opacity_distance_bm_Color');
vol_blending.append($("<option>").attr('value',"0").text("Composite"));
sel = $('<select class=colors_channels >').appendTo('#set_opacity_distance_bm_Color');
sel.append($("<option>").attr('value',"Reds").text("Reds"));
sel.append($("<option>").attr('value',"Blues").text("Blues"));
sel.append($("<option>").attr('value',"Greens").text("Greens"));
}
/**
* Delete the volume controls when vol checkbox is unticked
*/
function deleteVolumeStuff() {
vol_opacity.remove();
vol_distance.remove();
vol_blending.remove();
sel.remove();
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<input class="desire_viewer" type="checkbox" name="Viewers" id="v1" value="3D">3D
<input class="desire_viewer" type="checkbox" name="Viewers" id="v2" value="TRI-Planar">TRI-Planar
<input class="desire_viewer" type="checkbox" name="Viewers" id="v3" value="MPR">MPR
</div>
<div id="select_render_method" class="section_header_2" style="display:none;">
<input class="method_selection" type="checkbox" name="Render" id="r1" value="Vol" >Vol
<input class="method_selection" type="checkbox" name="Render" id="r2" value="Sur" >Sur
</div>
<div>
<input min=1 max=10 type="number" id="f" value="1">
<div>
<input name="inputFile" type="file" multiple id="btn1">
</div>
<div>
<button name="render" id="btn2">Render</button>
</div>
</div>
<div id="VOL_OPTIONS" style="display:none;">
<div id="set_opacity_distance_bm_Color">
<p><b>Scalar Opacity</b> <b>SampleDistance</b> <b>Blending</b> <b>Color</b></p>
</div>
</div>
<div id="SUR_OPTIONS" style="display:none;">
<div id="set_iso_Color">
<p><b>Scalar Opacity</b> <b>Iso value</b> <b>Color</b></p>
</div>
</div>
<div id="TRI_PLANAR_OPTIONS" style="display:none;">
<table>
<tbody>
<tr>
<td>XY</td>
<td>
<input class="XY" type="range" min="0" max="119" step="1" value="0">
</td>
</tr>
<tr>
<td>... etc ...</td>
<td> </td>
</tr>
</tbody>
</table>
</div>
Original answer
Problem 1:
var value = $("input[name='Viewers']:checked").val();
The selector will match all 3 of your checkboxes. But what will the .val() of 3 elements look like? Quoting the docs for .val():
Get the current value of the first element in the set of matched elements.
So you're only ever going to get one of your checkbox values, the first checked one. Try it:
$('.desire_viewer').on('click', function() {
console.log($('.desire_viewer:checked').val());
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input class="desire_viewer" type="checkbox" name="Viewers" value="3D">3D
<input class="desire_viewer" type="checkbox" name="Viewers" value="TRI-Planar">TRI-Planar
<input class="desire_viewer" type="checkbox" name="Viewers" value="MPR">MPR
So how do you check if a particular checkbox is checked? As you can imagine this is a pretty common problem and there are a lot of duplicates here, eg:
Getting all selected checkboxes in an array
Get checkboxes (with the same name) as array
Send same name multiple checkbox values via ajax
You need to iterate over each of the inputs, like so:
$('.desire_viewer').on('click', function() {
console.log('These are now checked:');
$('.desire_viewer:checked').each(function(i) {
console.log(i, ':', $(this).val());
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input class="desire_viewer" type="checkbox" name="Viewers" value="3D">3D
<input class="desire_viewer" type="checkbox" name="Viewers" value="TRI-Planar">TRI-Planar
<input class="desire_viewer" type="checkbox" name="Viewers" value="MPR">MPR
Note that inside the loop, $(this) represents the current jQuery object in the loop.
So in your case, your code might look something like:
$('.desire_viewer').on('click', function() {
$('.desire_viewer:checked').each(function(i) {
var val = $(this).val();
if (value == "3D") {
// Do stuff ...
} else if (value == "TRI-Planar") {
// Do other stuff ...
} else if (value == "MPR") {
// Do other different stuff ...
}
});
});
Problem 2:
$( "#btn1" ).change(function() {
This adds an event handler to your button. From this point on, any time that button is changed this handler will notice, and that function code will fire.
That's fine and will work. The problem is where it is added - when a checkbox is clicked. If the user decides they made a mistake and UNticks the TRI-Planar checkbox, guess what happens? Another identical event handler will be added to the button. And the best part? They will both fire! The handler function, whatever it is, will run 2x, in parallel. They don't overwrite each other, they all stack up, and they all run.
The (simplest) solution is to add event handlers independent of user interaction or other changes on the page, so they can only be bound once. If the code that runs is somehow dependent on where/when it would be triggered, set that up in the handler. Eg if this button change should only do something if TRI-Planar is checked, have the button event handler check if that is true before doing anything. Eg:
$("#btn1").change(function() {
// Maybe this should only happen if a certain checkbox is checked
$('.desire_viewer:checked').each(function(i) {
var val = $(this).val();
if (value == "TRI-Planar") {
// Do stuff
}
});
});
// Rest of your code - handlers are independent of user interaction and
// will only be bound once.
$('.desire_viewer').on('click', function() {
// ...
Note another option is to add handlers wherever you like, and use .off() to remove them, so you can dynamically add/remove them throughout your code. For simple applications I don't think this extra complexity is necessary.
There are lots of questions here about this too:
Is it correct to put an event inside an event?
jQuery click events firing multiple times
why is jQuery click event firing multiple times
Minor suggestion:
It looks like this is part of a bigger applicaton, and it looks like you're trying to reduce code repetition with variables like ID_desire_viewer = '.desire_viewer' etc. That's a good start but since those represent jQuery selectors, you may as well go just a tiny bit further and cache the actual selector.
Every time you do something like $(ID_desire_viewer) jQuery scans the whole DOM again to find matches. For small applications/pages you probably won't notice the performance hit doing that, but it is good practice to avoid it in case your app grows, and just in terms of read- and maintain-ability, DRY, etc.
To avoid that, save the results of the first search by doing:
let $viewers = $('.desire_viewer');
// Then you can do:
$viewers.on('click', function() { ...
Some references about that:
Does jQuery do any kind of caching of "selectors"?
Store jquery selector in variable
Try this
$('input["type=checkbox"]').attr("checked",'false');
i hope it was useful !
Problem
How to use radio buttons to control selection behavior by JQuery UI?
Right now, I can select all the green boxes (success) as intended with Check Out. Please note that when I select something it is orange.
My problem is that if I choose Check In, I cannot select any of the blue boxes. Also, I probably need a way to "refresh" when I change radio buttons so the green boxes are not still selected when I want to change radio buttons.
Code (view)
I am using JQuery selectable to get the job done. You can read more about it from the api documentation found here. I tried to get jquery to "filter" based on whether or not the radio box was checked. Clearly, this approach is failing.
Edit I think the approach is failing because it is loading the javascript once? So when I change the radio buttons, my filter definition is not changing.
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Details</title>
<link rel="stylesheet" href="~/css/table.css" />
<script>
$(document).ready(function(){
//Have this be a conditional based on radio input
var getRad1 = document.getElementById('optionsRadios1');
if (getRad1.checked)
{
console.log("Check has passed for Check in");
$("#selectable").selectable({
filter: ".success"
});
//getter
var filter = $(".selector").selectable("option", "filter");
}
//option 2
var getRad2 = document.getElementById('optionsRadios2');
if (getRad2.checked) {
//$("#selectable").selectable("refresh");
console.log("Check has passed for Check in");
$("#selectable").selectable({
filter: ".info"
});
//getter
var filter = $(".selector").selectable("option", "filter");
}
//I am not sure what this is doing
var select_range = false;
//queue of objects to deselect
var deselect_queue = [];
//http://stackoverflow.com/questions/3691773/jquery-ui-event-and-ui-object-properties
$("#selectable").selectable({
selecting: function(event, ui)
{
var selecting = $(ui.selecting);
if (selecting.hasClass('ui-selected')) {
deselect_queue.push(selecting);
}
},
//This is what keeps previous selected items as selected?
unselecting: function (event, ui) {
$(ui.unselecting).addClass('ui-selected');
},
//Triggered at the end of the select operation
stop: function () {
if (!select_range) {
for (var i = 0; i < deselect_queue.length; i++) {
deselect_queue[i]
.removeClass('ui-selecting')
.removeClass('ui-selected')
}
}
select_range = false;
deselect_queue = [];
//Something else went here that I didn't understand
}
});
});
</script>
</head>
<body>
#{ int columnN = Model.columnNumber;}
#{ int rowN = Model.rowNumber;}
#{ int index = 1;}
<table class="table table-striped table-hover">
<thead>
<tr>
<th>#</th>
#for (int j = 1; j <= columnN; j++)
{
<th>#j.ToString()</th>
}
</tr>
</thead>
<tbody id="selectable">
#for (int i = 1; i <= rowN; i++)
{
<tr>
<th>#i.ToString()</th>
#for (int k = 1; k <= columnN; k++)
{
if (k % 2 == 0)
{
<td class="book success" data-id=#index> #index.ToString() </td>
}
else
{
<td class="book info" data-id=#index> #index.ToString() </td>
}
index++;
}
</tr>
}
</tbody>
</table>
<form class="form-horizontal">
<fieldset>
<legend>Legend</legend>
<div class="form-group">
<label class="col-lg-2 control-label">Radios</label>
<div class="col-lg-10">
<div class="radio">
<label>
<input name="optionsRadios" id="optionsRadios1" type="radio" checked="" value="option1">
Check out (Depopulate)
</label>
</div>
<div class="radio">
<label>
<input name="optionsRadios" id="optionsRadios2" type="radio" value="option2">
Check in (populate)
</label>
</div>
</div>
</div>
</fieldset>
</form>
</body>
</html>
Attempts
I am trying to use conditionals inside the main javascript function. It works for the initial time and sets everything up and then fails.
I could have two separate views, but that defeats the purpose of having dynamic page content.
I think I am close with trying to read the dom elements and change my javascript behavior, but I can't quite get it to work right (I might be way off too). I deeply appreciate any assistance that could be rendered.
I am writing this solution in hopes that someone else might find this post useful.
Solution
The radio buttons need a listener. So it is necessary to add onclick="" to them. However, what I need is two functions to have the behavior I seek. Otherwise, the javascript will load and then become useless to us, even with radio buttons.
Select only elements are green
Select only elements who are blue
Thus, the following functions need to be added to javascript:
function populate() {
//$("#selectable").selectable("refresh");
console.log("Check has passed for Check in");
$(".selector").selectable("refresh");
$("#selectable").selectable({
filter: ".info"
});
var filter = $(".selector").selectable("option", "filter", ".info");
};
function depopulate() {
console.log("Check has passed for Check in");
$(".selector").selectable("refresh");
$("#selectable").selectable({
filter: ".success"
});
var filter = $(".selector").selectable("option", "filter", ".success");
};
The radio button needs to be modified as follows:
<input name="optionsRadios" id="optionsRadios1" type="radio" checked="" value="option1" onclick="depopulate()">
<input name="optionsRadios" id="optionsRadios2" type="radio" value="option2" onclick="populate()">
After this, clicking on the radio buttons will give us the behavior we desired.
I am attempting to make a list of check boxes disabled unless the user explicitly states that the said list applies to the situation. I have a form with nested tables, menus, data entry, and problems found list. Essentially, for better or worse, multiple tables on one form. This is beginning to cause me grief as the functions of this form are growing exponentially. For simplicity's sake, I am focusing on the "repairs to be made" table.
I have a checklist of various things to be repaired that is proceeded by a Yes or No question for the user. Instead of running JavaScript validation on each possible repair option, I want to disable the entire list if no repairs are necessary, (i.e. "does it need any repairs?", "No", checklist disabled). I am not using CSS as I have little to no experience in web form programming and have based my code on pre-existing code that did not include CSS.
My example will use generic names and variables, and is intended to illustrate that these forms are passed through several stages before they are considered completed, thus the PHP echo variables.
<?php
$previous_response_yes=='';
$previous_response_no=='';
if ($row_GetData[Question] == "1")
{
$previous_response_yes="checked";
}
else
{
$previous_response_no="checked";
}
?>
<table>
<tr>
<td colspan="2" align="center">
Are there any damaged components?
</td>
</tr>
<tr>
<!-- this variable is used in java script verification elsewhere -->
<td>
Yes: <input type="radio" name="question" value="1" id="yes" <?php echo $previous_response_yes; ?> />
</td>
<td>
No: <input type="radio" name="question" value="0" id="no" <?php echo $previous_response_no; ?> />
</td>
</tr>
<!-- various checklist items, example as follows... -->
<tr>
<td>
<input type="hidden" name="damaged_part" value="0" />
<input type="checkbox" name="damaged_part" value="1" id="damaged_part" <?php echo $damaged_part1 <!-- code for determining if = "checked" or not omitted --> ; ?> />
</td>
<td>
Damaged Part
</td>
</tr>
<!-- lists continues on for some time -->
</table>
Now I assume that I need an "onclick" or "oncheck" qualifier in either the Yes radio button, No radio button, or both to toggle back and forth between disabling and enabling the checklist that follows. I have found very similar ideas, but none have worked in my recreation of them. Essentially, what I want is something to the extent of
while <input type="radio" name="question" value="0" id="no" <?php echo $previous_response_no; ?> /> is checked
following checklist disabled="disabled"
As you probably know, using tables for layout is not the most optimal method. And, the effect that you are seeking can be fully implemented using CSS. Here's a fiddle: http://jsfiddle.net/X93Vj/.
HTML:
<form>
<label>Damaged components?</label> <input type = "checkbox" id = "damaged" />
<div class = "componentsList">
<label><input type = "checkbox" id = "electric">Electric</label>
<label><input type = "checkbox" id = "mechanical">Mechanical</label>
</div>
<p>Sample paragraph</p>
</form>
CSS:
form > label,
form > input[type = "checkbox"] {
vertical-align: bottom;
}
form > .componentsList {
margin: 5px 0 0 20px;
}
form > .componentsList > label {
float: left;
clear: left;
}
form > input[type = "checkbox"]:not(:checked) + .componentsList {
display: none;
}
form > input[type = "checkbox"]:checked + .componentsList {
display: table;
}
To fixes. Both disable and uncheck boxes if No is chosen and check for No being checked on load.
Here's a fix that will do things using plain JavaScript (jsfiddle - http://jsfiddle.net/k34zR/9/ -- this doesn't seem to work in jsfiddle, but works in an html document) :
document.addEventListener('DOMContentLoaded', function () {
var yesBox = document.getElementById('yes'),
noBox = document.getElementById('no'),
checkboxes = document.querySelectorAll('input[type=checkbox]');
if (noBox.checked) {
for (var i in checkboxes) {
if (checkboxes.hasOwnProperty(i)) {
checkboxes[i].disabled = true;
}
};
}
yesBox.addEventListener('click', function () {
for (var i in checkboxes) {
if (checkboxes.hasOwnProperty(i)) {
checkboxes[i].disabled = false;
}
};
});
noBox.addEventListener('click', function () {
for (var i in checkboxes) {
if (checkboxes.hasOwnProperty(i)) {
checkboxes[i].disabled = true;
checkboxes[i].checked = false;
}
};
});
});
Or if you're using jQuery (jsfiddle - http://jsfiddle.net/k34zR/10/):
$(document).ready(function () {
var $radios = $('input[type=radio]'),
$boxes = $('input[type=checkbox]');
if ($('#no').is('checked')) {
$boxes.attr('disabled', 'disabled');
}
$radios.on('click', function () {
var $this = $(this);
if ($this.attr('id') == "no") {
$boxes.attr('disabled', 'disabled');
$boxes.attr('checked', false);
} else {
$boxes.removeAttr('disabled');
}
});
});
I am an absolute beginner when it comes to anything JavaScript or JQuery. I am trying to get a few checkboxes open in a new tab if they are checked and then the submit button clicked. The code I have works only if one checkbox is checked. If more than one is checked, then only the first one is open in the tab. My code is as follows:
Javascript
function CheckCheckboxes(form)
{
var
i, counter = 0;
for (i = 0; i < form.elements.length; ++i) {
if ('checkbox' === form.elements[i].type && form.elements[i].checked) {++counter;
window.open('http://' + form.elements[i].value, '_blank');
}
}
if (!counter) {
alert('Please check at least one!');
}
}
HTML
<form onsubmit="CheckCheckboxes(this); return false;">
<table align="left" border="1" style="border-collapse: collapse;">
<tr style="height:30px">
<td colspan="8"><center>Companies</center></td>
</tr>
<tr>
<td><input type="checkbox" name="Google" value="www.google.com" />Google</td>
<td><input type="checkbox" name="Apple" value="www.apple.com" />Apple</td>
<td><input type="checkbox" name="Microsoft" value="www.Microsoft.com" />Microsoft</td>
<td><input type="checkbox" name="facebook" value="www.facebook.com" />Facebook</td>
<td><br /><input type="submit" value="Send Form" /></td>
</tr>
</table>
</form>
Any help would be greatly appreciated. Been at this for 3 and a half hours :)
Thanks
Your code is working but the browser is blocking the new windows after the first one is displayed. By default browsers are blocking multiple pop-ups from a website, you can turn this off though but don't expect your users to do the same.
See Fiddle
Your code window.open('http://' + form.elements[i].value, '_blank'); works :)
I'm creating an order form that when a button is clicked it displays an image in a separate div. The code works successfully for check boxes but with radio buttons doesn't hide the previously clicked image.
function displayImage(id) {
var el = document.getElementById(id);
if (el.style.display == "inline") {
el.style.display = "none";
} else {
el.style.display = "inline";
}
}
<tr>
<td>
<input type="radio" name="cheese" id="chkcheese" value="Yellow American" onclick="displayImage('imgamerican');" />
<label for="chkcheese">Yellow American</label>
</td>
<td>
<input type="radio" name="cheese" value="Pepper Jack" id="pepperjack" onclick="displayImage('imgjack');" />
<label for="chkjack">Pepper Jack</label>
</td>
<td>
<input type="radio" name="cheese" value="Mozzarella" id="chkmozz" onclick="displayImage('imgmozz');"/>
<label for="chkmozz">Mozzarella</label>
</td>
</tr>
<div class="cheese">
<img id="imgamerican" src="images/american-cheese-slice.png" style="display:none"/>
<img id="imgcheddar" src="images/agedcheddar.png" style="display:none"/>
<img id="imgjack" src="images/pepperJack.png" style="display:none" />
<img id="imgswiss" src="images/swisscheese.png" style="display:none" />
The click event only happens on the radio that was clicked.
You'll need to iterate the radio buttons and make sure that the deselected ones have their corresponding image hidden, or just iterate the images and hide them before showing the one that had its radio clicked.
function displayImage(id) {
var imgs = document.querySelectorAll(".cheese > img");
for (var i = 0; i < imgs.length; i++) {
imgs[i].style.display = "none";
}
document.getElementById(id).style.display = "inline";
}
It looks like your problem is that you're expecting the click event to fire when a radio button becomes unchecked. But it doesn't. You'll need to specifically change the display of the last-shown cheese, but only when it's a radio button that was clicked.
This solution is kind of a hack, but it should work in this situation:
JavaScript:
var lastUnique;
function displayImage(id, unique) {
var el = document.getElementById(id);
if (unique) {
if (lastUnique) {
lastUnique.style.display = 'none';
}
lastUnique = el;
}
el.style.display = 'block';
}
Radio buttons (note the added true):
<tr>
<td><input type="radio" name="cheese" id="chkcheese" value="Yellow American" onclick="displayImage('imgamerican', true);" />
<label for="chkcheese">Yellow American</label></td>
<td><input type="radio" name="cheese" value="Pepper Jack" id="pepperjack" onclick="displayImage('imgjack', true);" />
<label for="chkjack">Pepper Jack</label></td>
<td><input type="radio" name="cheese" value="Mozzarella" id="chkmozz" onclick="displayImage('imgmozz', true);" />
<label for="chkmozz">Mozzarella</label></td>
</tr>
So, the JavaScript keeps track of the last element shown with the unique argument being truthy, and hides it when another call with unique == true happens.
Aside:
You might look into how event handling is done in the modern world. This is the old way of doing it, and it's not exactly manageable.
Also, consider looking into modularization and encapsulation techniques.