Skip to content
Advertisement

How can I make only numbers can be written in the box? Limit is 6 digits

How can I make only numbers can be written in the box? Limit is 6 digits.

<?php
$barcode_name = "Seal Number:";
$barname = "placeholder="Scan the Serial Number"";
?>

<label class="control-label col-sm-4" for="barcodeno"><?php echo $barcode_name; ?></label>
  <div class="col-sm-4">
    <p class="form-control-static" style="margin-top: -6px;">
        <textarea class="form-control" rows="10" id="barcodeno" name="barcodeno" onkeydown="return KeyDown()" onkeyup="this.value=this.value.toUpperCase()" <?php echo $barname; ?>></textarea>
    </p>
  </div>
  <br>

Added Javascript

var barcodeno = $('#barcodeno').val().trim();
barcodeno = barcodeno.split('n');
//checking duplicate barcodeno
let barcodeno_array = []
for (let i = 0; i < barcodeno.length; i++) {
  if (barcodeno_array.indexOf(barcodeno[i]) == -1) {
    barcodeno_array.push(barcodeno[i])
  }
}

Advertisement

Answer

So, a few starting notes:

  • Generally speaking you wouldn’t use a <textarea/> for a single data point value– you would use an <input/> or other form control. <textarea/> is usually reserved for large amounts of text data. However, as is not necessarily clear from your question, you are using it for a sort of “bulk entry” of multiple values, so for this reason it is probably acceptable.
  • Some comments suggested that using type="number" is the correct move, but I would caution against jumping to that anytime the entry characters are numeric– number inputs are specifically for when the value contained represents a quantity or otherwise numeric data point– however, there are many other situations, such as a numeric pin or a product ID, which may be constrained to numeric characters but don’t specifically represent a number
  • There is a pattern attribute that you can use to specify a pattern to be adhered to for the entry; however:
    1. This is restricted to only a handful of form elements, which do not include the <textarea/>
    2. The pattern attribute doesn’t actually restrict input; it merely is leveraged for native validation, which differs from your use case.

For these reasons, your best bet is, unfortunately, probably to leverage JavaScript. I would recommend running a script on every key entered to validate that it is either a numeric character or a newline, and otherwise don’t write it to the <textarea/>. Given your example code is leveraging jQuery, I will do the same for my example:

$(document).ready(() => {
  const pidTextarea = $('#productIds');
  const allowedChars = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'Enter'];
  pidTextarea.on('keypress', (e) => {
    const { key } = e;
    if (!allowedChars.includes(key)) {
      e.preventDefault();
    }
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<label for="productIds">Product IDs (bulk input)</label>
<textarea id="productIds" name="productIds"></textarea>

This allows you to prevent input to only numeric keys and the enter key (and delete and backspace key and arrow keys are not captured by this script, so it allows editing).

However, this does not restrict entries to six digits or less. To do that, we could try to evaluate each keypress, figure out where the cursor is, and if the resulting new value will violate our restrictions. However, this seems quite complex– for instance, we need to manage if the user has selected a series of values to replace versus simply having a single cursor with no selection. Instead, we could cache the last value after each valid change, and then listen to all changes using .on('input', ...) and evaluate if the value is valid– if not, we restore the last good value:

$(document).ready(() => {
  const pidTextarea = $('#productIds').eq(0);
  const allowedChars = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'Enter'];
  let cachedTextAreaValue = pidTextarea.value;
  pidTextarea.on('keypress', (e) => {
    const { key } = e;
    if (!allowedChars.includes(key)) {
      e.preventDefault();
    }
  });
  pidTextarea.on('input', (e) => {
    const newValue = pidTextarea.val();
    const splitNewValue = newValue.split('n');
    for (let i = 0; i < splitNewValue.length; i++) {
      const currentVal = splitNewValue[i];
      if (currentVal.length > 6) {
        pidTextarea.val(cachedTextAreaValue);
        return;
      }
    }
    // if we exit the for loop having not left the function we cache the new value
    cachedTextAreaValue = newValue;
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<label for="productIds">Product IDs (bulk input)</label>
<textarea id="productIds" name="productIds"></textarea>

This has the added benefit of preventing bad inputs from pasting in a value.

NOTE:

A comment was made on your original question that raised a good point

Don’t hijack the keyboard. Display an error message if the characters entered aren’t numeric. – onosendi 10 hours ago

This is a good point– while my post does show you how to implement what you have asked, it makes no judgement as to whether or not it is actually a good idea. There is certainly a case to be made for not restricting the input, and instead waiting until the user attempts to submit the form to then validate and show meaningful feedback as to what may have gone wrong. Furthermore, you should make sure to provide clear direction with the form control as to what is expected to try to reduce friction– for instance, don’t make the user guess if the delimiter is a new line, a space, or a comma– instead, provide that messaging adjacent to the form field. While these are more UX concerns than software concerns, often when we are building front ends we also must be responsible for making choices to build the best, most accessible experience we can for our users. For what it is worth, I have found The Smashing Magazine publication Form Design Patterns by Adam Silver to be a good source of sound, reasoned design patterns for usable user interfaces.

User contributions licensed under: CC BY-SA
10 People found this is helpful
Advertisement