Utilizing VueJS to target and select checked checkboxes across various divs

As someone who is still getting the hang of VueJS, I've come across a challenge that would have been a breeze to tackle with jQuery. However, when it comes to VueJS, I'm struggling to find a solution even though I know it's possible.

Here's the scenario: I have a list of paths selected by the user, and for each path, I need to create a div with three checkboxes - add, edit, and delete.

Let's say the user selects two paths: '/foo' and '/bar'. For these paths, I need to generate the following object based on the checkboxes checked:

[
{path: '/foo', actions: ["add","edit"]}, 
{path: '/bar' , actions: ["delete"]}
]

The function responsible for creating this object is triggered when the user hits a final submit button. Below is a snippet of the relevant code:

In the component template:

<li v-for = "selectedPath in newProfile.paths">
                <Card :card-name="selectedPath">
                    <h5>{{selectedPath}}</h5>
                    <base-checkbox :data-path="selectedPath" type = "default" name = "add">Add</base-checkbox>
                    <base-checkbox :data-path="selectedPath" name = "edit">Edit</base-checkbox>
                    <base-checkbox :data-path="selectedPath" name = "delete">Delete</base-checkbox>
                </Card>
            </li>

The JavaScript code includes vanilla JS to handle checkbox selection. The issue arises from using predefined checkboxes within a template, making it cumbersome to access the checked attribute directly. This approach feels clunky and not in alignment with VueJS best practices.

So, how can I successfully construct the desired object based on the checkboxes checked within each div?

Answer №1

To effectively manage your base-checkbox components in Vue, it is crucial to listen for events and update corresponding data structures accordingly. Remember that in Vue, JavaScript data serves as the primary source of truth over the DOM.

Approaching this task can vary depending on the most suitable data structures for a specific scenario. As stated in The Mythical Man-Month:

Representation is the essence of programming.

Considering this, the example below may not be utilizing the best data structures or handling them optimally:

Key points to note:

  • The computed property out contains the final formatted data used upon clicking the submit button. Although no submit button is included here, the data is presented for review purposes.
  • Maintaining separate paths and selectedPaths entities is not mandatory but aligns closely with your original code, with paths similar to newProfile.paths.
  • The format within selectedPaths follows
    {path1: {add: true, edit: false, delete: true}, path2: ...}
    . Properties are lazily created, defaulting to all checkboxes being false.
  • Since selectedPaths is initially empty, its properties lack reactivity, hence the use of $set. If prepopulating this object within the data method was feasible, omitting $set would suffice.
  • Checkbox elements are employed here, but a similar approach applies when using a checkbox component. A prop conveys the current value, while an event updates the data upon value alteration.
  • For scenarios involving v-for, segregating a distinct child component for children often simplifies operations by distributing workloads onto individual children components instead of manipulating complex parent data structures. Though not implemented here to keep everything within one component, exploring this approach in real-world scenarios is beneficial.
<template>
    <div>
        <ul>
            <li v-for="path in pathsWithSelections" :key="path.path">
                {{ path.path }}
                <input type="checkbox" :checked="path.add" @input="onChecked(path.path, 'add')">
                <input type="checkbox" :checked="path.edit" @input="onChecked(path.path, 'edit')">
                <input type="checkbox" :checked="path.delete" @input="onChecked(path.path, 'delete')">
            </li>
        </ul>
        {{ out }}
    </div>
</template>

<script>
    export default {
        data () {
            return {
                paths: ['path1', 'path2', 'path3'],
                selectedPaths: {}
            }
        },

        computed: {
            pathsWithSelections () {
                return this.paths.map(path => {
                    const selected = this.selectedPaths[path] || {}

                    return {
                        path,
                        ...selected
                    }
                })
            },

            out () {
                const out = []

                for (const path of this.pathsWithSelections) {
                    const actions = []

                    for (const action of ['add', 'edit', 'delete']) {
                        if (path[action]) {
                            actions.push(action)
                        }
                    }

                    if (actions.length) {
                        out.push({
                            path: path.path,
                            actions
                        })
                    }
                }

                return out
            }
        },

        methods: {
            onChecked (path, action) {
                const selectedPaths = this.selectedPaths

                const selected = selectedPaths[path] || {}

                this.$set(selectedPaths, path, selected)
                this.$set(selected, action, !selected[action])
            }
        }
    }
</script>

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

Preventing users from returning to the login screen by pressing the back button in their browser when using Vue-router

This snippet of code helps to prevent users from navigating back to the login screen by altering the URL. However, it does not prevent them from going back to the login screen by simply using the browser's back button even after logging in. Once a us ...

Apollo-Server presents errors in a polished manner

It seems like the question explains itself adequately. I am currently using 'apollo-server-core' version 3.6.5 Desired Errors: { "errors": [ { "message": "Syntax Error: Unexpected < ...

Is it possible for me to define TypeScript interfaces to be used in vanilla JavaScript projects within VSCode?

While using the MS VisualCode editor, I am attempting to implement type checking in my Javascript code. I want to maintain the flexibility of Javascript while also benefiting from type checking interfaces and data structures. Based on the vscode documenta ...

Using Angular directive with ng-class to display or hide element

I am trying to implement a feature in my directive template where an element is shown or hidden on mouseenter. Below is the code for my directive: angular.module('myApp') .directive("addToRoutes",['$http', '$timeout', functio ...

Http Angular service lacks a provider

@Injectable() export class MyService { constructor(private http: Http, @Inject('name') @Optional() public name?: string) { } When setting up my appModule, I attempted to define a provider for MyService service. MyService, import ...

Ensuring the Line Breaks in CSS and JavaScript to Easily Modify the Style

Is there a way to determine when a line will break so I can apply different styles? The design team needs 3 buttons in a grid (3 columns) with specific sizes. They want buttons with content that breaks onto the next line to have a border-radius of 13px, w ...

Increase the size of a centered image within a table

Lately, I've felt like my mind is starting to unravel. Here's the issue at hand: I've been attempting to resize an image within a table cell so that it spans the full width of the cell. Strangely enough, this seems to be harder than anticip ...

What methods can be used to verify if an Ajax request was actually sent by the server?

Currently, I am working with Laravel and have a form that I need to send to the server via Ajax (using Jquery). How can I verify that an Ajax request is actually coming from the server? There are numerous methods for CSRF attacks, and sending data via Ajax ...

Vue.js: Issue with applying class binding while iterating over an object

I've been working with an object data that looks like this: object = { "2020092020-08-01":{ "value":"123", "id_number":"202009" }, "2020092020-09-01":{ "value& ...

Encountering issues retrieving data using Vuex in combination with axios

I have undertaken the task of creating 2 projects - one for the backend and one for the frontend using a combination of Laravel and VueJS. In Laravel, I have set up an API endpoint to cater to all users: Laravel routes/api.php Route::prefix('users&ap ...

Is there a way to access the real-time data outside of the window resize event?

Is there a way to retrieve the current height value after window.resize event? $(window).resize(function(){ var currentHeight = $('#window-fixed').height(); }); console.log( currentHeight ); //Uncaught ReferenceError: currHeight is ...

The HTML document is wider than the screen

Encountering a strange issue where the <body> tag is wider than my monitor, even though it shouldn't be. I have implemented some JavaScript to create a parallax effect by adjusting the background based on scroll offset. However, when the backgro ...

Neither the context nor props contain the element 'store' that you are searching for

Just stepping into the world of React can be overwhelming, but I'm determined to get my page to render properly: import React, { Component } from "react"; import { connect } from "react-redux"; import Header from '../components/Header'; imp ...

Having trouble retrieving information from the database using socket.io and node.js

As a beginner in node.js and socket.io, I am experimenting with my simple project to fetch data from a database. My index.html serves as a real-time chat example using socket.io with a basic ajax request. <!doctype html> <html> <head> ...

The angular 2 router is failing to navigate properly when using the history forward/backward button

The history push state feature is not working properly with the Angular 2 router in both Chrome and Firefox. The forward button never works, and the backward button only works for 2 steps before the UI stops responding to it. Here is the code I am using: ...

What is the best way to ensure that the larger child divs always fit perfectly within the parent div?

Creating a Responsive Layout <div class="container"> <div class="box1"></div> <div class="box2"></div> <div class="box3"></div> </div> CSS Styling .box1, .box2, .box3{ display: block; f ...

When the icon is clicked, the text goes over the ul and the mobile slide menu goes beneath it

click here for the image Is there a way to make the text move below when I click on the hamburger menu icon? ...

How do I recognize the combination of Click and modifier keys (Shift, Ctrl, Alt) in a reactjs click event?

When a user clicks with the [Ctrl] key pressed, I want to perform additional actions, but it seems that detecting if the Ctrl key is being pressed during the click event is proving challenging. Here are some details from the copied event object: bubbles ...

When an onClick event is triggered in jQuery, generate a certain number of div blocks based on the available list items, such as image source and heading text

Is it possible to generate input fields dynamically based on a dynamic list with checkboxes, labels, text, images, etc.? I currently have a working solution for checkboxes and labels using the code snippet below: let $checkboxContent = $('.checkboxes ...

Sending multiple arguments using a JavaScript .NET postback

I've successfully integrated a JavaScript function that enables me to perform a .NET (4.0) postback Javascript __doPostBack('__Page', argument) C# public void RaisePostBackEvent(string eventArgument) { //some action tak ...