Home > OS >  Editable <td> filed using jQuery and AJAX, limit count and allow numbers only
Editable <td> filed using jQuery and AJAX, limit count and allow numbers only

Time:09-02

The following is an inline insert using HTML5 table data to a database table using jQuery and AJAX. I would like to limit the fields only with number and limit count. These are not text input fields.

For example all fields should only be able to input numbers. and Number field allows numbers up-to 2 digit all other fields allows numbers up-to 3 digits.

how can I do this this ?

$("#btnSaveAction").on("click", function() {
  params = ""
  $("td[contentEditable='true']").each(function() {
    if ($(this).text() != "") {
      if (params != "") {
        params  = "&";
      }
      params  = $(this).data('id')   "="   $(this).text();
    }
  });
  if (params != "") {
    $.ajax({
      url: "insert-row.html",
      type: "POST",
      data: params,
      success: function(response) {
        $("#ajax-response").append(response);
        $("td[contentEditable='true']").text("");
      }
    });
  }
});
<script src="http://code.jquery.com/jquery-1.10.2.js"></script>
<div id="add-product">
  <div >Add Product</div>
  <table cellpadding="10" cellspacing="1">
    <tbody>
      <tr>
        <th><strong>Number</strong></th>
        <th><strong>Count</strong></th>
        <th><strong>Code</strong></th>
        <th style="text-align:right;"><strong>Price</strong></th>
      </tr>
      <tr>
        < <td contentEditable="true" data-id="product_number"></td>
          <td contentEditable="true" data-id="product_count"></td>
          <td contentEditable="true" data-id="product_code"></td>
          <td contentEditable="true" data-id="product_price" style="text-align:right;"></td>
      </tr>
    </tbody>
  </table>
  <div id="btnSaveAction">Save to Database</div>
</div>

code is from here

CodePudding user response:

To differentiate between contentEditable regions that are specifically to accept 2-digit numbers rather than 3-digit in the below I added a dataset attribute to identify as a number.

If a field with that data attribute triggers the keyup ( or whichever event ) the acceptable length will be limited to 2 - every other contentEditable region accepts up to 3 digit.

The logic tests whether the given input is NaN - if it is it will be removed from the string. If it is not NaN the test for length proceeds as per the assigned length of either 2 or 3.

document.addEventListener('keyup', (e) => {

  let length=e.target.dataset.type=='number' ? 2 : 3;
  
  if (e.target.hasAttribute('contentEditable') && e.target.getAttribute('contentEditable') == 'true') {
    if( isNaN( e.target.textContent.trim() ) ) {
      e.target.textContent = e.target.textContent.substr(0, e.target.textContent.length - 1);
      return false;
    } else {
      if ( Number( e.target.textContent ) > Number( String.fromCharCode(57).repeat(length) ) ) {
        e.target.textContent = String.fromCharCode(57).repeat(length);
        alert(`A Maximum of ${length} digits are permitted`);
        return;
      }
    }
  }
})
<div id="add-product">
  <div >Add Product</div>
  <table cellpadding="10" cellspacing="1">
    <tbody>
      <tr>
        <th><strong>Number</strong></th>
        <th><strong>Count</strong></th>
        <th><strong>Code</strong></th>
        <th><strong>Price</strong></th>
      </tr>
      <tr>
        <td data-type='number' contentEditable="true" data-id="product_number"></td>
        <td contentEditable="true" data-id="product_count"></td>
        <td contentEditable="true" data-id="product_code"></td>
        <td contentEditable="true" data-id="product_price"></td>
      </tr>
    </tbody>
  </table>
  <div id="btnSaveAction">Save to Database</div>
</div>

CodePudding user response:

You need to add an event listener to your td[contentEditable="true"]s and check the pressed key and the length of the text. Then just call e.preventDefault() to deny the edit whenever the key is not allowed or it would put the length beyond the limit. Below I used the "keydown" event as it fires before the keypress is complete and before the character is added to the element.

$('td[contentEditable="true"]').on("keydown", e => {
  // define allowed keys
  const allow = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.', 'Tab', 'Backspace']
  // get pressed key
  const k = e.key
  if (allow.includes(k)) {
    // get the value before this keydown
    const val = e.target.textContent
    // determine the limit according to your logic
    const limit = ("product_price" === e.target.dataset['id']) ? 3 : 2;
    if (val.length == limit && 'Tab' != k && 'Backspace' != k) {
      // pressing this key would put the value over the limit
      e.preventDefault()
      console.log('deny: '   k, val, limit)
    } else
      console.log('allow: '   k, val, limit)

  } else {
    // key not allowed
    e.preventDefault()
    console.log('deny: '   k)
  }

})
$("#btnSaveAction").on("click", function() {
  params = ""
  $("td[contentEditable='true']").each(function() {
    if ($(this).text() != "") {
      if (params != "") {
        params  = "&";
      }
      params  = $(this).data('id')   "="   $(this).text();
    }
  });
  if (params != "") {
    $.ajax({
      url: "insert-row.html",
      type: "POST",
      data: params,
      success: function(response) {
        $("#ajax-response").append(response);
        $("td[contentEditable='true']").text("");
      }
    });
  }
});
<script src="http://code.jquery.com/jquery-1.10.2.js"></script>
<div id="add-product">
  <div >Add Product</div>
  <table cellpadding="10" cellspacing="1">
    <tbody>
      <tr>
        <th><strong>Number</strong></th>
        <th><strong>Count</strong></th>
        <th><strong>Code</strong></th>
        <th style="text-align:right;"><strong>Price</strong></th>
      </tr>
      <tr>
        < <td contentEditable="true" data-id="product_number"></td>
          <td contentEditable="true" data-id="product_count"></td>
          <td contentEditable="true" data-id="product_code"></td>
          <td contentEditable="true" data-id="product_price" style="text-align:right;"></td>
      </tr>
    </tbody>
  </table>
  <div id="btnSaveAction">Save to Database</div>
</div>

  • Related