Updating several inputs programmatically in VueJSLet's explore how to

I am working on a form that requires updating multiple other fields when one field is updated. For instance, I have a contact name field and depending on the name entered, I need to update the email and phone number fields as well.

<template>
  <custom-input :value="contact.name" @input="event => contact.name = event.target.value" />
  <custom-input :value="contact.phone" @input="event => contact.phone = event.target.value" />
  <custom-input :value="contact.email" @input="event => contact.email = event.target.value" /> 
</template>

<script>
...
props: {
  contact: {
    type: Object,
    required: true
  }
},
watch: 
  "contact.name": function(value) {
    if (this.contact.name === "john") {
      this.contact.email = "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="244e4b4c4a644149454d480a474b49">[email protected]</a>"
      this.contact.phone = "1111111111"
    } else if (this.contact.name === "ed") {
      this.contact.email = "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="6e0b0a2e0b030f0702400d0103">[email protected]</a>"
      this.contact.phone = "2222222222"  
    }
  }
}

...
</script>

It appears that Vue dislikes this approach because it segregates the DOM from the data model. Initially, I thought about using $refs, but those are only readable. What would be the correct method for accomplishing this task?

Another idea I had was to assign computed properties to the values of name and phone. However, this causes an issue since it will not trigger any changes in the parent component's form.

This problem may also stem from my misunderstanding of "two-way" binding. I always believed that the form represents one direction while the data within the component's script serves as the other, which is evidently not the case. So, what is the alternative?

A final consideration I have is emitting an event instead:

<template>
  <custom-input :value="contact.name" @input="event => contact.name = event.target.value" />
  <custom-input ref="phone" :value="contact.phone" @input="event => contact.phone = event.target.value" />
  <custom-input ref="email" :value="contact.email" @input="event => contact.email = event.target.value" /> 
</template>

<script>
...
props: {
  contact: {
    type: Object,
    required: true
  }
},
watch: 
  "contact.name": function(value) {
    if (this.contact.name === "john") {
       this.$refs.email.$emit("input", "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="d6bcb9beb896b3bb7bdbaf8b5bbb9">[email protected]</a>")
       this.$refs.phone.$emit("input", "111111111111")
    } else if (this.contact.name === "ed") {
       this.$refs.email.$emit("input", "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="284d4c684d45494144064b4745">[email protected]</a>")
       this.$refs.phone.$emit("input", "222222222222")
    }
  }
}

Unfortunately, this solution does not seem to work either. Quite disappointing.

Edit

Syntax errors fixed.

Edit 2

Demonstrated that input is actually a separate child component.

Answer №1

I have observed that there is an attempt to alter the value of props in Vue, which is not allowed by the framework. It's important to maintain a one-way data flow in Vue where child components do not directly modify data passed as props from the parent. This helps in ensuring clarity and predictability in how data moves through the application. For more information on this topic, you can refer to the official documentation at: https://v2.vuejs.org/v2/guide/components-props.html#One-Way-Data-Flow

Vue provides the data property for each component, serving as a local private memory that can be modified within the component.

To address this issue, a common approach is to copy the data from props into the data property of the child component when it is mounted, allowing modifications to be made on the local data instead.

Below is an updated code example (also reflected in Codepen) demonstrating this concept:

Template:

<div id="app">
  <div>
    <my-form :contact="contact"></my-form>
  </div>
</div>

Javascript:

Vue.component('my-form', {
  data() {
    return { name: '', phone: '', email: '' }
  },
  props: {
    contact: { type: Object, required: true }
  },
  mounted() {
    this.name = this.contact.name;
    this.phone = this.contact.phone;
    this.email = this.contact.email;
  },
  template: `
    <div>
      <input v-model="name" />
      <input v-model="phone"/>
      <input v-model="email"/>
      <p>
        value of input: {{ JSON.stringify({ name, phone, email }) }}
      </p>
    </div>
  `,
    watch: {
      name(value) {
        if(value === 'john') {
           this.phone = '123456';
           this.email = '<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="235746505763444e424a4f0d404c4e">[email protected]</a>';
        }
      }
    }
});
new Vue({
  el: '#app',
  data() {
    return { contact: { name: 'initial name', phone: '123456', email: '<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="a6cfc8cfd2cfc7ca88c3cbc7cfcae6c1cbc7cfca88c5c9cb">[email protected]</a>' } }
  }
})

Check out the updated code pen for a hands-on demonstration: https://codepen.io/aptarmy/pen/PoqgpNJ

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

How come I am unable to pass JavaScript values to my PHP5 code?

I'm struggling with this code snippet: <?php $html=file_get_contents('testmaker_html.html'); echo $html; ?> <script type="text/javascript"> document.getElementById('save_finaly_TEST').addEventLis ...

Issue encountered while trying to update field using dynamically created row

I am encountering a problem while trying to update the unit cost and total cost of dynamically generated rows in an inventory form that submits inventories to a database. The product names are fetched via autocomplete jQuery, as shown in the snapshots belo ...

Acquire information from a JSON formatted string

I am having trouble extracting the first name from the JSON data provided below. While I am able to display the entire string using JavaScript [ alert(data); ], I am struggling to isolate just the first names. Any assistance would be greatly appreciated! ...

Error: The parent class is not defined as an object

My program is currently attempting to utilize this.state, but I encountered an error. Can anyone provide assistance on resolving this issue? https://i.stack.imgur.com/wgxBf.png ...

What is the process for determining the default character length in a <p> tag based on its height and width?

I'm trying to determine the default length for the <p> tag in HTML. It should be displayed based on the height and width of the <p> tag. For example: Consider the following code snippet, <p style="height:300px;width:200px;"> </ ...

The negative z-index is causing issues with my ability to select classes using jQuery

By setting a z-index of -3 for several divs in my background, I thought they wouldn't affect the formatting of elements in the foreground. But now I'm facing an issue where I can't click on those background divs when trying to target them wi ...

When does an xmlHttpRequest object parse serialized XML into a DOM during its lifecycle?

When a JavaScript code with xmlHttpRequest.responseXML() runs, it creates a DOM Document object from the XML-structured HTTP response body. Have you ever wondered at what moment the XML string is turned into the DOM Document by an xmlHttpRequest object? ...

Converting a local Node.js server to an online server: A step-by-step guide

Currently working on a game for my school project. Originally designed to be an online multiplayer game, but have only been able to test it locally so far. Need help figuring out how to modify my server code to make it functional as a legitimate online ser ...

Why does this code snippet throw an error if let is not hoisted or in the temporal dead zone? It could have simply used the global reference instead

var b = 6; { console.log(b) let b = 55 } When running this code snippet, I encounter the following error message: ReferenceError: Cannot access 'b' before initialization Why is the console.log(b) not displaying 6 as expected? ...

Give it a little time before uploading a widget onto the page

As a newcomer to programming, I recently came across this code from an open source project. I am in the process of loading a widget onto a website. Instead of having the widget load instantly, I would like it to wait 10 seconds before displaying. Below i ...

Does vuetify offer a card footer or card deck feature in its designs?

I'm trying to achieve a layout similar to this: https://getbootstrap.com/docs/4.0/components/card/#card-groups The goal is to keep the height of the box consistent even when the description varies Here's my codepen link : https://codepen.io/po ...

Encountering an issue in Next.js when using getStaticProps: reading 'map' of undefined properties

The Image above shows the error and the code I have attempted.Server Error TypeError: Cannot read properties of undefined (reading 'map') This particular error occurred during the page generation process. Any console logs will appear in the term ...

Leveraging Enjoyhint within nextJS

I am attempting to create a code tour using EnjoyHint, but encountered an error after installing the xbs-enjoyhint library. The error reads: Server Error - ReferenceError: CanvasRenderingContext2D is not defined. This issue is within the jquery.enjoyhint ...

Checking to see if the prop 'isChecked' has been modified

I'm currently facing a challenge with testing whether a class's prop value changes after clicking the switcher. Below is the component class I am working with: import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core&a ...

Display the contents of a <div> tag from one HTML file onto another HTML file

Recently I embarked on learning HTML and came across a peculiar doubt. My goal is to create a section div on the first page that changes dynamically based on the menu item clicked, rather than redirecting to another HTML page. I've experimented with s ...

Is there a solution for the continuous automatic incrementing of the jQuery UI spinner that occurs when I right-click on it?

Only Linux and Mac OS users are facing this particular issue, indicating a potential bug with the jQuery spinner. The bug also affects the spinner located at the following link: https://jqueryui.com/spinner/ <input class="spinner"/> $(".spinner"). ...

Obtain the URL for making an asynchronous request using PHP and SQL

I'm encountering some issues with a website I am attempting to update. A script named "jquery.script.js" is called in the head section containing some code. $.ajax({ url: 'function.js.php?option=urlget&id='+movie_id, ...

Is it possible to maintain the sidebar while eliminating the scrolling JavaScript?

Looking to recreate the image display style on Facebook where pictures appear in a lightbox format. The challenge I'm facing is figuring out how they manage to have the sidebar with no visible scroll bar inside... If you want to see this for yourself ...

Is there a feature similar to Google/YouTube Insight called "Interactive PNGs"?

Recently, I have been exploring the YouTube Insight feature and I am intrigued by how their chart PNGs are generated. When you view the statistics for a video, the information is presented in interactive PNG images. These images seem to be entirely compos ...

Create a feature in three.js that allows users to click on an object to display information about the

After loading an object using the GLTF loader into my scene, I want to create a point on this object to display popup info. Is there a way to add a point to a specific location on the object? ...