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

Struggling to make antd compatible with my create-react-app project

Exploring ant.design with create-react-app piqued my interest, so I decided to follow the steps outlined in the antd documentation. https://ant.design/docs/react/use-with-create-react-app npx create-react-app antd-demo npm add antd Within the app.js fil ...

"Transmitting a message with socket.io upon establishing connection

Currently getting the hang of socket.io and giving it a try. I have a straightforward app where clicking the display button shows an image on the screen in real time. I have a couple of questions. Firstly, my main concern is regarding the synchronization ...

Invoke a function that generates an array within a v-for loop and iterate through the elements in a Vue.js component

Seeking guidance on the optimal approach for this task. I need to invoke a method within a v-for loop that lazily loads data from a related model. Can anyone advise on the best practice for achieving this? <div v-for="speaker in allSpeaker" :k ...

The error message "ReferenceError: obj is not defined using webcomponents & polymer" indicates that the object

I am diving into the world of web components for the first time with this project, and my knowledge of js/jquery is quite limited. I'm encountering an issue and I'm unsure why it's happening. I've created a custom element in "search-fo ...

"Silently update the value of an Rxjs Observable without triggering notifications to subscribers

I'm currently working on updating an observable without alerting the subscribers to the next value change. In my project, I am utilizing Angular Reactive Forms and subscribing to the form control's value changes Observable in the following manner ...

The content of the string is not appearing

I've hit a snag while trying to create components and templates. I'm closely following the instructions provided in this link: My code is very similar to the one shown in the instructional video (except for the error, of course). The issue I&ap ...

Oh no! There seems to be an unexpected token "<" in my React Native project on Visual Studio Code

When utilizing react-native in VS Code, I encounter an issue where my code fails to compile and throws a syntax error for the "<" symbol. Strangely, many tags work fine with "react-native run-android" from the Terminal. This is the code snippet that I ...

React.Children does not reveal the presence of any offspring

I am looking to implement react-native-maps-clustering in my project. However, this library only accepts markers that are direct children of the maps component. An example of how it should be structured: <MapView> <Marker/> <Marker/> ...

Determine whether an element is currently focused using a Vue.js directive

I'm attempting to verify if an element is currently in focus, specifically an input field, and then apply a class to another element. This is the code I have been working on, but for some reason the hasFocus() function isn't functioning as expect ...

How come my useEffect still contains outdated data?

I have encountered an issue with my useEffect in a React component. Despite having all the necessary dependencies, the state does not update after the useEffect completes. It always displays the previous render. Below is the code snippet of the hook: exp ...

What are some ways to optimize the use of the jquery.mCustomScrollbar.js script?

I have a myriad of inquiries and would greatly appreciate your assistance in addressing them. Despite spending countless hours attempting to solve the issue independently, I have been unsuccessful. One question that plagues me is why, when using Google Ch ...

Utilizing the Google Geocode API to handle a promise with a substantial array

My Objective To efficiently process a large array using the .map method and interact with the Google Geocoder API through promises to get location data. The goal is to utilize Promise.all to store results in a .json file upon completion of the operation. ...

Extracting Raw Body from Stripe Webhook in NextJS

I'm feeling frustrated trying to get a raw body passed for the Stripe webhook in NextJS! Despite trying numerous solutions from various sources, I just can't seem to get it to work. Calling upon the developers with special powers (of which I am ...

Creating seamless scrolling in ReactJS without any pre-built components

Can anyone guide me on how to implement an infinite scroll in reactJs using a JSON dataset? I prefer building it from scratch without relying on any library. {data?.map((conto) => { return ( <Suspense key={conto._uid} fallback={<p>Loadin ...

Uninstall all packages that are no longer listed in the package.json file using Npm

Seeking guidance on how to uninstall packages from the node_modules directory that are no longer listed in package.json. These packages were removed by another developer and the package.json file has been updated on git. Any tips on how to accomplish this ...

Format the date using moment() for the last week of the current year and return it with the year. Next year's

I encountered an unusual problem when using Moment.js with Angular.js. When I use the .toISOString() method, I get the correct date, but when I use the .format() method, the date is completely wrong. Here is an example to illustrate the issue: Code snip ...

Step-by-step guide on adding data to an arraylist using JavaScript

My ajax callback function receives a json object (arraylist parsed into json in another servlet) as a response, and then iterates through it. Ajax section: $.ajax({ url:'ServiceToFetchDocType', data: {" ...

Vue 3 presently does not support dynamically requiring "highcharts"

I've been working on integrating highcharts-vue into my project with the following code: import { createApp } from 'vue' import { createPinia } from 'pinia' import App from './App.vue' import router from './router&a ...

Guide to Sending Form Data from Vue.js to Spring Boot

I am looking to submit form data from Vue to Spring Boot. Are there any recommendations on how to do this effectively? Below is the structure of my project: .mvn .vscode frontend - Vue Project src - Spring Boot src target .gitignore ... In Registe ...

Comprehending the significance of *this* within class structures

I've got this code snippet below. class Node { constructor(value, parent, possibleChildren = []) { this.value = value; this.parent = parent; this.children = [] this.setChildren(possibleChildren); } setChildren(possibleChil ...