function bpFieldInitTableElement(element) {
      var $tableWrapper = element.parent('[data-field-type=table]');
      var $rows = (element.attr('value') != '') ? $.parseJSON(element.attr('value')) : '';
      var $max = element.attr('data-max');
      var $min = element.attr('data-min');
      var $maxErrorTitle = element.attr('data-maxErrorTitle');
      var $maxErrorMessage = element.attr('data-maxErrorMessage');
      var $addButton = $tableWrapper.find('[data-button-type=addItem]')


      // add rows with the information from the database
      if($rows != '[]') {
          $.each($rows, function(key) {

              addItem();

              $.each(this, function(column , value) {
                  $tableWrapper.find('tbody tr:last').find('input[data-cell-name="item.' + column + '"]').val(value);
              });

              // if it's the last row, update the JSON
              if ($rows.length == key+1) {
                  updateTableFieldJson();
              }
          });
      }

      // add minimum rows if needed
      var items = $tableWrapper.find('tbody tr').not('.clonable');
      if($min > 0 && items.length < $min) {
          $rowsToAdd = Number($min) - Number(items.length);

          for(var i = 0; i < $rowsToAdd; i++){
              addItem();
          }
      }

      items = $tableWrapper.find('tbody tr').not('.clonable');
      if($max > -1 && items.length == $max) {
          $addButton.hide();
      }

      // after adding previous values and min rows, update the row action buttons
      updateTableRowsActionButtons(items)

      $tableWrapper.find('.sortableOptions').sortable({
          handle: '.sort-handle',
          axis: 'y',
          helper: function(e, ui) {
              ui.children().each(function() {
                  $(this).width($(this).width());
              });
              return ui;
          },
          update: function( event, ui ) {
              updateTableFieldJson();
          }
      });


      $addButton.click(function() {                    
          addItem();
          updateTableFieldJson();

          let totalRows = $tableWrapper.find('tbody tr').not('.clonable');
          let totalCount = $tableWrapper.find('tbody tr').not('.clonable').length;
          // hide the add button when max is reached.
          if (totalCount == $max) {
              $addButton.hide();
          }
          updateTableRowsActionButtons(totalRows);
      });

      function addItem() {
          $tableWrapper.find('tbody').append($tableWrapper.find('tbody .clonable').clone().show().removeClass('clonable'));
      }

      function updateTableRowsActionButtons(totalRows) {
          let totalCount = totalRows.length;
    
          // show/hide row buttons
          totalRows.each(function(){
              // show the delete buttons on all rows if we are above the minimum
              if(totalCount > $min) {   
                  $(this).find('.removeItem').show();
              }
              // hide the delete buttons on all rows if we are at minimum rows
              if(totalCount <= $min) {   
                  $(this).find('.removeItem').hide();
              }
              // show the sort button when more than one row is on table
              if (totalCount > 1) {
                  $(this).find('.sort-handle').show();
              }
              // hide the sort button when there is only one row
              if (totalCount == 1) {
                  $(this).find('.sort-handle').hide();
              }
          });
      }

      $tableWrapper.on('click', '.removeItem', function() {                    
          $(this).closest('tr').remove();
          updateTableFieldJson();

          var totalRows = $tableWrapper.find('tbody tr').not('.clonable');

          if(totalRows.length < $max) {
              $addButton.show();
          }
          updateTableRowsActionButtons(totalRows);   
      });

      $tableWrapper.find('tbody').on('keyup', function() {
          updateTableFieldJson();
      });


      function updateTableFieldJson() {
          var $rows = $tableWrapper.find('tbody tr').not('.clonable');
          var $hiddenField = $tableWrapper.find('input.array-json');

          var json = '[';
          var otArr = [];
          var tbl2 = $rows.each(function(i) {
              x = $(this).children().closest('td').find('input');
              var itArr = [];
              x.each(function() {
                  if(this.value.length > 0) {
                      var key = $(this).attr('data-cell-name').replace('item.','');
                      itArr.push('"' + key + '":' + JSON.stringify(this.value));
                  }
              });
              otArr.push('{' + itArr.join(',') + '}');
          })
          json += otArr.join(",") + ']';

          var totalRows = $rows.length;

          $hiddenField.val( totalRows ? json : null ).trigger('change');
      }

      $tableWrapper.find('input.array-json').on('CrudField:disable', function(e) {
          $tableWrapper.find('[data-button-type=addItem]').attr('disabled','disabled');
          
          $tableWrapper.find('.removeItem').each(function(i, el) {
              $(el).on('click.prevent', function(e) {
							e.stopImmediatePropagation();
							return false;
						});
              // make the event we just registered, the first to be triggered
              $._data($(el).get(0), "events").click.reverse();
          });
          $tableWrapper.find('input, textarea, select').attr('disabled', 'disabled');
          $tableWrapper.find('.sortableOptions').sortable("option","disabled", true);
      });

      $tableWrapper.find('input.array-json').on('CrudField:enable', function(e) {
          $tableWrapper.find('[data-button-type=addItem]').removeAttr('disabled');
          
          $tableWrapper.find('.removeItem').each(function(i, el) {
              $(el).unbind('click.prevent');
          });
          $tableWrapper.find('input, textarea, select').removeAttr('disabled');
          $tableWrapper.find('.sortableOptions').sortable("option","disabled", false);
      });
      // on page load, make sure the input has the old values
      updateTableFieldJson();
  }

    