Fixed #972
parent
f89d755530
commit
72dbd25535
|
@ -706,6 +706,10 @@ input.p-dropdown-label {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.p-dropdown-item-group {
|
||||||
|
cursor: auto;
|
||||||
|
}
|
||||||
|
|
||||||
.p-dropdown-items {
|
.p-dropdown-items {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
|
|
@ -326,6 +326,10 @@ export default {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.p-listbox-item-group {
|
||||||
|
cursor: auto;
|
||||||
|
}
|
||||||
|
|
||||||
.p-listbox-filter-container {
|
.p-listbox-filter-container {
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,18 +6,23 @@ interface MultiSelectProps {
|
||||||
optionLabel?: string;
|
optionLabel?: string;
|
||||||
optionValue?: any;
|
optionValue?: any;
|
||||||
optionDisabled?: boolean;
|
optionDisabled?: boolean;
|
||||||
|
optionGroupLabel?: string;
|
||||||
|
optionGroupChildren?: string;
|
||||||
scrollHeight?: string;
|
scrollHeight?: string;
|
||||||
placeholder?: string;
|
placeholder?: string;
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
filter?: boolean;
|
|
||||||
tabindex?: string;
|
tabindex?: string;
|
||||||
inputId?: string;
|
inputId?: string;
|
||||||
dataKey?: string;
|
dataKey?: string;
|
||||||
|
filter?: boolean;
|
||||||
filterPlaceholder?: string;
|
filterPlaceholder?: string;
|
||||||
filterLocale?: string;
|
filterLocale?: string;
|
||||||
|
filterMatchMode?: string;
|
||||||
|
filterFields?: string[];
|
||||||
ariaLabelledBy?: string;
|
ariaLabelledBy?: string;
|
||||||
appendTo?: string;
|
appendTo?: string;
|
||||||
emptyFilterMessage?: string;
|
emptyFilterMessage?: string;
|
||||||
|
emptyMessage?: string;
|
||||||
display?: string;
|
display?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
</div>
|
</div>
|
||||||
<transition name="p-connected-overlay" @enter="onOverlayEnter" @leave="onOverlayLeave">
|
<transition name="p-connected-overlay" @enter="onOverlayEnter" @leave="onOverlayLeave">
|
||||||
<div :ref="overlayRef" class="p-multiselect-panel p-component" v-if="overlayVisible">
|
<div :ref="overlayRef" class="p-multiselect-panel p-component" v-if="overlayVisible">
|
||||||
|
<slot name="header" :value="modelValue" :options="visibleOptions"></slot>
|
||||||
<div class="p-multiselect-header">
|
<div class="p-multiselect-header">
|
||||||
<div class="p-checkbox p-component" @click="onToggleAll" role="checkbox" :aria-checked="allSelected">
|
<div class="p-checkbox p-component" @click="onToggleAll" role="checkbox" :aria-checked="allSelected">
|
||||||
<div class="p-hidden-accessible">
|
<div class="p-hidden-accessible">
|
||||||
|
@ -44,8 +45,9 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="p-multiselect-items-wrapper" :style="{'max-height': scrollHeight}">
|
<div class="p-multiselect-items-wrapper" :style="{'max-height': scrollHeight}">
|
||||||
<ul class="p-multiselect-items p-component" role="listbox" aria-multiselectable="true">
|
<ul class="p-multiselect-items p-component" role="listbox" aria-multiselectable="true">
|
||||||
|
<template v-if="!optionGroupLabel">
|
||||||
<li v-for="(option, i) of visibleOptions" :class="['p-multiselect-item', {'p-highlight': isSelected(option), 'p-disabled': isOptionDisabled(option)}]" role="option" :aria-selected="isSelected(option)"
|
<li v-for="(option, i) of visibleOptions" :class="['p-multiselect-item', {'p-highlight': isSelected(option), 'p-disabled': isOptionDisabled(option)}]" role="option" :aria-selected="isSelected(option)"
|
||||||
:aria-label="getOptionLabel(option)" :key="getOptionRenderKey(option)" @click="onOptionSelect($event, option)" @keydown="onOptionKeyDown($event, option)" :tabindex="tabindex||'0'" v-ripple>
|
:key="getOptionRenderKey(option)" @click="onOptionSelect($event, option)" @keydown="onOptionKeyDown($event, option)" :tabindex="tabindex||'0'" :aria-label="getOptionLabel(option)" v-ripple>
|
||||||
<div class="p-checkbox p-component">
|
<div class="p-checkbox p-component">
|
||||||
<div :class="['p-checkbox-box', {'p-highlight': isSelected(option)}]">
|
<div :class="['p-checkbox-box', {'p-highlight': isSelected(option)}]">
|
||||||
<span :class="['p-checkbox-icon', {'pi pi-check': isSelected(option)}]"></span>
|
<span :class="['p-checkbox-icon', {'pi pi-check': isSelected(option)}]"></span>
|
||||||
|
@ -55,9 +57,34 @@
|
||||||
<span>{{getOptionLabel(option)}}</span>
|
<span>{{getOptionLabel(option)}}</span>
|
||||||
</slot>
|
</slot>
|
||||||
</li>
|
</li>
|
||||||
<li v-if="filterValue && (!visibleOptions || (visibleOptions && visibleOptions.length === 0))" class="p-multiselect-empty-message">{{emptyFilterMessage}}</li>
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<template v-for="(optionGroup, i) of visibleOptions" :key="getOptionGroupRenderKey(optionGroup)">
|
||||||
|
<li class="p-multiselect-item-group">
|
||||||
|
<slot name="optiongroup" :option="optionGroup" :index="i">{{getOptionGroupLabel(optionGroup)}}</slot>
|
||||||
|
</li>
|
||||||
|
<li v-for="(option, i) of getOptionGroupChildren(optionGroup)" :class="['p-multiselect-item', {'p-highlight': isSelected(option), 'p-disabled': isOptionDisabled(option)}]" role="option" :aria-selected="isSelected(option)"
|
||||||
|
:key="getOptionRenderKey(option)" @click="onOptionSelect($event, option)" @keydown="onOptionKeyDown($event, option)" :tabindex="tabindex||'0'" :aria-label="getOptionLabel(option)" v-ripple>
|
||||||
|
<div class="p-checkbox p-component">
|
||||||
|
<div :class="['p-checkbox-box', {'p-highlight': isSelected(option)}]">
|
||||||
|
<span :class="['p-checkbox-icon', {'pi pi-check': isSelected(option)}]"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<slot name="option" :option="option" :index="i">
|
||||||
|
<span>{{getOptionLabel(option)}}</span>
|
||||||
|
</slot>
|
||||||
|
</li>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
<li v-if="filterValue && (!visibleOptions || (visibleOptions && visibleOptions.length === 0))" class="p-multiselect-empty-message">
|
||||||
|
<slot name="emptyfilter">{{emptyFilterMessageText}}</slot>
|
||||||
|
</li>
|
||||||
|
<li v-else-if="(!options || (options && options.length === 0))" class="p-multiselect-empty-message">
|
||||||
|
<slot name="empty">{{emptyMessageText}}</slot>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
<slot name="footer" :value="modelValue" :options="visibleOptions"></slot>
|
||||||
</div>
|
</div>
|
||||||
</transition>
|
</transition>
|
||||||
</div>
|
</div>
|
||||||
|
@ -67,6 +94,7 @@
|
||||||
import {ConnectedOverlayScrollHandler} from 'primevue/utils';
|
import {ConnectedOverlayScrollHandler} from 'primevue/utils';
|
||||||
import {ObjectUtils} from 'primevue/utils';
|
import {ObjectUtils} from 'primevue/utils';
|
||||||
import {DomHandler} from 'primevue/utils';
|
import {DomHandler} from 'primevue/utils';
|
||||||
|
import {FilterService} from 'primevue/api';
|
||||||
import Ripple from 'primevue/ripple';
|
import Ripple from 'primevue/ripple';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -77,18 +105,28 @@ export default {
|
||||||
optionLabel: null,
|
optionLabel: null,
|
||||||
optionValue: null,
|
optionValue: null,
|
||||||
optionDisabled: null,
|
optionDisabled: null,
|
||||||
|
optionGroupLabel: null,
|
||||||
|
optionGroupChildren: null,
|
||||||
scrollHeight: {
|
scrollHeight: {
|
||||||
type: String,
|
type: String,
|
||||||
default: '200px'
|
default: '200px'
|
||||||
},
|
},
|
||||||
placeholder: String,
|
placeholder: String,
|
||||||
disabled: Boolean,
|
disabled: Boolean,
|
||||||
filter: Boolean,
|
|
||||||
tabindex: String,
|
tabindex: String,
|
||||||
inputId: String,
|
inputId: String,
|
||||||
dataKey: null,
|
dataKey: null,
|
||||||
|
filter: Boolean,
|
||||||
filterPlaceholder: String,
|
filterPlaceholder: String,
|
||||||
filterLocale: String,
|
filterLocale: String,
|
||||||
|
filterMatchMode: {
|
||||||
|
type: String,
|
||||||
|
default: 'contains'
|
||||||
|
},
|
||||||
|
filterFields: {
|
||||||
|
type: Array,
|
||||||
|
default: null
|
||||||
|
},
|
||||||
ariaLabelledBy: null,
|
ariaLabelledBy: null,
|
||||||
appendTo: {
|
appendTo: {
|
||||||
type: String,
|
type: String,
|
||||||
|
@ -96,7 +134,11 @@ export default {
|
||||||
},
|
},
|
||||||
emptyFilterMessage: {
|
emptyFilterMessage: {
|
||||||
type: String,
|
type: String,
|
||||||
default: 'No results found'
|
default: null
|
||||||
|
},
|
||||||
|
emptyMessage: {
|
||||||
|
type: String,
|
||||||
|
default: null
|
||||||
},
|
},
|
||||||
display: {
|
display: {
|
||||||
type: String,
|
type: String,
|
||||||
|
@ -136,6 +178,15 @@ export default {
|
||||||
getOptionRenderKey(option) {
|
getOptionRenderKey(option) {
|
||||||
return this.dataKey ? ObjectUtils.resolveFieldData(option, this.dataKey) : this.getOptionLabel(option);
|
return this.dataKey ? ObjectUtils.resolveFieldData(option, this.dataKey) : this.getOptionLabel(option);
|
||||||
},
|
},
|
||||||
|
getOptionGroupRenderKey(optionGroup) {
|
||||||
|
return ObjectUtils.resolveFieldData(optionGroup, this.optionGroupLabel);
|
||||||
|
},
|
||||||
|
getOptionGroupLabel(optionGroup) {
|
||||||
|
return ObjectUtils.resolveFieldData(optionGroup, this.optionGroupLabel);
|
||||||
|
},
|
||||||
|
getOptionGroupChildren(optionGroup) {
|
||||||
|
return ObjectUtils.resolveFieldData(optionGroup, this.optionGroupChildren);
|
||||||
|
},
|
||||||
isOptionDisabled(option) {
|
isOptionDisabled(option) {
|
||||||
return this.optionDisabled ? ObjectUtils.resolveFieldData(option, this.optionDisabled) : false;
|
return this.optionDisabled ? ObjectUtils.resolveFieldData(option, this.optionDisabled) : false;
|
||||||
},
|
},
|
||||||
|
@ -277,7 +328,7 @@ export default {
|
||||||
let nextItem = item.nextElementSibling;
|
let nextItem = item.nextElementSibling;
|
||||||
|
|
||||||
if (nextItem)
|
if (nextItem)
|
||||||
return DomHandler.hasClass(nextItem, 'p-disabled') ? this.findNextItem(nextItem) : nextItem;
|
return DomHandler.hasClass(nextItem, 'p-disabled') || DomHandler.hasClass(nextItem, 'p-multiselect-item-group') ? this.findNextItem(nextItem) : nextItem;
|
||||||
else
|
else
|
||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
|
@ -285,7 +336,7 @@ export default {
|
||||||
let prevItem = item.previousElementSibling;
|
let prevItem = item.previousElementSibling;
|
||||||
|
|
||||||
if (prevItem)
|
if (prevItem)
|
||||||
return DomHandler.hasClass(prevItem, 'p-disabled') ? this.findPrevItem(prevItem) : prevItem;
|
return DomHandler.hasClass(prevItem, 'p-disabled') || DomHandler.hasClass(prevItem, 'p-multiselect-item-group') ? this.findPrevItem(prevItem) : prevItem;
|
||||||
else
|
else
|
||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
|
@ -366,23 +417,49 @@ export default {
|
||||||
return !(this.$el.isSameNode(event.target) || this.$el.contains(event.target) || (this.overlay && this.overlay.contains(event.target)));
|
return !(this.$el.isSameNode(event.target) || this.$el.contains(event.target) || (this.overlay && this.overlay.contains(event.target)));
|
||||||
},
|
},
|
||||||
getLabelByValue(val) {
|
getLabelByValue(val) {
|
||||||
let label = null;
|
let option;
|
||||||
|
|
||||||
if (this.options) {
|
if (this.options) {
|
||||||
for (let option of this.options) {
|
if (this.optionGroupLabel) {
|
||||||
let optionValue = this.getOptionValue(option);
|
for (let optionGroup of this.options) {
|
||||||
|
option = this.findOptionByValue(val, this.getOptionGroupChildren(optionGroup));
|
||||||
if(ObjectUtils.equals(optionValue, val, this.equalityKey)) {
|
if (option) {
|
||||||
label = this.getOptionLabel(option);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
option = this.findOptionByValue(val, this.options);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return label;
|
return option ? this.getOptionLabel(option): null;
|
||||||
|
},
|
||||||
|
findOptionByValue(val, list) {
|
||||||
|
for (let option of list) {
|
||||||
|
let optionValue = this.getOptionValue(option);
|
||||||
|
|
||||||
|
if(ObjectUtils.equals(optionValue, val, this.equalityKey)) {
|
||||||
|
return option;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
},
|
},
|
||||||
onToggleAll(event) {
|
onToggleAll(event) {
|
||||||
const value = this.allSelected ? [] : this.visibleOptions && this.visibleOptions.map(option => this.getOptionValue(option));
|
let value = null;
|
||||||
|
|
||||||
|
if (this.allSelected) {
|
||||||
|
value = [];
|
||||||
|
}
|
||||||
|
else if (this.visibleOptions) {
|
||||||
|
if (this.optionGroupLabel) {
|
||||||
|
value = [];
|
||||||
|
this.visibleOptions.forEach(optionGroup => value = [...value, ...this.getOptionGroupChildren(optionGroup)]);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
value = this.visibleOptions.map(option => this.getOptionValue(option));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.$emit('update:modelValue', value);
|
this.$emit('update:modelValue', value);
|
||||||
this.$emit('change', {originalEvent: event, value: value});
|
this.$emit('change', {originalEvent: event, value: value});
|
||||||
|
@ -421,10 +498,24 @@ export default {
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
visibleOptions() {
|
visibleOptions() {
|
||||||
if (this.filterValue && this.filterValue.trim().length > 0)
|
if (this.filterValue) {
|
||||||
return this.options.filter(option => this.getOptionLabel(option).toLocaleLowerCase(this.filterLocale).indexOf(this.filterValue.toLocaleLowerCase(this.filterLocale)) > -1);
|
if (this.optionGroupLabel) {
|
||||||
else
|
let filteredGroups = [];
|
||||||
|
for (let optgroup of this.options) {
|
||||||
|
let filteredSubOptions = FilterService.filter(this.getOptionGroupChildren(optgroup), this.searchFields, this.filterValue, this.filterMatchMode, this.filterLocale);
|
||||||
|
if (filteredSubOptions && filteredSubOptions.length) {
|
||||||
|
filteredGroups.push({...optgroup, ...{items: filteredSubOptions}});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return filteredGroups
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return FilterService.filter(this.options, this.searchFields, this.filterValue, 'contains', this.filterLocale);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
return this.options;
|
return this.options;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
containerClass() {
|
containerClass() {
|
||||||
return [
|
return [
|
||||||
|
@ -468,25 +559,54 @@ export default {
|
||||||
},
|
},
|
||||||
allSelected() {
|
allSelected() {
|
||||||
if (this.filterValue && this.filterValue.trim().length > 0) {
|
if (this.filterValue && this.filterValue.trim().length > 0) {
|
||||||
let allSelected = true;
|
if (this.visibleOptions.length === 0) {
|
||||||
if(this.visibleOptions.length > 0) {
|
return false;
|
||||||
for (let option of this.visibleOptions) {
|
}
|
||||||
|
|
||||||
|
if (this.optionGroupLabel) {
|
||||||
|
for (let optionGroup of this.visibleOptions) {
|
||||||
|
for (let option of this.getOptionGroupChildren(optionGroup)) {
|
||||||
if (!this.isSelected(option)) {
|
if (!this.isSelected(option)) {
|
||||||
allSelected = false;
|
return false;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
allSelected = false;
|
|
||||||
return allSelected;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return this.modelValue && this.options && (this.modelValue.length > 0 && this.modelValue.length === this.options.length);
|
for (let option of this.visibleOptions) {
|
||||||
|
if (!this.isSelected(option)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (this.modelValue && this.options) {
|
||||||
|
let optionCount = 0;
|
||||||
|
if (this.optionGroupLabel)
|
||||||
|
this.options.forEach(optionGroup => optionCount += this.getOptionGroupChildren(optionGroup).length);
|
||||||
|
else
|
||||||
|
optionCount = this.options.length;
|
||||||
|
|
||||||
|
return optionCount > 0 && optionCount === this.modelValue.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
equalityKey() {
|
equalityKey() {
|
||||||
return this.optionValue ? null : this.dataKey;
|
return this.optionValue ? null : this.dataKey;
|
||||||
|
},
|
||||||
|
searchFields() {
|
||||||
|
return this.filterFields || [this.optionLabel];
|
||||||
|
},
|
||||||
|
emptyFilterMessageText() {
|
||||||
|
return this.emptyFilterMessage || this.$primevue.config.locale.emptyFilterMessage;
|
||||||
|
},
|
||||||
|
emptyMessageText() {
|
||||||
|
return this.emptyMessage || this.$primevue.config.locale.emptyMessage;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
directives: {
|
directives: {
|
||||||
|
@ -568,6 +688,10 @@ export default {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.p-multiselect-item-group {
|
||||||
|
cursor: auto;
|
||||||
|
}
|
||||||
|
|
||||||
.p-multiselect-header {
|
.p-multiselect-header {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
|
@ -34,6 +34,52 @@ data() {
|
||||||
<h5>Placeholder</h5>
|
<h5>Placeholder</h5>
|
||||||
<p>Common pattern is providing an empty option as the placeholder when using native selects, however Dropdown has built-in support using the placeholder option so it is suggested to use it instead of creating an empty option.</p>
|
<p>Common pattern is providing an empty option as the placeholder when using native selects, however Dropdown has built-in support using the placeholder option so it is suggested to use it instead of creating an empty option.</p>
|
||||||
|
|
||||||
|
<h5>Grouping</h5>
|
||||||
|
<p>Options groups are specified with the <i>optionGroupLabel</i> and <i>optionGroupChildren</i> properties.</p>
|
||||||
|
<pre v-code.script><code>
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
selectedGroupedCity: null,
|
||||||
|
groupedCities: [{
|
||||||
|
label: 'Germany', code: 'DE',
|
||||||
|
items: [
|
||||||
|
{label: 'Berlin', value: 'Berlin'},
|
||||||
|
{label: 'Frankfurt', value: 'Frankfurt'},
|
||||||
|
{label: 'Hamburg', value: 'Hamburg'},
|
||||||
|
{label: 'Munich', value: 'Munich'}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'USA', code: 'US',
|
||||||
|
items: [
|
||||||
|
{label: 'Chicago', value: 'Chicago'},
|
||||||
|
{label: 'Los Angeles', value: 'Los Angeles'},
|
||||||
|
{label: 'New York', value: 'New York'},
|
||||||
|
{label: 'San Francisco', value: 'San Francisco'}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Japan', code: 'JP',
|
||||||
|
items: [
|
||||||
|
{label: 'Kyoto', value: 'Kyoto'},
|
||||||
|
{label: 'Osaka', value: 'Osaka'},
|
||||||
|
{label: 'Tokyo', value: 'Tokyo'},
|
||||||
|
{label: 'Yokohama', value: 'Yokohama'}
|
||||||
|
]
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></pre>
|
||||||
|
|
||||||
|
<pre v-code><code><template v-pre>
|
||||||
|
<Dropdown v-model="selectedGroupedCity" :options="groupedCities"
|
||||||
|
optionLabel="label" optionGroupLabel="label" optionGroupChildren="items">
|
||||||
|
</Dropdown>
|
||||||
|
</template>
|
||||||
|
</code></pre>
|
||||||
|
|
||||||
<h5>Filtering</h5>
|
<h5>Filtering</h5>
|
||||||
<p>Filtering allows searching items in the list using an input field at the header. In order to use filtering, enable <i>filter</i> property. By default,
|
<p>Filtering allows searching items in the list using an input field at the header. In order to use filtering, enable <i>filter</i> property. By default,
|
||||||
optionLabel is used when searching and <i>filterFields</i> can be used to customize the fields being utilized. Furthermore, <i>filterMatchMode</i> is available
|
optionLabel is used when searching and <i>filterFields</i> can be used to customize the fields being utilized. Furthermore, <i>filterMatchMode</i> is available
|
||||||
|
|
|
@ -38,23 +38,6 @@ data() {
|
||||||
<pre v-code><code>
|
<pre v-code><code>
|
||||||
<Listbox v-model="selectedCity" :options="cities" optionLabel="name" :multiple="true"/>
|
<Listbox v-model="selectedCity" :options="cities" optionLabel="name" :multiple="true"/>
|
||||||
|
|
||||||
</code></pre>
|
|
||||||
|
|
||||||
<h5>Templating</h5>
|
|
||||||
<p>Label of an option is used as the display text of an item by default, for custom content support define an <i>option</i> template that gets the option instance as a parameter.
|
|
||||||
In addition <i>optiongroup</i>, <i>header</i>, <i>footer</i>, <i>emptyfilter</i> and <i>empty</i> slots are provided for further customization.</p>
|
|
||||||
<pre v-code><code><template v-pre>
|
|
||||||
<Listbox v-model="selectedCars" :options="cars" :multiple="true" :filter="true" optionLabel="brand" listStyle="max-height:250px" style="width:15em">
|
|
||||||
<template #header></template>
|
|
||||||
<template #option="slotProps">
|
|
||||||
<div>
|
|
||||||
<img :alt="slotProps.option.brand" :src="'demo/images/car/' + slotProps.option.brand + '.png'" />
|
|
||||||
<span>{{slotProps.option.brand}}</span>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<template #footer></footer>
|
|
||||||
</Listbox>
|
|
||||||
</template>
|
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<h5>Grouping</h5>
|
<h5>Grouping</h5>
|
||||||
|
@ -97,9 +80,9 @@ export default {
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<pre v-code><code><template v-pre>
|
<pre v-code><code><template v-pre>
|
||||||
<Listbox v-model="selectedGroupedCity" :options="groupedCities"
|
<Listbox v-model="selectedGroupedCity" :options="groupedCities"
|
||||||
optionLabel="label" optionGroupLabel="label" optionGroupChildren="items">
|
optionLabel="label" optionGroupLabel="label" optionGroupChildren="items">
|
||||||
</Listbox>
|
</Listbox>
|
||||||
</template>
|
</template>
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
|
@ -110,6 +93,23 @@ export default {
|
||||||
<pre v-code><code>
|
<pre v-code><code>
|
||||||
<Listbox v-model="selectedCity" :options="cities" optionLabel="name" :filter="true"/>
|
<Listbox v-model="selectedCity" :options="cities" optionLabel="name" :filter="true"/>
|
||||||
|
|
||||||
|
</code></pre>
|
||||||
|
|
||||||
|
<h5>Templating</h5>
|
||||||
|
<p>Label of an option is used as the display text of an item by default, for custom content support define an <i>option</i> template that gets the option instance as a parameter.
|
||||||
|
In addition <i>optiongroup</i>, <i>header</i>, <i>footer</i>, <i>emptyfilter</i> and <i>empty</i> slots are provided for further customization.</p>
|
||||||
|
<pre v-code><code><template v-pre>
|
||||||
|
<Listbox v-model="selectedCars" :options="cars" :multiple="true" :filter="true" optionLabel="brand" listStyle="max-height:250px" style="width:15em">
|
||||||
|
<template #header></template>
|
||||||
|
<template #option="slotProps">
|
||||||
|
<div>
|
||||||
|
<img :alt="slotProps.option.brand" :src="'demo/images/car/' + slotProps.option.brand + '.png'" />
|
||||||
|
<span>{{slotProps.option.brand}}</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template #footer></footer>
|
||||||
|
</Listbox>
|
||||||
|
</template>
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<h5>Properties</h5>
|
<h5>Properties</h5>
|
||||||
|
|
|
@ -11,10 +11,20 @@
|
||||||
<div class="content-section implementation">
|
<div class="content-section implementation">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<h5>Basic</h5>
|
<h5>Basic</h5>
|
||||||
<MultiSelect v-model="selectedCities1" :options="cities" optionLabel="name" placeholder="Select a City" />
|
<MultiSelect v-model="selectedCities1" :options="cities" optionLabel="name" placeholder="Select Cities" />
|
||||||
|
|
||||||
<h5>Chips</h5>
|
<h5>Chips</h5>
|
||||||
<MultiSelect v-model="selectedCities2" :options="cities" optionLabel="name" placeholder="Select a City" display="chip" />
|
<MultiSelect v-model="selectedCities2" :options="cities" optionLabel="name" placeholder="Select Cities" display="chip" />
|
||||||
|
|
||||||
|
<h5>Grouped</h5>
|
||||||
|
<MultiSelect v-model="selectedGroupedCities" :options="groupedCities" optionLabel="label" optionGroupLabel="label" optionGroupChildren="items" placeholder="Select Cities">
|
||||||
|
<template #optiongroup="slotProps">
|
||||||
|
<div class="p-d-flex p-ai-center country-item">
|
||||||
|
<img src="../../assets/images/flag_placeholder.png" :class="'flag flag-' + slotProps.option.code.toLowerCase()" width="18" />
|
||||||
|
<div>{{slotProps.option.label}}</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</MultiSelect>
|
||||||
|
|
||||||
<h5>Advanced with Templating and Filtering</h5>
|
<h5>Advanced with Templating and Filtering</h5>
|
||||||
<MultiSelect v-model="selectedCountries" :options="countries" optionLabel="name" placeholder="Select Countries" :filter="true" class="multiselect-custom">
|
<MultiSelect v-model="selectedCountries" :options="countries" optionLabel="name" placeholder="Select Countries" :filter="true" class="multiselect-custom">
|
||||||
|
@ -50,6 +60,7 @@ export default {
|
||||||
selectedCities1: null,
|
selectedCities1: null,
|
||||||
selectedCities2: null,
|
selectedCities2: null,
|
||||||
selectedCountries: null,
|
selectedCountries: null,
|
||||||
|
selectedGroupedCities: null,
|
||||||
cities: [
|
cities: [
|
||||||
{name: 'New York', code: 'NY'},
|
{name: 'New York', code: 'NY'},
|
||||||
{name: 'Rome', code: 'RM'},
|
{name: 'Rome', code: 'RM'},
|
||||||
|
@ -68,7 +79,34 @@ export default {
|
||||||
{name: 'Japan', code: 'JP'},
|
{name: 'Japan', code: 'JP'},
|
||||||
{name: 'Spain', code: 'ES'},
|
{name: 'Spain', code: 'ES'},
|
||||||
{name: 'United States', code: 'US'}
|
{name: 'United States', code: 'US'}
|
||||||
|
],
|
||||||
|
groupedCities: [{
|
||||||
|
label: 'Germany', code: 'DE',
|
||||||
|
items: [
|
||||||
|
{label: 'Berlin', value: 'Berlin'},
|
||||||
|
{label: 'Frankfurt', value: 'Frankfurt'},
|
||||||
|
{label: 'Hamburg', value: 'Hamburg'},
|
||||||
|
{label: 'Munich', value: 'Munich'}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'USA', code: 'US',
|
||||||
|
items: [
|
||||||
|
{label: 'Chicago', value: 'Chicago'},
|
||||||
|
{label: 'Los Angeles', value: 'Los Angeles'},
|
||||||
|
{label: 'New York', value: 'New York'},
|
||||||
|
{label: 'San Francisco', value: 'San Francisco'}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Japan', code: 'JP',
|
||||||
|
items: [
|
||||||
|
{label: 'Kyoto', value: 'Kyoto'},
|
||||||
|
{label: 'Osaka', value: 'Osaka'},
|
||||||
|
{label: 'Tokyo', value: 'Tokyo'},
|
||||||
|
{label: 'Yokohama', value: 'Yokohama'}
|
||||||
|
]
|
||||||
|
}]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
|
@ -79,7 +117,7 @@ export default {
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.p-multiselect {
|
.p-multiselect {
|
||||||
min-width: 15rem;
|
width: 18rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
::v-deep(.multiselect-custom) {
|
::v-deep(.multiselect-custom) {
|
||||||
|
@ -101,4 +139,10 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 640px) {
|
||||||
|
.p-multiselect {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -42,11 +42,68 @@ data() {
|
||||||
|
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<h5>Custom Content</h5>
|
<h5>Grouping</h5>
|
||||||
<p>Label of an option is used as the display text of an item by default, for custom content support define an <i>option</i> template that gets the option instance as a parameter.</p>
|
<p>Options groups are specified with the <i>optionGroupLabel</i> and <i>optionGroupChildren</i> properties.</p>
|
||||||
<p>In addition the <i>value</i> template can be used to customize the selected values display instead of the default comma separated list.</p>
|
<pre v-code.script><code>
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
selectedGroupedCities: null,
|
||||||
|
groupedCities: [{
|
||||||
|
label: 'Germany', code: 'DE',
|
||||||
|
items: [
|
||||||
|
{label: 'Berlin', value: 'Berlin'},
|
||||||
|
{label: 'Frankfurt', value: 'Frankfurt'},
|
||||||
|
{label: 'Hamburg', value: 'Hamburg'},
|
||||||
|
{label: 'Munich', value: 'Munich'}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'USA', code: 'US',
|
||||||
|
items: [
|
||||||
|
{label: 'Chicago', value: 'Chicago'},
|
||||||
|
{label: 'Los Angeles', value: 'Los Angeles'},
|
||||||
|
{label: 'New York', value: 'New York'},
|
||||||
|
{label: 'San Francisco', value: 'San Francisco'}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Japan', code: 'JP',
|
||||||
|
items: [
|
||||||
|
{label: 'Kyoto', value: 'Kyoto'},
|
||||||
|
{label: 'Osaka', value: 'Osaka'},
|
||||||
|
{label: 'Tokyo', value: 'Tokyo'},
|
||||||
|
{label: 'Yokohama', value: 'Yokohama'}
|
||||||
|
]
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></pre>
|
||||||
|
|
||||||
|
<pre v-code><code><template v-pre>
|
||||||
|
<MultiSelect v-model="selectedGroupedCities" :options="groupedCities"
|
||||||
|
optionLabel="label" optionGroupLabel="label" optionGroupChildren="items">
|
||||||
|
</MultiSelect>
|
||||||
|
</template>
|
||||||
|
</code></pre>
|
||||||
|
|
||||||
|
<h5>Filtering</h5>
|
||||||
|
<p>Filtering allows searching items in the list using an input field at the header. In order to use filtering, enable <i>filter</i> property. By default,
|
||||||
|
optionLabel is used when searching and <i>filterFields</i> can be used to customize the fields being utilized. Furthermore, <i>filterMatchMode</i> is available
|
||||||
|
to define the search algorithm. Valid values are "contains" (default), "startsWith" and "endsWith".</p>
|
||||||
|
|
||||||
|
<pre v-code><code>
|
||||||
|
<MultiSelect v-model="selectedCars" :options="cars" :filter="true" optionLabel="brand" placeholder="Select Brands"/>
|
||||||
|
|
||||||
|
</code></pre>
|
||||||
|
|
||||||
|
<h5>Templating</h5>
|
||||||
|
<p>Label of an option is used as the display text of an item by default, for custom content support define an <i>option</i> template that gets the option instance as a parameter.
|
||||||
|
In addition <i>value</i>, <i>optiongroup</i>, <i>header</i>, <i>footer</i>, <i>emptyfilter</i> and <i>empty</i> slots are provided for further customization.</p>
|
||||||
<pre v-code><code><template v-pre>
|
<pre v-code><code><template v-pre>
|
||||||
<MultiSelect v-model="selectedCars2" :options="cars" optionLabel="brand" placeholder="Select a Car">
|
<MultiSelect v-model="selectedCars2" :options="cars" optionLabel="brand" placeholder="Select a Car">
|
||||||
|
<template #header></template>
|
||||||
<template #value="slotProps">
|
<template #value="slotProps">
|
||||||
<div class="p-multiselect-car-token" v-for="option of slotProps.value" :key="option.brand">
|
<div class="p-multiselect-car-token" v-for="option of slotProps.value" :key="option.brand">
|
||||||
<img :alt="option.brand" :src="'demo/images/car/' + option.brand + '.png'" />
|
<img :alt="option.brand" :src="'demo/images/car/' + option.brand + '.png'" />
|
||||||
|
@ -62,15 +119,9 @@ data() {
|
||||||
<span>{{slotProps.option.brand}}</span>
|
<span>{{slotProps.option.brand}}</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
<template #footer></template>
|
||||||
</MultiSelect>
|
</MultiSelect>
|
||||||
</template>
|
</template>
|
||||||
</code></pre>
|
|
||||||
|
|
||||||
<h5>Filter</h5>
|
|
||||||
<p>Filtering allows searching items in the list using an input field at the header. In order to use filtering, enable the <i>filter</i> property.</p>
|
|
||||||
<pre v-code><code>
|
|
||||||
<MultiSelect v-model="selectedCars" :options="cars" :filter="true" optionLabel="brand" placeholder="Select Brands"/>
|
|
||||||
|
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<h5>Properties</h5>
|
<h5>Properties</h5>
|
||||||
|
@ -116,12 +167,54 @@ data() {
|
||||||
<td>null</td>
|
<td>null</td>
|
||||||
<td>Property name or getter function to use as the disabled flag of an option, defaults to false when not defined.</td>
|
<td>Property name or getter function to use as the disabled flag of an option, defaults to false when not defined.</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>optionGroupLabel</td>
|
||||||
|
<td>string</td>
|
||||||
|
<td>null</td>
|
||||||
|
<td>Property name or getter function to use as the label of an option group.</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>optionGroupChildren</td>
|
||||||
|
<td>string</td>
|
||||||
|
<td>null</td>
|
||||||
|
<td>Property name or getter function that refers to the children options of option group.</td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>scrollHeight</td>
|
<td>scrollHeight</td>
|
||||||
<td>string</td>
|
<td>string</td>
|
||||||
<td>200px</td>
|
<td>200px</td>
|
||||||
<td>Height of the viewport in pixels, a scrollbar is defined if height of list exceeds this value.</td>
|
<td>Height of the viewport in pixels, a scrollbar is defined if height of list exceeds this value.</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>filter</td>
|
||||||
|
<td>boolean</td>
|
||||||
|
<td>false</td>
|
||||||
|
<td>When specified, displays a filter input at header.</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>filterPlaceholder</td>
|
||||||
|
<td>string</td>
|
||||||
|
<td>null</td>
|
||||||
|
<td>Placeholder text to show when filter input is empty.</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>filterLocale</td>
|
||||||
|
<td>string</td>
|
||||||
|
<td>undefined</td>
|
||||||
|
<td>Locale to use in filtering. The default locale is the host environment's current locale.</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>filterMatchMode</td>
|
||||||
|
<td>string</td>
|
||||||
|
<td>contains</td>
|
||||||
|
<td>Defines the filtering algorithm to use when searching the options. Valid values are "contains" (default), "startsWith" and "endsWith"</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>filterFields</td>
|
||||||
|
<td>array</td>
|
||||||
|
<td>null</td>
|
||||||
|
<td>Fields used when filtering the options, defaults to optionLabel.</td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>placeholder</td>
|
<td>placeholder</td>
|
||||||
<td>string</td>
|
<td>string</td>
|
||||||
|
@ -134,12 +227,6 @@ data() {
|
||||||
<td>false</td>
|
<td>false</td>
|
||||||
<td>When present, it specifies that the component should be disabled.</td>
|
<td>When present, it specifies that the component should be disabled.</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
|
||||||
<td>filter</td>
|
|
||||||
<td>boolean</td>
|
|
||||||
<td>false</td>
|
|
||||||
<td>When specified, displays an input field to filter the items on keyup.</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
<tr>
|
||||||
<td>tabindex</td>
|
<td>tabindex</td>
|
||||||
<td>string</td>
|
<td>string</td>
|
||||||
|
@ -158,18 +245,6 @@ data() {
|
||||||
<td>null</td>
|
<td>null</td>
|
||||||
<td>A property to uniquely identify an option.</td>
|
<td>A property to uniquely identify an option.</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
|
||||||
<td>filterPlaceholder</td>
|
|
||||||
<td>string</td>
|
|
||||||
<td>null</td>
|
|
||||||
<td>Placeholder text to show when filter input is empty.</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>filterLocale</td>
|
|
||||||
<td>string</td>
|
|
||||||
<td>undefined</td>
|
|
||||||
<td>Locale to use in filtering. The default locale is the host environment's current locale.</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
<tr>
|
||||||
<td>ariaLabelledBy</td>
|
<td>ariaLabelledBy</td>
|
||||||
<td>string</td>
|
<td>string</td>
|
||||||
|
@ -186,7 +261,13 @@ data() {
|
||||||
<td>emptyFilterMessage</td>
|
<td>emptyFilterMessage</td>
|
||||||
<td>string</td>
|
<td>string</td>
|
||||||
<td>No results found</td>
|
<td>No results found</td>
|
||||||
<td>Text to display when filtering does not return any results.</td>
|
<td>Text to display when filtering does not return any results. Defaults to value from PrimeVue locale configuration.</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>emptyMessage</td>
|
||||||
|
<td>string</td>
|
||||||
|
<td>No results found</td>
|
||||||
|
<td>Text to display when there are no options available. Defaults to value from PrimeVue locale configuration.</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>display</td>
|
<td>display</td>
|
||||||
|
@ -270,6 +351,53 @@ data() {
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<h5>Slots</h5>
|
||||||
|
<div class="doc-tablewrapper">
|
||||||
|
<table class="doc-table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>Parameters</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>option</td>
|
||||||
|
<td>option: Option instance <br />
|
||||||
|
index: Index of the option</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>optiongroup</td>
|
||||||
|
<td>option: OptionGroup instance <br />
|
||||||
|
index: Index of the option group</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>value</td>
|
||||||
|
<td>value: Value of the component <br />
|
||||||
|
placeholder: Placeholder prop value</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>header</td>
|
||||||
|
<td>value: Value of the component <br />
|
||||||
|
options: Displayed options</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>footer</td>
|
||||||
|
<td>value: Value of the component <br />
|
||||||
|
options: Displayed options</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>emptyfilter</td>
|
||||||
|
<td>-</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>empty</td>
|
||||||
|
<td>-</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
<h5>Styling</h5>
|
<h5>Styling</h5>
|
||||||
<p>Following is the list of structural style classes, for theming classes visit <router-link to="/theming">theming</router-link> page.</p>
|
<p>Following is the list of structural style classes, for theming classes visit <router-link to="/theming">theming</router-link> page.</p>
|
||||||
<div class="doc-tablewrapper">
|
<div class="doc-tablewrapper">
|
||||||
|
@ -331,10 +459,20 @@ data() {
|
||||||
|
|
||||||
<pre v-code><code><template v-pre>
|
<pre v-code><code><template v-pre>
|
||||||
<h5>Basic</h5>
|
<h5>Basic</h5>
|
||||||
<MultiSelect v-model="selectedCities1" :options="cities" optionLabel="name" placeholder="Select a City" />
|
<MultiSelect v-model="selectedCities1" :options="cities" optionLabel="name" placeholder="Select Cities" />
|
||||||
|
|
||||||
<h5>Chips</h5>
|
<h5>Chips</h5>
|
||||||
<MultiSelect v-model="selectedCities2" :options="cities" optionLabel="name" placeholder="Select a City" display="chip"/>
|
<MultiSelect v-model="selectedCities2" :options="cities" optionLabel="name" placeholder="Select Cities" display="chip" />
|
||||||
|
|
||||||
|
<h5>Grouped</h5>
|
||||||
|
<MultiSelect v-model="selectedGroupedCities" :options="groupedCities" optionLabel="label" optionGroupLabel="label" optionGroupChildren="items" placeholder="Select Cities">
|
||||||
|
<template #optiongroup="slotProps">
|
||||||
|
<div class="p-d-flex p-ai-center country-item">
|
||||||
|
<img src="../../assets/images/flag_placeholder.png" :class="'flag flag-' + slotProps.option.code.toLowerCase()" width="18" />
|
||||||
|
<div>{{slotProps.option.label}}</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</MultiSelect>
|
||||||
|
|
||||||
<h5>Advanced with Templating and Filtering</h5>
|
<h5>Advanced with Templating and Filtering</h5>
|
||||||
<MultiSelect v-model="selectedCountries" :options="countries" optionLabel="name" placeholder="Select Countries" :filter="true" class="multiselect-custom">
|
<MultiSelect v-model="selectedCountries" :options="countries" optionLabel="name" placeholder="Select Countries" :filter="true" class="multiselect-custom">
|
||||||
|
@ -364,6 +502,7 @@ export default {
|
||||||
selectedCities1: null,
|
selectedCities1: null,
|
||||||
selectedCities2: null,
|
selectedCities2: null,
|
||||||
selectedCountries: null,
|
selectedCountries: null,
|
||||||
|
selectedGroupedCities: null,
|
||||||
cities: [
|
cities: [
|
||||||
{name: 'New York', code: 'NY'},
|
{name: 'New York', code: 'NY'},
|
||||||
{name: 'Rome', code: 'RM'},
|
{name: 'Rome', code: 'RM'},
|
||||||
|
@ -382,7 +521,34 @@ export default {
|
||||||
{name: 'Japan', code: 'JP'},
|
{name: 'Japan', code: 'JP'},
|
||||||
{name: 'Spain', code: 'ES'},
|
{name: 'Spain', code: 'ES'},
|
||||||
{name: 'United States', code: 'US'}
|
{name: 'United States', code: 'US'}
|
||||||
|
],
|
||||||
|
groupedCities: [{
|
||||||
|
label: 'Germany', code: 'DE',
|
||||||
|
items: [
|
||||||
|
{label: 'Berlin', value: 'Berlin'},
|
||||||
|
{label: 'Frankfurt', value: 'Frankfurt'},
|
||||||
|
{label: 'Hamburg', value: 'Hamburg'},
|
||||||
|
{label: 'Munich', value: 'Munich'}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'USA', code: 'US',
|
||||||
|
items: [
|
||||||
|
{label: 'Chicago', value: 'Chicago'},
|
||||||
|
{label: 'Los Angeles', value: 'Los Angeles'},
|
||||||
|
{label: 'New York', value: 'New York'},
|
||||||
|
{label: 'San Francisco', value: 'San Francisco'}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Japan', code: 'JP',
|
||||||
|
items: [
|
||||||
|
{label: 'Kyoto', value: 'Kyoto'},
|
||||||
|
{label: 'Osaka', value: 'Osaka'},
|
||||||
|
{label: 'Tokyo', value: 'Tokyo'},
|
||||||
|
{label: 'Yokohama', value: 'Yokohama'}
|
||||||
|
]
|
||||||
|
}]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -432,16 +598,26 @@ export default {
|
||||||
<div class="content-section implementation">
|
<div class="content-section implementation">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<h5>Basic</h5>
|
<h5>Basic</h5>
|
||||||
<MultiSelect v-model="selectedCities1" :options="cities" optionLabel="name" placeholder="Select a City" />
|
<MultiSelect v-model="selectedCities1" :options="cities" optionLabel="name" placeholder="Select Cities" />
|
||||||
|
|
||||||
<h5>Chips</h5>
|
<h5>Chips</h5>
|
||||||
<MultiSelect v-model="selectedCities2" :options="cities" optionLabel="name" placeholder="Select a City" display="chip" />
|
<MultiSelect v-model="selectedCities2" :options="cities" optionLabel="name" placeholder="Select Cities" display="chip" />
|
||||||
|
|
||||||
|
<h5>Grouped</h5>
|
||||||
|
<MultiSelect v-model="selectedGroupedCities" :options="groupedCities" optionLabel="label" optionGroupLabel="label" optionGroupChildren="items" placeholder="Select Cities">
|
||||||
|
<template #optiongroup="slotProps">
|
||||||
|
<div class="p-d-flex p-ai-center country-item">
|
||||||
|
<img src="../../assets/images/flag_placeholder.png" :class="'flag flag-' + slotProps.option.code.toLowerCase()" width="18" />
|
||||||
|
<div>{{slotProps.option.label}}</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</MultiSelect>
|
||||||
|
|
||||||
<h5>Advanced with Templating and Filtering</h5>
|
<h5>Advanced with Templating and Filtering</h5>
|
||||||
<MultiSelect v-model="selectedCountries" :options="countries" optionLabel="name" placeholder="Select Countries" :filter="true" class="multiselect-custom">
|
<MultiSelect v-model="selectedCountries" :options="countries" optionLabel="name" placeholder="Select Countries" :filter="true" class="multiselect-custom">
|
||||||
<template #value="slotProps">
|
<template #value="slotProps">
|
||||||
<div class="country-item country-item-value" v-for="option of slotProps.value" :key="option.code">
|
<div class="country-item country-item-value" v-for="option of slotProps.value" :key="option.code">
|
||||||
<img src="https://www.primefaces.org/wp-content/uploads/2020/05/placeholder.png" />
|
<img src="../../assets/images/flag_placeholder.png" :class="'flag flag-' + option.code.toLowerCase()" />
|
||||||
<div>{{option.name}}</div>
|
<div>{{option.name}}</div>
|
||||||
</div>
|
</div>
|
||||||
<template v-if="!slotProps.value || slotProps.value.length === 0">
|
<template v-if="!slotProps.value || slotProps.value.length === 0">
|
||||||
|
@ -450,7 +626,7 @@ export default {
|
||||||
</template>
|
</template>
|
||||||
<template #option="slotProps">
|
<template #option="slotProps">
|
||||||
<div class="country-item">
|
<div class="country-item">
|
||||||
<img src="https://www.primefaces.org/wp-content/uploads/2020/05/placeholder.png" />
|
<img src="../../assets/images/flag_placeholder.png" :class="'flag flag-' + slotProps.option.code.toLowerCase()" />
|
||||||
<div>{{slotProps.option.name}}</div>
|
<div>{{slotProps.option.name}}</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -467,6 +643,7 @@ export default {
|
||||||
selectedCities1: null,
|
selectedCities1: null,
|
||||||
selectedCities2: null,
|
selectedCities2: null,
|
||||||
selectedCountries: null,
|
selectedCountries: null,
|
||||||
|
selectedGroupedCities: null,
|
||||||
cities: [
|
cities: [
|
||||||
{name: 'New York', code: 'NY'},
|
{name: 'New York', code: 'NY'},
|
||||||
{name: 'Rome', code: 'RM'},
|
{name: 'Rome', code: 'RM'},
|
||||||
|
@ -485,13 +662,40 @@ export default {
|
||||||
{name: 'Japan', code: 'JP'},
|
{name: 'Japan', code: 'JP'},
|
||||||
{name: 'Spain', code: 'ES'},
|
{name: 'Spain', code: 'ES'},
|
||||||
{name: 'United States', code: 'US'}
|
{name: 'United States', code: 'US'}
|
||||||
|
],
|
||||||
|
groupedCities: [{
|
||||||
|
label: 'Germany', code: 'DE',
|
||||||
|
items: [
|
||||||
|
{label: 'Berlin', value: 'Berlin'},
|
||||||
|
{label: 'Frankfurt', value: 'Frankfurt'},
|
||||||
|
{label: 'Hamburg', value: 'Hamburg'},
|
||||||
|
{label: 'Munich', value: 'Munich'}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'USA', code: 'US',
|
||||||
|
items: [
|
||||||
|
{label: 'Chicago', value: 'Chicago'},
|
||||||
|
{label: 'Los Angeles', value: 'Los Angeles'},
|
||||||
|
{label: 'New York', value: 'New York'},
|
||||||
|
{label: 'San Francisco', value: 'San Francisco'}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Japan', code: 'JP',
|
||||||
|
items: [
|
||||||
|
{label: 'Kyoto', value: 'Kyoto'},
|
||||||
|
{label: 'Osaka', value: 'Osaka'},
|
||||||
|
{label: 'Tokyo', value: 'Tokyo'},
|
||||||
|
{label: 'Yokohama', value: 'Yokohama'}
|
||||||
|
]
|
||||||
|
}]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}`,
|
}`,
|
||||||
style: `<style lang="scss" scoped>
|
style: `<style lang="scss" scoped>
|
||||||
.p-multiselect {
|
.p-multiselect {
|
||||||
min-width: 15rem;
|
width: 18rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
::v-deep(.multiselect-custom) {
|
::v-deep(.multiselect-custom) {
|
||||||
|
@ -507,11 +711,16 @@ export default {
|
||||||
margin-right: .5rem;
|
margin-right: .5rem;
|
||||||
background-color: var(--primary-color);
|
background-color: var(--primary-color);
|
||||||
color: var(--primary-color-text);
|
color: var(--primary-color-text);
|
||||||
}
|
|
||||||
|
|
||||||
img {
|
img.flag {
|
||||||
width: 17px;
|
width: 17px;
|
||||||
margin-right: 0.5rem;
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 640px) {
|
||||||
|
.p-multiselect {
|
||||||
|
width: 100%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>`
|
</style>`
|
||||||
|
|
Loading…
Reference in New Issue