I've follow this solution to make multiselect works without using "Ctrl" in keyboard.

And here's the result: enter image description here

Its work great, but i can't save in database.
As far as i debug, the values of this multiselect are correct, but when i click "Save Vendor", its post the old values of multiselect.
I thing it's because of this simple solution doesn't work with ui component. enter image description here
How to solve this? Thanks

1 Answer 1


Fount it.
So my solution is each time the option is clicked, we add the option value to a html tag called data-new, then we catch that data-new in multiselect.js, and replace it with data, which will be saved to the database some how.
To do this, you will need 2 js files.
Note: shipping_methods_no_free is attribute code


], function ($) {
    'use strict';
    $( document ).ready(function() {
        $(document).on('mousedown', 'div[data-index="shipping_methods_no_free"] select', function(e){
            // use mousedown instead of change, don't know why
            var currentData = [];
            if ($(this).attr('data-new') === undefined) {
                // first load
                currentData = $(this).val();
            } else if ($(this).attr('data-new') === "") {
                // if data-new is null
                currentData = [];
            } else if ($(this).attr('data-new') !== "") {
                // if data-new is not null
                currentData = $(this).attr('data-new').split(',');
            var selected = e.target.value;

            if ($.inArray(selected, currentData) !== -1) {
                // remove selected from array
                currentData = jQuery.grep(currentData, function(value) {
                    return value != selected;

                // style the option again, use linear-gradient and -webkit-text-fill-color to pass "user agent stylesheet" problem
                $('div[data-index="shipping_methods_no_free"] select option[value="' + selected + '"]')
                    .css('background', 'linear-gradient(#FFF, #FFF)');
                $('div[data-index="shipping_methods_no_free"] select option')
                    .css('-webkit-text-fill-color', 'rgb(16, 16, 16)');
            } else {
                // add selected to array

                // style the option again, use linear-gradient and -webkit-text-fill-color to pass "user agent stylesheet" problem
                var i;
                for (i = 0; i < currentData.length; ++i) {
                    $('div[data-index="shipping_methods_no_free"] select option[value="' + currentData[i] + '"]')
                        .css('background', 'linear-gradient(rgb(206, 206, 206), rgb(206, 206, 206))')
                        .css('-webkit-text-fill-color', 'rgb(16, 16, 16)');
                $('div[data-index="shipping_methods_no_free"] select option[value="' + selected + '"]')
                    .css('-webkit-text-fill-color', '#fff');

            $(this).attr('data-new', currentData.toString());
        }).on('mousemove', 'div[data-index="shipping_methods_no_free"] select', function(e){e.preventDefault()});


other contents of this file are the same, only need to override setPrepareToSendData()

        setPrepareToSendData: function (data) {
            if (_.isUndefined(data) || !data.length) {
                data = '';

            // START custom
            var element = document.getElementsByName('vendor[shipping_methods_no_free]');
            if (element.length) {
                // custom add new data so it can post the correct data.
                var newData = element[0].getAttribute('data-new');
                var newData = newData.split(",");
                data = newData;
            // END custom

            this.source.set(this.dataScope + '-prepared-for-send', newData);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.