Vue is set up to monitor changes in two connected input fields for user input exclusively

Two input fields are available, where the value of one can affect the other.

If a value between 1 and 200 is entered in the level field, Vue will look up the corresponding points for that level and populate the points field with them.

Conversely, if a user enters a specific amount of points in the points field, Vue will determine the associated level based on those points.

The current functionality works fine, but there's an issue with Vue performing double calculations because it's monitoring both fields. For example, entering 300 in the points field correctly returns level 4, but then it changes the points to 250 when it detects the change in the level field.

I'd like Vue to only trigger recalculations when the user actively changes a field, instead of reacting after each change.

Here's a snippet of data retrieved from an axios request:

[
    {"level":1,"points":0},
    {"level":2,"points":72},
    {"level":3,"points":175},
    {"level":4,"points":250},
    {"level":5,"points":401,}
]

Below is a simplified Vue component illustrating the process:

<template>
    <div>
        <div class="card-body">
            <form>
                <div class="row">
                    <div class="col">
                        <div class="form-group">
                            <input type="text" v-model="currentLevel" class="form-control">
                        </div>
                        <div class="form-group">
                            <input type="text" v-model="currentPoints" class="form-control">
                        </div>
                    </div>
                </div>
            </form>
        </div>
    </div>   
</template>

<script>
    export default { 
        data() {
            return {
                currentLevel: 1,
                currentPoints: 0,
                pointsTable: []
            }
        },
        mounted() {
            axios.get('/api/points').then(this.fetchPointsTable);
        },
        methods: {
            fetchPointsTable({data}) {
                this.pointsTable = data;
            }
        },
        watch: {
            currentLevel: function() { 
                const result = this.pointsTable.find( ({ level }) => level === parseInt(this.currentLevel) );

                this.currentPoints = result.experience;
            },
            currentPoints: function() {
                var levels = [];
                var goal = this.currentXp;

                var closest = this.xpTable.reduce(function(prev, curr) {
                    if (curr.points <= goal) {
                        levels = curr.level;
                    }
                    return Math.max(levels);
                });

                this.currentLevel = closest;
            }
        }
    }
</script>

Answer №1

If you're searching for the event that triggers when a user modifies the input value, look no further than the change event.

According to MDN (emphasis added):

The change event is triggered for <input>, <select>, and <textarea> elements when the user commits an alteration to the element's value. Unlike the input event, the change event may not be fired for every change to an element's value.

This implies that when a user changes the value in either input field, the change event will be activated, executing the designated method and updating the other input field accordingly. The process occurs seamlessly because updates made programmatically won't trigger a change event on the other input field (unlike a watcher that monitors all value changes), thereby avoiding unnecessary method invocation.

Adjusted version of your code snippet:

<template>
    <div>
        <div class="card-body">
            <form>
                <div class="row">
                    <div class="col">
                        <div class="form-group">
                            <input
                                type="text"
                                v-model="currentLevel" 
                                class="form-control" 
                                @change="updateCurrentPoints"
                            >
                        </div>
                        <div class="form-group">
                            <input
                                type="text"
                                v-model="currentPoints"
                                class="form-control"
                                @change="updateCurrentLevel"
                            >
                        </div>
                    </div>
                </div>
            </form>
        </div>
    </div>   
</template>

<script>
    export default { 
        data() {
            return {
                currentLevel: 1,
                currentPoints: 0,
                pointsTable: []
            }
        },
        mounted() {
            axios.get('/api/points').then(this.fetchPointsTable);
        },
        methods: {
            fetchPointsTable({data}) {
                this.pointsTable = data;
            },
            updateCurrentPoints() { // contents of currentLevel watcher
                const result = this.pointsTable.find( ({ level }) => level === parseInt(this.currentLevel) );

                this.currentPoints = result.experience;
            },
            updateCurrentLevel() { // contents of currentPoints watcher
                var levels = [];
                var goal = this.currentXp;

                var closest = this.xpTable.reduce(function(prev, curr) {
                    if (curr.points <= goal) {
                        levels = curr.level;
                    }
                    return Math.max(levels);
                });

                this.currentLevel = closest;
            },
        }
    }
</script>

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

The function webpack.validateSchema does not exist

Out of the blue, Webpack has thrown this error: Error: webpack.validateSchema is not defined Everything was running smoothly on Friday, but today it's not working. No new changes have been made to the master branch since Friday. Tried pruning NPM ...

Vuetify: How to restore the input value in v-text-field

This app is designed with a simple v-text-field for user input. The issue I am facing is that when I enter a combination of numbers and letters like 11a, then quickly tab out or click out of the input field before losing focus, it only shows 11. However, ...

persistent storage issue leading to vuex state not reflecting changes

I'm currently facing a puzzling issue regarding the lack of state change persistence in vuex. A snippet of the code causing me trouble is displayed below: <v-btn :disabled="!isEditing" color="success" @cl ...

JavaScript Async Ordering

I have a specific question regarding asynchronous operations in Javascript. I am currently building a Node.js API to interact with an OrientDB database, using the Node-orient package for basic connectivity functions. Some of these functions are as follows: ...

Learn the process of eliminating special characters from input or textarea fields with AngularJs!

My attempts to integrate an AngularJS directive to remove special characters from input and textarea fields have been unsuccessful. Despite no errors being reported in the console, I am facing issues with the character count tooltip not displaying numbers ...

How to select the li element in a nested menu using jQuery

My goal is to extract the text from a specific li element when it is clicked on. The code snippet provided below outlines the structure: <div> <ul> <li>list item 1</li> <li>list item 2</li> <li> ...

Building a TTL based schema in NestJs with MongooseIn this guide, we will explore

In my NestJs(TypeScript) project, I am attempting to create a self-destructing schema using the mangoose and @nestjs/mongoose libraries. Unfortunately, I have been unable to find a clear way to implement this feature. While I know how to do it in an expres ...

Transform Promise-based code to use async/await

I'm attempting to rephrase this code using the async \ await syntax: public loadData(id: string): void { this.loadDataAsync() .then((data: any): void => { // Perform actions with data }) .catch((ex): v ...

The comparison between dynamically adding elements through Javascript and hiding them using CSS

I am contemplating the advantages and disadvantages of adding elements to a page and setting display:none versus creating a function that dynamically generates the elements and appends them where needed. In my current situation, I am implementing a reply ...

"Exploring JSON data with jQuery: A guide to efficient search techniques

I have a local file containing JSON data which I successfully loaded using jQuery. My current task is to specifically find the pId with the value of "foo1". The JSON data { "1":{ "id": "one", "pId": "foo1", "cId": "bar1" }, "2":{ ...

Can state values be utilized as content for Meta tags?

I am looking for a way to display image previews and titles when sharing a page link. In order to achieve this, I am using the Nextjs Head Component. The necessary details are fetched on page load and used as content for the meta attributes. let campaign = ...

Unlocking the secrets of accessing elements within a Vue.js template using $refs

I am facing an issue with an h1 element that is truncating text if it is too long to fit on the screen, displaying an ellipsis when this occurs. In order to determine whether the ellipsis is active or not, I attempted to use a ref on the h1 element and th ...

Encountering a problem with npm installation during the setup of node-sass

While attempting to run the npm install command, I encountered an error during the installation of node-sass. https://i.stack.imgur.com/qcDaA.png https://i.stack.imgur.com/YxDi2.png Here is my package.json file: { "name": "XXXXX", ...

Is there a way to incorporate a variable into a JSON URL?

I'm attempting to incorporate a variable I have defined into the JSON URL: var articleName = "test"; $.getJSON( "https://www.googleapis.com/customsearch/v1?key=API_MY&cx=CX_MY&q='+articleName+'&searchType=image&fileType= ...

Monitor the fullscreenChange event with angularJs

Utilizing a button to activate fullscreen mode for a DOM element using the fullscreen API is functioning correctly. The challenge arises when exiting fullscreen mode, requiring the listening for the fullscreen change event in order to resize the DOM elemen ...

Setting minimum and maximum limits for a JavaScript variable: tips and tricks

Currently, I am implementing a pagination feature using vuejs to display my algolia data. I am determining whether the user has clicked on either the previous button, next button, or directly inputted a page number (1, 2, 3, etc.) setPage: function(p ...

Can Mustache syntax {{}} be used to inject a Vue component?

I am dealing with a markdown file that includes YAML frontmatter. Within the frontmatter, I am trying to reference a component like so: --- title: Hello world component: <component-a></component-a> --- Lorem ipsum... My goal is to reference th ...

Delivering Background Videos with Node.JS

Apologies if my question seems off base or confusing, as I am not very knowledgeable in the world of nodejs. I have been comfortable using just plain PHP and Apache for a while until I discovered ZURB Foundation's stack with Handlebars and SASS, along ...

Navigating to a particular value in Vue: A step-by-step guide

In my Vue application, I have a basic table structure: <tbody> <tr v-for="(item, index) in items"> <td> ... </td> </tr> </tbody> The items are dynamically added using the unsh ...

Switching between TWO classes in Vuejs

I've been grappling with how to add or remove TWO classes in Vue JS for hours. The documentation examples only demonstrate toggling one class. My goal is to change a button's class to either: active toggle-on or toggle-off when clicked. While ...