CalAlt CalAlt - 1 month ago 13
jQuery Question

Jquery trouble randomly selecting divs in a grid

I have a grid of 9 divs nested in columns of three. When the grid (

#left
) is clicked , 2 divs from the middle row,
row="1"
should have the class
.show
randomly applied to it, in the column where the no class was applied the div on the bottom row,
row="2"
should have the class '.show' applied. The attached picture shows the possible random outcomes. The same outcome should never appear consecutively.

I attached a code snippet of my code, currently, my index selection is not working as desired and I have struggled to find the reason why.

mock-up of wanted outcomes



var obj = {
bindEvents: function() {
var _this = this;
$('#left').on("click", $.proxy(_this.interaction, _this));
},
interaction: function() {
var selector = this.randomGenerator(0, 3);
console.log('selector = ' + selector());
var $midRow = $('#left').find('div[row=1]');
var $bottomRow = $('#left').find('div[row=2]');

$midRow.removeClass('show');
$bottomRow.removeClass('show');
$midRow.not(':eq(' + selector() + ')').addClass('show');
$bottomRow.eq(selector()).addClass('show');
},
randomGenerator: function(min, max) {
var last;
console.log('last = ' + last);

return function () {
var random;
do {
random = Math.floor(Math.random() * (max - min)) + min;
} while (random === last);
last = random;
return random;
};
},
}
obj.bindEvents();

#left {
display: flex;
}
div[row] {
border: 1px solid black;
width: 20px;
background-color: yellow;
}
.show {
background-color: red !important;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="left">
<div col="0">
<div row="0">0</div>
<div row="1">1</div>
<div row="2">2</div>
</div>
<div col="1">
<div row="0">0</div>
<div row="1">1</div>
<div row="2">2</div>
</div>
<div col="2">
<div row="0">0</div>
<div row="1">1</div>
<div row="2">2</div>
</div>
</div>




Answer Source

You do not pass any element to the functions.
There is no this... You have to provide it.

EDIT
When you call selector(), you are aware that it is a function... And that a new number is produced each time you call the function.

If you want the same "number" to be used in both .eq() statement, run the function just once and keep the number in a variable.

See changes in code.

var obj = {
  bindEvents: function(el) {  // pass an element!
    //var _this = this;
    //$('#left').on("click", $.proxy(_this.interaction, _this));
    el.on("click", $.proxy(obj.interaction(el), el));   // Call the obj function.
  },
  interaction: function(el) {  // pass an element again!
    var selector = obj.randomGenerator(0, 3);   // Call the obj function.
    

    // Get a number
    var number = selector();
    console.log('selector = ' + number);

    var $midRow = $('#left').find('div[row=1]');
    var $bottomRow = $('#left').find('div[row=2]');
            
    $midRow.removeClass('show');
    $bottomRow.removeClass('show');
    $midRow.not(':eq(' + number + ')').addClass('show');
    $bottomRow.eq(number).addClass('show');
  },
  randomGenerator: function(min, max) {
    var last;
    console.log('last = ' + last);

    return function () {
      var random;
      do {
        random = Math.floor(Math.random() * (max - min)) + min;
      } while (random === last);
        last = random;
        return random;
      };
    },
}
obj.bindEvents($("#left"));
#left {
  display: flex;
}
div[row] {
  border: 1px solid black;
  width: 20px;
  background-color: yellow;
}
.show {
  background-color: red !important;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="left">
    <div col="0">
        <div row="0">0</div>
        <div row="1">1</div>
        <div row="2">2</div>
    </div>
    <div col="1">
        <div row="0">0</div>
        <div row="1">1</div>
        <div row="2">2</div>
    </div>
    <div col="2">
        <div row="0">0</div>
        <div row="1">1</div>
        <div row="2">2</div>
    </div>
</div>