HTML Table

by Akhmedov Khumoyun

HTML

<div class="controls">
 <div class='mouse-position'>
  x: 0 | y: 0
 </div>  
 
 <div class="control-btns">
   <button class="add-btn btn">Add Table</button> 
   <button class="remove-btn btn">Remove Table</button> 
 </div>
  
</div>


<div class="box">
</div>




<div class="table-box">

  <div class="dotty col-dotty">
    <div>...</div>
  </div>
  <table>
    <tr>
      <td>11</td>
      <td>12</td>
    </tr>
    <tr>
      <td>11</td>
      <td>12</td>
    </tr>
  </table>
  
  <div class="dotty row-dotty">
    <div>...</div>
  </div>
  

  
</div>

CSS

* {
  box-sizing: border-box;  
}

/* --before-top: -10px;
--after-left: -10px; */

.controls {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-evenly;
}

.mouse-position {
  padding: 10px 20px;
  background-color: dodgerBlue;
  color: #fff;
}

.box {
  width: 90%;
  margin: 50px auto;
  padding: 50px;
  box-sizing: border-box;
  border: 1px solid #e6e6e6;
  background-color: #fcfff7;
}

.btn {
  border: none;
  outline: none;
  padding: 5px 10px;
  border-radius: 5px;
  color: #fff;
  font-size: 14px;
  cursor: pointer;
  opacity: 0.8;
}

.add-btn {
  background-color: dodgerBlue;
}

.remove-btn {
  background-color: #ff4242;
}


.btn:active {
  opacity: 1;
}



table {
  width: 95%;
  position: relative;
  max-width: 500px;
  border-collapse: collapse;
  border-spacing: 0;
  outline: none;
  background-color: white;
  margin: 10px auto;
}

table .row-control {
  position: absolute;
}

table .col-control {
  
}


td {
  max-width: 300px;
  min-width: 100px;
  border: 1px solid #e6e6e6;
  padding: 0.5em;
  transition: 0.4s;
  font-size: 12px;
  text-align: center
}

/* table tr td:hover {
  background: rgb(245, 247, 255);
} */

table tr td:first-child:hover {
  background: rgb(245, 247, 255);
}

/* table tr td:last-child div:before {
  
} */

/* table tr:nth-child(2) td {
  background-color: rgb(245, 247, 255);
  border-top-color: green;
  border-bottom-color: green;
}
 */
 
table tr td:nth-child(1) {
  border-right-color: green;
}

table tr td:nth-child(2) {
  background-color: rgb(245, 247, 255);
  border-right-color: green;
}

table tr:first-child td:nth-child(2) {
  border-top-color: green;
}

table tr:first-child td:nth-child(2) > div {
  position: relative;
}

table tr:last-child td:nth-child(2) {
  border-bottom-color: green;
}

/* table::before {
  background-color: #5813de;
  content: "";
  position: absolute;
  width: 20px;
  height: 5px;
  top: var(--before-top);
  left: var(--before-left);
  border-radius: 10px;
 ...

JavaScript

class Table {
	constructor(rows, cols) {
  	this.t = document.createElement('table');
    this.t.setAttribute('id', Table.randName(11));
    this.t.setAttribute('contenteditable', true);
    this.t.setAttribute('class', 'chotki-table');
    //this.t.setAttribute('data-before', '-41px');
    //this.t.setAttribute('data-after', '-41px');
		this.t.style.setProperty('--before-top', '-4px');
    this.t.style.setProperty('--before-left', '4px');
   
    this.t.style.setProperty('--after-left', '-4px');
		this.t.style.setProperty('--after-top', '4px');

		// style.setProperty('--h', y + 'px')
    this.rows = [];
    this.cols = [];
    this.cells = [];
    
    for (let r=0; r<rows; r+=1) {
      this.t.insertRow(r);
      this.rows.push(this.t.rows[r]);
      
      for (let c=0; c<cols; c+=1) {
				this.t.rows[r].insertCell(c);
        this.cells.push(this.t.rows[r].cells[c]);
        
        this.addEvent(
        	this.t.rows[r].cells[c], 
          'click', 
          this.callback,
          false, 
          { row: r, col: c }
        );
      }    
    }
  }
  
  addEvent(el, evType, cb, capture = false, data = {}) {
  	if (el) {
    	el.addEventListener(evType, cb, capture);
      el.tdata = data; 
    }
  }
  
  callback(e) {
		// e.target.innerHTML = `row: ${e.target.tdata.row}, col: ${e.target.tdata.col}`; 
    // console.log('-> rectbox: ', e.target.getBoundingClientRect() )
		const bbox = e.target.getBoundingClientRect();
    const data = e.target.tdata;
    const el = e.path[3];
    const elbbox = el.getBoundingClientRect();
    
    const leftTop = bbox.x - elbbox.left;
    const topLeft = bbox.y - elbbox.top;
    console.log('-> bbox: ' , bbox);
    console.log('-> elbbox: ' , elbbox);
    console.log('leftTop: ', leftTop);
    console.log('topLeft: ', topLeft);
    if (el.tagName === 'TABLE') {
	    console.log('table: ', el.tagName);
			
      el.style.setProperty('--before-left', `${leftTop}px`); // horizontal
     ...