Vue.js numerical input module

My approach involves utilizing Numeral.js:

        Vue.filter('formatNumber', function (value) {
            return numeral(value).format('0,0.[000]')
        })

        Vue.component('input-number', {
            template: '\
    <div>\
      <label v-if="label">{{ label }}</label>\
      <input\
        ref="input"\
        v-bind:value="displayValue(value)"\
        v-on:input="updateValue($event.target.value)"\
        v-on:focus="selectAll"\
      >\
    </div>\
  ',
            props: {
                value: {
                },
                label: {
                }
            },
            methods: {
                updateValue: function (inputValue) {

                    var valToSend = inputValue

                    var numVal = numeral(valToSend).value()
                    
                    if (isNaN(numVal)) {
                        valToSend = this.value.toString()
                        numVal = numeral(valToSend).value()
                    }

                    var formattedVal = numeral(numVal).format('0,0.[000]')

                    this.$refs.input.value = formattedVal + (valToSend.endsWith('.') ? '.' : '')

                    this.$emit('input', numeral(formattedVal).value())
                    

                },
                displayValue: function (inputValue) {
                    return numeral(inputValue).format('0,0.[000]')
                },
                selectAll: function (event) {
                    // Workaround for Safari bug
                    // http://stackoverflow.com/questions/1269722/selecting-text-on-focus-using-jquery-not-working-in-safari-and-chrome
                    setTimeout(function () {
                        event.target.select()
                    }, 0)
                }
            }
        })
        var app = new Vue({
            el: '#app',
            data: {
                pricePerGram: '160000',
                weightInGrams: '1.5',
            },
            computed: {
                totalPrice: function () {
                    return (this.pricePerGram * this.weightInGrams)
                },
                toatlWithVat: function () {
                    return (this.totalPrice *1.09)
                }
            }
        })
<script src="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="8ff9faeacfbda1baa1beb9">[email protected]</a>/dist/vue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/numeral.js/2.0.6/numeral.min.js"></script>

    <div id="app">
        <input-number v-model="pricePerGram" label="Price per gram:"></input-number><br />
        <input-number v-model="weightInGrams" label="Weight in grams:"></input-number><br />
        <div><label>Total price: </label><span dir="ltr">{{totalPrice | formatNumber}}</span></div><br />
        <div><label>Total + Vat: </label><span dir="ltr">{{toatlWithVat | formatNumber}}</span></div><br />
    </div>

Does my implementation meet the requirements? Are there alternative approaches for implementing a numeric-only input?

I am open to enhancing this solution further. While Numeral.js is currently used, it is not obligatory. It's just a library I came across.

Some aspects of the current implementation include:

  • Supports thousand separators while typing.

  • Handles decimal points with 3 digits (I aim to enhance this to support an unlimited number of decimal digits. The limitation arises from the format 0,0.[000], as Numeral.js does not seem to offer a format accommodating unlimited decimal digits.)

  • Only accepts numbers, commas, and decimal points (no other characters permitted).

    Considering using regular expressions instead of Numeral.js as a potential improvement. Would this be advisable?

Answer №1

Here is a solution that should be effective (Codepen):

Vue.component("input-number", {
  template: '<input type="string" v-model="model">',

  props: {
    value: {
      type: String,
      required: true,
    }
  },

  computed: {
    model: {
      get() {
        // Extracting decimal number to maintain accuracy while typing
        let value = this.value.split(".");
        let decimal = typeof value[1] !== "undefined"
          ? "." + value[1]
          : "";

        return Number(value[0]).toLocaleString("en-GB") + decimal;
      },

      set(newValue) {
        this.$emit("input", newValue.replace(/,/g, ""));
      }
    }
  }
});

new Vue({
  el: "#app",
  data: {
    input: "1234567.890",
  }
});

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Guide to placing a button on the same line as text with the use of JavaScript

Does anyone know how to add a button to the right of text that was added using JS DOM? I've tried multiple techniques but can't seem to get it right - the button always ends up on the next line. Any tips on how to achieve this? var text = docu ...

activating javascript function in rails when the page reloads

I have a rails4 app and I'm looking to implement some specific JavaScript events when the page loads, but only if the user is coming from a certain page. On the post#index page, all comment replies are initially hidden. When a user clicks on a specif ...

Rendering content on the server side and creating a cached version of the index.html file using Vuejs and Nodejs

Having multiple websites (site1.com, site2.com) connected to a single server poses an interesting challenge. I am able to capture the domain name when a user enters a site, and based on that domain name, I fetch appropriate JSON data from an API to display ...

Can Vue recognize array changes using the Spread syntax?

According to Vue documentation: Vue is unable to detect certain changes made to an array, such as: Directly setting an item using the index, for example vm.items[indexOfItem] = newValue Modifying the length of the array, like vm.items.length = newLength ...

The initial render in a Kanban board seems to be causing issues with the functionality of react-beautiful-dnd

I recently integrated a Kanban board into my Next.js and TypeScript project. While everything seemed to be working fine, I encountered a minor glitch during the initial rendering. Interestingly, when I refreshed the page, the drag and drop functionality st ...

Making sure to consistently utilize the service API each time the form control is reset within Angular 4

In the component below, an external API service is called within the ngOnInit function to retrieve an array of gifs stored in this.items. The issue arises when the applyGif function is triggered by a user clicking on an image. This function resets the For ...

Need help figuring out how to use Javascript:void(0) to click a button in Selenium?

Struggling with finding the right solution, I have attempted various methods. Apologies for any formatting errors, but the element that requires clicking is: <button href="javascript:void(0)" id="payNewBeneficiary" class="button-new-payee"> ...

How can I choose which button to click in selenium if there are multiple buttons on the page with the same name, value, and id?

This particular button actually opens a popup, even though it is located on the same page. ![click here for image description][1] I attempted to interact with the element using the following code: driver.findElement(By.tagName("td")).findElement(By.id( ...

The search button is malfunctioning after I submit search data and generate dynamic HTML using axios

When a user clicks on the search button, I retrieve the input value and then use axios to send a GET request with the search data. Everything works fine, but when I query the database and dynamically create data from the mongoose data, the page reloads w ...

Issue with Jquery function not executing on second attempt

/** Creates a table of iTunes data in HTML format **/ var appendValues = function(songArray) { songArray.each(function() { var title = $(this).find("im\\:name").eq(0).text(); var songImage = $(this).find("im\\:image").eq(0).text(); var ...

Retrieving the total count of data entries from the JSON server endpoint

Working on a practice application with the JSON server serving as the backend, I have a question. Is there a way to determine the total number of records at an endpoint without actually loading all the records? For example, if my db.json file contains da ...

Which language should I focus on mastering in order to create a script for my Epson receipt printer? (Check out the manual for reference)

Printer Model: TM-T88V User Manual: Receipt-marker Web template for the printer: (Provided by Epson) I'm completely new to computer languages and have been trying to understand how to print receipts. I've researched XML, HTML, CSS, and Jav ...

Adjust google maps to fill the entire vertical space available

I found this helpful resource for integrating Google Maps into my Ionic app. Everything is working smoothly, but I am trying to make the map fill the remaining height below the header. Currently, I can only set a fixed height in pixels like this: .angula ...

Introducing a pause in the function while rendering objects

After inserting setInterval into the code, it is causing all lasers to be delayed by one second. I am looking to have them fired in this order: - initially fire laser1 and laser2. - then take a 1-second break before firing another set of lasers, a ...

Competition among fetch requests

I am currently developing a tracker that is designed to gather data from our clients' websites and send it to our API using fetch requests when site users navigate away from the page. Initially, I planned to utilize the beforeunload event handler to ...

Can Vue.js import both element-ui and Bootstrap components?

After importing element-ui components, I realized that I also need some common styles such as reset.css and others from Bootstrap. I am wondering if these two can coexist in the same project without causing conflicts? ...

Express 4 Alert: Headers cannot be modified once they have been sent

I recently upgraded to version 4 of Express while setting up a basic chat system. However, I encountered an error message that says: info - socket.io started Express server listening on port 3000 GET / 304 790.443 ms - - Error: Can't set headers ...

Change the default direction of content scrolling in CSS and JavaScript to scroll upwards instead of

I am currently working on a website where the navigation bar spans the entire width and remains fixed in place. Below the navigation bar is a cover image, followed by the main content section. As you scroll down, the navigation bar covers the image from t ...

How come my data is not appearing on the screen despite receiving a result in the console log?

I am facing an issue with displaying data obtained from Supabase. I am passing the data as a prop and using map to iterate over it in order to show the required values. However, despite logging the correct results for `programme.title`, nothing is being re ...

Adding a JSON array to all JSON objects in JavaScript: A step-by-step guide

Here is a JSON Object that I am working with: { "status": "CREATED", "overrides": { "name": "test_override" }, "package_name": "test", "name": "app1", "defaults": { "job": { "example": { "executors_num": "2", "fr ...