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

Using JavaScript to apply styling on images with overlays

I am currently facing an issue with placing an overlay on top of a background image. Despite my efforts, I am unable to get the background color to appear on top of the image. Any helpful suggestions on how to resolve this would be greatly appreciated. M ...

Node.js's module-only scope concept allows variables and functions defined within

Currently, I am attempting to create a function that can set a variable at the top-level scope of a module without it leaking into the global scope. Initially, I believed that implicit variable declarations within a module would remain confined to the modu ...

Creating a directive with a dynamically generated name in Vue Bootstrap

Currently, I am working with a dropdown component from Vue bootstrap and looking to incorporate collapsible elements within it. My goal is to have a button that toggles the visibility of each element in the collapsible list. In Vue bootstrap, achieving th ...

Receiving the error "Undefined chart type" when using $q.all with Google Chart API Promise

I am currently working on implementing angular-google-charts using the $http service to retrieve data and display it on charts. I found a helpful tutorial on this blog post: since the GitHub README for angular-google-charts lacks examples of backend data ...

Modifying a Sass variable using a Knockout binding or alternative method

Is it feasible to dynamically alter a sass variable using data-binding? For instance, I am seeking a way to modify the color of a variable through a button click. I am considering alternative approaches apart from relying on Knockout.js. $color: red; ...

Tips for concealing an authentication token in Nuxt.js 2

After encountering some challenges with querying my Strapi backend from my NuxtJS frontend via Apollo, using a JWT authentication token, I embarked on a search for ways to securely hide the authentication token in Nuxt.js 2. I experimented with different m ...

What are the key principles of designing web and native mobile applications using React.js architecture?

I am intrigued by the idea of incorporating React.js for server-side rendering into my web service. However, I am facing a challenge when trying to transition from my current web service built with Express.js. At present, my web service caters to two platf ...

Aligning divs, prevent duplicate HTML within multiple divs

Currently, I am attempting to troubleshoot a jsfiddle issue. The main problem lies in my desire for the first two divs (with class="fbox") to be aligned next to each other on the same level. Furthermore, I am looking to enable dragging the image into the ...

Adding jQuery and other libraries to Typescript for optimal functionality

After spending days researching and struggling, I am reaching out here for clarification on the process of importing a library in Typescript. I used to just add the script tag and everything would work fine. Now that I am working on building a MEAN-Stack ...

Every time I try to upload image files to cloudinary, I encounter this frustrating error message

https://i.stack.imgur.com/kRYVZ.png The issue at hand revolves around node and the challenge of using the https module with new certificates, proving to be unsuccessful... The proposed solution is ambiguous, leaving me unsure how to proceed and resolve thi ...

Steps for displaying a bootstrap modal in alignment with the triggering button's position

Recently diving into the world of bootstrap and AngularJs has been quite the learning experience for me. One challenge I encountered was trying to implement a bootstrap modal dialog box to show additional details within a table column. My goal was to hav ...

`Trigger a page reload when redirecting`

Currently, I am tackling some bug fixes on an older Zend Framework 1.10 project and encountering difficulties with redirection and page refresh. The issue: The task at hand is to make an AJAX call, verify if a person has insurance assigned, and prevent de ...

Utilizing the power of Vue Router with DataTables

I am currently facing an issue where I want to include links or buttons in my DataTable rows that can navigate to a vue route when clicked. The straightforward approach would be to add a normal <a> element with the href attribute set to "/item/$ ...

Implementing dynamic component swapping in Vue 3 using components from another component

I currently have a display component called app-display, which contains a dynamic component inside (by default, it is set to app-empty): app.component('appDisplay', { template: `<component :is="currentComponent"></c ...

Making adjustments to text in HTML without altering the CSS or styling is proving to be challenging

When attempting to modify a h1 tag without changing the CSS, I encountered an issue. Below is the string with and without the JavaScript: String without JavaScript: String with JavaScript: This problem seems isolated as other code snippets were successf ...

How can you disable a single button when clicked using the map method, and update the className after a timer runs out in React?

Is there a way to disable only one button when clicked using the map method? I currently have a disabled hook that affects all pressed buttons. Also, how can I revert the 'current__events__hot-price disabled' className back to 'current__even ...

Tips on implementing live updates in Firebase without the need for reloading the page

After a user changes their profile picture, the update does not appear until they refresh the page. Here is the code snippet causing this issue: const handleProfile = async (e: any) => { const file = e.target.files[0] const storageRef = firebase ...

Trouble connecting JavaScript to Node application for proper functionality

After setting up Node/Express/EJS, I am now trying to include js files, but my alert("working"); is not working as expected. Quite ironic, isn't it? The main objective is to load learnJs.js in the browser and trigger the alert so that I can confirm e ...

How to Highlight Text in a textField Using Vuetify

Is there a way to dynamically set the value of a text field in Vuetify, focus it, and select its text? I encountered an error stating "select is not a function". This method works for regular text inputs but seems to be incompatible with Vuetify text fie ...

What is the best way to utilize the useSWR hook when there are necessary logical operations to be performed on the response before proceeding with the next API call

I am currently utilizing the swr library in a Create React App and require the usage of the useSWR hook for data fetching that is both contingent and conditional. The specific task at hand involves: Making an API call to retrieve an id which will be used ...