0

So I have 2 problems here

  1. The if which checks this $isitchecked = $('#group' + groupnumber).hasClass("checked"); returns always false even though the class has the class "checked"
  2. even though the groupnumber icrements it still works just with the first group.

            var progressProcent = 0;
            var groupnumber = 1;

        $('#group' + groupnumber + ' input[type="radio"]').click(function(){

         $whatgroup = "#group" + groupnumber;

         $isitchecked = $('#group' + groupnumber).hasClass("checked");

          if ($isitchecked) {

          }else{
            progressProcent = progressProcent + 2.27272727;
          }

            $("#progress-container").removeClass("hide");
            $( $whatgroup).addClass("checked");

            $("#progress-bar").css('width', progressProcent + '%');

          groupnumber = groupnumber + 1;

        });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<div class="question form-group">
          <h3>Question 1</h3>
          <fieldset class="test-field pull-left" id="group1">
            <input type="radio" name="q1" id="q1option1" class="left" value="-3">

            <input type="radio" name="q1" id="q1option2" class="left" value="-2">

            <input type="radio" name="q1" id="q1option3" class="left" value="-1">

            <input type="radio" name="q1" id="q1neotral1" value="0">

            <input type="radio" name="q1" id="q1option1r" class="right" value="1">

            <input type="radio" name="q1" id="q1option2r" class="right" value="2">

            <input type="radio" name="q1" id="q1option3r" class="right" value="3">
          </fieldset>
        </div>
        <br>
        <div class="question form-group">
          <h3>Question 2</h3>
          <fieldset class="test-field pull-left" id="group2">
            <input type="radio" name="q2" id="q2option1" class="left" value="-3">

            <input type="radio" name="q2" id="q2option2" class="left" value="-2">

            <input type="radio" name="q2" id="q2option3" class="left" value="-1">

            <input type="radio" name="q2" id="q2neotral1" value="0">

            <input type="radio" name="q2" id="q2option1r" class="right" value="1">

            <input type="radio" name="q2" id="q2option2r" class="right" value="2">

            <input type="radio" name="q2" id="q2option3r" class="right" value="3">
          </fieldset>
        </div>
         <br />
         <br />
        <div class="progress-container" id="progress-container">
          <div class="progress">
            <div class="progress-bar progress-bar-striped active" id="progress-bar" role="progressbar" aria-valuenow="45" aria-valuemin="0" aria-valuemax="100" >
            </div>
          </div>
        </div>
key
  • 1,334
  • 1
  • 19
  • 39
  • 7
    Forget about your jQuery code. What exactly you want to achieve, can you explain that?(explain in question) – Alive to die - Anant Sep 12 '17 at 11:46
  • You only ever hook the `click` event on `#group1 input[type="radio"]`, not on any other element. – T.J. Crowder Sep 12 '17 at 11:50
  • whenever I answer a question with are 44, the progress bar should move or added 2.27272727, but if I change my mind about one question, the progress bard should not add anything because i already checked (answered) that block. does that make sense? – key Sep 12 '17 at 11:51
  • @T.J.Crowder yes, but if I add a console.log behing the click function it inrements. so from #group1 to #group2 etc., but it still does not work – key Sep 12 '17 at 11:54
  • Right -- because you're not hooking up any handler on those other elements. You're calling `click` (hooking up the handler) **once**. – T.J. Crowder Sep 12 '17 at 12:05

5 Answers5

2
var groupnumber = 1;
$('#group' + groupnumber + ' input[type="radio"]').click(function(){

is same as

$('#group1 input[type="radio"]').click(function(){

groupnumber = groupnumber + 1;// doesn't do anything??

This just binds click event to radio buttons in group1


Even if you implement it by correcting above issue, you cannot guarantee if user does select in the order group1, group2, group3.


Even when you need a reference to the parent group, it is better to get it relatively, rather than using the group numbers

$isitchecked = $('#group' + groupnumber).hasClass("checked");

can be something like

$isitchecked = $(this).parent().hasClass("checked");

But again, jQuery has :checked selector built-in and there is no need to implement it again and can cause edge cases and errors.


Here is a different approach to the problem.

Attribute selectors used in [id^="group"]

$('fieldset[id^="group"] input[type="radio"]').click(function() {
// click event on all fields with id starting with group
  var checked = $("input[type='radio']:checked").length;
  // get number of radio button checked
  var total = $('fieldset[id^="group"]').length;
  // get total number of field sets
  var percent = checked/total*100;
  $("#progress-bar").css('width', percent + '%');
});

$('[id^="group"] input[type="radio"]').click(function() {
  var checked = $("input[type='radio']:checked").length;
  var total = $('fieldset[id^="group"]').length;
  var percent = checked/total*100;
  $("#progress-bar").css('width', percent + '%');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<div class="question form-group">
  <h3>Question 1</h3>
  <fieldset class="test-field pull-left" id="group1">
    <input type="radio" name="q1" id="q1option1" class="left" value="-3">

    <input type="radio" name="q1" id="q1option2" class="left" value="-2">

    <input type="radio" name="q1" id="q1option3" class="left" value="-1">

    <input type="radio" name="q1" id="q1neotral1" value="0">

    <input type="radio" name="q1" id="q1option1r" class="right" value="1">

    <input type="radio" name="q1" id="q1option2r" class="right" value="2">

    <input type="radio" name="q1" id="q1option3r" class="right" value="3">
  </fieldset>
</div>
<br>
<div class="question form-group">
  <h3>Question 2</h3>
  <fieldset class="test-field pull-left" id="group2">
    <input type="radio" name="q2" id="q2option1" class="left" value="-3">

    <input type="radio" name="q2" id="q2option2" class="left" value="-2">

    <input type="radio" name="q2" id="q2option3" class="left" value="-1">

    <input type="radio" name="q2" id="q2neotral1" value="0">

    <input type="radio" name="q2" id="q2option1r" class="right" value="1">

    <input type="radio" name="q2" id="q2option2r" class="right" value="2">

    <input type="radio" name="q2" id="q2option3r" class="right" value="3">
  </fieldset>
</div>
<br />
<br />
<div class="progress-container" id="progress-container">
  <div class="progress">
    <div class="progress-bar progress-bar-striped active" id="progress-bar" role="progressbar" aria-valuenow="45" aria-valuemin="0" aria-valuemax="100">
    </div>
  </div>
</div>
sabithpocker
  • 15,274
  • 1
  • 42
  • 75
0

Your if statement is executed first

$isitchecked = $('#group' + groupnumber).hasClass("checked");

and then you're adding the class "checked"

$( $whatgroup).addClass("checked");

This is why it always returns false.

Also, you don't have to use increment logic, you could use this to find out the radio which was clicked.

Dhagej
  • 11
  • 1
  • 2
  • I have to add the class after the if statement, other-vice the thing doesn't work at all. but good point, thanks – key Sep 12 '17 at 12:07
  • Use condition based the checked attribute instead of class as sabithpocker mentioned in his answer – Dhagej Sep 12 '17 at 12:28
0

Easiest way to do:-

progressProcent = 0;
$("input[type='radio']").on('click',function(){
   if($(this).parent().find('.checked').length ==0){
      progressProcent = progressProcent + 2.27272727;
      $("#progress-bar").css('width', progressProcent + '%');
   } 
   $(this).addClass('checked');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<div class="question form-group">
  <h3>Question 1</h3>
  <fieldset class="test-field pull-left" id="group1">
    <input type="radio" name="q1" id="q1option1" class="left" value="-3">

    <input type="radio" name="q1" id="q1option2" class="left" value="-2">

    <input type="radio" name="q1" id="q1option3" class="left" value="-1">

    <input type="radio" name="q1" id="q1neotral1" value="0">

    <input type="radio" name="q1" id="q1option1r" class="right" value="1">

    <input type="radio" name="q1" id="q1option2r" class="right" value="2">

    <input type="radio" name="q1" id="q1option3r" class="right" value="3">
  </fieldset>
</div>
<br>
<div class="question form-group">
  <h3>Question 2</h3>
  <fieldset class="test-field pull-left" id="group2">
    <input type="radio" name="q2" id="q2option1" class="left" value="-3">

    <input type="radio" name="q2" id="q2option2" class="left" value="-2">

    <input type="radio" name="q2" id="q2option3" class="left" value="-1">

    <input type="radio" name="q2" id="q2neotral1" value="0">

    <input type="radio" name="q2" id="q2option1r" class="right" value="1">

    <input type="radio" name="q2" id="q2option2r" class="right" value="2">

    <input type="radio" name="q2" id="q2option3r" class="right" value="3">
  </fieldset>
</div>
 <br />
 <br />
<div class="progress-container" id="progress-container">
  <div class="progress">
    <div class="progress-bar progress-bar-striped active" id="progress-bar" role="progressbar" aria-valuenow="45" aria-valuemin="0" aria-valuemax="100" >
    </div>
  </div>
</div>

Explanation:-

on click of radio button:-

1.First check that it's parent div have any radio button with checked class or not?

2.If no then do the addition+progress-bar increase and after that add the checked class to the clicked radio button.

3.2nd step will insure that next time when other radio button of the same div will clicked.Nothing will happen.

Alive to die - Anant
  • 70,531
  • 10
  • 51
  • 98
0

At the end of the click event you increase groupnumber by one. It makes a future click check for a different id, thats why you always get false.

Based on what I believe you want to achieve, you should do something like this (I tried to change your code at minimum):

var progressProcent = 0;

// Selects all inputs inside the fieldsets (since all of them
// have the .test-field class)

$('.test-field input[type="radio"]').click(function(){
    
    // Gets the closest fieldset
    $whatgroup = $(this).closest('.test-field');
    
    $isitchecked = $whatgroup.hasClass("checked");
    
    if ($isitchecked) {
        
    }else{
        progressProcent = progressProcent + 2.27272727;
    }
    
    $("#progress-container").removeClass("hide");
    $whatgroup.addClass("checked");
    
    $("#progress-bar").css('width', progressProcent + '%');   
    
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<div class="question form-group">
    <h3>Question 1</h3>
    <fieldset class="test-field pull-left" id="group1">
        <input type="radio" name="q1" id="q1option1" class="left" value="-3">
        
        <input type="radio" name="q1" id="q1option2" class="left" value="-2">
        
        <input type="radio" name="q1" id="q1option3" class="left" value="-1">
        
        <input type="radio" name="q1" id="q1neotral1" value="0">
        
        <input type="radio" name="q1" id="q1option1r" class="right" value="1">
        
        <input type="radio" name="q1" id="q1option2r" class="right" value="2">
        
        <input type="radio" name="q1" id="q1option3r" class="right" value="3">
    </fieldset>
</div>
<br>
<div class="question form-group">
    <h3>Question 2</h3>
    <fieldset class="test-field pull-left" id="group2">
        <input type="radio" name="q2" id="q2option1" class="left" value="-3">
        
        <input type="radio" name="q2" id="q2option2" class="left" value="-2">
        
        <input type="radio" name="q2" id="q2option3" class="left" value="-1">
        
        <input type="radio" name="q2" id="q2neotral1" value="0">
        
        <input type="radio" name="q2" id="q2option1r" class="right" value="1">
        
        <input type="radio" name="q2" id="q2option2r" class="right" value="2">
        
        <input type="radio" name="q2" id="q2option3r" class="right" value="3">
    </fieldset>
</div>
<br />
<br />
<div class="progress-container" id="progress-container">
    <div class="progress">
        <div class="progress-bar progress-bar-striped active" id="progress-bar" role="progressbar" aria-valuenow="45" aria-valuemin="0" aria-valuemax="100" >
        </div>
    </div>
</div>
0

Changed the jQuery part somewhat, should be pretty self-explanatory.
In general: don't use the same id for multiple elements; numbers appended or not. I cannot think of a single situation where that is required or not messy.

var progressProcent = 0.0;
var questions = [];
var $questions;

function updateProgress(add) {
  if (add) progressProcent += 100 / $questions.length;
  $("#progress-container").removeClass("hide");
  $("#progress-bar").css('width', progressProcent + '%');
}

$(function() {
  $questions = $('.question');
  $questions.each(function(i) {
    $fieldset = $(this).find('fieldset');
    for (var v = -3; v <= 3; v++) {
      var theClass = v !== 0 ? (v < 0 ? "left" : "right") : null;
      var $input = $('<input>').attr("type", "radio").val(v).addClass(theClass).on('change', function() {
        if (!questions[i]) updateProgress(true);
        questions[i] = Number($(this).val());
        console.log(questions);
      });
      $fieldset.append($input);
    }
  });
});
fieldset input.left {
  margin-right: 5px
}

fieldset input.right {
  margin-left: 5px
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<div class="question form-group">
  <h3>Question 1</h3>
  <fieldset class="test-field pull-left" id="group1">
  </fieldset>
</div>
<br>
<div class="question form-group">
  <h3>Question 2</h3>
  <fieldset class="test-field pull-left" id="group2">
  </fieldset>
</div>
<br>
<br>
<div class="progress-container" id="progress-container">
  <div class="progress">
    <div class="progress-bar progress-bar-striped active" id="progress-bar" role="progressbar" aria-valuenow="45" aria-valuemin="0" aria-valuemax="100">
    </div>
  </div>
</div>

I'll also recommend to auto-generate the inputs for your questions; if you find yourself copy-pasting lots of code, then changing numbers around, you're again almost guaranteed to do it wrong.