Showing posts with label contenteditable. Show all posts
Showing posts with label contenteditable. Show all posts

Monday, February 19, 2018

Make DataTable Cell contenteditable





Example code  DataTable Cell  contenteditable
html:
<div style="padding:20px">
  <div class="row rowAddLine">
    <div style=" text-align: right;">
      <button type="button" id="btnAddRow" class="btn btn-info"><i class="fa fa-plus" style="margin-right:10px;"></i>Add</button>
    </div>
  </div>
  <div class="row">
    <div class="table-responsive">
      <table id="id_table" class="table table-striped table-bordered" cellspacing="0" width="100%">
        <thead>
          <tr>
            <th>Column1</th>
            <th>Column2</th>
            <th>Column3</th>
            <th class="noWidth">Column4</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td>freerf</td>
            <td>rfrfe</td>
            <td>erferfrfe</td>
            <td class="noWidth">
              <button class="action btn btn-default" type="button">
                <span class="glyphicon glyphicon-remove"></span>
              </button>
            </td>
          </tr>
        </tbody>
      </table>
    </div>
  </div>
</div>

 
JS

$(document).ready( function () {
    var myTable = $('#id_table').DataTable({"bSort" : false, "createdRow": function ( row, data, index ){
                    $("td:last", row).addClass("noWidth");}
                });
 
    function makeEmptyArray(nbElements){
            var arr = [];
            for(var i=0; i<nbElements-1; i++)
            {
                arr.push("");
            }
            arr[i] = '<button type="button" class="action btn btn-default"><span class="glyphicon glyphicon-remove"></span></button>';
            return arr;
        }


 var emptyArrayOfElement = makeEmptyArray(myTable.columns().nodes().length);


  // Add row after click on the button 'add row'
  $("#btnAddRow").click(function(){
    var row = myTable.row.add(emptyArrayOfElement).draw(false).node();
    myTable.page('last').draw('page');
    $('html, body').animate({
      scrollTop : $(row)[0].offsetTop
    }, 500);
  });
 
 
  // Making TD editable exept td with action button
  $('body').on('dblclick', 'td:not(:has(button))', function(){
    // The cell that has been clicked will be editable
    $(this).attr('contenteditable', 'true');
    var el = $(this);
    // We put the cursor at the beginning
    var range = document.createRange();
    var sel = window.getSelection();
    if(el[0].childNodes.length > 0)
    {
      range.setStart(el[0].childNodes[0],0);
      range.collapse(true);
      sel.removeAllRanges();
      sel.addRange(range);
    }
    // The cell have now the focus
    el.focus();

    $(this).blur(endEdition);
  });

  function endEdition()
  {
  
    // We get the cell
    var el = $(this);
   
    // We tell to datatable to refresh the cache with the DOM, like that the filter will find the new data added in the table.
    // BUT IF WE EDIT A ROW ADDED DYNAMICALLY, THIS INSTRUCTION IS A PROBLEM
    myTable.cell( el ).invalidate().draw();
   
    // When the user finished to edit a cell and click out of the cell, the cell can't be editable, unless the user double click on this cell another time
    el.attr('contenteditable', 'false');

    el.off('blur', endEdition); // To prevent another bind to this function
  }
 
  } );

  CSS
  .noWidth {width: 0px;}
  Reference
  https://codepen.io/robert91/pen/wWwmeE

contenteditable div vs textarea





contenteditable div   is more flexible comparing to textarea.  The height is adjusted automatically.
Example  of contenteditable div:
<div contenteditable='true'  id='award' class='award_name cfl_row' style= 'border: 1px solid red; min-height:70px;width:200px;border-radius: 5px;
        border-color:green;margin: 5px 0px;padding:5px 5px 5px 5px;background-color: #F5EAF7;'></div>

To get value of contenteditable div, using id and html()
$('#award').html();

Using  focusout instead of change for contenteditable div

$('.changeable').focusout(function() {
  alert('Handler for .change() called.');
});
 
Example of textarea:
<textarea id='award' class='comments cfl_row' cols=25 rows=2></textarea> 
To get value of textarea:
$('#award').val();
(Note $('#award').text(); works sometimes and fails other times! It's not reliable)