List Grid Part 5: Mouse Control

by nevkatz

HTML

<script src="https://unpkg.com/vue@2"></script>

<!-- set the root -->
<div id="root" v-on:mousedown="isDown = true" v-on:mouseup="isDown=false">
  {{ isDown }}
   <div>

   <input id="numCols" type="range" min="1" max="15" v-model.number="numCols" v-on:change="setMap"/>
     <label for="numCols">Columns: {{ numCols }} </label>

   </div>
   <div>

   <input id="numRows" type="range" min="1" max="15" v-model.number="numRows" v-on:change="setMap"/>
      <label for="numRows">Rows: {{ numRows }}</label>
   </div>
   <div>
   <p>
   last clicked: {{ lastClicked }}
   </p>
   </div>
    <table id="theme-switcher">
    <template v-for="row in numRows">
      <tr>
      <template v-for="cell in numCols">
        <td data-type="floor" :data-row="row" :data-col="cell" v-on:mouseover="checkMouse" v-on:mousedown="setCurrent"> 

           <label>{{ row }}-{{ cell }}</label>
   
       
       </td>
      </template>
    
      </tr>
      </template>
    </table>
    <div id="output">
      {{ printedMap }}
    </div> 
    <!-- this is the markup that gets styled. -->
   
</div>

CSS

body {
  font-family: Arial;
}
table {
  border-collapse: collapse;
}
td {
  width: 30px;
  height: 30px;

  padding: 0px;
  font-size: 10px;
  position: relative;
  cursor: pointer;
  border: 1px solid grey;
  background-clip: padding-box;
  background-color: lightgrey;
  color: grey;
  
}
td[data-type="1"] {
  background-color: navy;
  color: white;
}
td label {
  pointer-events: none;
  position: absolute;
  top: 0px;
  left: 0px;
  
  border-width: 0px;
}
input[type="range"] {
  position: relative;
  top: 6px;
}
div#output {
  font-family: Courier;
}

JavaScript

function init() {
  //define a new vue that grabs onto the root element.
  let vm = new Vue({
    el:'#root',
    data: {
      isDown:false,
      numRows:2,
      numCols:2,
      lastClicked:"none",
      map:{
        grid:"hello"
      },
      printedMap:'none'
    },

 
    methods:{
      showAlert:function() {
         alert('alert!');
      },
     
     initMap:function () {
    
        this.map.grid = [];
         for (var i = 0; i < this.numRows; i++) {
            this.map.grid[i] = [];
          for (var j = 0; j < this.numCols; j++) {
             this.map.grid[i][j] = 0;
          }
         }
         this.printedMap = JSON.stringify(this.map);
         
          
       },
       
       setMap:function() {
      // this.map.grid = [];
        for (var i = 0; i < this.numRows; i++) {
          console.log('row ' + i +': ' + this.map.grid[i]);
           if (!this.map.grid[i]) {
                this.map.grid[i] = [];
                for (var k = 0; k < this.numCols; ++k) {
                this.map.grid[i][k] = 0;
                }
           }
           else {
            for (var j = 0; j < this.numCols; j++) {
             if (this.map.grid[i][j] == undefined) {
                console.log('creating ' + i + ',' + j);
                this.map.grid[i][j] = 0;
              }
              // check for revealed cells.
         
                let val = this.map.grid[i][j];
                console.log('val '+i+'-'+j+': ' + val);
                let row = document.querySelectorAll('tr')[i];
                let cell = row.querySelectorAll('td')[j];
                cell.setAttribute('data-type',val);
              
            } // end for 
           }
          
         }
         this.printedMap = JSON.stringify(this.map);
       },
       updateMapItem:function(i,j,val) {
          if (!this.map.grid[i]) {
             this.map.grid[i] = [];
          }
          
          this.map.grid[i][j] = val;
          this.printedMap =...