I'm making a quiz app.To show the progress of the quiz there is question pallette of small boxes which turn yellow when users click on any of the the radio button to show that the user has attempted the question.Along with this there is a button to move to the previous question.To show the users initial answer I have used ng-checked directive with some logic in the controller.Everything is working fine but after attempting a question when I move to the next question and click on the same option as the previous question then the question pallette box does not turn yellow.But when I click on the other option it works fine.
.html
<div class="questionsBox" >
<div class="questions">{{liveCtrl.questions[liveCtrl.activeQuestion].question}}</div>
<ul class="answerList">
<li>
<label>
<input data-id="{{liveCtrl.activeQuestion}}" type="radio" ng-checked="liveCtrl.useranswers[liveCtrl.activeQuestion].q===1" ng-click="liveCtrl.answers(liveCtrl.activeQuestion,1)" name="answerGroup" value="0" > {{liveCtrl.questions[liveCtrl.activeQuestion].optionA}}</label>
</li>
<li>
<label>
<input data-id="{{liveCtrl.activeQuestion}}" type="radio" ng-checked="liveCtrl.useranswers[liveCtrl.activeQuestion].q===2" ng-click="liveCtrl.answers(liveCtrl.activeQuestion,2)" name="answerGroup" value="1" > {{liveCtrl.questions[liveCtrl.activeQuestion].optionB}}</label>
</li>
<li>
<label>
<input data-id="{{liveCtrl.activeQuestion}}" type="radio" ng-checked="liveCtrl.useranswers[liveCtrl.activeQuestion].q===3" ng-click="liveCtrl.answers(liveCtrl.activeQuestion,3)" name="answerGroup" value="2" > {{liveCtrl.questions[liveCtrl.activeQuestion].optionC}}</label>
</li>
<li>
<label>
<input data-id="{{liveCtrl.activeQuestion}}" type="radio" ng-checked="liveCtrl.useranswers[liveCtrl.activeQuestion].q===4" ng-click="liveCtrl.answers(liveCtrl.activeQuestion,4)" name="answerGroup" value="3" > {{liveCtrl.questions[liveCtrl.activeQuestion].optionD}}</label>
</li>
</ul>
<div class="questionsRow">
<button ng-disabled="liveCtrl.questions.length==liveCtrl.activeQuestion+1" class="subques btn btn-lg btn-secondary" ng-click="liveCtrl.nextQuestion()">Save & Next</button>
<button ng-click="liveCtrl.prevQuestion()" ng-disabled="liveCtrl.activeQuestion == 0" class="subques btn btn-lg btn-secondary" >Previous</button>
</div>
</div>
//Question Pallete
<div class="question-pallete">
<div id="{{$index}}" ng-repeat="question in liveCtrl.questions" class="square">
<a ng-click="liveCtrl.gotoQues($index)">
{{$index + 1}}
</a>
</div>
//jquery to give color to the boxes
<script type="text/javascript">
$(document).on('click',"input[name='answerGroup']",function(){
var qid=$(this).data('id');
console.log(qid);
$('#'+qid).addClass('box-color');
});
</script>
Controller functions
this.nextQuestion=()=>{
live.activeQuestion++;
//console.log(live.activeQuestion);
};
this.prevQuestion=()=>{
live.activeQuestion--;
//console.log(live.activeQuestion);
};
this.gotoQues=(qno)=>{
live.activeQuestion=qno;
}
this.answers=(qid,option)=>{
//console.log(qid);
live.useranswers[qid]={
q:option
};
When I'm tried to console qid in jquery part it outputs the same qid for the same option in the next question but it is not the case for other options.I think "data-id" in html is not updating for that case.Sorry If I was not able to explain it properly.
I find 2 issues with your implementation.
I don't see ng-model in any of your input field.
Why don't you use ng-class instead of using jquery to get the id and add class?
<label ng-class="val==0 ? 'highlight':''">
<input type="Radio" ng-model="val" ng-value="0">Option A</label>
Here is the jsfiddle link
Related
I have radio button
Html code:
<input type="radio" class="first" name="bright" checked>
<input type="radio" class="second" name="bright" >
<input type="radio" class="third" name="bright">
<input type="radio" class="four" name="bright">
And i have a nav bar
Html code
<ul class="nav">
<li class="st st1 active" data-cont="first">
<h2 class="inner">وزارة الاستثمار</h2>
</li>
<li class="st st2" data-cont="second">
<h2 class="inner">وزارة التجارة</h2>
</li>
<li class="st st3" data-cont="third">
<h2 class="inner">جهات حكومية اخرى</h2>
</li>
<li class="st st4" data-cont="four">
<h2 class="inner">مكتب هندسي</h2>
</li>
</ul>
These 2 are conected with the data-cont that have the class of the radio button
I want when i click on the li the correct radio button be checked using javascript
I tried to make it using this code in JavaScript
let radio = document.querySelectorAll("input");
let radioArray = Array.from(radio);
let tabs = document.querySelectorAll(".nav li");
let tabsArray = Array.from(tabs);
tabsArray.forEach((ele) => {
ele.addEventListener("click", function (e) {
tabsArray.forEach((ele) => {
ele.classList.remove("active");
});
e.currentTarget.classList.add("active");
document.querySelector(e.currentTarget.dataset.cont).checked = true;
});
});
I try to remove the active class from li and put it on the li where i click then i want the radio button be checked
Any body can help me on this?
the last querySelector is where your code is failing you're not referencing the class for your input it needs to be document.querySelector('.' + e.currentTarget.dataset.cont).checked = true; note the "." prefix
Although that answers your question there is probably more value in pointing out that by changing your html markup to be a little more accessible you can eliminate the need for all of the javascript in your example
e.g.
input:checked + label {
color:Red;
}
<div><input type="radio" id="first" name="bright" checked>
<label for='first'>وزارة الاستثما</label>
</div>
<div>
<input type="radio" id="second" name="bright" >
<label for='second'>وزارة التجارة</label>
</div>
<div>
<input type="radio" id="third" name="bright">
<label for='third'>جهات حكومية اخرى</label>
</div>
<div>
<input type="radio" id="four" name="bright">
<label for='four'>مكتب هندسي</label>
</div>
The use of labels associated with your radio buttons is now significantly more accessible and you can drastically reduce a lot of your markup ( though to be accessible you would need to provide a more meaningful name for for attribute.
Hi I am developing web application in angularjs. I am generating radiobuttons dynamically using ng-repeat as below.
<ul>
<li ng-repeat="level in permissions">
<input name="level.perm_levelname" type="radio" ng-model="level.perm_levelname" value="{{level.perm_levelname}}"> {{level.perm_levelname}}
<a ng-click="gotopermMap({permisssionID: level.id})">View</a>
</li>
</ul>
<input type="button" value="APPLY" ng-click="apply()" />
I am trying to get selected radio button as below.
$scope.apply=function()
{
var permname = $scope.name;
console.log($scope.level.perm_levelname);
}
I am getting error Cannot read property 'perm_levelname' of undefined. May i get help here to get selected radio button? Thank you
group radio buttons by a name and specify a common scope variable for radio buttons ng-modal
<ul>
<li ng-repeat="level in permissions">
<input name="myradiobtn" type="radio" ng-model="myradioBtnValue" ng-value="level.perm_levelname">
{{level.perm_levelname}}
<a ng-click="gotopermMap({permisssionID: level.id})">View</a>
</li>
</ul>
<input type="button" value="APPLY" ng-click="apply()"/>
Use ng-click event for radio button to get current selected value and assign the value a scope object. then get the value from saved scope abject while you click apply button.
DEMO:
function TodoCtrl($scope) {
$scope.permissions= [{perm_levelname:"hai"},{perm_levelname:"bye"},{perm_levelname:"come"},{perm_levelname:"go"}]
$scope.apply=function()
{
alert($scope.currecntClickValue);
}
$scope.currecntClick=function(currecntClickValue)
{
$scope.currecntClickValue=currecntClickValue.perm_levelname;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app>
<h2>Todo</h2>
<div ng-controller="TodoCtrl">
<ul>
<li ng-repeat="level in permissions">
<input name="groupName" type="radio" ng-click="currecntClick(level)" ng-value="level.perm_levelname">
{{level.perm_levelname}}
View
</li>
</ul>
<input type="button" value="APPLY" ng-click="apply()"/>
</div>
</div>
you should use radio button group like this--
<ul>
<li ng-repeat="level in permissions">
<input name="btnGroup" type="radio" ng-model="radioButtonValue" value="{{level.perm_levelname}}">
{{level.perm_levelname}}
<a ng-click="gotopermMap({permisssionID: level.id})">View</a>
</li>
</ul>
<input type="button" value="APPLY" ng-click="apply()"/>
And inside of Controller-
$scope.radioButtonValue='';
$scope.apply=function()
{
var permname = $scope.name;
console.log($scope.radioButtonValue);
}
I have a product page on my website with product options, two with sub options. For those options with sub options they are using type="radio"
I've created javascript buttons which emulate clicking those sub options. I'd like to set up clearing the form and emulating the clicks all on one button. Currently I have a separate clear button, which still doesn't work.
Picture Example: http://i.imgur.com/uAlLBAK.jpg
Code examples below
Sub option code:
<li class="option">
<label for="09f0c74f3d92847ecfcf5837eb6b2f8b">
<input type="radio" class="validation" name="attribute[249]" value="127" id="09f0c74f3d92847ecfcf5837eb6b2f8b"/>
<span class="name">65cc</span>
</label>
</li>
<li class="option">
<label for="06fc48a0a3949a17c28162ea0eb1f406">
<input type="radio" class="validation" name="attribute[249]" value="128" id="06fc48a0a3949a17c28162ea0eb1f406"/>
<span class="name">75cc</span>
</label>
</li>
First button:
<input onclick="document.getElementById('06fc48a0a3949a17c28162ea0eb1f406').click(); document.getElementById('a596a2e871da26ba9b1cf7fffe325848').click();" type="button" value="0911" />
Second button:
<input onclick="document.getElementById('09f0c74f3d92847ecfcf5837eb6b2f8b').click(); document.getElementById('a596a2e871da26ba9b1cf7fffe325848').click();" type="button" value="0916" />
Clear options:
<input onclick="Clear();" type="button" value="Clear" />
<script type="text/javascript">// <![CDATA[
function Clear()
{
clearRadioGroup("09f0c74f3d92847ecfcf5837eb6b2f8b");
clearRadioGroup("a596a2e871da26ba9b1cf7fffe325848");
}
function clearRadioGroup(GroupName)
{
var ele = document.getElementsById(GroupName);
for(var i=0;i<ele.length;i++)
ele[i].checked = false;
}
// ]]></script>
In the above example the second button click would un-select the second element if the buttons were clicked in succession. Thoughts on at the very least being able to clear the form?
There is a typo in function clearRadioGroup. It should be
"var ele = document.getElementById(GroupName);" and not
"var ele = document.getElementsById(GroupName);".
The Clear function will work then.
Each of my radio buttons is inside a div, and immediately beside the input (radio) I have some text in a span with the CSS set to display:none. Since I have multiple radio buttons I'm trying set the span to show for ONLY the span beside the radio button that's selected. Thoughts?
Here's what I have currently.
$('input:checked').next().show();
Here's my fiddle for the full quiz I'm trying to build
http://jsfiddle.net/YSSWL/96/
Feel free to critique the rest of my jquery, as I'm likely over complicating something. I don't have a ton of experience with jquery or js (working on it).
Solution Edit: As Chausser pointed out I can use
$('input:checked').parent().find('span').show();
to select the span nearest the parent of the selected input and apply .show();
You can use:
$('input:checked').parent().find('span').show();
I updated your html to use some consistent classes and fixed your reset function as well. For working code check:
http://jsfiddle.net/YSSWL/106/
You can solve this completely with CSS:
.incorrect .incor { display: inline; }
http://jsfiddle.net/YSSWL/105/
Here is a better way to write this I think. A bit more flexible. Sorry I deleted a bunch of your stuff to make it clear what was going on.
JS:
$(document).ready(function () {
$(document).on('click', '#radiochk1', function(){
var checkedRadio = $('input[name="question1"]:checked');
$('.correct, .incorrect').removeClass('correct').removeClass('incorrect');
if(checkedRadio.hasClass('rightAnswer')){
checkedRadio.parent().find('span.answer').addClass('correct');
}else{
checkedRadio.parent().find('span.answer').addClass('incorrect');
}
});
$(document).on('click', '#resetq1', function(){
$('.correct, .incorrect').removeClass('correct').removeClass('incorrect');
$('input[name="question1"]').attr('checked', false);
});
});
HTML:
<form class="ra">
<div class="cor">
<input type="radio" name="question1" class="c1" />A. Choice A<span class="hiddencorr">Correct answer</span>
</div>
<div class="inc">
<input type="radio" name="question1" class="i1" />B. <span class="answer">Choice B</span>
</div>
<div class="inc">
<input type="radio" name="question1" class="i2 rightAnswer" />C. <span class="answer">Choice C</span>
</div>
<div class="inc">
<input type="radio" name="question1" class="i3" />D. <span class="answer">Choice D</span>
</div>
<div class="inc">
<input type="radio" name="question1" class="i4" />E. <span class="answer">Choice E</span>
</div>
</form>
<p class="rationale1"><b>Rationale:</b>
<br />
<br /><span class="rattext">Explanation of what was done wrong.</span>
</p>
<button id="radiochk1" class="checkhide">Check your answer</button>
<button id="resetq1" class="reset">Reset</button>
I have 2 problems
1.First i need to allow only one div open , so when div question1 is show
div question2 and all other should hide, actually its not case in my poor code :).
2.Second problem , I achieve to made a code with an addclass when "is checked", but actually i duplicate all the code for each div .. Perhaps someone have a better elegant option to merge the code and avoiding duplicate code..
$(".checkbox").hide();
$(".question").show();
$('.question').click(function(){
$(".checkbox").toggle(10);
});
$('#test').change(function(){
if($(' input[type=checkbox]:checked').length) {
$('div.question').addClass("question-active");
} else {
$('div.question').removeClass("question-active");
}
});
$(".checkbox2").hide();
$(".question2").show();
$('.question2').click(function(){
$(".checkbox2").toggle(10);
});
$('#test2').change(function(){
if($(' input[type=checkbox]:checked').length) {
$('div.question2').addClass("question-active");
} else {
$('div.question2').removeClass("question-active");
}
});
Here is my code : http://jsfiddle.net/5C3p9/3/
Thanks for help
Regards
If you want to keep your HTML markup as it is, this should work:
// The ^= selector is used to select the elements which have the
// property starting with the text provided.
// ie: class starting with checkbox
$("div[class^='checkbox']").hide();
$("div[class^='question']").show();
$("div[class^='question']").click(function () {
// This way you are able to close the clicked one itself
$("div[class^='checkbox']").not($(this).next()).hide();
$(this).next("div[class^='checkbox']").toggle(10);
});
$("ul[id^='test']").change(function () {
// You can use the .toggleClass() method giving the class name
// and a boolean (add/remove) as parameters
$(this)
.parents()
.prev("div[class^='question']")
.toggleClass("question-active", $("input[type='checkbox']:checked").length != 0);
});
Demo: http://jsfiddle.net/5C3p9/7/
EDIT: I've put some comments in the code.
Some minor dom changes
<div class="quest question"></div>
<div class="ans checkbox">
<ul id="test">
<li>
<input type="checkbox" name="question-1" value="1"
/> is it vegetables ?
</li>
<li>
<input type="checkbox" name="question-2" value="2"
/> is it melon ?
</li>
</ul>
</div>
<div class="quest question2"></div>
<div class="ans checkbox2">
<ul id="test2">
<li>
<input type="checkbox" name="question-1" value="1"
/> is it vegetables ?
</li>
<li>
<input type="checkbox" name="question-2" value="2"
/> is it melon ?
</li>
</ul>
</div>
then
$(".quest").show();
$(".ans").hide();
$('.quest').click(function(){
$(this).next().toggle(10);
});
$('.ans').change(function(){
var $ans = $(this).closest('.ans');
$ans.prev().toggleClass('question-active', $ans.find('input:checkbox:checked').length > 0)
});
Demo: Fiddle
I made some modifications to your code. What I did is that I added some HTML-classes and made the javascript more general and traverse the HTML instead of pointing straight to the element.
Here's the jsFiddle: http://jsfiddle.net/E595w/1/
The new HTML:
<div class="question"></div>
<div class="checkbox">
<ul id="test" class="test">
<li>
<input type="checkbox" name="question-1" value="1"> is it vegetables ?
</li>
<li>
<input type="checkbox" name="question-2" value="2"> is it melon ?
<li>
</ul>
</div>
<div class="question"></div>
<div class="checkbox">
<ul id="test2" class="test">
<li>
<input type="checkbox" name="question-1" value="1"> is it vegetables ?
</li>
<li>
<input type="checkbox" name="question-2" value="2"> is it melon ?
<li>
</ul>
</div>
And here's the resulting Javascript:
$(".checkbox").hide();
$(".question").show();
$('.question').click(function(){
$('.checkbox').hide();
$(this).next(".checkbox").toggle(10);
});
$('.test').change(function(){
if($(' input[type=checkbox]:checked').length) {
$(this).parents('.checkbox').prev('div.question').addClass("question-active");
} else {
$(this).parents('.checkbox').prev('div.question').removeClass("question-active");
}
});
EDIT: Updated with code to answer your #1 question. See updated link to jsFiddle.
put to all your questions same class .question
if you want to differentiate between questions, use ids instead
also, put to to all answers container .checkbox
then use this function which will work for questions , no matter how many you have
$('.question').click(function(){
$(".checkbox").hide();
$(this).next(".checkbox").show(10);
});