Managing toggles for save and edit buttons in Vue - a comprehensive guide

I am currently working on a Vue 'app' within a larger Django application as a means to enhance my understanding of Vue.

My objective is to create unique forms that can be edited independently.

I have been experimenting with this for some time now, trying to determine how to 'disable all forms except the one being edited'.

If a new piece of 'evidence' is added, that specific form should become enabled while the rest remain uneditable.

On the other hand, if an existing evidence is being edited, the 'add evidence' button should no longer be active and only the form being edited should be editable.

This is what my Vue setup looks like - there is a base container (representing the Vue app) and a component (standing for the forms):

var evidenceFormComponent = Vue.component("evidence-form", {
    template: "#evidenceFormTemplate",
    props: ["csrf_token", "evaluation_id", "element"],
    components: {},
    data: function () {
        console.log("data function");
        return {
            evidence: getEvidence(),
            subdomains: getSubdomains(),
            isDisabled: null,
            baseUrl: null
        };
    },
    created: function () {
        console.log("created_function!");
        this.baseUrl = "/api/";
        this.subdomainUrl = "/api/";
        this.fetchAdditionalEvidence();
        this.fetchSubdomainList();
        this.isDisabled = true;
    },
    methods: {
        fetchSubdomainList: function () {
            // get the evidence if any using a Jquery ajax call
            console.log("this should be fetching the subdomains");
            return getSubdomains;
        },
        fetchAdditionalEvidence: function () {
            // get the evidence if any using a Jquery ajax call
            console.log("this is fetching additional evidence");
            return getEvidence();
        },
        editForm: function (element) {
            console.log("editing the form!");
            this.isDisabled=false;
        },
        cancelEdit: function () {
            console.log("cancel the edit!");
        }
    }
});
const vm = new Vue({
    el: "#evidenceFormsContainer",
    data: function () {
        console.log("parent data function");
        return {
            evidence: getEvidence(),
            subdomains: getSubdomains(),
            isDisabled: false,
            baseUrl: null
        };
    },
    methods: {
      addForm: function () {
        console.log("adding a child form!");
        this.evidence.unshift({});
      },
    }
});

getEvidence and getSubdomains simply provide generic information as expected from an API at the moment.

I have read recommendations to have all UI elements present in case JavaScript is disabled or similar scenarios. Therefore, I opted to display all 4 buttons and show/hide them based on their disable/enable status.

                        <button class="btn btn-primary text-white valign-button" v-on:click.prevent="element.isDisabled=false" @click="editForm()">
                            <i class="far fa-edit"></i> EDIT
                        </button>
                        <button :id="'saveButton'+element.id" v-if="element.isDisabled" v-on:click.prevent="element.removedRow=true" class="btn btn-primary text-white valign-button">
                            <i class="far fa-save"></i> SAVE
                        </button>
                        <button class="btn bg-danger text-white valign-button" data-toggle="modal" data-target="#deleteEvidenceModal" v-on:click.prevent>
                            <i class="fal fa-trash-alt"></i> DELETE
                        </button>
                        <button v-if="element.isDisabled" v-on:click.prevent="element.removedRow=true" class="btn bg-secondary text-white valign-button" @click="cancelEdit()">
                            <i class="fas fa-minus"></i> CANCEL
                        </button>

The main issue I'm encountering relates to distinguishing between editing an existing element and adding a new one, and properly disabling/enabling all other components accordingly.

To illustrate this clearly, I have created a JSFiddle demonstration.

Upon clicking 'add evidence' in the example, you will notice that while the form remains 'disabled', the ability to click 'edit' persists in the other forms.

I am feeling a bit perplexed. Would it be better to utilize a child component for the buttons? This way, when editing or creating a new form, I could hide all buttons on other instances?

All suggestions are greatly appreciated!

Answer №1

To create a universal reference to the activeForm element:

 data: function () {
        console.log("data function");
        return {
            evidence: getEvidence(),
            subdomains: getSubdomains(),
            isDisabled: null,
            baseUrl: null,
            activeForm: null // this is what we're adding
        };
    },

When you're iterating through a loop, record the index of the current element being manipulated and pass it to your function:

@click="editForm(index)"

Assign this index value to your activeForm variable:

editForm (index) {
  this.activeForm = index
}

Adjust the comparator in your v-if statement to check if the current index matches the activeForm:

v-if="activeForm && activeForm === index

This way, a single variable dictates the editing status.

If you wish to disable all forms during addition, introduce a new variable named adding and toggle it with true/false similar to the other functions. Modify thev-if conditions on the edit and delete buttons accordingly:

v-if="(activeForm && activeForm === index) && !adding"

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

Populate Chart.js with a specific set of JSON data

As I delve into the world of JavaScript, I'm faced with a challenging issue that I need help resolving: I have a JSON file housing an array of data. What I aim to do is extract specific arrays from the month of August (Reports, Average, Global) and d ...

Vue js image not displaying due to path issue

This project utilizes Laravel and Vue.js. The image directory is located in "public/images/products". Image data in the database is stored as "image":"images/products/image_name.jpg". The route path is set to "127.0.0.1:8000/product". When accessin ...

Change the spread operator in JavaScript to TypeScript functions

I'm struggling to convert a piece of code from Javascript to Typescript. The main issue lies in converting the spread operator. function calculateCombinations(first, next, ...rest) { if (rest.length) { next = calculateCombinations(next, ...res ...

There was an error because the variable "items" has not been defined

Having some trouble with an AngularJS service where I am attempting to add an item to an array every 5 seconds. However, I keep encountering the error 'items is not defined' after the first dynamic addition... I've been tinkering with this ...

Comparing Arrays with jQuery

I am currently working on a tic-tac-toe project that involves a simple 3x3 grid. I have been storing the index of each selected box in an array for each player. However, I am facing difficulty in comparing my player arrays with the winner array to determin ...

Images in the JavaScript menu are not remaining fixed in place

Can someone help me with my website? I'm having trouble with the menu for different pages, it should stay gray for the active page. It was working fine before I switched to Wordpress, but now I'm not sure what the issue is. Could someone take a ...

Tips on creating reusable scoped styles for 3 specific pages in Vue.js without impacting other pages

Our project includes global classes for components that are utilized throughout the entire system. <style lang="scss" scoped> .specialPages { padding: 0 10px 30px 10px; } /deep/ .SelectorLabel { white-space: nowrap; al ...

I possess an array containing objects of different lengths depending on the chosen city. How can I pinpoint the element that contains an object with a specific property?

My dilemma arises from the fact that the length of an array depends on the selected city, making it impossible to select elements using an index. In this scenario, I need to devise a method to choose elements based on the value of one of their properties. ...

Restricting Entry to a NodeJS Express Route

Currently, I am in the process of developing an express project where I have set up routes to supply data to frontend controllers via ajax calls, specifically those that start with /get_data. One issue I am facing is how to secure these routes from unauth ...

Leveraging React hooks to combine an array and an object within an array

Struggling to incorporate an array and an object into another array. This is the setup in my constructor: const [dashboard, setDashboard] = useState({ loading: true, data: [], address: '' }) This is how I envision the final data structure: { ...

Generate a random number to select a song file in Javascript: (Math.floor(Math.random() * songs) + 1) + '.mp3'

My current JavaScript code selects a random song from the assets/music folder and plays it: audio.src = path + 'assets/music/'+(Math.floor(Math.random() * songs) + 1)+'.mp3' However, I've noticed that sometimes the same trac ...

Utilizing ng-route to parse the URL and identify the corresponding controller by its name

I am implementing ng-click and ng-view to navigate my div id= "listings" in order to display various mobile listings including iphone 4, iphone 5, nexus 4, nexus 5, nexus 6, lg g3, and more. You can check out my code on Plunkr. <div ng-repeat = ' ...

When utilizing a third-party library in conjunction with Vuetify, the V-menu may have a tendency to automatically close right after

Incorporating cytoscape into a vuetify SPA has been successful for the most part. The graph renders within a v-card-element, and I can navigate to a different page using the vue router when clicking a note in the graph. However, when attempting to replace ...

No charts are displaying in Vue with Apex Charts, despite following the tutorial closely

Currently, I am a newcomer to Vue development, and my goal is to display a page containing 4 charts. I envision them being shown in a 2x2 format, with 2 charts side by side and the other 2 stacked below each other. To kick things off, I decided to work on ...

What are the best practices for utilizing "async/await" and "promises" in Node.js to achieve synchronous execution?

I'm fairly new to the world of web development and still grappling with concepts like promises and async/await. Currently, I'm working on a project to create a job posting site, but I've hit a roadblock trying to get a specific piece of code ...

Is it possible for an angular directive to transmit arguments to functions within specified expressions in the directive's attributes?

I am working on a form directive that utilizes a specific callback attribute with an isolate scope: scope: { callback: '&' } This directive is placed within an ng-repeat, where the expression passed in includes the id of the object as an ar ...

Troubleshooting VueJS, Electron, and Webpack integration with Hot Reload feature

I have been immersed in a new project that involves utilizing Electron, VueJS, and Webpack for HMR functionality. Unfortunately, I am encountering difficulties with the Hot Module Replacement feature not working as expected. Here is my current configurati ...

Having trouble with v-for in Vue js on vsCode?

https://i.stack.imgur.com/u3vzh.png It seems that I always encounter this issue when utilizing v-for in my projects. While I didn't face any problems with it previously, I've noticed that it has become a frequent error as of late. Why is it tha ...

Issues with Adding Dynamic Rows to MySQL

Struggling with adding dynamic rows and posting to MySQL. The variables seem off, but the script works fine. Need help with MYSQL posting specifically. As a beginner, I seek your forgiveness... The Script is running smoothly! <script type='text/ ...

Using the highcharts-ng library in combination with ng-repeat was successful in creating multiple charts. However, in order to display different data for each chart, the

I need to provide the date either from the view template or possibly from the controller in order for the highchart to display the data specified by the <highchart /> directive. Explanation : <ul> <li ng-repeat="li in list"> ...