Radio buttons not changing how javascript selects elements my table? - javascript

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.

Related

Show hide text box from a dynamic element jQuery c#

Below is my code, I am trying to hide and show dynamic elements. The problem I am having is, I only want my hidden div to only show one at a time if only I check "Other". However, the code below will show the hidden div for all number of #dynamicRows I have. so it works for initial 1st #dynamicRow added, the problem is when I have two or more #dynamicRows
$('#dynamicRow').on('click', 'input[id^=race]', function () {
if ($(this).is(":checked")) {
if ($(this).val() == "Other") {
$(".cssclass").each(function (index) {
$(this).closest("div").show();
});
}
else {
$(".cssclass").each(function () {
$(this).closest("div").hide();
});
}
}
});
Below are dynamic rows, for help purposes i am showing the html code, however, it doesn't exist on the screen, a user will click "ADD" to generate the code below. I have no problem in generating dynamic row and it is not why I am posting. note the name in my radio button is generated by c# and everything works. Again the problem is not how to create a dynamic row, it is nicely taken care of in C#.
Dynamic row one works with the above jQuery:
<div id="dynamicRow">
<input type="radio" value="No" id="race[]" name="Person[hhhhhh].race"> No:
<input type="radio" value="Other" id="race[]" name="Person[hhhhhh].race"> Other:
<div id="iamhidden" class="cssclass">
I appear one at a time, when other radio button is checked
</div>
</div>
Dynamic row two doesn't work with the above jquery and it takes the above form events as its own, so if i check the radio button in row 2, the 1st dynamic row responds to that event and vice versa:
<div id="dynamicRow">
<input type="radio" value="No" id="race[]" name="Person[hhhhh].race"> No:
<input type="radio" value="Other" id="race[]" name="Person[hhhhh].race"> Other:
<div id="iamhidden" class="cssclass">
I appear one at a time, when other radio button is checked
</div>
</div>
Working Example
id should be unique in same document, replace the duplicate ones by a class :
<input type="radio" value="No" class="race" name="Person[hhhhhh].race"> No:
<input type="radio" value="Other" class="race" name="Person[hhhhhh].race"> Other:
Also add class and not id to the dynamic rows generated by your C# code :
<div class="dynamicRow">
Then in your js use this class :
$(".cssclass").hide();
$('.dynamicRow').on('click', '.race', function () {
if ($(this).val() == "Other") {
$(this).next(".cssclass").show();
} else {
$(this).nextAll(".cssclass").hide();
}
});
Hope this helps.
Try this:
$('body').on('click', '#dynamicRow', function () {
if ($(this).find('[value=Other]').is(":checked")) {
$(".cssclass").each(function (index) {
$(this).closest("div").show();
});
} else {
$(".cssclass").each(function () {
$(this).closest("div").hide();
});
}
});
He is a working example of what you wanted. I am generating the required with js only.
Few Points to mention
you add the event listener to the parent of the dynamic generated content.
Avoid use of IDs if they are not going to be unique and prefer classes and pseudo selectors if required
var counter = 0;
function addNewEntry(){
++counter;
var str = '<div class="dynamicRow"><input type="radio" value="No" id="race[]" name="Person[hh'+counter+'].race"> No:<input type="radio" value="Other" id="race[]" name="Person[hh'+counter+'].race"> Other:<div id="iamhidden" class="cssclass"> I appear one at a time, when other radio button is checked</div> </div>';
$('#dynamicRowContainer').append(str);
$("#dynamicRowContainer .dynamicRow:last-child .cssclass").hide()
}
$('#dynamicRowContainer').on('change', '.dynamicRow > input', function () {
if(this.value=="Other"){
$(this).siblings('.cssclass').show();
}else{
$(this).siblings('.cssclass').hide();
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button onclick="addNewEntry()">Add New Entry</button>
<div id="dynamicRowContainer">
</div>

AngularJS - Deselect Radio button

Is there a way I can deselect a radio button on click of it? I'm using AngularJS 1.4.4. Using one of the solutions I found here, I've added an ng-click event, but it doesn't work.
foreach (var part in Model.ChildParts)
{
<div class="radio col-md-12">
<input type="radio"
id="#Model.FieldName"
name="#Model.FieldName"
ng-model="gPA(#Model.Id).value"
value="#((part as BaseInputPartVM).GetStringValue())"
ng-click="uncheck($event, #Model.Id)" />
</div>
}
In the controller, I have the following code. The below "if" condition is always turning to true and hence everytime I try selecting a radio, it is always set to false. My goal is to deselect a radio button on click of it, if it is already selected.
$scope.uncheck = function (event, partId) {
if ($scope.gPA(partId).value == event.target.value)
$scope.gPA(partId).value = false
}
The radio button, by design, is not supposed to be unselected. I would consider using a checkbox instead. https://ux.stackexchange.com/questions/13511/why-is-it-impossible-to-deselect-html-radio-inputs
Following code worked:
foreach (var part in Model.ChildParts)
{
<div class="radio col-md-12">
<input type="radio"
id="#Model.FieldName"
name="#Model.FieldName"
ng-model="gPA(#Model.Id).value"
value="#((part as BaseInputPartVM).GetStringValue())"
ng-mouseup = "setPreviousSelectedValue(#Model.Id)"
ng-click="uncheck($event, #Model.Id)" />
</div>
}
<input type="hidden" id="previousRadioSelection" name="previousRadioSelection" ng-model="previousRadioSelection" value="" />
In the controller,
//set previous selected value of radio button
$scope.setPreviousSelectedValue = function (partId) {
$scope.previousRadioSelection = $scope.gPA(partId).value;
}
//uncheck radio button
$scope.uncheck = function (event, partId) {
if ($scope.previousRadioSelection == event.target.value)
$scope.gPA(partId).value = null;
}

Displaying different <tr> depending on radio button (in Knockout)

OK, here goes.
Problem 1:
I want to, based on the radio button checked, display a tr-element or not. Threre will be 3 buttons, displaying 'unlocked achievements', 'locked', and 'all' (both locked + unlocked).
The code below shows how it looks when I try to call three different functions, each setting the tr:s visibility to true/false depending on radio button checked. (D.R.Y, I know, but right now I'm just looking for the functionality).
Problem 2:
Making the for-loop run. itemsListForFilter is declared globally, outside the filter function. itemsListForFilter is a copy of an object arrayMap which is initiallized and filled elsewhere in the code. The array contains items with - amongst other things - the boolean "radioCheck", with the default value "true", which I want to check.
When I access itemsListForFilter in the function where the copying takes place it's filled with items but...
When I try to access itemsListForFilter in the filter function it displays as having the value of null. So the copy is "lost" somewhere :)
View / HTML:
<div class="widget-header-container">
<h3 class="widget-header">Achievements</h3>
<div class="wrapper">
<input type="radio" name="appliedFilter" value="all" data-bind="checked: filterAll"/><label for="all">Show all</label>
<input type="radio" name="appliedFilter" value="unlocked" data-bind="checked: filterUnlocked"/><label for="unlocked">Unlocked</label>
<input type="radio" name="appliedFilter" value="locked" data-bind="checked: filterLocked"/><label for="locked">Locked</label>
</div>
<div><div class="widget-header-line-game1"></div><div class="widget-header-line-game2"></div><div class="widget-header-line-shadow"></div></div>
</div>
<div>
<div class="rounded-box" style="padding:15px;padding-top: 0;background-color:#fff;overflow:hidden;">
<table id="game-achievements" class="table table-condensed" style="margin-top:10px;">
<tbody data-bind="foreach: viewGame.achievements()">
<tr data-bind="visible: radioCheck" style="display: none">
Viewmodel / JS:
filterUnlocked: function(){
return filter('unlocked');
},
filterLocked: function(){
return filter('locked');
},
filterAll: function(){
return filter('all');
},
filter: function(x){
for (var item in itemsListForFilter){
if (x === 'locked'){
item.radioCheck = '!achieved';
}
if (x === 'unlocked') {
item.radioCheck = 'achieved';
}
else {item.radioCheck = true;}
}
Observe that the viewmodel is an object and not a function:
var gamesViewModel = {
self: this,
settings: null,
gameId: null,
authorized: false,
(...)
Right now the functions named filterUnlocked, etc (except filter) displays as "unused properties" in the JS file. What should i do to call them from the HTML? Or is there a better way to accomplish what I'm looking for?
Thank you.
You can get the effect you want with less complexity.
First, the radio group. The checked binding in Knockout kind of replaces (or acts like) the name attribute for a radio group: all the radio buttons should share one. The bound variable will be updated to the value of the selected radio button, which will cause others bound to the same variable to de-select. Now you have one variable to look at instead of three.
Instead of doing filtering by hiding rows, it is more usual to have a computed filter the data, and the table just displays it. The computed can get the data from "outside"; it doesn't have to be an observable or part of the viewmodel (although if it's not an observable, you'll need to tell the computed when to update, if the source changes).
Here's a little working example:
var achievements = [{
name: 'The locked one',
locked: true
}, {
name: 'The unlocked one',
locked: false
}];
var vm = {
appliedFilter: ko.observable('all'),
viewGame: {}
};
vm.viewGame.achievements = ko.computed(function() {
var filter = vm.appliedFilter();
if (filter === 'all') {
return achievements;
}
return ko.utils.arrayFilter(achievements, function(item) {
return item.locked === (filter === 'locked');
});
});
ko.applyBindings(vm);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<div class="widget-header-container">
<h3 class="widget-header">Achievements</h3>
<div class="wrapper">
<input type="radio" value="all" data-bind="checked: appliedFilter" />
<label for="all">Show all</label>
<input type="radio" value="unlocked" data-bind="checked: appliedFilter" />
<label for="unlocked">Unlocked</label>
<input type="radio" value="locked" data-bind="checked: appliedFilter" />
<label for="locked">Locked</label>
</div>
</div>
<div>
<div class="rounded-box" style="padding:15px;padding-top: 0;background-color:#fff;overflow:hidden;">
<table id="game-achievements" class="table table-condensed" style="margin-top:10px;">
<tbody data-bind="foreach: viewGame.achievements()">
<tr><td data-bind="text: name"></td></tr>
</tbody>
</table>
</div>
</div>

Dynamically enabling a check list based on radio button (yes/no) response in a form

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');
}
});
});

How to know which radio is checked from a fieldset

I have the following code:
<fieldset id="dificuldade">
<legend>Dificuldade:</legend>
<input type="radio" name="dificuldade" value="facil"> Fácil </input>
<input type="radio" name="dificuldade" value="medio"> Médio </input>
<input type="radio" name="dificuldade" value="dificil"> Difícil </input>
</fieldset>
<fieldset id="tipo">
<legend>Tipo de jogo:</legend>
<input type="radio" name="Tipodejogo" value="somar"> Somar </input>
<input type="radio" name="Tipodejogo" value="subtrair"> Subtrair </input>
<input type="radio" name="Tipodejogo" value="dividir"> Dividir </input>
<input type="radio" name="Tipodejogo" value="multiplicar"> Multiplicar </input>
</fieldset>
<input type="button" value="Começa" id="button" ></input>
</form>
and here is the jsfiddle with both the html and the js http://jsfiddle.net/3bc9m/15/ . I need to store the values of the 2 fieldset so I, depending on the values picked can generate a game, but my javascript isn't returning any of them. What is wrong? I've been told that JQuery is much easier but i can't use it.
Your code on jsFiddle seems to be working fine for the most part. The only thing was that the elements output and output2 don't exist on the page.
So this code that was supposed to display the selected values wasn't working:
document.getElementById('output').innerHTML = curr.value;
document.getElementById('output2').innerHTML = tdj.value;
The part that actually retrieves the selected values is working fine.
Just add those two elements to the page, like this:
<p>Selected Values:</p>
<div id="output"></div>
<div id="output2"></div>
An updated jsFiddle can be found here.
EDIT
If a radio button from only one of the sets is selected, the code fails. You could use this code to find the selected values instead:
document.getElementById('button').onclick = function() {
var dif = document.getElementsByName('dificuldade');
var tip = document.getElementsByName('Tipodejogo');
var difValue;
for (var i = 0; i < dif.length; i++) {
if (dif[i].type === "radio" && dif[i].checked) {
difValue = dif[i].value;
}
}
var tipValue;
for (var i = 0; i < tip.length; i++) {
if (tip[i].type === "radio" && tip[i].checked) {
tipValue = tip[i].value;
}
}
document.getElementById('output').innerHTML = difValue;
document.getElementById('output2').innerHTML = tipValue;
};​
An updated jsFiddle is here.
Consider this post that adresses the issue. It shows a few javascript methods as well as how you would use it in jQuery.
How can I check whether a radio button is selected with JavaScript?
Is there a specific reason you want to break it down by fieldset instead of directly accessing the radio buttons by name?

Categories

Resources