Manipulating selected values in VueJs v-select using methods

I am currently working on achieving the following goal:

When I select the option "Alle openstaande" (result_id = 0), I want to select all these result_ids: [-1,-2,-3,-5,-7,-8,-11,-12] and deselect result_id 0.

The variable mergedResults stores an array of the result_ids that need to be selected

I am struggling to find a way to add to the currently selected options using the methods available

My blade file includes:

              <dd-results
                        name="resultcodes-select"
                        v-model="selected.resultcodes"
                        :select-all="true"
                        :multiple="true"
                        :openstaande="true"
                        :include-ids="true"
                        :project-id="selected.project"
                        title="@lang('rapportage.resultcode')"
                        :include-negative="true"
                        return-key="result_id"
                        >
                    </dd-results>

My vue file:

<template>
    <span>
        <label v-if="title">{{title}}</label>
        <v-select
            :options="results"
            label="name"
            :placeholder="placeholderText"
            :close-on-select="closeOnSelectValue"
            :disabled="isDisabled"
            :multiple="multiple"
            :value="value"
            @input="handleInput($event)"
            :loading="isLoading"
            :reduce="reduceKey"
        >
        <div slot="no-options">{{noOptionsText}}</div>
        </v-select>
    </span>

</template>

<script>
import vSelect from "vue-select";
import Language from "../../classes/Language";

export default {
    name: 'dd-results',
    components: {
        'v-select': vSelect
    },
    props: {
        placeholder: {
            type: String,
            default: null
        },
        closeOnSelect: {
            type: Boolean,
            default: true
        },
        isDisabled: {
            type: Boolean,
            default: false,
        },
        // Select multiple values
        multiple: {
            type: Boolean,
            default: false
        },
        openstaande: {
            type: Boolean,
            default: false
        },
        value: {
            default: null
        },
        // Show/hide 'All projects' placeholder
        selectAll: {
            type: Boolean,
            default: false
        },
        projectId: {
            default: null,
            required: true
        },
        title: {
            type: String,
            default: null
        },
        includeIds: {
            type: Boolean,
            default: false
        },
        // Show/not show negative result codes
        includeNegative: {
            type: Boolean,
            default: false
        },
        // If filled: only return this value, otherwise full object
        returnKey: {
            type: String,
            default: null,
        },
        excludeTypes: {
            type: Array,
        }
    },
    data() {
        return {
            language: new Language,
            results: [],
            isLoading: false,
        }
    },
    created() {
        var self = this;
        this.language.set(lan);
    },
    methods: {
        reduceKey(option) {
            return this.returnKey != null ? option[this.returnKey] : option;
        },

        handleInput($event) {
            this.$emit('input', $event);
       
            if($event.includes(0)) {
                this.addOpenstaande($event);
            }
        },

        addOpenstaande(value) {
            var openstaandeResult = [-1,-2,-3,-5,-7,-8,-11,-12];

            var mergedResults = [... new Set (value.concat(openstaandeResult))];

            const removeIndex = mergedResults.indexOf(0);
            if (removeIndex > -1) {
                mergedResults.splice(removeIndex, 1); 
             }

             this.reset(mergedResults);

            console.log(mergedResults);

        },

        reset(selected=false) {
            // 1. Remove selected itemboxes
            console.log(this.$el,$(this.$el).find('.vs__selected'));
            $(this.$el).find('.vs__selected').remove();
            setTimeout(() => {
                // 2. Reset the placeholder
                $(this.$el).find('.vs__selected-options input').attr('placeholder', this.placeholderText);
            }, 100);

            if(selected !== false) {

            }

        }
    },
    computed: {
        // Text in dropdown when no options available
        noOptionsText() {
            return this.language.trans('app', 'no_results');
        },
        // Determine placeholder text. Depends on selectAll option. Custom placeholder always overrides.
        placeholderText() {
            if(this.placeholder != null) {
                return this.placeholder;
            }
            else if(this.selectAll) {
                return this.language.trans('rapportage', 'resultcode_alle');
            } else {
                return this.language.trans('rapportage', 'resultcode_selecteren');
            }
        },
        // Default to not closing after selection when multiple projects can be selected
        closeOnSelectValue() {
            if(this.multiple) {
                return false;
            } else {
                return this.closeOnSelect;
            }
        }
    },
    watch: {
        'projectId'(newVal) {

            if(this.value != null) {
              if(this.value.length != null) {
                this.value.length = 0;
              }
            }
            
            var self = this;
            if(newVal != null) {
                self.isLoading = true;
                // Get results and fill dropdown
                axios.get('/projects/'+newVal+'/results').then(result => {
                    self.results = Object.values(result.data);
                    console.log(self.results);

                    for (var i = 0; i < self.results.length; i++) {
                        // If negatives need to be filtered and index is negative: remove
                        if(self.results[i].result_id < 0 && !this.includeNegative) {
                            self.results.splice(i, 1);
                            i--; // Reset index due to removed item
                            continue;
                        } 
                        // If type is in excludeTypes: remove
                        if (this.excludeTypes) {
                            if (this.excludeTypes.indexOf(self.results[i].type) > -1) {
                                self.results.splice(i, 1);
                                i--;
                                continue;
                            }
                        }
                    }
                    for (var i = 0; i < self.results.length; i++) {
                        if (self.includeIds) {
                            // Change "name" to "(result_id) name"
                            self.results[i].name = "(" + self.results[i].result_id + ") " + self.results[i].name;
                        }
                    }

                    
                    if(this.multiple === true && this.openstaande) {
                        self.results.unshift({
                            result_id: 0,
                            name: this.language.trans('app', 'alle_openstaande')
                        })
                    }
                }).catch(error => {
                    console.log(error);
                }).then(data => {
                    self.isLoading = false;
                })
            } else {
                this.results = [];
            }
        }
    }
}
</script>


<style>
    select:required:invalid {
        color: gray;
    }

    .vs--disabled .vs__dropdown-toggle, .vs--disabled .vs__clear, .vs--disabled .vs__search, .vs--disabled .vs__selected, .vs--disabled .vs__open-indicator {
        background-color: #D3D3D3;
        color: #808080;
    }
    
    option {
        color: black;
    }

    .vs__dropdown-toggle {
        background: #fff;
    }

</style>

Answer №1

After some trial and error, I managed to get everything working by utilizing the $emit function within the handleInput($event) method. (Looking back, it seems so apparent now, but at the time I was clueless about what this.$emit('input', $event); actually did)

I made adjustments to these three methods:

handleInput($event) {
    this.$emit('input', $event);

    if($event.includes(0)) {
        this.addOpenstaande($event);
    }
},

addOpenstaande(value) {
    var openstaandeResult = [-1,-2,-3,-5,-7,-8,-11,-12];

    var mergedResults = [... new Set (value.concat(openstaandeResult))];

    const removeIndex = mergedResults.indexOf(0);
    if (removeIndex > -1) {
        mergedResults.splice(removeIndex, 1); 
     }

     this.$emit('input', mergedResults);
},

reset(selected=false) {
    // 1. Remove the selected itemboxes
    $(this.$el).find('.vs__selected').remove();
    setTimeout(() => {
        // 2. Restore the placeholder text
        $(this.$el).find('.vs__selected-options input').attr('placeholder', this.placeholderText);
    }, 100);
}

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

How can I verify if a user is logged in using express.Router middleware?

Is there a way to incorporate the isLoggedIn function as a condition in a get request using router.route? const controller = require('./controller'); const Router = require('express').Router; const router = new Router(); function isLo ...

Display navigation bar upon touch or lift

In the mobile version of a website, there is a fixed navigation bar at the top. The positioning of this navbar is achieved using position:absolute: .navbar-fixed-top{position:absolute;right:0;left:0;z-index:1000; The goal is to make the navbar invisible ...

Incorporating a JavaScript code into my SharePoint master page to automatically deselect a checkbox resulted in updating the page title

I've integrated the following JavaScript code into my SharePoint master page: <script type="text/javascript> function DefaultUploadOverwriteOff() { if (document.title== "Upload a document") { var input=document.querySelectorAll("input"); ...

Needing to utilize the provide() function individually for every service in RC4

In Beta, my bootstrapping code was running smoothly as shown below: bootstrap(App, [ provide(Http, { useFactory: (backend: XHRBackend, defaultOptions: RequestOptions, helperService: HelperService, authProvider: AuthProvider) => new CustomHt ...

Tips for increasing the size of a textarea

I'm attempting to extend a textarea by adjusting the margin-top property, but it doesn't seem to be working as intended. Here is the code snippet in question: #sqlcontainerLoggedInPage2 { margin-top: 60px; } <div class="container-fluid" i ...

Trouble accessing state when React child calls parent method

Within my project, I am working with 3 components that are nested as follows: App->GameList->GameItem The App (parent) component has a method that is triggered by the onClick event within the GameItem (child) component Upon clicking the GameItem co ...

Storing dataset characteristics in a JSON file utilizing Vue.js form response

I am currently working on creating a JSON file to store all the answers obtained from a Form. Some of the input fields have an additional dataset attribute (data-tag). When saving the Form, I aim to extract these 'tags' and include them in the JS ...

Set up a JavaScript function that triggers an alert if two numbers are determined to be equal

I created a code snippet that should display an alert message when a button is clicked, indicating whether two random numbers generated are equal or not. The random numbers must be integers between 1 and 6. I implemented this functionality in JavaScript bu ...

How can one determine if a DOM element has been generated dynamically?

Some of the content on this page is dynamically created after an ajax request, while other content was pre-loaded when the page refreshed. When I click on an anchor tag, I need to know if it was created dynamically or not. I did manage to solve this issu ...

Is it possible to use a hash map to monitor progress while looping through this array in JavaScript?

I've been exploring some algorithmic problems and I'm puzzled about the most efficient way to solve this particular question. While nested for loops are an option, they don't seem like the optimal choice. I'm considering using a hash ma ...

What steps can I take in JavaScript to assign a value of 0 to values[1] in order to prevent receiving NaN as the output

I'm currently working on a program that calculates the sum of 6 input values, but I've encountered an issue where if a value is missing (for example, only providing 5 values), the result becomes NaN. I attempted to address this by assigning empty ...

Every time I attempt to launch my Discord bot, I encounter an error message stating "ReferenceError: client is not defined." This issue is preventing my bot from starting up successfully

My setup includes the following code: const fs = require('fs'); client.commands = a new Discord Collection(); const commandFiles = fs.readdirSync('./commands/').filter(file => file.endsWith('.js')); for(const file of com ...

Ways to retrieve output from a JavaScript function

How can I successfully return the result from response.on within the signIn function? const signIn = async (password) => { var request = new DeviceAuthQuery(); request.setPassword(password); var response = client.authenticate(request, {}, (err, ...

We were unable to find an existing Kibana index, therefore we are unable to establish a connection

When setting up vue-storefront-api and vue-storefront on my Windows machine, I encountered an error in windows Power Shell or Command Prompt while running docker-compose up. The error message stated that no existing Kibana index was found, along with the i ...

Is there a way to create animated CSS box-shadow depth using jQuery or CSS3 transitions?

This code snippet applies delays but doesn't seem to update the style changes until the loop completes: for (i=20;i>=0;i--) { var boxShadow = i+"px "+i+"px "+i+"px #888"; $('article').css("box-shadow", boxShadow); ...

XPages component retrieval function is malfunctioning

Utilizing an XPage with JQuery dialog and client-side validation adds efficiency to the user input process. However, there seems to be a disconnect between the client-side validation and server-side properties. Although the client-side validation functions ...

Can someone help me figure out how to make my Dropdown stay open when I highlight input, drag, and release

While working with the react bootstrap Dropdown component, I've encountered a specific behavior that is causing some trouble. To better illustrate the issue, I've attached some images. In my dropdown, there is an input filter box along with a li ...

Issue with setting HTML content using jQuery's .html() method

I have a simple functionality. When a user clicks on the edit link, it transforms the previous element into an input element for editing, and changes the edit link into a cancel link. If the user decides not to edit, they can click on cancel and everything ...

Having trouble getting images to display in Vue markdown?

I am currently utilizing the vue-markdown package for rendering markdown content. The package works fine except for images, which do not display as expected. Interestingly, when using an img element with the correct file path, the image shows up without an ...

How to retrieve the current event handler's value with jQuery

To assign an onclick event handler using jQuery, I simply use the following code: $('#id').click(function(){ console.log('click!'); }); Now, my question is how can I retrieve a reference to the function that is currently handling th ...