shentao / vue-multiselect

Universal select/multiselect/tagging component for Vue.js
https://vue-multiselect.js.org/
MIT License
6.69k stars 988 forks source link

New render function Vue 2 #135

Closed nikolaynesov closed 7 years ago

nikolaynesov commented 7 years ago

Hi,

Thank you for such a great package. Can you please provide any example for Instead of Vue.partial for custom option templates you can use a custom render function. Sorry, if I missed something in docs but I really tried to find before asking :)

shentao commented 7 years ago

Thanks for the kind words!

Sadly the docs for 2.0 are still in progress. :( Here is an example how such render function can look: https://github.com/monterail/vue-multiselect/blob/2.0/src/Multiselect.vue#L189 This is the default render function that is used, so this is also the props to which you have to pass the new render function.

nikolaynesov commented 7 years ago

@shentao thank you for quick response. I've got an issue with Multiple select box. I selected 3 options from drop-down. When I'm clicking on the cross on the badge of 2nd it removes the last one, when I click on 1st - it removes the last. So clicking on cross to remove any selected option for Multiple select always removes the last one no matter on which you clicked. Expected : to remove those option that I clicked cross on. Not sure why, maybe it's on my side so didn't create a new issue post. my options array looks like:

options: Array[x]
   0: Object
      id: 1
      name: "The name"
      slug: "the_slug"
   1: Object
      ... etc...

I call the component this way:

<multiselect v-model="selected" v-show="!working"

            :options="options"
            :multiple="true"
            :selected="selected"
            label="name"
            key="id"
            placeholder="Placeholder"
            select-label="+"
            deselect-label="-"
            :disabled="disabledSync"

        >
        </multiselect>

in package.json

...
"vue-multiselect": "next",
...
shentao commented 7 years ago

Please change key to track-by. This is due to the internal changes in Vue 2.0. Additionally you have to change the :selected to :value. The new version of multiselect Beta also allows for using v-model! Refer to the top of the Readme for more changes in

I should publish the new docs soon after I finish the grouping feature (almost done!) and some needed refactoring.

adrianthedev commented 7 years ago

Hi,

Great package! Congratulations! I'm trying to implement, with VueJS2, custom templates for options. I can't seem to make it render the item as html. I'm using it like this:

  <multiselect
  :options="options"
  :selected="selected"
  :multiple="false"
  :local-search="false"
  :clear-on-select="true"
  :close-on-select="true"
  :loading="isLoading"
  id="ajax"
  v-on:search-change="asyncFind"
  v-on:input="asyncUpdate"
  track-by="id"
  placeholder="Type to search"
  :option-function="productList"
  ></multiselect>

---

productList(){
  return '<strong>option</strong>';
}

Please help. I'm trying to fix this for an hour now.

Thanks a lot!

shentao commented 7 years ago

Hey @adrianthedev! Change the productList function to:

productList (h, option, label) {
  return h('strong', {}, option)
}

to display the whole object (not recommended as it will display as [Object object]). In this case you probably want to use something like option.somePropToDisplay. or

productList (h, option, label) {
  return h('strong', {}, label)
}

To just display the generated label.

nikolaynesov commented 7 years ago

@adrianthedev hey,

just in case @shentao example was not clear enough I will give you a real life example how to view friends list with avatars

             searchList (h, friend, label) {

                    return h(
                            'span',
                            {
                                'class': {
                                    'friends-list-item': true
                                },
                                attrs: {
                                    id: 'friends-list-item-'+friend.name
                                },
                                domProps: {
                                    innerHTML: '<img src="' + friend.avatar_url + '" alt="' + friend.full_name + '"> ' + label
                                }
                            },
                            label
                    );

                },

Basically you just need to follow the Data Object Structure. Maybe it will help someone else. Good luck!

shentao commented 7 years ago

Thanks! However, now that scoped slots are released (Vue v2.1), I think I can change this to a simple scoped slot.

<multiselect config-props-here>
  <template slot="option" scope="props">
     <span class="friends-list-item" :id="'friends-list-item-" + props.friend.name>
       <img src="props.friend.avatar_url">
       {{ props.label }} 
     </span>
  </template>
</multiselect>

Or something similar. Will have to try it out soon. :)

fabd commented 7 years ago

Any updates on this? Trying to get a custom option template to work with Vue 2.1.8 and vue-multiselect 2.0.0-beta.13. edit: problem is I don't know how to pass the template / render function. option-function doesn't seem to do anything, <template ...> doesn't seem to work.