2

I'm trying to add the scores from Level 1 and Level 2 and display the result in the <div id="score"></div>.

This is so far what I've made but it not only doesn't work for all the inputs but also seems like a mess that I think is not the right way to solve what I'm trying to achieve. I've repeated the almost same thing, again and again, there should be a simpler and poetic way of writing.

I'd very much appreciate the suggestions how could I write it better?

$(document).ready(function() {
    $(document).on("input", function() {
        FScore = 0;
        if (document.getElementById("1").checked) {
            Score = FScore + 1;
        }
        if (document.getElementById("2").checked) {
            Score = FScore + 2;
        }
        if (document.getElementById("3").checked) {
            Score = FScore + 3;
        }
        if (document.getElementById("4").checked) {
            Score = FScore + 4;
        }
        if (document.getElementById("5").checked) {
            Score = FScore + 5;
        }
        if (document.getElementById("6").checked) {
            Score = FScore + 6;
        }
        if (document.getElementById("7").checked) {
            Score = FScore + 7;
        }
        if (document.getElementById("8").checked) {
            Score = FScore + 8;
        }
        $('#score').html(Score);
    })
    $("#1").trigger("input");
});
form { 
    position: relative; 
    top: 100px; 
    left: 100px; 
    background: -webkit-linear-gradient(bottom,#eaeaea, #fafafa);
    padding: 10px;
    display: inline-block;
    box-shadow: 0 1px 1px rgba(0,0,0,.65);
    border-radius: 3px;
    border: solid 1px #ddd;
}
input { display: none; }
input:checked + label { 
    background: -webkit-linear-gradient(top,#4D90FE,#4787ED);
    border: solid 1px rgba(0,0,0,.15);
    color: white; 
    box-shadow: 0 1px 1px rgba(0,0,0,.65), 0 1px 0 rgba(255,255,255,.1) inset;
    text-shadow: 0 -1px 0 rgba(0,0,0,.6);
}
label { 
    font-family: helvetica;
    cursor: pointer; 
    display: inline-block; 
    border: solid 1px transparent;
    margin-right: 2px; 
    width: 50px; 
    height: 40px; 
    text-align: center; 
    line-height: 40px;
    border-radius: 3px; 
}
label:last-child { margin-right: 0; }
label:hover {     
    background: rgba(77, 144, 254, .5); 
    border: solid 1px rgba(0,0,0,.15); 
}
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
   <form>
      Level One:<br>
      <input type="radio" name="first" id="1" value="1" checked="checked" /> 
      <label for="1">1</label>
      <input type="radio" name="first" id="2" value="2" />     
      <label for="2">2</label>
      <input type="radio" name="first" id="3" value="3" />     
      <label for="3">3</label>
      <input type="radio" name="first" id="4" value="4" />     
      <label for="4">4</label>
   </form>
   <form>
      Level Two:<br>
      <input type="radio" name="second" id="5" value="5" checked="checked" /> 
      <label for="small">5</label>
      <input type="radio" name="second" id="6" value="6" />     
      <label for="6">6</label>
      <input type="radio" name="second" id="7" value="7" />     
      <label for="7">7</label>
      <input type="radio" name="second" id="8" value="8" />     
      <label for="8">8</label>
   </form>
</div>
<div class="container">
   <label>Result:</label>
   <div id="score"></div>
</div>
Ashonko
  • 533
  • 8
  • 34
  • Shouldn't all your `Score = FScore + ...` statements be `FScore = FScore + ...`? Also note that you seem to have a typo in `Score = Score + 5;` based on your other rules – j08691 May 17 '18 at 18:19
  • Also, you don't need to check each radio to see if it is checked. You gave them all the same name, so you can do things like `$('.first').filter(':checked').val()` – Taplar May 17 '18 at 18:20
  • Use the answers at https://stackoverflow.com/questions/678434/how-to-retrieve-a-value-from-input-using-jquery to get the form values then add them together. You probably don't want two forms either. – Scott Rickman May 17 '18 at 18:24

2 Answers2

2

The easier way to do this would be as follows:

$(document).ready(function() {
    $("input").change(function() {
        $('#score').html( +$('input[name="first"]:checked').val() + +$('input[name="second"]:checked').val() );
    })
    $("#1").trigger("change");
});
form { 
    position: relative; 
    top: 100px; 
    left: 100px; 
    background: -webkit-linear-gradient(bottom,#eaeaea, #fafafa);
    padding: 10px;
    display: inline-block;
    box-shadow: 0 1px 1px rgba(0,0,0,.65);
    border-radius: 3px;
    border: solid 1px #ddd;
}
input { display: none; }
input:checked + label { 
    background: -webkit-linear-gradient(top,#4D90FE,#4787ED);
    border: solid 1px rgba(0,0,0,.15);
    color: white; 
    box-shadow: 0 1px 1px rgba(0,0,0,.65), 0 1px 0 rgba(255,255,255,.1) inset;
    text-shadow: 0 -1px 0 rgba(0,0,0,.6);
}
label { 
    font-family: helvetica;
    cursor: pointer; 
    display: inline-block; 
    border: solid 1px transparent;
    margin-right: 2px; 
    width: 50px; 
    height: 40px; 
    text-align: center; 
    line-height: 40px;
    border-radius: 3px; 
}
label:last-child { margin-right: 0; }
label:hover {     
    background: rgba(77, 144, 254, .5); 
    border: solid 1px rgba(0,0,0,.15); 
}
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
   <form>
      Level One:<br>
      <input type="radio" name="first" id="1" value="1" checked="checked" /> 
      <label for="1">1</label>
      <input type="radio" name="first" id="2" value="2" />     
      <label for="2">2</label>
      <input type="radio" name="first" id="3" value="3" />     
      <label for="3">3</label>
      <input type="radio" name="first" id="4" value="4" />     
      <label for="4">4</label>
   </form>
   <form>
      Level Two:<br>
      <input type="radio" name="second" id="5" value="5" checked="checked" /> 
      <label for="5">5</label>
      <input type="radio" name="second" id="6" value="6" />     
      <label for="6">6</label>
      <input type="radio" name="second" id="7" value="7" />     
      <label for="7">7</label>
      <input type="radio" name="second" id="8" value="8" />     
      <label for="8">8</label>
   </form>
</div>
<div class="container">
   <label>Result:</label>
   <div id="score"></div>
</div>

Note the syntax +$('input[name="first"]:checked') coerces the string value of the checked input to a number. You could also have used the parseInt() function.

Ashonko
  • 533
  • 8
  • 34
j08691
  • 204,283
  • 31
  • 260
  • 272
  • Wow! Thanks for the suggestion. This looks neat. But have you noticed the issue that when I select anything else from Level Two, I cannot select `5` back again? – Ashonko May 17 '18 at 18:32
  • 1
    Thanks for the lesson indeed. @j08691 – Ashonko May 17 '18 at 18:40
1

To be noticed, a HTML ID cannot starts with a number. (not blocking issue here but good to know I guess)

Try this :

$(document).on("change", "form", function() {

  var result = 0;

  $("input:checked").each(function() {
    result += Number($(this).val());
  })

  $("#score").html(result)

});
dvd
  • 179
  • 3
  • 11
  • 1
    @dvd see https://stackoverflow.com/questions/22141358/why-can-an-element-id-not-start-with-an-integer and https://stackoverflow.com/questions/70579/what-are-valid-values-for-the-id-attribute-in-html – j08691 May 17 '18 at 18:42