Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Issues with if-statement adding players with `is-inactive` class to input

Problem

The maximum number of players for each position is:

  • 2 out of 4 goalies
  • 6 out of 15 defencemen
  • 12 out of 31 forwards

I've gotten to the point where I'll click on a hockey player and that name gets added to a input field in a form, but if you already have two goalies selected, ie has a class of is-active and then click on one of the other two unselected players with the default is-inactive class, that name will still be added into an input when there should only be two goalies max. And unfortunately, this is also the case with the defencemen and the forwards too.

Goal

When starredGoaltenders === maxGoaltenders or starredDefencemen === maxDefencemen or starredForwards === maxFowards the names of players that do not have not been selected of that specific position and do not have an is-active class should not be added to any input in the form.

scripts.js

    function countSelected() {
        $(".player").on("click", function(){

            // Checks if the maximum number of players have been selected
            // If so, return false and then do nothing
            // If not, the class will toggle from `is-inactive` to `is-active`
            if ($(this).find(".picked.is-inactive.full").length > 0) return false;
            $(this).find(".picked").toggleClass("is-inactive is-active");
            $(".player").removeClass("not-picked");
            $(".player").not(":has(.is-active)").addClass("not-picked");

            // Count the number of players with stars
            var starredGoaltenders = $(".player--goalie").find(".picked.is-active").length;
            var starredDefencemen = $(".player--defencemen").find(".picked.is-active").length;
            var starredForwards = $(".player--forward").find(".picked.is-active").length;

            console.log(starredGoaltenders, starredDefencemen, starredForwards);

            // The number of starred players for each position cannot exceed the following numbers
            var maxGoaltenders = 2;
            var maxDefencemen = 6;
            var maxFowards = 12;

            // If the number of starred players hits its max, a class of `is-completed` is adding to the corresponding checkmark to indicate that the task has been completed
            if (starredGoaltenders === maxGoaltenders) {
                $(".checkmark--goalie").addClass("is-completed");
                $(".player--goalie").find(".picked").addClass("full");
            } else {
                $(".checkmark--goalie").removeClass("is-completed");
                $(".player--goalie").find(".picked.is-inactive").removeClass('full');
            }

            if (starredDefencemen === maxDefencemen) {
                $(".checkmark--defencemen").addClass("is-completed");
                $(".player--defencemen").find(".picked").addClass("full");
            } else {
                $(".checkmark--defencemen").removeClass("is-completed");
                $(".player--defencemen").find(".picked.is-inactive").removeClass('full');
            }

            if (starredForwards === maxFowards) {
                $(".checkmark--forward").addClass("is-completed");
                $(".player--forward").find(".picked").addClass("full");
            } else {
                $(".checkmark--forward").removeClass("is-completed");
                $(".player--forward").find(".picked.is-inactive").removeClass('full');
            }

            // If all the conditions are met show the submit vote button
            if (starredGoaltenders === maxGoaltenders && starredDefencemen === maxDefencemen && starredForwards === maxFowards) {
                $(".btn--submit").show();
                $(".btn--submit").addClass("slideLeft");
            } else{
                $(".btn--submit").hide();
                $(".btn--submit").removeClass("slideLeft");
            }
        });
} countSelected();


// Every time a player is clicked, note the name of the player
$(".player").on("click", function(){
    var playerNames = [];
    $("input:text").each(function(i, t) { playerNames.push(t.value) });

    if ($(this).find("picked.is-active")) {
        var playerName = $(this).find(".player__name").html();
        var index = playerNames.indexOf(playerName);

        if (index == -1) // Add player
            $("input:text:eq(" + playerNames.indexOf("") + ")").val(playerName);
        else // Remove player
            $("input:text:eq(" + index + ")").val("");
    } else {
        $("input").val("");
    }
});

index.html - Snippet includes form and one out of the 60 available players to be clicked on

<form id="form">
   <input type="text" name="p1"  id="p1">
   <input type="text" name="p2"  id="p2">
   <input type="text" name="p3"  id="p3">
   <input type="text" name="p4"  id="p4">
   <input type="text" name="p5"  id="p5">
   <input type="text" name="p6"  id="p6">
   <input type="text" name="p7"  id="p7">
   <input type="text" name="p8"  id="p8">
   <input type="text" name="p9"  id="p9">
   <input type="text" name="p10" id="p10">
   <input type="text" name="p11" id="p11">
   <input type="text" name="p12" id="p12">
   <input type="text" name="p13" id="p13">
   <input type="text" name="p14" id="p14">
   <input type="text" name="p15" id="p15">
   <input type="text" name="p16" id="p16">
   <input type="text" name="p17" id="p17">
   <input type="text" name="p18" id="p18">
   <input type="text" name="p19" id="p19">
   <input type="text" name="p20" id="p20">
   <button class="btn btn--submit" type="submit"><img src="src/img/ballot-alt.png" class="image--ballot">Submit Vote</button>
</form>
<div class="player player--forward year--2000 year--2010">
   <div class="tooltip">
      <p class="tooltip__name">Mark Stone</p>
      <p class="tooltip__hometown"><span>Hometown:</span> Winnipeg, Man.</p>
      <p class="tooltip__years"><span>Years Played:</span> 2008-2012</p>
      <div class="tooltip__stats--inline">
         <div class="stats__group stats--games">
            <p class="stats__header">GP</p>
            <p class="stats__number stats__number--games">232</p>
         </div>
         <div class="stats__group stats--goals">
            <p class="stats__header">G</p>
            <p class="stats__number stats__number--goals">106</p>
         </div>
         <div class="stats__group stats--assists">
            <p class="stats__header">A</p>
            <p class="stats__number stats__number--assists">190</p>
         </div>
         <div class="stats__group stats--points">
            <p class="stats__header">Pts</p>
            <p class="stats__number stats__number--points">296</p>
         </div>
         <div class="stats__group stats--penalties">
            <p class="stats__header">Pim</p>
            <p class="stats__number stats__number--penalties">102</p>
         </div>
      </div>
   </div>
   <div class="player__headshot player--mstone">
      <div class="picked is-inactive"><i class="fa fa-star" aria-hidden="true"></i></div>
   </div>
   <p class="player__name">Mark Stone</p>
   <p class="player__position">Forward</p>
</div>
like image 449
Andrew Nguyen Avatar asked Oct 19 '22 02:10

Andrew Nguyen


1 Answers

Probably, the easiest way to approach this problem is to repopulate all your inputs every time someone clicks on a player, rather than trying to populate each input once. This means you can keep your application state in a simple, easily understood data structure that is independent of your DOM/UI, rather than having to consult the DOM each time something new happens.

This is how I would probably write it.

var players = [
        {name: 'Ovechkin', type: 'F'},
        {name: 'Dubnyk', type: 'G'}
        // your complete player list goes here
    ],
    selectedPlayers: []; // these are the players the user has chosen


var getCurrentPlayerCount = function (playerType) {
    // return the number of players currently selected of one type
    return selectedPlayers.reduce(function (count, player) {
        if (player.type === playerType) return count + 1;
        return count;
    }, 0);
}

var selectPlayer = function (player) {
    // You call this when someone clicks on a player
    var currentForwardCount = getCurrentPlayerCount('F')
        currentDefenceCount = getCurrentPlayerCount('D'),
        currentGoalieCount = getCurrentPlayerCount('G');

    // Do nothing (or show a UI message) if someone goes over their
    // player-type limit
    if (player.type === 'F' && currentForwardCount > 12) return;
    if (player.type === 'D' && currentDefenceCount > 6) return;
    if (player.type === 'G' && currentGoalieCount > 2) return;

    // If you get here, it means the player can be added, so add
    // it to the user's list
    selectedPlayers.push(player);

    updateUI();
}

I'm not including updateUI here. You can work that out on your own.

If you need to support IE 8 or any other browser that does not support Array.prototype.reduce, you will need to do getCurrentPlayerCount differently.

like image 160
Andrew Avatar answered Oct 21 '22 06:10

Andrew