mstnorris's avatar

Using Vue-Multiselect

Can someone please give me a quick walkthrough on how to get this thing up and running.

http://monterail.github.io/vue-multiselect/

I'm not familiar with ES6, Webpack, etc, and every time I try and use a cool tool like this, I can't get it to work.

I'm using the latest version of Laravel, and Elixir, so from what I understand it should be fairly straight forward but I'm just not getting it.

0 likes
18 replies
zachleigh's avatar

Im using that package in a couple projects. Its really nice. What are you trying to set up? Just a simple drop down? A searchable multiselect? Show us what you have so far and maybe we can help you get it going.

mstnorris's avatar

ARGHHHHHH! It seems that each time I post a reply the connection to the server drops and my reply is lost :/

Anyway, as for the JavaScript itself, I don't know much. I'm new to the whole import/export modules thing, and never wrapped my head around the require part. I want to finally get over this hurdle so I can produce something good.

So far I am using select2 across my app. In this particular case I only need a single select (see screenshot below) however in other places in my app I require tagging, multiple selections, searching etc so any help you can offer with that is greatly appreciated. I'm sure in doing so you will help to answer most/all my other JS questions as they are usually related the newer concepts that I'm not familiar with.

screenshot

Thanks again for the offer to help.

zachleigh's avatar

I assume youre already using Vue. This is how I use multiselect for a simple, unsearchable dropdown.

<template>
    <div class="dropdown">
        <multiselect
            :selected.sync="selected"
            :show-labels="false"
            :options="options"
            :placeholder="placeholder"
            :searchable="false"
            :allow-empty="false"
            :multiple="false"
            key="name"
            label="name"
        ></multiselect>
        <label v-show="showLabel" for="multiselect"><span></span>Language</label>
    </div>
</template>

<script>
    import { Multiselect } from 'vue-multiselect';

    export default {
        components: { Multiselect },

        props: {
            options: {},
            placeholder: {
                default: 'Select one' 
            },
            showLabel: {
                type: Boolean,
                default: true
            },
            selected: ''
        }
    };
</script>

And then I use it in my html like this:

<drop-down
    :options="options"
    :selected.sync="selected"
    :show-label="false"
></drop-down>
mstnorris's avatar

This is where I am stuck/confused, where does your first code-block go...? I'm at that level at the moment.

Do I need to do anything special with gulp? (I'm using the latest version of Elixir - 6.0.0-9) If so, what goes in the gulp file?

Sorry, I forgot to say than you by the way :)

zachleigh's avatar

I put it in a file called DropDown.vue in resources/assets/js/components/. Then, in my app.js file, I have my Vue instance:

"use strict";

var Vue = require('vue');

var DropDown = require('./components/DropDown.vue');

var vm = new Vue({
    el: '#app',

    components: {
        DropDown
    }
});
mstnorris's avatar

I have done that... I get this error: "ReferenceError: Can't find variable: require" and that appears in "global code — app.js:3" which is this line: "var Vue = require('vue');".

It's always the require part that throws these errors. I thought that by using Laravel-Elixir I wouldn't have this issues.

zachleigh's avatar

Hmmm... It could be a few things. First, did you run npm install after starting your project? Did you get any errors when doing this? What does your gulp file look like?

mstnorris's avatar

Yeah I've ran nam install - no errors.

This is my gulpfile.js

var elixir = require('laravel-elixir');
var gulp = require('gulp');
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
var uglify_css = require('gulp-minify-css');
var sass = require('gulp-sass');
var sourcemaps = require('gulp-sourcemaps');
var strip = require('gulp-strip-css-comments');

gulp.task('vendor', function() {

    gulp.src([
            './node_modules/jquery/dist/jquery.js',
            './node_modules/tether/dist/js/tether.js',
            './node_modules/bootstrap/dist/js/bootstrap.js',
            './node_modules/simplemde/dist/simplemde.min.js',
            './node_modules/moment/moment.js',
            './node_modules/moment-timezone/moment-timezone.js',
            './node_modules/fullcalendar/dist/fullcalendar.js',
            './node_modules/marked/lib/marked.js',
            './resources/assets/js/vue-marked.js',
            './node_modules/dropzone/dist/dropzone.js',
            './node_modules/select2/dist/js/select2.js',
            './node_modules/eonasdan-bootstrap-datetimepicker/build/js/bootstrap-datetimepicker.min.js',
            './resources/assets/js/readingTime.js',
            './node_modules/bootbox/bootbox.js',
            './node_modules/sortablejs/Sortable.js',
            './node_modules/vue/dist/vue.js',
            './node_modules/vue-resource/dist/vue-resource.js'
        ])
        .pipe(concat('vendor.js.output'))
        .pipe(uglify())
        .pipe(gulp.dest('./resources/assets/js'));

    gulp.src([
            './node_modules/animate.css/animate.css',
            './node_modules/fullcalendar/dist/fullcalendar.css',
            './node_modules/simplemde/dist/simplemde.min.css',
            './node_modules/dropzone/dist/dropzone.css'
        ])
        .pipe(strip())
        .pipe(concat('vendor.css.output'))
        .pipe(sourcemaps.init())
        .pipe(uglify_css())
        .pipe(sourcemaps.write())
        .pipe(gulp.dest('./resources/assets/css'));

    gulp.src([
            './node_modules/font-awesome/fonts/*'
        ])
        .pipe(gulp.dest('./public/build/fonts'));
});

elixir(function(mix) {
    mix.sass('app.scss', 'resources/assets/css/app.scss.output')
        .styles([
            'vendor.css.output',
            'app.scss.output'
        ], 'public/css/app.css')
        .scripts([
            'vendor.js.output',
            'window-scroll.js',
            'alert.js',
            'cookie.js',
            'tooltips-everywhere.js',
            'multi-select.js',
            'app.js'
        ], 'public/js/app.js')
        .version(['css/app.css', 'js/app.js']);
});
mstnorris's avatar

Ok, I have added the mix.browserify() to my gulpfile, now when I run it, it complains about DropDown.vue - "ParseError: Unexpected token"

<template>
^

My "DropDown.vue" file

<template>
    <div class="dropdown">
        <multiselect
                :selected.sync="selected"
                :show-labels="false"
                :options="options"
                :placeholder="placeholder"
                :searchable="false"
                :allow-empty="false"
                :multiple="false"
                key="name"
                label="name"
        ></multiselect>
        <label v-show="showLabel" for="multiselect"><span></span>Language</label>
    </div>
</template>

<script>
    import { Multiselect } from 'vue-multiselect';

    export default {
        components: { Multiselect },

        props: {
            options: {},
            placeholder: {
                default: 'Select one'
            },
            showLabel: {
                type: Boolean,
                default: true
            },
            selected: ''
        }
    };
</script>
zachleigh's avatar

In order to use vue files, you need to install laravel-elixir-vueify through npm and require it in your gulp file.

require ('laravel-elixir-vueify');
mstnorris's avatar

I thought that it was included by default. I'm not getting a weird error when I run gulp vendor

node_modules/laravel-elixir-vueify/index.js:3
Elixir.config.js.browserify.transformers.push({
                           ^

TypeError: Cannot read property 'transformers' of undefined
mstnorris's avatar

I don't need to use Browserify as this package (https://www.npmjs.com/package/laravel-elixir-vue) is included in Laravel Elixir 6 already.

I am however still getting the "ReferenceError: Can't find variable: require" in my app.js file:

"use strict";

var Vue = require('vue');

var DropDown = require('./components/DropDown.vue');

var vm = new Vue({
    el: '#app',

    components: {
        DropDown
    }
});
zachleigh's avatar

You still need to run your scripts through browserify...

mstnorris's avatar

I'm using Elixir 6, and it pulls in laravel-elixir-vue. I've run the code through mix.webpack(...) as per the latest docs and that is working so thank you very much for getting me this far.

Can you share with me a code sample of yours that pulls in data for the options, and allows for searching/tagging support.

Thanks

mstnorris's avatar

Are you able to provide me with an example of how to get the options via ajax. Is it a simple case of pulling in vue-resource?

Also, would I put vue-resource in the .vue file and then just supply a url from the tag within the HTML?

zachleigh's avatar

I usually just send the options in the html. Something like this:

<drop-down
    :options="{{ $getAll }}"
    :selected.sync="getAll"
    :show-label="false"
    placeholder="Select Category"
></drop-down>

But if you wanted to do it with ajax, then you could either hardcode the url in your vue file or, if you wanted it to be reusable, send it through as a property in your html.

To use Vue resource, simply tell Vue to use it in your main js file.

Vue.use(require('vue-resource'));

And then use it:

this.$http.post('/contact/send', {
    key: value,
    _token: document.querySelector('meta[name="csrf-token"]').content
}).then(function (response) {
    // On success
}, function (error) {
    // On error
});
1 like

Please or to participate in this conversation.