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

What is the reason behind Chrome Dev Tools not automatically adding the parentheses when a method is selected?

In the console of Dev Tools, if you have an object named x with three methods/functions - a(), b(), and c(i, j, k), why doesn't it automatically insert the parentheses, along with the correct spaces for the parameters (similar to eclipse for Java) whe ...

What is the best way to test a try/catch block within a useEffect hook?

Hey, I'm currently dealing with the following code snippet: useEffect(() => { try { if (prop1 && prop2) { callThisFunction() } else { callThatFunction() } ...

Unlocking the power of python with web2py by tapping into html form values

I'm working on a project using web2py and need to incorporate ajax/javascript with a form. Currently, when a user selects an option in the departure box, the arrival box appears. However, I'm unsure of how to filter the list of arrival options ba ...

When I make a post request, I receive a response in the form of an HTTPS link, but it is not redirected to

I'm making a post request and receiving the response as follows: " [Symbol(Response internals)]: {url: 'https://login.somenewloginpage'}" My intention is to open a new page using that URL, but unfortunately it does not redirect t ...

The Antd table documentation mentions that rowKey is expected to be unique, even though it appears they are already

Having trouble with a React code issue. I have a list of products, each with an array of 7 items that contain 40 different data points. This data is used as the source for a table. {label : someStringLabel, key: someUniqueKey, attribute1: someInt,..., at ...

Tips on modifying the interface based on the selected entry using jQuery

I am attempting to display a text when different options are selected from the dropdown list. Here is the code for the drop-down list: <div class="dropdown"> <select class="form-control" id="ltype" name="ltype"> <option value=""&g ...

Vue.js error: Reaching maximum call stack size due to failed data passing from parent to child component

I'm having trouble passing data from a parent component to a child component. I tried using props and returning data, but with no success. The parent component is a panel component that contains the data, while the child component is a panelBody. Thi ...

Error: The variable "Set" cannot be found in the react.js code, specifically in Safari browser

An issue has been identified in Safari where a ReferenceError is thrown: "Can't find variable: Set" when using react.js. This error occurs only in Safari, while all other browsers work perfectly fine. The error message points to the main.js file which ...

Utilizing JSON strings within an onclick function

Hey there, currently I am working on sending an encoded JSON through the onclick attribute. However, I am facing a challenge because the JSON contains strings with a lot of apostrophes and quotes which end up closing the quotes in the onclick attribute. Up ...

What is the best way to integrate JavaScript and Python for seamless collaboration?

I'm looking to create a bidirectional communication model between JavaScript and Python. The idea is for JavaScript to handle data processing, send it to Python for further processing, and then receive the results back from Python. However, I'm u ...

The tablesort feature is experiencing difficulty sorting tables with dynamically changing content

I have a question about sorting columns in a PHP file that calls a JS file. The PHP file contains two tables with the table sorter plugin implemented, but one of them works and the other doesn't. The working table is populated through an Ajax call, wh ...

How can Vue be utilized to display static data in a modal window?

I have a pair of 'cards' containing the following content: <div class='card'> <span>title one </span> <button @click='open = !open'>show</button> </div> <div class=& ...

Implementing a rate limit on the login API that is specific to individual IP addresses rather than being

I have successfully implemented the [email protected] module, but I am facing an issue where it is blocking the API globally instead of for a specific API that is receiving hits. This is my current code: const limiter = new RateLimit({ windo ...

Encountering an issue with eslint-loader in a new VueJS project: TypeError - eslint.CLIEngine is not recognized as

Embarking on a fresh VueJS venture with WebStorm. A brand new VueJS project has been established, NPM upgraded, Vuetify added, and upon server initiation, an error pops up: ERROR Failed to compile with 1 errors ...

Obtain asynchronous view model for component

Is it possible to retrieve a view model from the server and incorporate it into my component? I attempted to do so with the following code snippet, but it is not working as expected: function fetchViewModelFromServerAsync(){ setTimeout(function(){ ...

What is the impact of util.inherits on the prototype chain in JavaScript?

Exploring this particular design: Function ConstrA () { EventEmitter.call(this); } util.inherits(ConstrA, EventEmitter); var obj = new ConstrA(); If util.inherits is omitted, ConstrA and obj will each establish their own distinct prototype chain. T ...

A guide on using jQuery to iterate through 3 separate div elements

Seeking assistance with creating a dynamic loop for multiple divs (3 or more) using jQuery. The desired outcome is to have the main image div on the homepage rotate with other divs, changing both the background image and links within each div. I initially ...

Failed to build development environment: Unable to assign the attribute 'fileSystem' to a null value

I'm attempting to launch an Ionic 2 Application, but I keep encountering this error when running ionic serve Error - build dev failed: Unable to assign a value to the 'fileSystem' property of object null Here is the complete log: λ ion ...

Tips for adding animation to a React state value change triggered by an input

In my React application, I have a form with multiple fields that each contain a text input and a range input. Currently, both inputs share the same state value and onChange function to keep them synchronized. However, I would like to add an animation effe ...

What is the process for deploying a Vue app in a production environment?

Looking for guidance on deploying a Vue app in production? I've built the frontend of my project with Vue, and the backend uses Express.js APIs. Now, I'm ready to deploy it for production, but unsure of the process. After running "npm run build ...