Chris
Chris

Reputation: 1321

How to get the position of a table cell on click

I have a table, that when I click within it, I would like a module to appear using the nearest cell attributes to align the module correctly.

<table id="calendar" style = "margin-top: 65px; width: 100%; border-collapse: collapse;">
              <!--<thead>
              <tr>
                  <th>Sun</th>
                  <th>Mon</th>
                  <th>Tue</th>
                  <th>Wed</th>
                  <th>Thu</th>
                  <th>Fri</th>
                  <th>Sat</th>
              </tr>
            </thead>-->

              <tbody id="calendar-body" style = "border: 2px lightgray solid;">

              </tbody>
          </table>
//onclick function calculating where to place module
window.onclick = function(event) {
    document.getElementById("module");
    module.style.left = event.x;
    module.style.top = event.y;
}
//made table with dom
  let today = new Date();
  let currentMonth = today.getMonth();
  let currentYear = today.getFullYear();
  let selectYear = document.getElementById("year");
  let selectMonth = document.getElementById("month");

  let months = ["January", "Febuary", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];

  let monthAndYear = document.getElementById("monthAndYear");
  var hello = document.getElementById("calendar");
  hello.style.height = window.innerHeight - 65 + "px";
  showCalendar(currentMonth, currentYear);


  function next() {
  currentYear = (currentMonth === 11) ? currentYear + 1 : currentYear;
  currentMonth = (currentMonth + 1) % 12;
  showCalendar(currentMonth, currentYear);
  }

  function previous() {
  currentYear = (currentMonth === 0) ? currentYear - 1 : currentYear;
  currentMonth = (currentMonth === 0) ? 11 : currentMonth - 1;
  showCalendar(currentMonth, currentYear);
  }

  function showCalendar(month, year) {

  let firstDay = (new Date(year, month)).getDay();
  let daysInMonth = 32 - new Date(year, month, 32).getDate();

  let tbl = document.getElementById("calendar-body"); // body of the calendar

  // clearing all previous cells
  tbl.innerHTML = "";

  // filing data about month and in the page via DOM.
  monthAndYear.innerHTML = months[month] + " " + year;
  // creating all cells
  let date = 1;

  //creating individual cells, filing them up with data.
  var daysInWeek = ["SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"];

  for (let i = 0; i < 5; i++) {
      // creates a table row
      let row = document.createElement("tr");

      for (let j = 0; j < 7; j++) {
        if(i === 0) {

          let cell = document.createElement("td");
          let celltext = document.createTextNode(daysInWeek[j]);
          let br = document.createElement("br");
          cell.appendChild(celltext);
          cell.appendChild(br);
          cell.style.border = "2px solid lightgray";
          cell.style.color = "gray";
          if(j >= firstDay) {
            let celltext2 = document.createTextNode(date);
            cell.appendChild(celltext2);
            date++;
          }else {
            let celltext2 = document.createElement("br");
            cell.appendChild(celltext2);
          }
          row.appendChild(cell);

        }else if (date > daysInMonth) {
            let cell = document.createElement("td");
            let cellText = document.createTextNode("");
            cell.style.border = "2px lightgray solid";
            cell.style.color = "gray";
            cell.appendChild(cellText);
            row.appendChild(cell);
        }else {
            let cell = document.createElement("td");
            let cellText = document.createTextNode(date);
            if (date === today.getDate() && year === today.getFullYear() && month === today.getMonth()) {
                cell.style.backgroundColor = "yellow";

            } // color today's date
            cell.style.border = "2px lightgray solid";
            cell.style.color = "gray";
            cell.appendChild(cellText);
            row.appendChild(cell);

            date++;

        } //end of condition statements
      }
      tbl.appendChild(row);
  }//end of both fors
}//end of show calendar_today

var table = document.getElementById("calendar-body");


  </script>

The problem with this code is that sometimes the module appears offscreen and in order to counteract this, I want to get where I clicked within a table, and the get the x and y values of the nearest cell, so I can place my module accordingly.

I do not want the index of the nearest cell, but the actual left and top attributes of the cell.

Upvotes: 1

Views: 1661

Answers (2)

Enrique Gonz&#225;lez
Enrique Gonz&#225;lez

Reputation: 241

A way to do exactly what you're asking for (Getting the coordinates of the clicked cell) would be to call getBoundingClientRect(). You will need to send the dom element, not the event, as a parameter:

I will ellaborate over the example in the previous answer by @justDan:

function cellClick (element){
console.log (element.getBoundingClientRect());
}
td {
  border: 1px solid;
}
<table>
  <tr>
    <th>Firstname</th>
    <th>Lastname</th>
    <th>Age</th>
  </tr>
  <tr>
    <td onClick="cellClick(this)">Jill</td>
    <td onClick="cellClick(this)">Smith</td>
    <td onClick="cellClick(this)">50</td>
  </tr>
  <tr>
    <td onClick="cellClick(this)">Eve</td>
    <td onClick="cellClick(this)">Jackson</td>
    <td onClick="cellClick(this)">94</td>
  </tr>
</table>

Upvotes: 2

justDan
justDan

Reputation: 2333

Not much to work with here, but I think this is what you are after.

document.addEventListener('click', function(e) {
  var pos = {
    top: e.offsetY,
    left: e.offsetX
  };
  console.log(pos);
});
td {
  border: 1px solid;
}
<table>
  <tr>
    <th>Firstname</th>
    <th>Lastname</th>
    <th>Age</th>
  </tr>
  <tr>
    <td>Jill</td>
    <td>Smith</td>
    <td>50</td>
  </tr>
  <tr>
    <td>Eve</td>
    <td>Jackson</td>
    <td>94</td>
  </tr>
</table>

Upvotes: 1

Related Questions