Create explanation(s) box for radio button form with jQuery - javascript

I'll use a simplified version below but am trying to build a form with simple yes/no questions. If the answer is no, no explanation is required. If the answer is yes, a new table row is inserted and textarea appears requiring an explanation for that particular question.
Of note, I use the jQuery validate plugin to make sure values are checked and plan to implement a required-dependency function for each field in the end.
My Form:
<form name="formtest" action="">
<table class="background_table">
<tbody>
<tr>
<td>Are you a man?</td>
<td>
<input type="radio" name="q1" id="yes1">Yes
<input type="radio" name="q1" id="no1">No
</td>
</tr>
<tr>
<td>Do you have hair?</td>
<td>
<input type="radio" name="q2" id="yes2">Yes
<input type="radio" name="q2" id="no2">No
</td>
</tr>
<tr>
<td>Do you have children?</td>
<td>
<input type="radio" name="q3" id="yes3">Yes
<input type="radio" name="q3" id="no3">No
</td>
</tr>
</tbody>
</table>
<input type="submit" />
</form>
I believe my jQuery function would iterate through all fields (given my actual form has 20+ questions) using the .each() function and then run a test on the individual fields to see if the value was yes:checked. If it was a new row is insert after the field with a blank text area.
I am not quite sure what the best method for naming and identifying the text areas might be at this time. Ultimately, all text area answers could be combined into an array I suppose and broken out by an ID and value but not sure how I'd like to handle that quite yet.
jQuery function:
$(function() {
$('input').each( function() {
if( $('#yes1').is(':checked')) { //need to figure out how to find the yes value for each input
$('#yes1').closest('tr').after('<tr><td colspan="2">Please explain below:<br><textarea name="a1" id="a1"></textarea></td></tr>');
}
});
$("#formtest").validate({
errorLabelContainer: "#form_error_message",
wrapper: "li",
rules: {
q1: 'required',
q2: 'required',
q3: 'required',
q4: 'required',
a1: { required: "yes1:checked" },
a2: { required: "yes2:checked" },
a3: { required: "yes3:checked" },
a4: { required: "yes4:checked" }
},
messages: {
//custom messages for all rules above
},
submitHandler: function() {
//Do processing
}
});
});
My function currently does not work but am looking for guidance as to how this can best be achieved. In the end it may just be easier to present a single text area for explanation of ANY checkbox is answered 'yes' at the end of the form but feel the initial method looks nicer and allows me to separate responses if I wanted.
final update
Of note, as part of a form, users have the ability to get back to this page. To prevent them having to retype answers and selections, I use PHP SESSION variables to contain previously entered data. I needed to make sure the explanation boxes showed or hid themselves as necessary. To prevent any issues with non-js browsers, I have all my explain boxes display initially then are set to hidden if the value of the corresponding checkbox is not equal to value of 1:
$(":radio:checked").each(function() {
if( $(this).val() != 1) {
$(this).closest('tr').next().hide();
}
});

It looks like you are only checking on the initial DOM load. You need to fire off a check on click events so that your box will appear/disappear on click. I would add a hidden tr row containing each comment box, and then either show or hide as appropriate. Something like this:
$('input:radio').click(function() {
$commentTr = $(this).closest('tr').next();
if ($(this).val() == 'Yes') {
$commentTr.hide();
}
else {
$commentTr.show();
}
});
On closer inspection, I suppose the check for a value of "Yes" wouldn't quite work. I'd recommend using HTML label tags with the "for" attribute populated with unique IDs of each input.
<input type="radio" name="q1" id="yes1"><label for="yes1">Yes</label>
Then you could have a check like:
$('label[for="' + id + '"'].html() == 'Yes'

I've set up a jsfiddle here which I think does what you're looking for.

There are a couple of things to consider with your current solution. First of all, as Danimal37 mentions, you are only running this on load of the page. You want the explanation boxes to show/hide whenever the value of each radio button change. Second of all, there is a built-in way to distinguish between the 'yes' and the 'no'. Just give the input elements value attributes. To fix these problems, I propose the following (I've ignored the validation portion and you can see it in action in this jsfiddle: http://jsfiddle.net/xonev/RU986/2/):
// The Javascript
$('input[value="1"]').change(function () {
var explainId = $(this).attr('name') + 'explain';
$(this).closest('tr').after('<tr id="' + explainId + '"><td colspan="2">Please explain below:<br><textarea name="a1" id="a1"></textarea></td></tr>');
});
$('input[value="0"]').change(function () {
var explainId = $(this).attr('name') + 'explain';
$(this).closest('tr').next('tr#' + explainId).remove();
});
<!-- The HTML -->
<form name="formtest" action="">
<table class="background_table">
<tbody>
<tr>
<td>Are you a man?</td>
<td>
<input type="radio" name="q1" id="yes1" value="1" />Yes
<input type="radio" name="q1" id="no1" value="0" />No
</td>
</tr>
<tr>
<td>Do you have hair?</td>
<td>
<input type="radio" name="q2" id="yes2" value="1" />Yes
<input type="radio" name="q2" id="no2" value="0" />No
</td>
</tr>
<tr>
<td>Do you have children?</td>
<td>
<input type="radio" name="q3" id="yes3" value="1" />Yes
<input type="radio" name="q3" id="no3" value="0" />No
</td>
</tr>
</tbody>
</table>
<input type="submit" />
</form>

Related

convert radio buttons to star rating

I am trying to convert the radio buttons in the form to star rating
I am using nintex forms and the way it has DOM structure for the radio button is as below
<table class="controls rating">
<tr>
<td>
<span>
<input type="radio" name="review-rating" id="1" value="1" />
<label for="1">1</label>
</span>
</td>
<td>
<span>
<input type="radio" name="review-rating" value="2" id="2" />
<label for="2">2</label>
</span>
</td>
<td>
<span>
<input type="radio" name="review-rating" value="3" id="3" />
<label for="3">3</label>
</span>
</td>
<td>
<span>
<input type="radio" name="review-rating" value="4" id="4" />
<label for="4">4</label>
</span>
</td>
<td>
<span>
<input type="radio" name="review-rating" value="5" id="5" />
<label for="5">5</label>
</span>
</td>
</tr>
</table>
Now I found a jsfiddle which does what I expected, but the dom structure was different
I made some tweaks and got the radio buttons appear as star, but its not working as expected
Here is the fiddle
I want the star rating on top to work like the star rating in bottom.
P.S: Its ok if the bottom one doesn't work after changes. I just want the star rating to be working for my DOM structure(top one in fiddle)
Try this, I just added the undo
$('.controls.rating')
.addClass('starRating') //in case js is turned off, it fals back to standard radio button
.on('mouseenter', 'label', function(){
DisplayRating($(this)); // when we hover into a label, show the ratings
}
)
.on('mouseleave', function() {
// when we leave the rating div, figure out which one is selected and show the correct rating level
var $this = $(this),
$selectedRating = $this.find('input:checked');
if ($selectedRating.length == 1) {
DisplayRating($selectedRating); // a rating has been selected, show the stars
} else {
$this.find('label').removeClass('on'); // nothing clicked, remove the stars
};
}
);
var DisplayRating = function($el){
// for the passed in element, add the 'on' class to this and all prev labels
// and remove the 'on' class from all next labels. This stops the flicker of removing then adding back
$el.addClass('on');
$el.parent('label').addClass('on');
$el.closest('td').prevAll().find('label').addClass('on');
$el.closest('td').nextAll().find('label').removeClass('on');
};
Edit: I just notice a bug lately so I edited it and fix the bug
JS Fiddle
The problem: your "label" are not next to each other. Convert css and event select to your "td".
https://jsfiddle.net/8cn2mekf/1/
You need to use find to remove the on class on deeper nodes children only works on level one child nodes
https://jsfiddle.net/sanddune/z1sws1w7/

Why does my radio button event trigger when a different radio button is pressed?

I am using the following code to show "pers" and hide "bus" and vice versa
JQuery:
$('input[name="perorbus"]').click(function() {
if ($(this).attr('id') == 'bus') {
$('#showbus').show();
$('#showper').hide();
}
if ($(this).attr('id') == 'pers') {
$('#showper').show();
$('#showbus').hide();
}
});
HTML:
<fieldset id="perorbus">
<label style="font-size: large;">Personal Or Business?</label>
<br/>
<input type="radio" class="PerOrBus" value="pers" id="pers" name="perorbus"/>
<label style="font-size: medium;">Personal Customer</label>
<input type="radio" class="PerOrBus" id="bus" value="bus" name="perorbus"/>
<label style="font-size: medium;">Business Customer?</label>
<br/>
</fieldset>
<table id="showper">
<tr>
<td>Show Personal</td>
</table>
<table id="showbus">
<tr>
<td>Show Business</td>
</table>
Any other Radio button that I put on the page triggers this. They are all given a name attribute like the following:
<fieldset id="CACCc">
<input type="radio" id="1b" class="2b" value="4b" name="1b"/> Yes
<br/>
<input type="radio" id="id12" class="4class" value="4c" name="id12"/> No ​
<br/></fieldset>
However, I have to assign the name on doc ready with jquery like the following:
document.getElementById("1b").setAttribute('name', '1b');
document.getElementById("id12").setAttribute('name', 'id12');
This is due to me being limited to not using name attributes in the HTML (long story)
Any help would be great, thanks
Try going by the radio button and then the name of the radio button. Also use the change trigger. By the way, your fieldset has the same name. That could be an issue.
$(document).ready(function() {
// Update names
$('input[type=radio][name=perorbus]').change(function() {
if (this.id == 'bus') {
$('#showbus').show();
$('#showper').hide();
}
if (this.id == 'pers') {
$('#showper').show();
$('#showbus').hide();
}
});
});
The answer to my issue specifically is that is was a Sharepoint caching issue. Because I do not have access to remove cache, I simply renamed and re-id'd everything and got it working.
This will not solve other peoples issues, probably but the other answers should.

Hide div for Radio button selected value using jquery- Not working

I want to hide a div (AppliedCourse), when radi button value is Agent. I wrote below code but it is not working.
Any idea?
$('#HearAboutUs').click(function() {
$("#AppliedCourse").toggle($('input[name=HearAboutUs]:checked').val()='Agent');
});
<tr><td class="text"><input type="radio" name="HearAboutUs" value="Press">Press & Print media
<input type="radio" name="HearAboutUs" value="Internet">Internet
<input type="radio" name="HearAboutUs" value="Agent">Agent
<input type="radio" name="HearAboutUs" value="Friend">Friend
<input type="radio" name="HearAboutUs" value="Other" checked="checked">Other</td></tr>
Either your HTML is incomplete or your first selector is wrong. It is possible that your click handler is not being called because you have no element with id 'HeadAboutUs'. You might want to listen to clicks on the inputs themselves in that case.
Also, your logic is not quite right. Toggle hides the element if the parameter is false, so you want to negate it using !=. Try:
$('input[name=HearAboutUs]').click(function() {
var inputValue = $('input[name=HearAboutUs]:checked').val()
$("#AppliedCourse").toggle( inputValue!='Agent');
});
I have made a JSFiddle with a working solution: http://jsfiddle.net/c045fn2m/2/
Your code is looking for an element with id HearAboutUs, but you don't have this on your page.
You do have a bunch of inputs with name="HearAboutUs". If you look for those, you'll be able to execute your code.
$("input[name='HearAboutUs']").click(function() {
var clicked = $(this).val(); //save value of the input that was clicked on
if(clicked == 'Agent'){ //check if that val is "Agent"
$('#AppliedCourse').hide();
}else{
$('#AppliedCourse').show();
}
});
JS Fiddle Demo
Another option as suggested by #Regent is to replace the if/else statement with $('#AppliedCourse').toggle(clicked !== 'Agent');. This works too.
Here is the Fiddle: http://jsfiddle.net/L9bfddos/
<tr>
<td class="text">
<input type="radio" name="HearAboutUs" value="Press">Press & Print media
<input type="radio" name="HearAboutUs" value="Internet">Internet
<input type="radio" name="HearAboutUs" value="Agent">Agent
<input type="radio" name="HearAboutUs" value="Friend">Friend
<input type="radio" name="HearAboutUs" value="Other" checked="checked">Other
</td>
Test
$("input[name='HearAboutUs']").click(function() {
var value = $('input[name=HearAboutUs]:checked').val();
if(value === 'Agent'){
$('#AppliedCourse').hide();
}
else{
$('#AppliedCourse').show();
}
});

How to disable an checkbox once a certain radio button is clicked.

Want to disable the checkbox "animation" once the "3D" radio button is selected. and too un-disable once the "2D" is selected.
html code
<script type="text/x-handlebars" id="createProject">
<div class="projectForm">
<table cellpadding="10">
<tr>
<td> Project Name </td>
<td> <input type="text" name="projectName" /> </td>
</tr>
<tr>
<td> Project Description </td>
<td> <textarea name="projectDesc" > </textarea> </td>
</tr>
<tr>
<td> Pipleline Type </td>
<td>
<input type="radio" name="pipelineType" value="2d" id="2d" checked="checked" onclick="displayType"> 2D Pipleline <br>
<input type="radio" name="pipelineType" value="3d" id="3d" onclick="displayType"> 3D Pipleline </td>
</tr>
<tr>
<td> Project Roles </td>
<td> <input type="checkbox" name="projectRoles" id="animation"value="Animation Clean Up"> Animation Clean Up
<input type="checkbox" name="projectRoles" value="Background Painting"> Background Painting
<input type="checkbox" name="projectRoles" value="Casting & Recording"> Casting & Recording
<input type="checkbox" name="projectRoles" value="Color Styling"> Color Styling
</td>
</tr>
</table>
</div>
</script>
Im new at ember.js, I have the java code in the app.js. Would it be better if it was placed in another js file?
javascrirpt
function displayType() {
if(document.getElementById('2d').checked) {
document.getElementById('animation').disabled = false;
}
else {
document.getElementById('animation').disabled=true;
}
}
Any suggestion would be really helpful. Thanks.
The first thing I noticed is that you have forgotten to make your onclick calls into function calls:
onclick="displayType"
Needs to change to
onclick="displayType()"
Next, when I put your code into a jsfiddle, it was not finding the function because it was not in the global scope. When I changed the function definition from:
function displayType() {
to:
window.displayType = function () {
it solved the problem. This may be different depending on where you put your code.
Try the following to disable it:
document.getElementById('animation').removeAttribute('disabled');
try this solution,
remove <script type="text/x-handlebars" id="createProject"> and its closing tag.
Change your code from onclick="displayType" to onclick="displayType()" in first two radio buttons.
Shorthand, pass a variable to determine which radio button is clicked
function displayType(def) {
var checked = def === '3d';
document.getElementById('animation').disabled = checked;
}
HTML, pass a variable to the javascript function indicating whether its 3d or 2d thats clicked
<input type="radio" name="pipelineType" value="2d" id="2d" checked="checked" onclick="displayType('2d')"> 2D Pipleline <br>
<input type="radio" name="pipelineType" value="3d" id="3d" onclick="displayType('3d')"> 3D Pipleline </td>

jQuery - checkboxes selecting all on a row or with similar names & ID's

Using jQuery 1.9.1 & getting XML returned from a query that needs to be displayed in a web page as shown in the picture below. I had asked a similar question several days ago but was all over the place in what I was asking. Hope to ask better questions this time.
For the items in the picture, the XML input would be:
<Classrooms>
<Room Number="3">
<Machine>310</Machine>
<Machine>320</Machine>
<Machine>340</Machine>
<Machine>350</Machine>
</Room>
<Room Number="8">
<Machine>810</Machine>
<Machine>820</Machine>
<Machine>840</Machine>
</Room>
<Room Number="10">
<Machine>1010</Machine>
<Machine>1020</Machine>
</Room>
</Classrooms>
The code below is a function that is called upon a successful AJAX GET and builds the checkboxes in a table on the web page.
var $roomList = $( items );
var roomListString = jQ_xmlDocToString( $roomList );
var roomListXML = $.parseXML(roomListString);
$(roomListXML).find("Row").each(function() {
var activeRooms = $( roomListXML ).find("Row").text();
var nbrRooms = $(activeRooms).find("Room").size();
$(activeRooms).find("Room").each(function() {
var roomNo = $(this).attr("Number");
var roomchk = "Room"+roomNo;
var $tr = $("<tr />");
$tr.append('<td><input type="checkbox" name="'+roomchk+'" id="'+roomchk+'" class="checkall" /><label for="'+roomchk+'">Room '+roomNo+'</td>');
$("#mytable").append( $tr );
$(this).children().each(function() {
var machID = $(this).text();
var idname = "Room"+roomNo+"Mach"+machID;
$tr.append('<td><input type="checkbox" name="'+idname+'" id="'+idname+'" /><label for="'+idname+'">'+machID+'</td>');
$("#mytable").append( $tr );
});
});
});
When the above code is run on the data, the HTML in the table is as shown below.
<tbody>
<tr>
<td>
<input name="Room3" id="Room3" class="checkall" type="checkbox" />
<label for="Room3">Room 3</label>
</td>
<td>
<input name="Room3Mach310" id="Room3Mach310" type="checkbox" />
<label for="Room3Mach310">310</label>
</td>
<td>
<input name="Room3Mach320" id="Room3Mach320" type="checkbox" />
<label for="Room3Mach320">320</label>
</td>
<td>
<input name="Room3Mach340" id="Room3Mach340" type="checkbox" />
<label for="Room3Mach340">340</label>
</td>
<td>
<input name="Room3Mach350" id="Room3Mach350" type="checkbox" />
<label for="Room3Mach350">350</label>
</td>
</tr>
<tr>
<td>
<input name="Room8" id="Room8" class="checkall" type="checkbox" />
<label for="Room8">Room 8</label>
</td>
<td>
<input name="Room8Mach810" id="Room8Mach810" type="checkbox" />
<label for="Room8Mach810">810</label>
</td>
<td>
<input name="Room8Mach820" id="Room8Mach820" type="checkbox" />
<label for="Room8Mach820">820</label>
</td>
<td>
<input name="Room8Mach840" id="Room8Mach840" type="checkbox" />
<label for="Room8Mach840">840</label>
</td>
</tr>
<tr>
<td>
<input name="Room10" id="Room10" class="checkall" type="checkbox" />
<label for="Room10">Room 10</label>
</td>
<td>
<input name="Room10Mach1010" id="Room10Mach1010" type="checkbox" />
<label for="Room10Mach1010">1010</label>
</td>
<td>
<input name="Room10Mach1020" id="Room10Mach1020" type="checkbox" />
<label for="Room10Mach1020">1020</label>
</td>
</tr>
</tbody>
Selection of any checkbox on the page will enable a SUBMIT button on the page, which when clicked will pass the value of the boxes checked into another function. The user can select any number of the individual boxes (the ones with the number beside them), regardless of the room those items are associated with. When the user selects a Room checkbox though, ALL the individual checkboxes for that room should also be checked. The individual values are the ones I want. When the SUBMIT button is clicked, the individual values are all that will be sent to that function.
I had looked at this topic about using a checkbox class to select all.
I'm using the code below to find what's checked. I can see when I select an individual box that it gets added to the array. I can also see when I select a Room that the checkall is found, but I can't seem to make the individual checkboxes get checked once I do. I had been attempting to use the Attribute Starts With jQuery selector, but haven't been able to get it to check the boxes.
$("#mytable").click(function(e) {
var ele = $(this).find(":checkbox");
var zall = $(this).find(":checkbox.checkall:checked");
if (zall) {
var zname = $(zall).attr("name");
var selectallmachines = "input[name^='" + zname +"']:checked:enabled";
$( $(selectallmachines), "#mytable");
}
var arr = [];
$(":checkbox:checked").each(function(i) {
arr[i] = $(this).val();
});
});
I'm sure that it is something that I'm overlooking, but what am I missing? Would appreciate any suggestions or guidance on what I'm doing wrong, or if there's perhaps a better way to do what I'm doing.
Thanks!
You can do something like this
$('.checkall').change(function(){
$('input[id^='+this.id+']').prop('checked',this.checked);
});
when .checkall is clicked/changes - set checked property on all inputs with an id that starts with the current clicked elements id
FIDDLE
Though you probably should delegate since you are using ajax to get the elements - this is assuming #mytable exists on DOM Ready - or replace with an ancestor element that does
$('#mytable').on('click','.checkall',function(){
$('input[id^='+this.id+']').prop('checked',this.checked);
});
another alternative is to give the checkall id as a class to the relative checkboxes
$tr.append('<td><input type="checkbox" name="'+idname+'" id="'+idname+'" class="'+roomchk+'"/><label for="'+idname+'">'+machID+'</td>');
then you can do
$('#mytable').on('click','.checkall',function(){
$('input.'+this.id).prop('checked',this.checked);
});
FIDDLE

Categories