Clickable shapes

Clickable shapes with automatically added event listeners.

by William Foulkes

HTML

<body>
  <h1>
Clickable shape demo
</h1>
  <p>
    Try clicking on the shapes below
  </p>

  <svg width="100" height="100">
    <rect id="asset1" x="25" y="50" width="20" height="20" />
    <rect id="asset2" x="50" y="15" width="20" height="20" />
    <rect id="asset3" x="60" y="70" width="20" height="20" />
  </svg>

  <!-- The Modal -->
  <div id="modal" class="modal">
    <!-- Modal content -->
    <div class="modal-content">
      <span class="close">&times;</span>
      <span id="theInfo">No info set</span>
    </div>
  </div>

  <!--Information about each asset, that is added to the modal before it's displayed -->
  <div id="html_asset1" class="hiddenInfo" data-category="redCategory">
    <p>This is some information about asset one.</p>
  </div>

  <div id="html_asset2" class="hiddenInfo" data-category="blueCategory">
    <p>This is some information about asset two.</p>
  </div>

  <div id="html_asset3" class="hiddenInfo" data-category="blueCategory">
    <p>This is some information about asset three.</p>
    <table>
      <caption>Here is a table with information about asset 3:</caption>
      <tr>
        <th>Column A</th>
        <th>Column B</th>
      </tr>
      <tr>
        <td>data</td>
        <td>data</td>
      </tr>
      <tr>
        <td>data</td>
        <td>data</td>
      </tr>
    </table>
  </div>

</body>

CSS

body {
  color: grey;
}

table,
th,
td {
  border: 1px solid;
}

th,
td {
  padding: 5px;
}

svg {
  border: 2px solid grey;
}

.button:hover {
  opacity: 0.5;
}

rect {
  fill: powderblue;
  stroke: black;
}

rect.redCategory {
  fill: red;
}

rect.blueCategory {
  fill: blue;
}


/* The Modal (background) */

.modal {
  display: none;
  /* Hidden by default */
  position: fixed;
  /* Stay in place */
  z-index: 1;
  /* Sit on top */
  left: 0;
  top: 0;
  width: 100%;
  /* Full width */
  height: 100%;
  /* Full height */
  overflow: auto;
  /* Enable scroll if needed */
  background-color: rgb(0, 0, 0);
  /* Fallback color */
  background-color: rgba(0, 0, 0, 0.4);
  /* Black w/ opacity */
}


/* Modal Content/Box */

.modal-content {
  background-color: #fefefe;
  margin: 15% auto;
  /* 15% from the top and centered */
  padding: 20px;
  border: 1px solid #888;
  width: 80%;
  /* Could be more or less, depending on screen size */
}


/* The Close Button */

.close {
  color: #aaa;
  float: right;
  font-size: 28px;
  font-weight: bold;
}

.close:hover,
.close:focus {
  color: black;
  text-decoration: none;
  cursor: pointer;
}

.hiddenInfo {
  display: none
}

JavaScript

var rect = document.querySelectorAll('rect');

rect.forEach(item=>{
  item.addEventListener('click', displayModal);
});

var hiddenInfo = document.getElementsByClassName('hiddenInfo');

for (i=0; i<hiddenInfo.length; i++) {
	for (j=0; j<rect.length; j++) {
  	//check if the the hiddenInfo corresponds to the assetID
    if (hiddenInfo[i].id.includes(rect[j].id)) {
    	//if it does, make it a button
    	rect[j].className.baseVal += " button";
      console.log(hiddenInfo[i].dataset.category);
      rect[j].className.baseVal += " " + hiddenInfo[i].dataset.category;
    }
  }
}

// Get the modal
var modal = document.getElementById("modal");

// Get the <span> element that closes the modal
var span = document.getElementsByClassName("close")[0];

//Populate the information in the modal and then make it visible
function displayModal() {
	var hiddenHTMLid = "html_" + this.id
  //use the hidden HTML to populate the modal
  document.getElementById("theInfo").innerHTML = document.getElementById(hiddenHTMLid).innerHTML;
  modal.style.display = "block";
}

// When the user clicks on <span> (x), close the modal
span.onclick = function() {
  modal.style.display = "none";
}

// When the user clicks anywhere outside of the modal, close it
window.onclick = function(event) {
  if (event.target == modal) {
    modal.style.display = "none";
  }
}