Search code examples
javascriptjqueryif-statementparent

Using one if else statement to color progress bars in different contexts


I’ve got some simple rolling progress bars, fed by a percentage number on the page (later this will come from a database), which change color and width dependent upon this number. Got them working nicely in one context, but on another page they need to use different colors. I’d like to use the same code for both, but I can’t get it to work.

In my statement, I'm saying I want percentage ranges to display the bar in their respective colors and at a width corresponding to that percentage.

The trouble comes in the last else statement, when I say that if the score is exactly 100 AND if the score's parent has the class '.report', color the bar gray. Tried everything I can think of and it either doesn't work or blows up the script entirely.

Still a freshie with JQuery/Javascript, but I think I love it... until I get stuck like this. Clearly I'm missing something fundamental here – probably in the parent() portion of the js, which I'm still shaky on, but what exactly is going wrong?

In my thinking, all the 100% bars here should be gray.

$( document ).ready(function(){
	
	$( '.score' ).each( function() {
        //get each score and apply width to progress bar
    var score = $( this ).text().trim();
		$( this ).closest( '.progbar' ).css('width', score + '%');
		
	var bar = $( this ).closest( '.progbar' );
	//apply colors to bar based on performance or progress
	var parent = $( '.score' ).closest( 'progbar' );
	
	if (score == 0){
		$( bar ).css('width', '0');
	} else if (score <= 100 && score >= 95){
		$( bar ).css( 'background-color', 'rgba( 53, 182, 103, .5)' );
		//console.log(parent);
	} else if (score <= 94 && score >= 80){
		$( bar ).css( 'background-color', 'rgba( 24, 133, 157, .5)' );
		//console.log(score);
	} else if (score <= 79 && score >= 60){
		$( bar ).css( 'background-color', 'rgba( 239, 149, 33, .5)' );
	} else if (score < 60){
		$( bar ).css( 'background-color', 'rgba( 198, 32, 55, .5)' );
	} else if ( score === 100 && score.parent().hasClass( '.report' ) ){//this is where it falls apart
		$( bar ).css( 'background-color', 'rgba(0, 0, 0, .5)' );
		alert('hasClass');
	}
	});
});
th{
    text-align:left;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table class="report-table1 math">
                <!--<caption>
          Level 1 Reading to Common Core Standards
          </caption>-->
                
                <col>
                <col>
                <tr class="tabletop">
                  <th scope="col"><div>Standards in Strand </div></th>
                  <th scope="col"><div>Progress</div></th>
                </tr>
                <tr>
                  <th colspan="2" class="name sub2"><div>Common Core</div></th>
                </tr>
                <tr>
                  <th class="name tooltip"><div>• CCSS.MATH.CONTENT.K.CC.A.1</div></th>
                  <td class="report-table1 reading"><div class="progbar-wrap">
                      <div class="progbar report"><span class="score">100</span>%</div>
                    </div></td>
                </tr>
                <tr>
                  <th class="name tooltip"><div>• CCSS.MATH.CONTENT.K.CC.A.2</div></th>
                  <td class="report-table1 reading"><div class="progbar-wrap">
                      <div class="progbar"><span class="score">100</span>%</div>
                    </div></td>
                </tr>
                <tr>
                  <th class="name tooltip"><div>• CCSS.MATH.CONTENT.K.CC.A.3</div></th>
                  <td class="report-table1 reading"><div class="progbar-wrap">
                      <div class="progbar report"><span class="score">99</span>%</div>
                    </div></td>
                </tr>
                <tr>
                  <th class="name tooltip"><div>• CCSS.MATH.CONTENT.K.CC.B.4</div></th>
                  <td class="report-table1 reading"><div class="progbar-wrap">
                      <div class="progbar report"><span class="score">98</span>%</div>
                    </div></td>
                </tr>
                <tr>
                  <th class="name tooltip"><div>• CCSS.MATH.CONTENT.K.CC.B.4.A</div></th>
                  <td class="report-table1 reading"><div class="progbar-wrap">
                      <div class="progbar report"><span class="score">0</span>%</div>
                    </div></td>
                </tr>
                <tr>
                  <th class="name tooltip"><div>• CCSS.MATH.CONTENT.K.CC.B.4.B</div></th>
                  <td class="report-table1 reading"><div class="progbar-wrap">
                      <div class="progbar report"><span class="score">10</span>%</div>
                    </div></td>
                </tr>
                <tr>
                  <th class="name tooltip"><div>• CCSS.MATH.CONTENT.K.CC.B.4.C</div></th>
                  <td class="report-table1 reading"><div class="progbar-wrap">
                      <div class="progbar report"><span class="score">86</span>%</div>
                    </div></td>
                </tr>
                <tr>
                  <th class="name tooltip"><div>• CCSS.MATH.CONTENT.K.CC.B.5</div></th>
                  <td class="report-table1 reading"><div class="progbar-wrap">
                      <div class="progbar report"><span class="score">83</span>%</div>
                    </div></td>
                </tr>
                <tr>
                  <th class="name tooltip"><div>• CCSS.MATH.CONTENT.K.CC.C.6</div></th>
                  <td class="report-table1 reading"><div class="progbar-wrap">
                      <div class="progbar report"><span class="score">70</span>%</div>
                    </div></td>
                </tr>
              </table>

Here's a fiddle:

http://jsfiddle.net/halfacre/08Lm3hvf/


Solution

  • Change (also see note at the end of my answer):

    } else if (score <= 100 && score >= 95) {
    

    To:

    } else if (score < 100 && score >= 95) {
    

    And:

    } else if (score === 100 && score.parent().hasClass( '.report' ))
    

    To:

    } else if (score == 100 && $(this).parent().hasClass( 'report' ))
    

    If I make those changes using your fiddle I get grey bars for 100%. The first change prevents the value of 100 being caught by the score <= 100 condition, the second change allows JS to convert the arguments to the same type before comparing them, alternatively you could convert the score to an integer score = parseInt(score) before your series of if tests.

    Note: If you want bars with a score of 100 to be green if a .report report class is not defined against the parent then you dont need to change the } else if (score <= 100 && score >= 95) { but rather move it so it's the last test in the series.