Andrew Nguyen Andrew Nguyen - 3 months ago 7
HTML Question

Add text to input only if div has class `is-active`

Problem




  • Players that have not been selected, ie. do not have a class of
    picked.is-active
    should not be added to any of the input fields when they are clicked on

  • The maximum number of players that be be picked from each category is 2 out of 4 goalies, 6 of 15 defencemen and 12 out of 31 forwards.



Update #3



Added link to the Github repo here: https://github.com/onlyandrewn/wheatkings

Update #2



Added the snippet, which shows how the
is-inactive
and the
is-active
classes are being toggled.

Update #1 -



I've removed the second snippet which may be causing some confusion

This Javascript snippet below grabs the name of the player clicked and then puts it into an input field, if it has a class of
picked.is-active
. However, let's say you've selected two goalies already, but then click on the two remaining goalies in that category when are unselected (have the default class
in-active
) those unselected players still get added to the inputs, which is not what we want.




scripts.js - This snippet, which needs fixing, currently adds player name to input field even if max number players in specific category has been reached



$(".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("");
}
});


scripts.js (How
is-inactive
and
is-active
classes are toggled)



$(".btn--random").on("click", function() {

// CHECK THESE NUMBERS
var goalies_array = getRandomNumbers(1, 4, 2);
var defensemen_array = getRandomNumbers(5, 19, 6);
var forwards_array = getRandomNumbers(20, 50, 12);

$(".goalies").text(goalies_array.join(","));
$(".defensemen").text(defensemen_array.join(","));
$(".forwards").text(forwards_array.join(","));

var players_array = goalies_array.concat(defensemen_array).concat(forwards_array);

// Add the class `is-active` based on the numbers generated
var player = $(".player");
$(".is-active").removeClass("is-active").addClass("is-inactive");


$.each(players_array, function(index, value) {
var player_index = value - 1; // Subtract one based on zero-indexing
player.eq(player_index).find(".is-inactive").removeClass("is-inactive").addClass("is-active");
});
});

function getRandomNumbers(start, end, howMany) {
var arr = [];
for (var i = start, j = 0; i <= end; j++, i++)
arr[j] = i
arr.sort(function() {
return Math.floor((Math.random() * 3) - 1)
});

return arr.splice(0, howMany)
}


index.html (Form snippet)



<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>


index.html (Player snippet)



<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>

Answer

Storing app state into dom/html element is not a good way to implement business. you should have really used data objects to hold app states. however following will enforce max count constraint for each category, assuming your player names are unique.

(function () {
    var maxCounts = {
        forward: 12,
        defenceman: 6,
        goalie: 2
    };

    var getSelectePlayerNames = function () {
        var names = [];
        $("input:text").each(function (i, t) {
            t.value && names.push(t.value);
        });

        return names;
    };
    var getPlayerPositionCounts = function (players) {
        var $players = $('.player');
        var positions = [];
        $.each(players, function (i, player) {
            positions.push($players.find(".player__name:contains('" + player + "')").next().text().toLowerCase());
        });

        return positions.reduce(function (memo, val) {
            memo[val]++;
            return memo;
        }, { forward: 0, defenceman: 0, goalie: 0 });
    };

    $(".player").on("click", function () {
        var $el = $(this);

        var playerName = $el.find(".player__name").text();
        var selectedPlayerNames = getSelectePlayerNames();
        var index = selectedPlayerNames.indexOf(playerName);
        if (index > -1) {
            $("input:text:eq(" + index + ")").val("");

            return;
        }

        if (!$el.find(".picked.is-active").length) {
            return;
        }

        var playerPosition = $el.find(".player__position").text().toLowerCase();
        var selectedPositionCounts = getPlayerPositionCounts(selectedPlayerNames);
        if (selectedPositionCounts[playerPosition] < maxCounts[playerPosition]) {
            $("input:text:eq(" + selectedPlayerNames.length + ")").val(playerName);
        }
    });
})();
Comments