List Grid Part 7: LocalStorage

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

   <div id="palette-container">
      <ul id="palette">
      <template v-for="(type,idx) in numTypes">
        <li :data-type="idx" @click="setType">{{ idx }} </li>
      </template>
      </ul>
   </div>
   
   <div id="map-container">
   
    <div>
   <input id="numCols" type="range" min="1" max="16" v-model.number="numCols" v-on:change="setMap"/>
     <label for="numCols">Columns: {{ numCols }} </label>

   </div>
   <div>

   <input id="numRows" type="range" min="1" max="16" v-model.number="numRows" v-on:change="setMap"/>
      <label for="numRows">Rows: {{ numRows }}</label>
   </div>
   <div>
    <div id="curType" :data-type="currentType">
       {{ currentType }}
    </div>

   </div>
    <table id="theme-switcher">
    <template v-for="row in numRows">
      <tr>
      <template v-for="cell in numCols">
        <td data-type="0" :data-row="row" :data-col="cell" v-on:mouseover="checkMouse" v-on:mousedown="setCurrent"> 

           <label>{{ row }}-{{ cell }}</label>
   
       
       </td>
      </template>
    
      </tr>
      </template>
    </table>
    </div>
    <div id="export-button-container">
      <button id="export" @click="exportMap">
        Export Map Data
      </button>
    </div>
    <div id="output">
      {{ printedMap }}
    </div> 
   
    <!-- this is the markup that gets styled. -->
   
</div>

CSS

body {
  font-family: Arial;
}
div#root {
  display: flex;
  flex-wrap: wrap;
}
div#output {
  width: 100%;
  font-family: Courier;
}
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;
  
}
div#palette-container {
  width: 40px;
  margin-right: 20px;
}
div#map-container {
  display: block;
}
ul#palette {
  list-style-type: none;
  padding-left: 0px;

  
}
ul#palette li {
  width: 30px;
  height: 30px;
  cursor: pointer;
}
*[data-type="0"] {
  background-color: #000;
  color: #fff;
}
*[data-type="1"] {
  background-color: lightgrey;
}
*[data-type="2"] {
  background-color: navy;
  color: white;
}
*[data-type="3"] {
  background-color: brown;
  color: white;
}
*[data-type="4"] {
  background-color: green;
  color: white;
}
*[data-type="5"] {
  background-color: red;
  color: white;
}
*[data-type="6"] {
  background-color: orange;
 
}
*[data-type="7"] {
  background-color: blue;
  color: white;
}
td label {
  pointer-events: none;
  position: absolute;
  top: 0px;
  left: 0px;
  
  border-width: 0px;
}
input[type="range"] {
  position: relative;
  top: 6px;
}

div#curType {
  width: 30px;
  height: 30px;
  margin: 20px 0px;
}
div#export-button-container {
  width: 100%;
  margin: 10px 0px;
}

JavaScript

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

 
    methods:{
      showAlert:function() {
         alert('alert!');
      },
      exportMap:function() {
        // alert('export!');
        let filename = 'map.txt';
        this.downloadFile(filename,this.printedMap);
      },
     restoreMap:function() {
         this.numRows = this.map.grid.length;
         this.numCols = this.map.grid[0].length;
         let delay = 1;
         window.setTimeout(this.setMap, delay);
         //this.setMap();
         /*for (var i = 0; i < this.numRows; ++i) {
           for (var j  =0; j < this.numCols; ++j) {
               this.dataToMapTile(i,j);
           }
         }*/
     },
     downloadFile:function(filename,text) {
         var element = document.createElement('a');
  element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text));
  element.setAttribute('download', filename);

  element.style.display = 'none';
  document.body.appendChild(element);

  element.click();

  document.body.removeChild(element);
     },
     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);
         
         let map_str = localStorage.getItem('map');
         
         if (map_str) {
           this.map = JSON.parse(map_str);
           this.printedMap = map_str;
           this.restoreMap();
         }
        
         
          
       },
       setMap:function() {
        for (var i = 0; i < this.numRows; i++) {
        
           if...