1
votes

Hey I'm working on custom input component for integers only, with 2 modes based on acceptNegatives props, that indicates if it should accept the negative numbers or not, the problem is that my current implementation allows to add multiple - signs while the component should accept the negatives too.

What I'm trying to acomplish is to on prop acceptNegatives="true" the component should accept input or paste value like -2 or 2 not -0 or "--", "--2" because those values are treated as empty string for some reason.

Html of input component it uses default input from Buefy

<template>
  <b-input
    :placeholder="placeholder"
    :value="value"
    @input="handleChange"
    @paste.native="handlePaste"
    @keydown.native="handleKeyDown"
    @mousewheel.native="$event.preventDefault()"
    @blur="handleBlur"
    :icon-right="iconRight"
    :name="name"
    autocomplete="off"
    :type="type"
  ></b-input>
</template>

The JS part

  • Keydown event handler
handleKeyDown(event) {
      const { key } = event;
      if (this.acceptNegatives && this.isAdditionalKeyAllowed(event)) {
        this.$emit("keydown", key);
        return;
      }

      if (this.isAdditionalKeyAllowed(event) || this.isValidNumber(key)) {
        return this.allowPositiveNumbersOnly(event);
      }
      event.preventDefault();
    },
  • Is additional key
isAdditionalKeyAllowed(event) {
      const allowedKeyWithoutMeta = Object.values(ALLOWED_KEYS).includes(keyCode);

      if (this.hasAlreadyMinusSign(event.target.value, key)) {
        return false;
      }

      if (this.acceptNegatives) {
        return (
          allowedKeyWithoutMeta || key === "-"
        );
      }

      return allowedKeyWithoutMeta;
    },
  • hasAleardyMinusSign fn to check if we already have minus sign, fails because - is treated as empty string
hasAlreadyMinusSign(value, key) {
      return this.acceptNegatives && value.includes("-") && key === "-";
    },

I've prepared also little demo how it works in Vue. Currently I have no idea how to resolve this. Should I use watcher or the value should be computed value somehow? Thanks for advice.

https://codesandbox.io/s/integernumberinput-j4jlj?file=/src/components/IntegerNumberInput/IntegerNumberInput.js

1

1 Answers

2
votes

You need a way to strip the possibility of '------1', the easiest way to do this is using some regex:

inputVal() {
  // Regex that replaces all occurrences of "-" except the last
  return this.value.replace(/[-](?=.*[-])/g, "");
}

Then bind the input to this computed and use a getter and setter, something like this:

inputVal() {
  get() {
    // Regex that replaces all occurrences of "-" except the last
    return this.value.replace(/[-](?=.*[-])/g, "");
  },
  set(val) {
    this.value = val;
  }
}

Or you could add the first snippet I've provided as a method that you call during some other validation process. That's up to you to decide