Tips for extracting user input from a Vue dialog or modal

In my app, I have a component called MyList.vue which is directly imported. This component does not have subcomponents, but it imports the following:

import store from "../store/store";
import { USER_FETCHLIST } from "../store/actions/user";

The data structure in MyList.vue looks like this:

export default {
  data () {
    return {
      tableData: [],
      tableheader: []
    }
  },
  created: function(){
    store.dispatch(USER_FETCHLIST).then((res) => {

        this.tableData = res["data"]["tableData"]
        this.tableHeader = res["data"]["tableHeader"]
    })
},
  methods: {
    changeRecord: function(element){
      console.log(element)
    }
  }

}

MyList.vue also contains markup for a bootstrap-vue modal:

<template v-for="(element, index) in tableData">
   <tr>
    //rest of the markup generating the columns carrying the data
      <td>
        <button v-on:click="changeRecord(element)" v-b-modal="`modal-${index}`">Aendern</button>

        <b-modal :id="'modal-' + index" title="BootstrapVue">
      <template v-for="(value, name) in element">

         //more nested templates here

     </template>
    </b-modal>
  </td>
</tr>
</template>

When clicking the button, a dialog appears with input fields based on the data received:

https://i.sstatic.net/3yomu.jpg

The user should be able to make changes to the data in the background through this dialog. However, since I am new to vue, I am unsure about the best approach for capturing user input. Should I use v-model? And if so, how can I handle dynamically inserted data/observables? The goal is to format the user input into key-value pairs where the label of the input field is the key and the value entered by the user is the value.

Additionally, any changes made in the dialog should only affect the specific record being edited without altering the original dataset on the frontend.

Answer №1

If you're searching for a solution, here's one approach that may work for you.

The idea is to retain the original object as a reference and generate a copy of it. By using the copied version in your modal inputs, you can avoid altering the initial object. During the hide event, you can verify if the OK button was selected; if so, all values from the copy are transferred back to the original object.

In case the cancel option is chosen or the modal is closed through another method, simply clear both the selected object and its copy.

This method utilizes the lodash.set function, which needs to be added to your project.

Additionally, the modal has been relocated outside the table loop. Since only one record can be edited at a time, having just one modal on the page suffices.

new Vue({
  el: "#app",
  data() {
    return {
      data: [{
          Internal_key: "TESTKEY_1",
          extensiontable_itc: {
            description_itc: "EXTENSION_ITC_1_1",
            description_itc2: "EXTENSION_ITC_1_2",
          },
          extensiontable_sysops: {
            description_sysops: "EXTENSION_SYSOPS_1"
          }
        },
        {
          Internal_key: "TESTKEY_2",
          extensiontable_itc: {
            description_itc: "EXTENSION_ITC_2_1",
            description_itc2: "EXTENSION_ITC_2_2",
          },
          extensiontable_sysops: {
            description_sysops: "EXTENSION_SYSOPS_2_1"
          }
        }
      ],
      editingRecord: {
        original: null,
        copy: null
      }
    }
  },
  methods: {
    onEditModalHide(event) {
      if (event.trigger === "ok") {
        for(let fullKey in this.editingRecord.copy){
          const copyObject = this.editingRecord.copy[fullKey]
          set(this.editingRecord.original, fullKey, copyObject.value)
        }
      }
      
      this.editingRecord.original = null;
      this.editingRecord.copy = null;
    },
    changeRecord(record) {
      const flatCopy = this.flattenObject(record);
      this.editingRecord.original = record;
      this.editingRecord.copy = flatCopy;

      this.$nextTick(() => {
        this.$bvModal.show('edit-modal')
      })
    },
    flattenObject(ob) {
      var toReturn = {};

      for (var i in ob) {
        if (!ob.hasOwnProperty(i)) continue;

        if ((typeof ob[i]) == 'object' && ob[i] !== null) {
          var flatObject = this.flattenObject(ob[i]);
          for (var x in flatObject) {
            if (!flatObject.hasOwnProperty(x)) continue;
            console.log(x)
            toReturn[i + '.' + x] = {
              key: x,
              value: flatObject[x].value
            };
          }
        } else {
          toReturn[i] = {
              key: i,
              value: ob[i] 
          };
        }
      }
      return toReturn;
    }
  }
});
<link href="//unpkg.com/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet" />
<link href="//unpkg.com/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="5674777d787a75733e7b6c78667a65746569737a217c7072">[email protected]</a>/dist/bootstrap-vue.min.css" rel="stylesheet" />

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.js"></script>
<script src="//unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.min.js"></script>
<script src="https://unpkg.com/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="accdccc5caedaff8d5ccdfd9cccdc5c882cec3cb88c4c8ca">[email protected]</a>/index.js"></script>

<div id="app" class="p-4">
  <table class="table table-bordered">
    <tr v-for="element in data">
      <template v-for="field in element">
        <template v-if="typeof field==='object'">
          <td v-for="nestedObjectValue in field">
            {{nestedObjectValue}}
          </td>
        </template>
      <template v-else>
          <td>
            {{field}}
          </td>
        </template>
      </template>
      <td>
        <button class="btn btn-primary" @click="changeRecord(element)">
          Edit
        </button>
      </td>
    </tr>
  </table>
  <b-modal id="edit-modal" v-if="editingRecord.copy" @hide="onEditModalHide">
    <template v-for="obj in editingRecord.copy">
      <label>{{ obj.key }}</label>
      <input v-model="obj.value"  class="form-control"/>
    </template>
  </b-modal>
</div>

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

Experienced an unexpected setback with the absence of the right-click capability on a Javascript-powered hyperlink, specialized for

I am facing an issue with a hyperlink on my website. This particular hyperlink submits a hidden form using the POST method to redirect users to another site. However, when someone right-clicks on this hyperlink and tries to open it in a new tab, they are o ...

dayjs is not a valid operation

I've assigned two dayjs date values to global variables Vars.date. var dayjs = require("dayjs") for import Vars.date1 = dayjs(whateverdate1("add", 2)).format('MMM D, YYYY') Vars.date2 = dayjs(whateverdate2("add&q ...

Is it possible to incorporate a carousel within this parallax feature?

I recently downloaded a JavaScript library called paroller.js that has allowed me to create a captivating parallax effect on my website. The effect is based on a background image (forsidebillede2.jpg) that covers the entire screen, and I even managed to i ...

Angular Chart.js is throwing an error: "Uncaught SyntaxError: Cannot use import statement outside a module"

Upon opening the page, an error in the console related to Chart.js 4.2.1 is being displayed. Description of first image. Description of second image. Is it possible that this issue solely lies with Chart.js? How can it be resolved? To address the proble ...

Ensure the security of Node.js runtime by either enabling protection measures or turning off debugging

I currently have a nodejs application that utilizes Javascript to interact with online services by reading stdin for username and password input. Throughout the 24/7 running of the application, these credentials are stored in variables for potential re-lo ...

What is the best way to add a bottom border to each row in a textarea?

I am currently exploring methods to include a border-bottom line for each row in a <textarea>, but so far I have only been able to achieve this on the very bottom row. Is there any way to make this happen? .input-borderless { width: 80%; bord ...

Adding up the values of an array based on their position in Javascript

I came across a JavaScript array that looks like this: var array1 = [ [1, 2, 3], [7, 9, 2], [6, 8, 1] ] What I'm aiming for is to get the following output: var array2 = [ 14, 19, 6 ] array1[0] = 1 + 7 + 6 array1[1] = 2 + 9 + 8 array1[2] = 3 + 2 + ...

Creating a RESTful API

To begin with, I am a newcomer to web frameworks and we are currently using Meteor. In our database, we have a collection of Students: Students = new Mongo.Collection('students'); At the moment, we have defined a Rest API as follows: // Maps t ...

Jasmine test case failing due to undefined variable even though it should be in scope

I am currently working on testing a controller that listens for an event to perform certain actions. The event handler relies on a crucial global variable named Main. Despite my efforts to mock all dependencies in the unit test, an error is being thrown by ...

Changing multiple tags in JavaScript within an HTML document

Here is the JSON data I have: [ { "menu": { "MenuID":"1", "OmfID":"1", "menu_name":"Coyote Blues Louisiana Menu", "menu_description":"Full menu served all day.", "menu_note":null, "currency_symbol":"$ ...

How can I add items to a multi-dimensional array within a loop using JavaScript?

When I parse JSON data, I am retrieving 3 values in each node. $.each($.parseJSON(data), function (key, val) { Var X = val.date; Var y = val.type; Var z = val.text; }); An example of JSON data is as follows: val.date= '2011/02/09', ...

Unable to interact with options in a dropdown menu while utilizing selenium

As a newcomer to the world of web scraping with Python using Selenium, I am trying to extract information on tennis players from the website "https://www.itftennis.com/en/players/". The challenge I am facing is related to navigating a drop-down list of res ...

Invoking JavaScript function at set intervals of time

I am currently working on JavaScript code where I am trying to establish a connection with a remote asp.net page (aspx) using AJAX. My goal is to check this connection for a maximum of 2 minutes, with intervals of 10 seconds each. Here is the logic that I ...

The image looks great when viewed on the browser, but for some reason it's not displaying properly on

My local image displays perfectly on the browser, but doesn't show up on my android device. Here's the code: <center><img class="image-full" width="200" src="../img/logo.png"></center> The image appears fine on my computer, bu ...

Deconstructing arrays in the req.body object in a Node.js Express application

Received an array in the request body as follows: [ { "month" : "JUL", "year" :"2018" }, { "month" : "JAN", "year" :"2018" }, { "month" : "MAR", "year" :"2018" } ] This array consists of two parameters (month:enum and year:string). ...

Tips for styling a dynamically generated element in Angular

Requesting assistance without screenshots Utilizing Angular framework. CSS style defined: .tableEntryText{ font-family: Noto Sans; font-style: normal; font-weight: normal; font-size: 14px; line-height: 20px; text-align:center; width:50%; letter-spacing ...

Are there any methods available to adjust the size of a View component in react-native?

My react-native application includes a View that contains several components. The layout displays perfectly on iPhone 6 and 5 models, but on an iPhone 4s, the bottom of one component is being clipped slightly. I'm aware of scaling base64 icons, but I ...

The current initialization status does not show any instances of firebase.app.App

Initially, my main concern was ensuring that all the Firebase scripts were properly loaded in the correct order. To tackle this issue, I came up with a simple yet effective solution :) var my_firebase_init = function(){ firebase.initializeApp(my_fir ...

Rearrange div elements following an ajax request based on a data attribute and applying the .animate method

I am dealing with a collection of div elements, each assigned a unique numeric id and data-position in sequential order (1 for the first in the list, 2 for the second, and so on). Upon making an ajax call using jQuery, the response is a JSON object that r ...

What is the secret behind Node.js's ability to efficiently manage multiple requests using just one thread

After conducting some research on the topic, I noticed that most people tend to focus solely on Non-blocking IO. For instance, if we consider a basic application that simply responds with "Hello World" text to the client, there will still be some executio ...