Creating a user-friendly form in a Nuxt/Vue application that enables dynamic attribute creation

I am currently working on designing a form that enables users to create different variations for a product within a Nuxt/Vue application.

  • The goal is to provide users with the ability to specify attributes for each variation using a text field. These attributes will then be associated with the variants, and users can set their values as shown in the workflow below.
  • One challenge I'm facing is that when a user adds a new property to a variant, this new property is not automatically included in existing variants. My aim is to ensure that any newly added property is also applied to all previously created variants and any future ones.
  • Additionally, I would like to implement functionality that removes any attributes from the variants text field if they have been deleted.

Can anyone offer a solution to help me address this issue?

https://i.sstatic.net/P9SWR.gif

Here is the code snippet:

<template>
<div class="variant-holder mb-4">
   <div
      v-for="(variant, vindex) in form.variants"
      :key="vindex"
      class="variant table-responsive border rounded bg-white shadow-sm position-relative"
      >
      <button class="btn btn-sm btn-secondary-light px-2 position-absolute right-0 top-0">
         <b-icon icon="trash" variant="danger"></b-icon>
      </button>
      <b-table-simple borderless class="small">
         <b-tbody>
            <b-tr v-for="(detail, index) in variant.details" :key="index">
               <b-td class="align-middle">
                  <span class="capital">{{ detail.property }}</span>
               </b-td>
               <b-td class="align-middle">
                  <b-form-input v-model.trim="detail.value" size="sm" type="text" required></b-form-input>
               </b--td>
            </b-tr>
         </b-tbody>
      </b-table-simple>
   </div>
</div>

<b-button type="button" class="btn btn-sm btn-secondary-light btn-block mb-4" @click="addVariantComponent"">
   <b-icon icon="plus"></b-icon>
   Add another variant
</b-button>
</template>

<script>
export default {
  data() {
    return {
      form: {
        variant: {
          attributes: [],
        },
        variants: [],
      },
    }
  },
  methods: {
    addVariantComponent() {
      const variant = {
        details: this.variantDetails(),
      };
      this.form.variants.push(variant);
    },
    variantDetails() {
      const details = [];
      this.form.variant.attributes.forEach((attribute) => {
        details.push({ property: attribute, value: '' });
      });
      return details;
    },
  },
}
</script>

Answer №1

Utilizing a watcher to deeply monitor the form.variant.attributes array seems to be the appropriate approach for your situation. You will iterate through your current variants and generate a new details array for each variant by incorporating the latest attributes provided.

It is important to note that making modifications to variant details using this method may result in a reflow operation for each detail altered. This performance concern typically becomes noticeable once you have a large number of variants, say a hundred or more. If scalability isn't an issue for you, then this solution should work well.

watch: {
  'form.variant.attributes': function (attributes) {
    // map our new variants
    this.form.variants.map((variant) => {
      return {
        // create our new details object from our available attributes
        details: attributes.reduce((carry, attribute) => {
          carry.push(
            // use the existing value or supply a default
            variant.details.find(({ property }) => property === attribute) || {
              property: attribute, 
              value: ''
            }
          )
          return carry
        }, [])
      }
    })
  }
}

Answer №2

To start off, I would suggest breaking down the functionality into separate components.

One component that I would create is called "variation", which would receive a prop named "variationProperties".

By monitoring the changes in this prop within the variation component and updating the local data accordingly, the component can become reactive.

  watch: { 
    variationProperties: function(newVal, oldVal) { // keep an eye on it
      console.log('Prop has changed: ', newVal, ' | previously: ', oldVal)
    }
  }

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

Passport verification is successful during the login process, however, it encounters issues during registration

I am currently learning about passport.js and session management, and I'm in the process of implementing a local login feature on my website. Here is what I am attempting to achieve: Secret page: Authenticated users can access the secret page, while ...

The WYSIWYG niceEdit editor is incompatible with textareas generated through ajax-php calls, causing it to malfunction

My AJAX-generated textarea is not converting into a WYSIWYG Editor once loaded. The normal textarea works fine, but I need assistance in solving this issue. <!DOCTYPE html> <html> <head> ........ $.ajax({ type: "POST", ...

Tips for notifying a user about leaving a page without saving their information

I created a small table where users can input product names and numbers. My question is, how can I notify the user if they try to leave the page without saving the entered information? <form action="index.php" method="post"> <input type="text" ...

JavaScript lacks support for linear transformation and matrix multiplication functions, causing them to be

Currently, I am delving into the complexities of linear algebra and experimenting with crafting a simple program that incorporates fundamental linear transformations (rotating, scaling, translating). Behold, here is a fully functional example: https://cod ...

Crisp edges and corners casting shadows in Threejs BoxGeometry

I created a structure using BoxGeometry, with a DirectionalLight rotating around it. However, I am facing an issue with aliased light bleed in the corners. I've attempted adjusting the shadow.mapSize, the blur radius, and the renderer.shadowMap.type, ...

What is the most efficient way to enable seamless communication between sibling components in Vue.js 2?

Just starting out with Vue.js 2 and I'm really enjoying it so far despite being new to it. Currently using the latest version. I've begun working on my first larger application and ran into a scenario right off the bat where I have a main app co ...

Having trouble resolving '@auth0/nextjs-auth0' during deployment on Vercel? Check out this error message: "Can't resolve '@auth0/nextjs-auth0' in '/vercel/path0/pages'"

I recently deployed a project on Vercel and have been working on enhancing the layout to achieve a minimum viable product (MVP). As part of this process, I decided to switch my authentication method to @auth0/nextjs-auth0 package for Next.js. After running ...

What steps can be taken to create a seamless navigation experience that effectively emphasizes the user's current location?

Is there a way to dynamically add the "current" class to the navigation menu based on the user's current location on the page? This would make it easier for users to see which section of the site they are viewing as they scroll through. Check out this ...

Issues with AngularJS Directives not functioning properly when elements are added dynamically through an AJAX request

I am facing a scenario where I have a page featuring a modal window that is created using the AngularUI Bootstrap modal directive. The DOM structure for this modal is being dynamically loaded from the server, and it is triggered to open when a specific but ...

"Unlocking the Power: Sending a Complex JSON Object to PHP from the Dojo

Trying to send a complex JSON object to the server using PHP, but encountering difficulties in sending it. Here is the code snippet: Snippet from DOJO: var ObjArry=[]; var test1 = {key:value, key:value, key:value, key:value}; var test2 = {key:value, ...

What happens if setTimeout fails due to a page error?

My current setup involves using setTimeout to refresh the page, updating the jQuery template items. Here is a snippet of the relevant code: <script type="text/javascript"> var results = JSON.parse('@svgPath'.replace(/&quot;/g ...

Refresh Form (Reactive Forms)

This is the HTML code snippet: <div class="container"> <ng-template [ngIf]="userIsAuthenticated"> <form [formGroup]='form' name="test"> <div class="form-group"> <input type="text" class="form-contr ...

Differences in behavior of constructors when utilizing ES6 shorthand notation

ES6 introduced a new way to initialize objects with functions and properties using shorthand notation. // ES6 shorthand notation const obj1 = { a(b) { console.log("ES6: obj1"); } }; // ES5 var obj2 = { a: function a(b) { con ...

Ways to invoke a class method by clicking on it

My initialization function is defined as follows: init: function() { $("#editRow").click(function() { <code> } $(".removeRow").click(function() { <code> } } I am trying to find a way to call the class method removeRow directly in the onc ...

Transforming DOM elements into Objects

Here are some values that I have: <input name="Document[0][category]" value="12" type="text"> <input name="Document[0][filename]" value="abca.png" type="text" > I am looking for a way to convert them into an object using JavaScript or jQuer ...

Updating the state of an object within a mapping function

I've been struggling with this issue for two days now. Despite my efforts to find a solution online, I am still stuck and starting to believe that I might be missing something. The main functionality of the app is to click a button and watch an apple ...

Associate a variable with a model within a controller

My goal is to bind a variable in my Controller to a model linked to an input like this: <body ng-app="myApp"> <div ng-controller="MyController"> <input type="text" ng-model="myVar1" /> {{ myVar1 }} <br /> ...

Associate the ng-model with ng-options value and label

I'm currently using ng-options to create a select tag that displays location options. The labels represent the location names, while the values indicate the corresponding location ID as stored in the database. In addition to binding the value (locati ...

The Protractor Custom Locator is experiencing difficulty in finding the element

For our project, the automation team is incorporating a custom attribute called 'lid' to elements where unique identification is challenging. A new custom locator method has been developed to find elements using the 'lid' attribute: ...

Is there a way to retrieve the field names from a JSON array within a for loop?

Here is the structure of my Json array: var data = { "categories": { "category1": { "Name": "Maps", "Id": 3, "orderInList": 1 }, "category2": { "Name": "B ...