skip to Main Content

I made an HTML page that allows you to click a button to add row and column division. At the moment, the row div is added to the container div. I want to switch from the standard div adding to one that is mouse-click driven. This means that when a user clicks a button and selects a div, a row block is appended to that div. Looking for a solution

var i = 0;
var j = 0;

let newColNode = null;

function addRow() {
  const row = document.createElement('div');
  row.className = 'bloc';
  row.id = "b" + ++i;

  document.getElementById('contentBox').append(row);

  row.addEventListener('click', function(event) {
    console.log(newColNode)
    console.log(row)
    if (newColNode != null)
      row.appendChild(newColNode);
    newColNode = null
  });
}

// Column Addition

function addCol() {
  const col = document.createElement('div');
  col.className = 'bloc--inner';
  col.id = "c" + ++j;
  newColNode = col;
}
* {
  box-sizing: border-box;
}

.wrapper {
  float: left;
  width: 100%;
  height: 100vh;
}

body {
  padding: 0;
  margin: 0;
  position: relative;
}

.main-content {
  float: left;
  width: calc(100%);
  height: 100%;
  background: #fafafa;
}

.header {
  height: 60px;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  padding: 0 20px;
}

.content-box {
  width: 100%;
  height: calc(100% - 60px);
  padding: 15px;
}

button {
  background: #000;
  border: 0;
  padding: 0 20px;
  height: 40px;
  margin-left: 10px;
  font-weight: 600;
  color: white;
  cursor: pointer;
}

.row-block {
  width: 100%;
  border: 2px dashed #848484;
  padding: 20px;
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -ms-flex-wrap: wrap;
  flex-wrap: wrap;
  margin-bottom: 20px;
}

.row-block:hover {
  border-color: #2654d1;
}

.column-block {
  position: relative;
  width: 100%;
  min-height: 1px;
  padding-right: 10px;
  padding-left: 10px;
  margin: 0 10px;
  -ms-flex-preferred-size: 0;
  flex-basis: 0;
  -webkit-box-flex: 1;
  -ms-flex-positive: 1;
  flex-grow: 1;
  max-width: 100%;
  border: 2px dashed #848484;
  background-color: #dedede;
  padding: 20px;
}

.column-block:first-child {
  margin-left: 0;
}

.column-block:last-child {
  margin-right: 0;
}

.row-block .each-draggable-item {
  position: relative;
  width: 100%;
  min-height: 1px;
  padding-right: 10px;
  padding-left: 10px;
  -ms-flex-preferred-size: 0;
  flex-basis: 0;
  -webkit-box-flex: 1;
  -ms-flex-positive: 1;
  flex-grow: 1;
  max-width: 100%;
  margin-bottom: 0;
}

.gu-mirror {
  cursor: grabbing;
}

.container .ex-moved {
  background-color: #e74c3c;
}

.container.ex-over {
  background-color: rgba(255, 255, 255, 0.3);
}

.handle {
  background-color: rgba(0, 0, 0, 0.4);
  cursor: move;
  margin-right: 5px;
  padding: 0 5px;
}

.column-block h5 {
  margin: 0;
}


/* .gu-mirror {
    cursor: move;
    cursor: -webkit-grabbing;
    cursor: -moz-grabbing;
    cursor: grabbing;
    position: fixed !important;
    margin: 0 !important;
    z-index: 9999 !important;
    opacity: 1;
}
.gu-hide {
    display: none !important;
}
.gu-unselectable {
    -webkit-user-select: none !important;
    -moz-user-select: none !important;
    -ms-user-select: none !important;
    user-select: none !important;
}
.gu-transit {
    opacity: 0.4;
    -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=20)";
    filter: alpha(opacity=20);
} */

.gu-transit {
  opacity: 0.4;
  -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=20)";
  filter: alpha(opacity=20);
  transition: .3s ease-out;
}

.container {
  width: 100%;
}

.bloc {
  width: 100%;
  border: 2px dashed #848484;
  background: #ffefef;
  margin-bottom: 20px;
  padding: 20px;
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -ms-flex-wrap: wrap;
  flex-wrap: wrap;
}

.bloc--inner {
  margin: 0 10px;
  -ms-flex-preferred-size: 0;
  flex-basis: 0;
  -webkit-box-flex: 1;
  -ms-flex-positive: 1;
  flex-grow: 1;
  max-width: 100%;
  border: 2px dashed #848484;
  background-color: #d4ecff;
  padding: 20px;
}

.bloc--inner:first-child {
  margin-left: 0;
}

.bloc--inner:last-child {
  margin-right: 0;
}

.bloc--inner .bloc {
  margin: 0;
}
<div class="wrapper">
  <div class="main-content">
    <div class="header">
      <button class="add-row" onclick="addRow()">Add Row +</button>
      <button class="add-column" onclick="addCol()">Add Column +</button>
    </div>
    <div class="content-box" id="main-container">
      <div class="container" id="contentBox">

      </div>
    </div>
  </div>
</div>

Thanks in advance!!

Currently the div is appedning to the container div

3

Answers


  1. Is this what you want?

    jsfiddle.net/tog40yaq/1

    Login or Signup to reply.
  2. Is this more or less the intended result? Click on a div and then click on either button to add the appropriate element to the previously clicked div?

    var i = 0;
    var j = 0;
    
    let parent=false;
    
    /* delegated listener to set the global variable used to determine where new elements are added */
    document.querySelector('#main-container > .container').addEventListener('click',e=>{
      parent=e.target;
    });
    /* remove elements using right-click */
    document.querySelector('#main-container > .container').addEventListener('contextmenu',e=>{
      e.preventDefault();
      try{
        if( parent )parent.removeChild(e.target);
      }catch(err){
        console.clear();
        console.log(err.message);
      }
    });
    
    
    
    
    
    const warnuser=(e)=>{
      if( !parent ){
        return alert('Click a suitable parent to begin');
      }
      return true;
    }
    
    function addRow() {
      if( warnuser() ){
        i++;
        const row = document.createElement('div');
              row.className='bloc';
              row.id = `b${i}`;
        parent.append( row );
        return row;}
    }
    function addCol() {
      if( warnuser() ){
        j++;
        const col=document.createElement('div');
              col.className='bloc--inner';
              col.id = `c${j}`;
        parent.append( col );
        return col;
      }
    }
    * {
      box-sizing: border-box;
    }
    /*
      to ensure user can see contentBox initially
    */
    .container{
      border:2px dashed grey;
      padding:1rem
    }
    .bloc:after,
    .bloc--inner:after{
      content:attr(id)
    }
    
    
    
    .wrapper {
      float: left;
      width: 100%;
      height: 100vh;
    }
    
    body {
      padding: 0;
      margin: 0;
      position: relative;
    }
    
    .main-content {
      float: left;
      width: calc(100%);
      height: 100%;
      background: #fafafa;
    }
    
    .header {
      height: 60px;
      display: flex;
      align-items: center;
      justify-content: flex-end;
      padding: 0 20px;
    }
    
    .content-box {
      width: 100%;
      height: calc(100% - 60px);
      padding: 15px;
    }
    
    button {
      background: #000;
      border: 0;
      padding: 0 20px;
      height: 40px;
      margin-left: 10px;
      font-weight: 600;
      color: white;
      cursor: pointer;
    }
    
    .row-block {
      width: 100%;
      border: 2px dashed #848484;
      padding: 20px;
      display: -webkit-box;
      display: -ms-flexbox;
      display: flex;
      -ms-flex-wrap: wrap;
      flex-wrap: wrap;
      margin-bottom: 20px;
    }
    
    .row-block:hover {
      border-color: #2654d1;
    }
    
    .column-block {
      position: relative;
      width: 100%;
      min-height: 1px;
      padding-right: 10px;
      padding-left: 10px;
      margin: 0 10px;
      -ms-flex-preferred-size: 0;
      flex-basis: 0;
      -webkit-box-flex: 1;
      -ms-flex-positive: 1;
      flex-grow: 1;
      max-width: 100%;
      border: 2px dashed #848484;
      background-color: #dedede;
      padding: 20px;
    }
    
    .column-block:first-child {
      margin-left: 0;
    }
    
    .column-block:last-child {
      margin-right: 0;
    }
    
    .row-block .each-draggable-item {
      position: relative;
      width: 100%;
      min-height: 1px;
      padding-right: 10px;
      padding-left: 10px;
      -ms-flex-preferred-size: 0;
      flex-basis: 0;
      -webkit-box-flex: 1;
      -ms-flex-positive: 1;
      flex-grow: 1;
      max-width: 100%;
      margin-bottom: 0;
    }
    
    .gu-mirror {
      cursor: grabbing;
    }
    
    .container .ex-moved {
      background-color: #e74c3c;
    }
    
    .container.ex-over {
      background-color: rgba(255, 255, 255, 0.3);
    }
    
    .handle {
      background-color: rgba(0, 0, 0, 0.4);
      cursor: move;
      margin-right: 5px;
      padding: 0 5px;
    }
    
    .column-block h5 {
      margin: 0;
    }
    
    
    /* .gu-mirror {
        cursor: move;
        cursor: -webkit-grabbing;
        cursor: -moz-grabbing;
        cursor: grabbing;
        position: fixed !important;
        margin: 0 !important;
        z-index: 9999 !important;
        opacity: 1;
    }
    .gu-hide {
        display: none !important;
    }
    .gu-unselectable {
        -webkit-user-select: none !important;
        -moz-user-select: none !important;
        -ms-user-select: none !important;
        user-select: none !important;
    }
    .gu-transit {
        opacity: 0.4;
        -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=20)";
        filter: alpha(opacity=20);
    } */
    
    .gu-transit {
      opacity: 0.4;
      -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=20)";
      filter: alpha(opacity=20);
      transition: .3s ease-out;
    }
    
    .container {
      width: 100%;
    }
    
    .bloc {
      width: 100%;
      border: 2px dashed #848484;
      background: #ffefef;
      margin-bottom: 20px;
      padding: 20px;
      display: -webkit-box;
      display: -ms-flexbox;
      display: flex;
      -ms-flex-wrap: wrap;
      flex-wrap: wrap;
    }
    
    .bloc--inner {
      margin: 0 10px;
      -ms-flex-preferred-size: 0;
      flex-basis: 0;
      -webkit-box-flex: 1;
      -ms-flex-positive: 1;
      flex-grow: 1;
      max-width: 100%;
      border: 2px dashed #848484;
      background-color: #d4ecff;
      padding: 20px;
    }
    
    .bloc--inner:first-child {
      margin-left: 0;
    }
    
    .bloc--inner:last-child {
      margin-right: 0;
    }
    
    .bloc--inner .bloc {
      margin: 0;
    }
    <div class="wrapper">
      <div class="main-content">
      
        <div class="header">
          <button class="add-row" onclick="addRow()">Add Row +</button>
          <button class="add-column" onclick="addCol()">Add Column +</button>
        </div>
        
        <div class="content-box" id="main-container">
          <div class="container" id="contentBox"></div>
        </div>
        
      </div>
    </div>

    Perhaps I have this backwards – having re-read the question.


    If the process is to be initialised using the button to determine what is to be added when the user clicks within the target area then perhaps this is better than the previous which does seem backwards to the perceived mode of operation.

    var i = 0;
    var j = 0;
    let bRow=false;
    let bCol=false;
    
    let parent=false;
    let container=document.querySelector('#main-container > .container');
    let header=document.querySelector('.header');
    
    
    container.addEventListener('click',e=>{
      parent=e.target;
      if(bRow)addRow(e);
      if(bCol)addCol(e);
    });
    
    header.addEventListener('click',e=>{
      bRow=false;
      bCol=false;
      
      if( e.target.className=='add-row' )bRow=true;
      if( e.target.className=='add-column' )bCol=true;
    });
    
    container.addEventListener('contextmenu',e=>{
      e.preventDefault();
      try{
        if( parent )parent.removeChild( e.target );
      }catch(err){
        console.clear();
        console.log(err.message);
      }
    });
    
    function addRow(e) {
      i++;
      const row = document.createElement('div');
            row.className='bloc';
            row.id = `b${i}`;
      parent.append( row );
      return row;
    }
    
    function addCol(e) {
      j++;
      const col=document.createElement('div');
            col.className='bloc--inner';
            col.id = `c${j}`;
      parent.append( col );
      return col;
    }
    * {
      box-sizing: border-box;
    }
    /*
      to ensure user can see contentBox initially
    */
    .container{
      border:2px dashed fuchsia;
      background:silver;
      padding:1rem
    }
    .bloc:after,
    .bloc--inner:after{
      content:attr(id)
    }
    
    
    
    .wrapper {
      float: left;
      width: 100%;
      height: 100vh;
    }
    
    body {
      padding: 0;
      margin: 0;
      position: relative;
    }
    
    .main-content {
      float: left;
      width: calc(100%);
      height: 100%;
      background: #fafafa;
    }
    
    .header {
      height: 60px;
      display: flex;
      align-items: center;
      justify-content: flex-end;
      padding: 0 20px;
    }
    
    .content-box {
      width: 100%;
      height: calc(100% - 60px);
      padding: 15px;
    }
    
    button {
      background: #000;
      border: 0;
      padding: 0 20px;
      height: 40px;
      margin-left: 10px;
      font-weight: 600;
      color: white;
      cursor: pointer;
    }
    
    .row-block {
      width: 100%;
      border: 2px dashed #848484;
      padding: 20px;
      display: -webkit-box;
      display: -ms-flexbox;
      display: flex;
      -ms-flex-wrap: wrap;
      flex-wrap: wrap;
      margin-bottom: 20px;
    }
    
    .row-block:hover {
      border-color: #2654d1;
    }
    
    .column-block {
      position: relative;
      width: 100%;
      min-height: 1px;
      padding-right: 10px;
      padding-left: 10px;
      margin: 0 10px;
      -ms-flex-preferred-size: 0;
      flex-basis: 0;
      -webkit-box-flex: 1;
      -ms-flex-positive: 1;
      flex-grow: 1;
      max-width: 100%;
      border: 2px dashed #848484;
      background-color: #dedede;
      padding: 20px;
    }
    
    .column-block:first-child {
      margin-left: 0;
    }
    
    .column-block:last-child {
      margin-right: 0;
    }
    
    .row-block .each-draggable-item {
      position: relative;
      width: 100%;
      min-height: 1px;
      padding-right: 10px;
      padding-left: 10px;
      -ms-flex-preferred-size: 0;
      flex-basis: 0;
      -webkit-box-flex: 1;
      -ms-flex-positive: 1;
      flex-grow: 1;
      max-width: 100%;
      margin-bottom: 0;
    }
    
    .gu-mirror {
      cursor: grabbing;
    }
    
    .container .ex-moved {
      background-color: #e74c3c;
    }
    
    .container.ex-over {
      background-color: rgba(255, 255, 255, 0.3);
    }
    
    .handle {
      background-color: rgba(0, 0, 0, 0.4);
      cursor: move;
      margin-right: 5px;
      padding: 0 5px;
    }
    
    .column-block h5 {
      margin: 0;
    }
    
    
    /* .gu-mirror {
        cursor: move;
        cursor: -webkit-grabbing;
        cursor: -moz-grabbing;
        cursor: grabbing;
        position: fixed !important;
        margin: 0 !important;
        z-index: 9999 !important;
        opacity: 1;
    }
    .gu-hide {
        display: none !important;
    }
    .gu-unselectable {
        -webkit-user-select: none !important;
        -moz-user-select: none !important;
        -ms-user-select: none !important;
        user-select: none !important;
    }
    .gu-transit {
        opacity: 0.4;
        -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=20)";
        filter: alpha(opacity=20);
    } */
    
    .gu-transit {
      opacity: 0.4;
      -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=20)";
      filter: alpha(opacity=20);
      transition: .3s ease-out;
    }
    
    .container {
      width: 100%;
    }
    
    .bloc {
      width: 100%;
      border: 2px dashed #848484;
      background: #ffefef;
      margin-bottom: 20px;
      padding: 20px;
      display: -webkit-box;
      display: -ms-flexbox;
      display: flex;
      -ms-flex-wrap: wrap;
      flex-wrap: wrap;
    }
    
    .bloc--inner {
      margin: 0 10px;
      -ms-flex-preferred-size: 0;
      flex-basis: 0;
      -webkit-box-flex: 1;
      -ms-flex-positive: 1;
      flex-grow: 1;
      max-width: 100%;
      border: 2px dashed #848484;
      background-color: #d4ecff;
      padding: 20px;
    }
    
    .bloc--inner:first-child {
      margin-left: 0;
    }
    
    .bloc--inner:last-child {
      margin-right: 0;
    }
    
    .bloc--inner .bloc {
      margin: 0;
    }
    <div class="wrapper">
      <div class="main-content">
      
        <div class="header">
          <button class="add-row">Add Row +</button>
          <button class="add-column">Add Column +</button>
        </div>
        
        <div class="content-box" id="main-container">
          <div class="container" id="contentBox"></div>
        </div>
        
      </div>
    </div>
    Login or Signup to reply.
  3. Basically to get what you want, I added some states to the buttons that will enable / disable their functionality and just allow you to click where you want to add a row or col.

    var i = 0;
    var j = 0;
    
    let addRowBool = false;
    let addColBool = false;
    
    function addRowState(){
        if(addColBool){
        addColBool = !addColBool;
      }
        addRowBool = !addRowBool;
      
      setColors();
    }
    
    function addColState(){
        if(addRowBool){
        addRowBool = !addRowBool;
      }
        addColBool = !addColBool;
      setColors();
    }
    
    function setColors(){
        if(addRowBool) {
        document.querySelector(".add-row").style.backgroundColor = "green";
      } else {
        document.querySelector(".add-row").style.backgroundColor = "red";
      }
      
      if(addColBool) {
        document.querySelector(".add-column").style.backgroundColor = "green";
      } else {
        document.querySelector(".add-column").style.backgroundColor = "red";
      }
    }
    
    function addRowOrCol(evt){
        if(addRowBool){
        i++;
        const row = document.createElement('div');
        const txt = document.createTextNode("row"+i);
        row.appendChild(txt);
        row.className = 'bloc';
        row.id = "b" + i;
        
        evt.target.appendChild(row);
      }
      else if(addColBool){
        
        const col = document.createElement('div');
        const txt = document.createTextNode("col"+j);
        col.appendChild(txt);
        col.className = 'bloc--inner';
        col.id = "c" + ++j;
    
        evt.target.appendChild(col);
      }
    }
    * {
      box-sizing: border-box;
    }
    
    .add-row {
      background-color: red;
    }
    
    .add-column {
      background-color: red;
    }
    
    .wrapper {
      float: left;
      width: 100%;
      height: 100vh;
    }
    
    body {
      padding: 0;
      margin: 0;
      position: relative;
    }
    
    .main-content {
      float: left;
      width: calc(100%);
      height: 100%;
      background: #fafafa;
    }
    
    .header {
      height: 60px;
      display: flex;
      align-items: center;
      justify-content: flex-end;
      padding: 0 20px;
    }
    
    .content-box {
      width: 100%;
      height: calc(100% - 60px);
      padding: 15px;
    }
    
    button {
      background: #000;
      border: 0;
      padding: 0 20px;
      height: 40px;
      margin-left: 10px;
      font-weight: 600;
      color: white;
      cursor: pointer;
    }
    
    .row-block {
      width: 100%;
      border: 2px dashed #848484;
      padding: 20px;
      display: -webkit-box;
      display: -ms-flexbox;
      display: flex;
      -ms-flex-wrap: wrap;
      flex-wrap: wrap;
      margin-bottom: 20px;
    }
    
    .row-block:hover {
      border-color: #2654d1;
    }
    
    .column-block {
      position: relative;
      width: 100%;
      min-height: 1px;
      padding-right: 10px;
      padding-left: 10px;
      margin: 0 10px;
      -ms-flex-preferred-size: 0;
      flex-basis: 0;
      -webkit-box-flex: 1;
      -ms-flex-positive: 1;
      flex-grow: 1;
      max-width: 100%;
      border: 2px dashed #848484;
      background-color: #dedede;
      padding: 20px;
    }
    
    .column-block:first-child {
      margin-left: 0;
    }
    
    .column-block:last-child {
      margin-right: 0;
    }
    
    .row-block .each-draggable-item {
      position: relative;
      width: 100%;
      min-height: 1px;
      padding-right: 10px;
      padding-left: 10px;
      -ms-flex-preferred-size: 0;
      flex-basis: 0;
      -webkit-box-flex: 1;
      -ms-flex-positive: 1;
      flex-grow: 1;
      max-width: 100%;
      margin-bottom: 0;
    }
    
    .gu-mirror {
      cursor: grabbing;
    }
    
    .container {
      min-height: 50px;
      min-width: 100%;
      background-color: grey;
    }
    
    .container .ex-moved {
      background-color: #e74c3c;
    }
    
    .container.ex-over {
      background-color: rgba(255, 255, 255, 0.3);
    }
    
    .handle {
      background-color: rgba(0, 0, 0, 0.4);
      cursor: move;
      margin-right: 5px;
      padding: 0 5px;
    }
    
    .column-block h5 {
      margin: 0;
    }
    
    
    /* .gu-mirror {
        cursor: move;
        cursor: -webkit-grabbing;
        cursor: -moz-grabbing;
        cursor: grabbing;
        position: fixed !important;
        margin: 0 !important;
        z-index: 9999 !important;
        opacity: 1;
    }
    .gu-hide {
        display: none !important;
    }
    .gu-unselectable {
        -webkit-user-select: none !important;
        -moz-user-select: none !important;
        -ms-user-select: none !important;
        user-select: none !important;
    }
    .gu-transit {
        opacity: 0.4;
        -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=20)";
        filter: alpha(opacity=20);
    } */
    
    .gu-transit {
      opacity: 0.4;
      -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=20)";
      filter: alpha(opacity=20);
      transition: .3s ease-out;
    }
    
    .container {
      width: 100%;
    }
    
    .bloc {
      width: 100%;
      border: 2px dashed #848484;
      background: #ffefef;
      margin-bottom: 20px;
      padding: 20px;
      display: -webkit-box;
      display: -ms-flexbox;
      display: flex;
      -ms-flex-wrap: wrap;
      flex-wrap: wrap;
    }
    
    .bloc--inner {
      margin: 0 10px;
      -ms-flex-preferred-size: 0;
      flex-basis: 0;
      -webkit-box-flex: 1;
      -ms-flex-positive: 1;
      flex-grow: 1;
      max-width: 100%;
      border: 2px dashed #848484;
      background-color: #d4ecff;
      padding: 20px;
    }
    
    .bloc--inner:first-child {
      margin-left: 0;
    }
    
    .bloc--inner:last-child {
      margin-right: 0;
    }
    
    .bloc--inner .bloc {
      margin: 0;
    }
    <div class="wrapper">
      <div class="main-content">
        <div class="header">
          <button class="add-row" onclick="addRowState()">Add Row +</button>
          <button class="add-column" onclick="addColState()">Add Column +</button>
        </div>
        <div class="content-box" id="main-container">
          <div class="container" id="contentBox" onclick="addRowOrCol(event)">
    
          </div>
        </div>
      </div>
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search