Unique Ids to bind radio buttons to text areas? - javascript

I have a form with multiple yes/no radio buttons and text area I would like to disable ("grey out") when yes is selected and enable when no is selected.
What I have currently only works for the first text area, all other radio buttons only effect the first text area because they have matching ids.
This is my view I am using.
#for (int i = 0; i < Model.Questions.Count; i++)
{
<tr>
<td>
<div>
#Html.RadioButtonFor(p => Model.Questions[i].AnswerSelected, true, new { id = "radio" + i, #class = "class" + i, value = "yes", }) Yes
#Html.RadioButtonFor(p => Model.Questions[i].AnswerSelected, false, new { id = "radio" + i, #class = "class" + i, value = "no" }) No
</div>
</td>
<td>
#Html.TextAreaFor(p => Model.Questions[i].ActionToTake, new { id = "text" + i })
</td>
</tr>
}
I know I will need to generate unique ids somehow for each pair of radio buttons and bind them to the text area somehow. This is the script I'm currently using.
$(document).ready(function() {
$(".class1").change(function (e) {
if ($(this).val() === 'True') {
$("#text1").prop('readonly', true);
$("#text1").css('background-color', '#EBEBE4');
} else if ($(this).val() === 'False') {
$("#text1").prop('readonly', false);
$("#text1").css('background-color', '#FFFFFF');
}
});
})
Whats a good way to approach this? I'm still new to javascript so any additional explanation for what you're doing would be helpful.

As I said in my comments, you do not need to have IDs unless you use them elsewhere. You can simply have a group, may be a DIV with a class and radio buttons and text area as the group children. Did you want something like this?
$(function() {
var $choices = $(".group").find(":radio");
$choices.on("change", function() {
var $this = $(this);
var choice = $.trim( $this.val() );
var tarea = $this.closest(".group").find("textarea");
tarea.prop("readOnly", choice === "yes");
if ( choice === "yes" ) {
//do your stuff when val = yes
} else {
//do your stuff when val = no
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="group">
<input type="radio" name="choice1" value="yes" />Yes
<input type="radio" name="choice1" value="no" />No
<textarea rows="4" cols="20"></textarea>
</div>
<div class="group">
<input type="radio" name="choice2" value="yes" />Yes
<input type="radio" name="choice2" value="no" />No
<textarea rows="4" cols="20"></textarea>
</div>
<div class="group">
<input type="radio" name="choice3" value="yes" />Yes
<input type="radio" name="choice3" value="no" />No
<textarea rows="4" cols="20"></textarea>
</div>
<div class="group">
<input type="radio" name="choice4" value="yes" />Yes
<input type="radio" name="choice4" value="no" />No
<textarea rows="4" cols="20"></textarea>
</div>

Related

Pushing attribute value to two different arrays based on radio options selected

In short, if a user selects yes to a radio option, I'm trying to obtain the data-name attribute from that input and push it to an array called accepted_array.
If a user selects no, then store data-name to declined_array.
Here is a visual to the markup:
<div class="guest__options-group">
<input id="attending-yes-0" type="radio" name="attendance-0" value="yes" data-name="John" required />
<label for="attending-yes-0">Yes</label>
</div>
<div class="guest__options-group">
<input id="attending-no-0" type="radio" name="attendance-0" value="no" data-name="John" required />
<label for="attending-no-0">No</label>
</div>
<!-- options for Alex -->
<div class="guest__options-group">
<input id="attending-yes-1" type="radio" name="attendance-1" value="yes" data-name="Alex" required />
<label for="attending-yes-1">Yes</label>
</div>
<div class="guest__options-group">
<input id="attending-no-1" type="radio" name="attendance-1" value="no" data-name="Alex" required />
<label for="attending-no-1">No</label>
</div>
Here are 2 approaches I've experimented with:
First approache.
(function ($) {
$( ".guest__attendance-input" ).each(function(index) {
$(this).on("click", function(){
var $this = $(this);
var checkedVal = $this.val();
var accepted_array = [];
var declined_array = [];
if( checkedVal == "yes" ) {
var name = $this.data("name");
accepted_array.push(name);
} else {
declined_array.push(name);
}
console.log("accepted " + accepted_array.join(","));
console.log("declined " + accepted_array.join(","));
});
});
}) (jQuery);
This only executes for the selected user and adds the name to both arrays.
Second approache.
(function ($) {
$( ".guest__attendance-input" ).each(function(index) {
$(this).on("click", function(){
var $this = $(this);
var data = [];
var checked = $this.is(':checked');
var name = $this.attr('data-name');
if (checked) {
if (!data[name]) {
data[name] = []
}
data[name].push($this.val())
}
console.log(data);
});
});
}) (jQuery);
Which only adds the user to a single array.
If both select yes, I need both names in the accepted_array. If someone selects yes initially and then selects no I need to remove them from the accepted_array and vice versa.
You can use splice with inArray to remove value from array if someone selects yes initially and then selects no and vice versa.
Example:
var accepted_array = [];
var declined_array = [];
$('.guest__options-group > input[type=radio]').on('change', function() {
var $this = $(this);
var name = $this.data("name");
var checkedVal = $this.val();
var name = $this.data("name");
if (checkedVal == "yes") {
accepted_array.push(name);
declined_array.splice($.inArray(name, declined_array), 1);
} else {
declined_array.push(name);
accepted_array.splice($.inArray(name, accepted_array), 1);
}
console.log("accepted " + accepted_array.join(","));
console.log("declined " + declined_array.join(","));
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!-- options for John -->
<div class="guest__options-group">
<input id="attending-yes-0" type="radio" name="attendance-0" value="yes" data-name="John" required />
<label for="attending-yes-0">Yes</label>
</div>
<div class="guest__options-group">
<input id="attending-no-0" type="radio" name="attendance-0" value="no" data-name="John" required />
<label for="attending-no-0">No</label>
</div>
<!-- options for Alex -->
<div class="guest__options-group">
<input id="attending-yes-1" type="radio" name="attendance-1" value="yes" data-name="Alex" required />
<label for="attending-yes-1">Yes</label>
</div>
<div class="guest__options-group">
<input id="attending-no-1" type="radio" name="attendance-1" value="no" data-name="Alex" required />
<label for="attending-no-1">No</label>
</div>

Div not showing when radio button checked

I have a radio button that will show a div with an input text when it is checked 'NO'. But it is not showing the div, however when I play around the radio button then the div will show. Where am I missing?
function CheckboxCheck(checkbox) {
var firstCheckbox = document.getElementById('check1');
var secondCheckbox = document.getElementById('check2');
var rmk = document.getElementById("rmk");
if (firstCheckbox.checked == true) {
rmk.style.display = "none";
} else if (secondCheckbox.checked == true) {
rmk.style.display = "block";
document.getElementById("rmk").required = true;
}
}
<div>
<label>Have you registered the course?</label>
<table border=0>
<tr>
<td>YES </td>
<td><input type="radio" name="register" value="Y" id="check1" onclick="CheckboxCheck('first')">  </td>
<td>NO </td>
<td><input type="radio" name="register" value="N" checked id="check2" onclick="CheckboxCheck('second')"></td>
</table>
</div>
<div id="rmk" style="display:none">
<label>Reasons</label>
<input type="text" name="remarks" class="form-control">
</div>
There are a few structure and accessibility proposals going on in this suggestion but I think strictly speaking, the easiest solve for you is to invoke the function on page load. Give this example a look:
function CheckboxCheck(checkbox) {
var firstCheckbox = document.getElementById('check1');
var secondCheckbox = document.getElementById('check2');
var rmk = document.getElementById("rmk");
var rmkdiv = document.getElementById("rmk-div");
if (firstCheckbox.checked == true) {
rmkdiv.style.display = "none";
} else if (secondCheckbox.checked == true) {
rmkdiv.style.display = "block";
rmk.required = true;
}
}
CheckboxCheck()
<div>
<p>Have you registered the course?</p>
<label>
YES<input
type="radio"
name="register"
value="Y"
id="check1"
onclick="CheckboxCheck()"
/></label>
<label>NO
<input
type="radio"
name="register"
value="N"
checked
id="check2"
onclick="CheckboxCheck()"
/>
</label>
<div id="rmk-div" style="display: none">
<label>Reasons</label>
<input id="rmk" type="text" name="remarks" class="form-control" />
</div>
</div>
Your input field will only be visible when the function CheckboxCheck is executed. Since "NO" is checked from the beginning, the function will not be executed because it is only called when a change takes place.

Link Radiobox button to Input

I have 2 radio button, each valued Yes and No respectively and 1 textbox.. If I checked on No button, the input textbox will open. If checked on Yes, textbox will disabled.
This code is working fine but I want to delete content that input to the textbox if the user checked Yes
function ismcstopu() {
var chkNo = document.getElementById("radio2_ismcstop");
var mcnostopreason = document.getElementById("mcnostopreason");
mcnostopreason.disabled = chkNo.checked ? false : true;
if (!mcnostopreason.disabled) {
mcnostopreason.focus();
} else {
mcnostopreason.val('');
}
}
<input type="radio" class="form-check-input" id="radio1_ismcstop" name="ismcstop" onclick="ismcstopu()" value="Yes">Yes
<input type="radio" class="form-check-input" id="radio2_ismcstop" name="ismcstop" onclick="ismcstopu()" value="No">No
<label for="mcnostopreason">If No, Reason:</label>
<input class="inputstyle-100" type="text" id="mcnostopreason" name="mcnostopreason" value="" disabled>
.val is a jQuery construct but you are using DOM
Here is a better version using eventListener
Change the document.getElementById("container") to whatever container you have (your form for example)
Note: It is often better to test true than to test false
I also added labels to the radios so we can click the yes or no too
document.getElementById("container").addEventListener("click", function(e) {
const tgt = e.target;
if (tgt.name === "ismcstop") {
const mcnostopreason = document.getElementById("mcnostopreason");
mcnostopreason.disabled = tgt.value === "Yes";
if (mcnostopreason.disabled) {
mcnostopreason.value = '';
} else {
mcnostopreason.focus();
}
}
})
<div id="container">
<label><input type="radio" class="form-check-input" id="radio1_ismcstop" name="ismcstop" value="Yes">Yes</label>
<label><input type="radio" class="form-check-input" id="radio2_ismcstop" name="ismcstop" value="No">No</label>
<label for="mcnostopreason">If No, Reason:
<input class="inputstyle-100" type="text" id="mcnostopreason" name="mcnostopreason" value="" disabled>
</label>
</div>
jQuery version
$("[name=ismcstop]").on("click", function() {
if (this.name === "ismcstop") {
const $mcnostopreason = $("#mcnostopreason");
$mcnostopreason.prop("disabled", this.value === "Yes");
if ($mcnostopreason.is(":disabled")) {
$mcnostopreason.val("");
} else {
$mcnostopreason.focus();
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<label><input type="radio" class="form-check-input" id="radio1_ismcstop" name="ismcstop" value="Yes">Yes</label>
<label><input type="radio" class="form-check-input" id="radio2_ismcstop" name="ismcstop" value="No">No</label>
<label for="mcnostopreason">If No, Reason:
<input class="inputstyle-100" type="text" id="mcnostopreason" name="mcnostopreason" value="" disabled>
</label>
mcnostopreason is not a jQuery object. therefore you could do: var mcnostopreason = $("#mcnostopreason");
Or you could just change mcnostopreason.val('') to mcnostopreason.value = '' ( this will mean you don't need to change anything else)

check if at least one radio button is selected from inputs with the same class javascript

I am trying to make a small quiz web app using javascript/html. The individual questions on the page are separated by div tags with the same "quiz" class. There are 2 buttons on the page, a previous and a next button. Depending on what the user clicks, the page will display the next quiz on the page by hiding/showing the divs. What I am trying to do is add an input validation to the application. Before the user moves onto the next question I want to make it so that one radio button must be selected, otherwise show an alert box. The radio buttons that belong to the same question all have the same class (i.e. the radio buttons for question 1 all have the same class quiz1). Currently app is able to check which input has been selected (by using if element.checked). Following this logic, I tried using if(!element.checked) create an alert, however the alert box get stuck in a loop. Thus, so far the only other solution I have been able to come up with is to check if at least one radio button within the same class has been selected, which I am unsure how to achieve.
let savedAns = [];
const nextBtn = document.getElementById('next');
const prevBtn = document.getElementById('prev');
const quizes = document.querySelectorAll('.quiz');
const form = document.querySelector('form');
const inputEl = document.querySelectorAll('input');
const total = quizes.length;
//a variable to increment the classes
let ind = 0;
//get all the input elements for each question, assign a class
quizes.forEach(function(element) {
ind++;
let inputs = element.querySelectorAll('input');
inputs.forEach((input) => {
input.classList.add(`quiz${ind}`)
})
})
//keep a track of which question is visible
let count = 0;
//function to hide all the quizes
const hide = function() {
quizes.forEach((element) => {
element.style.display = 'none'
})
}
//show and hide divs when user presses next
nextBtn.addEventListener('click', function() {
if (count < total - 1) {
inputEl.forEach(function(element) {
if (element.checked) {
savedAns[count] = element.value;
console.log(savedAns)
}
})
count++;
} else {
inputEl.forEach(function(element) {
if (element.checked) {
savedAns[count] = element.value;
console.log(savedAns)
}
})
alert('no more questions left')
return
}
hide();
quizes[count].style.display = 'block'
})
prevBtn.addEventListener('click', function() {
if (count > 0) {
count--;
} else {
alert('no more previous questions')
return
}
hide();
quizes[count].style.display = 'block'
})
<div class="content">
<form>
<div class="quiz">
<p>Question 1</p>
<input type="radio" name="answer" value="1">
<input type="radio" name="answer" value="2">
<input type="radio" name="answer" value="3">
</div>
<div class="quiz" style="display: none;">
<p>Question 2</p>
<input type="radio" name="answer" value="1">
<input type="radio" name="answer" value="2">
<input type="radio" name="answer" value="3">
</div>
<div class="quiz" style="display: none;">
<p>Question 3</p>
<input type="radio" name="answer" value="1">
<input type="radio" name="answer" value="2">
<input type="radio" name="answer" value="3">
</div>
<div class="quiz" style="display: none;">
<p>Question 4</p>
<input type="radio" name="answer" value="1">
<input type="radio" name="answer" value="2">
<input type="radio" name="answer" value="3">
</div>
</form>
<button id="prev">Prev</button>
<button id="next">Next</button>
</div>
If there are any other ways to solve the problem, hints towards the right direction is greatly appreciated. I am also writing this application using purely javascript so no jquery please. Thank you.
Since you already know which question is active currently, you can check if any of the input under the active question is checked.
let selectedAnswer = -1;
const activeInputs = quizes[count].querySelectorAll('input');
activeInputs.forEach((input, index) => {
if(input.checked) selectedAnswer = index;
});
if (selectedAnswer === -1) {
alert('Select answer');
return;
}
below is the working code snippet.
let savedAns = [];
const nextBtn = document.getElementById('next');
const prevBtn = document.getElementById('prev');
const quizes = document.querySelectorAll('.quiz');
const form = document.querySelector('form');
const inputEl = document.querySelectorAll('input');
const total = quizes.length;
//a variable to increment the classes
let ind = 0;
//get all the input elements for each question, assign a class
quizes.forEach(function(element) {
ind++;
let inputs = element.querySelectorAll('input');
inputs.forEach((input) => {
input.classList.add(`quiz${ind}`)
})
})
//keep a track of which question is visible
let count = 0;
//function to hide all the quizes
const hide = function() {
quizes.forEach((element) => {
element.style.display = 'none'
})
}
//show and hide divs when user presses next
nextBtn.addEventListener('click', function() {
let selectedAnswer = -1;
const activeInputs = quizes[count].querySelectorAll('input');
activeInputs.forEach((input, index) => {
if(input.checked) selectedAnswer = index;
});
if (selectedAnswer === -1) {
alert('Select answer');
return;
}
if (count < total - 1) {
inputEl.forEach(function(element) {
if (element.checked) {
savedAns[count] = element.value;
console.log(savedAns)
}
})
count++;
} else {
inputEl.forEach(function(element) {
if (element.checked) {
savedAns[count] = element.value;
console.log(savedAns)
}
})
alert('no more questions left')
return
}
hide();
quizes[count].style.display = 'block'
})
prevBtn.addEventListener('click', function() {
if (count > 0) {
count--;
} else {
alert('no more previous questions')
return
}
hide();
quizes[count].style.display = 'block'
})
<div class="content">
<form>
<div class="quiz">
<p>Question 1</p>
<input type="radio" name="answer" value="1">
<input type="radio" name="answer" value="2">
<input type="radio" name="answer" value="3">
</div>
<div class="quiz" style="display: none;">
<p>Question 2</p>
<input type="radio" name="answer" value="1">
<input type="radio" name="answer" value="2">
<input type="radio" name="answer" value="3">
</div>
<div class="quiz" style="display: none;">
<p>Question 3</p>
<input type="radio" name="answer" value="1">
<input type="radio" name="answer" value="2">
<input type="radio" name="answer" value="3">
</div>
<div class="quiz" style="display: none;">
<p>Question 4</p>
<input type="radio" name="answer" value="1">
<input type="radio" name="answer" value="2">
<input type="radio" name="answer" value="3">
</div>
</form>
<button id="prev">Prev</button>
<button id="next">Next</button>
</div>

Add the sum of from the value select of radiobutton

For instance, radiobutton one = value 1, radiobutton two = value 2.
Here is the code I have:
Script file:
<script type="text/javascript">
$(document).ready(function () {
$("div[data-role='footer']").prepend('Back');
$(".Next").click(function () {
$.mobile.changePage("#" + $("#Answer").val());
});
$("input[type=radio]").click(function () {
var answer = $(this).val();
$("#Answer").val(answer);
});
$('.Answer').live("click", function () {
var NextQuestionID = $(this).attr('NextQuestionId');
if (NextQuestionID == '') {
location.href = "/Surveys/Index";
}
$("#survey").load('/Questions/GetQuestion', { Id: NextQuestionID }, function () {
$('#answerInput').textinput();
$(".Answer").button();
});
});
});
and here is my markup:
<input type="radio" name="Answer" id="radio-choice-1" value="Question2" />
<input id="Answer" class="Answer" type="hidden" value="first" />
<div class="innerspacer">
Next
</div>
How do I assign the radio button as value from 1 to 4 and sum up the value for all the question?
There is a lot going on in your question and it is unclear what you want. I'm taking a guess and assuming you have a say 5 radio buttons and you want the 5th radio button value to be the sum of the other 4 values. Is that correct?
Here is an example of doing that: jsfiddle
HTML:
<div id="container">
<label>
<input type="radio" name="something" value="1">
A?
</label>
<label>
<input type="radio" name="something" value="3">
B?
</label>
<label>
<input type="radio" name="something" value="5">
C?
</label>
<label>
<input type="radio" name="something" value="">
All?
</label>
</div>
JavaScript:
$(document).ready(function() {
var choices = $('input[name="something"]');
var total = 0;
choices.each(function() {
var choice = $(this);
var value = parseInt(choice.val(), 10);
if (!isNaN(value)) {
total += value;
}
});
choices.filter(':last').val(total);
});
You will need to adapt this to your HTML.

Categories

Resources