Vue-multiselect: Please add a way to support validation

Created on 11 Sep 2016  路  24Comments  路  Source: shentao/vue-multiselect

please include a way to make the fields mandatory, or even better a way to integrate into parsley js or jquery.validator. Thanks!

invalid question wontfix

Most helpful comment

@shentao It is probably a good idea to make the component work like any other input component would.

Sometimes, error libraries are used for more than just showing a message below the field itself. A simple example of that would be to disable the submit button while the form is not valid. If we have to write a validation function for every input, it would be chaos to mantain. This is why we use libs like Vee-Validate to manage the validations based on the form inputs.

In the end, Vue-Multiselect should be an input field, which can pass on validations to whatever library is handling them.

All 24 comments

if anyone is curious for possible quick solution i came up with this to place inside of the update method when a selection is changed. I did this and then i added a new prop to the Multiselect.vue file to add required to the input inside multiselect.

$('.multiselect__input.parsley-error').each(function () {
                    var input = $(this);
                    if(input.closest('.multiselect').find('.multiselect__content li.multiselect__option--selected span').val() != '') {
                        input.removeClass('parsley-error');
                        input.parent().find('.parsley-errors-list').children().remove();
                    }
                });

Hi @z1haze! :)
Validation is actually quite out of the scope of the multiselect itself. I believe that in the end, the validation should be more focused on the data itself, rather than components used to manipulate the data.
Right now Multiselect doesn鈥檛 support two-way binding anyway, as you always have to update your selected value it is super easy to create some kinds of validation around it.

Looking at your code example, I鈥檓 afraid that this would require from you a change of thinking to a more reactive direction.
As you鈥檙e using Vue, I would recommend not using jQuery for doing validation as then everything will become actually easier. Trust me on that. :)
In the docs, there is a small example of doing validation. Watch what happens if you click on the dropdown and then close it without selecting anything. You will see an error! :)

Multiselect gives you all the tools you need to construct an effective way of doing validation. You can create a computed value like:

isValidSelection () {
  return this.selected !== "" && this.selected !== "forbidden value"
}

And then simply create a error span below vue-multiselect like this:

<multiselect :selected="selected" :options="options" @update="updateSelected"></mutliselect>
<span class="parsley-error" v-show="!isValidSelection">This select is required!</span>

And that鈥檚 it!

@shentao It is probably a good idea to make the component work like any other input component would.

Sometimes, error libraries are used for more than just showing a message below the field itself. A simple example of that would be to disable the submit button while the form is not valid. If we have to write a validation function for every input, it would be chaos to mantain. This is why we use libs like Vee-Validate to manage the validations based on the form inputs.

In the end, Vue-Multiselect should be an input field, which can pass on validations to whatever library is handling them.

Hi @shentao, i believe this issue isn't as invalid as its presented. I really like how multiselect works up to some minor things. One of these is the missing html5 form validation.
Recently i've built a form where i wanted to make use of this basic validation feature and sadly recognised that its not possible without some nasty workarounds.
Without the html5 required attribute there are no error events and no warnings, whatsoever...
If its appreciated, i'd like to contribute this feature, since it comes handy.

This issue isn't invalid. You provid e a multi select for a form, yet there is no way to validate the select when submitting a form which is something 99.9% of all forms need to do. As stated above the thing isn't even a real html5 input so it can't be validated. It's not out of scope for the package it is something that should have been part of it from the very first release.

@z1haze I think you could use less blaming in your comment... Remember we are all here because we love what we do, not because we are paid for it. Everybody can do whatever libraries they want to, the way they want to. If we notice something amiss, we can simply poit that out nicely and wait for an answer. If the author does not solve the issue for whatever reason, the only options are to use a different lib or to make a fork of the project and implement that yourself.

Saying that the Author is wrong and diminishing the value of its work is not the best way to ask for a feature. Be careful about the words you choose, they can make it more dificult to make people understand what you are trying to communicate by sounding rude.

@Rickycezar I think its rude if someone takes the time to point out a legit flaw in your package, to help you make it better, and then dismisses your claim by marking it invalid.

Of course its free, of course no one HAS to use it, but it was built for people to use, and if you are going to publish it to the world, you should be willing to fix the issues that are pointed out, and not just dismissing them.

@z1haze I agree... It may feel very rude. I also believe that the actions of others shouldn't have impact on our politeness. You have a very valid point, I just wanted to remind you that using the right words can make the difference. =)

Cheers!

I too was hoping to use vee-validate with the otherwise great multiselect.

I would suggest to use Vuelidate, at it works just as well with multiselect or any other library of your choosing. There is no reason validation should be a part of UI component directly. It's a separate problem and should be treated as such.

If any other validation library doesn't allow to work with this component (which behaves pretty ordinarily if you ask me), I would consider that a design problem of that library. Any "glue code" between those two should stay in your application and it should be minimal. Otherwise there are way too many possible combinations that we would have to consider supporting directly, and it's usually not worth that tremendous effort.

As already mentioned 鈥撀燰ue-Multiselect is 100% compatible with Vuelidate (馃槀), which I believe is a more flexible way to handle validations in more complex applications. More on this here: https://www.monterail.com/blog/2016/rethinking-validations-for-vue-js

However, as already pointed out I think I could add a basic support for the required HTML5 validation by adding an invisible input. Any other validators will not be built in given the complex nature of this component and the fact it鈥檚 not an HTML input after all.

When it comes to Vee-validate I believe it should be fairly simple to create an adapter (a higher-order component / or a mixin used for extending Vue-Multiselect) so that it can implement the requirements for it to be validated by Vee-validate or another template-based validation library.

I鈥檓 happy to link to such an adapter in the documentation/readme if someone decides to build it.

Vee-validate seems to me the most popular validation lib for Vue (do you agree ?) and requires less typing/less code.
Vuelidate is interesting though and you have good point with separation of concerns. I might switch to it.

Would it be simple to style multiselect with a red border when left empty ?

@bformet Such an example (with a red border) is already in the docs: https://monterail.github.io/vue-multiselect/#sub-custom-configuration

All it requires is a CSS rule. In the above case that is:

.invalid .multiselect__tags {
  border-color: red;
}

The styles are not scoped so it should be fairly easy to override everything.

I do agree that Vee-validate is the most popular solution, but like it was written before above, the _glue code_ should probably be done in your app code or inside an adapter, to not hinder the usage with other validator libraries like the vue-validator.
When it comes to writing less code when using vee-validate, it might be true if you stick to simple forms with inputs only. However, in cases where you鈥檙e working with more complex interfaces like editable data tables, drag&drop lists, date/time pickers, custom input components or any combination of those this is no longer true. In such cases, you have to mix the validation results from a template-based validation library with your custom validation results (from computed properties for example). It can be a pain 鈥撀營鈥檝e been there before.

Vuelidate skips all that and goes straight to where the source for validation is located, namely the data model. The inputs are just a way to change the data.
And with Vuelidate you can run your validations on complex data structures, even the data stored in Vuex store (getters included) or props. Or an Rx stream. You can actually switch your form to a completely different structure and the validation might not change at all.
It is completely UI agnostic and thus much more powerful, yet simpler to argue and test. At least in my opinion.

There are also several other bonuses like the fact that all the validators are not-included which means you only use those that you actually need and providing your own validators is as simple as passing a function that has to return true or false. And this function has access to your data model as well, so it can, for example, compare the value with another value stored in a completely different place.

I hope this clarifies my opinion on integrating with other validation libraries. :)

Cheers!

@shentao Since you pointed out you could make a hidden field to handle HTML5, could you also apply any directives (except "id" and "class") given to the component directly on that hidden input? That would solve most of the custom validation compatibility.

Cheers!

A simple work around I've used for vee-validate and multi-select. Great pack btw, works great and looks good :

                            <multi-select
                              v-model="formData.title"
                              :options="titleOptions"
                              label="text" 
                              :class="{'is-danger': errors.has('title') }"
                              :taggable="true"
                              @tag="addTag">
                            </multi-select>
                            <input
                            v-model="formData.title"
                            class="form-control"
                            v-validate="'required'"
                            name="title"
                            type="text"
                            style="display:none;"
                            >

@RealWeeks Not that long ago, fields with style=display:none would not have been submitted. Apparently that's changed with most (all?) modern browsers. It might be a good idea when using this solution to browser test and verify that the field is being submitted, or perhaps use a different method for hiding it.

@shentao

the fact it鈥檚 not an HTML input after all

Regarding v3.0, I think from an accessibility perspective, it would make the most sense to assign the selected value to the <input> element. That's where a user would expect the value to be. Otherwise they won't be able find it without difficulty, if at all. And to accommodate that, you would need to mess with focus and tabindex, or maybe live regions, which would add unnecessary complexity to an already complex type of form input.

Whether this input is the one that needs validation, or whether it's a second hidden input (e.g., with an id), is a separate question. But at least the text search input would be avaialble for validation.

Here's a working vee-validate example by logaretm himself:
https://jsfiddle.net/logaretm/c4o5eymv/4/

Hope this helps out any future adventurers.

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

Just add this to your css file

[aria-invalid=true] .multiselect__tags {
  border: 1px solid red !important;
}

Not working with last version

hey guys,
I spend some time to vuelidate my vue-multiselect and fit it in my scenario using Objects for values and forms. Please check the code at https://jsfiddle.net/melvik/e0t9ncyr/
@shentao THANK YOU for creating both awesome components and what you do for Vue.js
I will appreciate if you double check my code 馃槈 馃憤 鈽傦笍

Hello,
I am new with vuejs and I started using vuemultiselect package which is a great one !
Unfortunately, I cannot find how to display invalid tooltip on the input with multiselect.
As an image is better than long text, I am trying to achieve this:
image

However, the "required" attribute doesn't change anything as it's not linked to the vuemultiselect input element.
I also tried to dynamically add the attribute "required" upon validation:

const vms = document.getElementsByClassName('multiselect__input');
vms.forEach(i => i.required = true);

but still not working.
Do you have any solution to get the same behavior and display invalid-tooltip or invalid-feedback like bootstrap validation?

https://getbootstrap.com/docs/4.0/components/forms/#tooltips

Hello,
I am new with vuejs and I started using vuemultiselect package which is a great one !
Unfortunately, I cannot find how to display invalid tooltip on the input with multiselect.
As an image is better than long text, I am trying to achieve this:
image

However, the "required" attribute doesn't change anything as it's not linked to the vuemultiselect input element.
I also tried to dynamically add the attribute "required" upon validation:

const vms = document.getElementsByClassName('multiselect__input');
vms.forEach(i => i.required = true);

but still not working.
Do you have any solution to get the same behavior and display invalid-tooltip or invalid-feedback like bootstrap validation?

https://getbootstrap.com/docs/4.0/components/forms/#tooltips

hey @Chup4Chups
I dont think you are in the right path. multiselect does all for you, so dont waste your time on JavaScript. all you need is proper CSS to style your error. check my code in detail and you will find out. I just added a validation for dropdown (multiselect). check the css part. use proper Bootstrap classes or create yours as I did mine.

Good luck

Was this page helpful?
0 / 5 - 0 ratings