Initiated MultiSelect
parent
cea5b3766b
commit
d26fb8196b
|
@ -15,6 +15,7 @@
|
|||
<router-link to="/inputswitch">● InputSwitch</router-link>
|
||||
<router-link to="/inputtext">● InputText</router-link>
|
||||
<router-link to="/listbox">● Listbox</router-link>
|
||||
<router-link to="/multiselect">● MultiSelect</router-link>
|
||||
<router-link to="/password">● Password</router-link>
|
||||
<router-link to="/radiobutton">● RadioButton</router-link>
|
||||
<router-link to="/rating">● Rating</router-link>
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
@import '../../components/inputtext/InputText.css';
|
||||
@import '../../components/inputswitch/InputSwitch.css';
|
||||
@import '../../components/listbox/Listbox.css';
|
||||
@import '../../components/multiselect/MultiSelect.css';
|
||||
@import '../../components/panel/Panel.css';
|
||||
@import '../../components/password/Password.css';
|
||||
@import '../../components/progressbar/ProgressBar.css';
|
||||
|
|
|
@ -0,0 +1,149 @@
|
|||
/** MultiSelect **/
|
||||
.p-multiselect {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
width: auto;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.p-multiselect .p-multiselect-trigger {
|
||||
border-right: none;
|
||||
border-top: none;
|
||||
border-bottom: none;
|
||||
cursor: pointer;
|
||||
width: 1.5em;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
padding: 0 .25em;
|
||||
}
|
||||
|
||||
.p-multiselect .p-multiselect-trigger .p-multiselect-trigger-icon {
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
margin-top: -.5em;
|
||||
margin-left: -.5em;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.p-multiselect .p-multiselect-label-container {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.p-multiselect .p-multiselect-label {
|
||||
display: block;
|
||||
padding: .25em 2em .25em .25em;
|
||||
width: auto;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.p-multiselect-label-empty {
|
||||
overflow: hidden;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.p-multiselect.p-disabled .p-multiselect-trigger,
|
||||
.p-multiselect.p-disabled .p-multiselect-label {
|
||||
cursor: auto
|
||||
}
|
||||
|
||||
.p-multiselect-panel {
|
||||
padding: 0.2em;
|
||||
position: absolute;
|
||||
min-width: 10em;
|
||||
}
|
||||
|
||||
.p-multiselect .p-multiselect-panel {
|
||||
min-width: 100%;
|
||||
}
|
||||
|
||||
.p-multiselect-panel .p-multiselect-items-wrapper {
|
||||
overflow: auto;
|
||||
position: relative;
|
||||
padding: 0.2em 0;
|
||||
}
|
||||
|
||||
.p-multiselect-panel .p-multiselect-list {
|
||||
border: 0 none;
|
||||
}
|
||||
|
||||
.p-multiselect-panel .p-multiselect-item {
|
||||
border: 0 none;
|
||||
cursor: pointer;
|
||||
font-weight: normal;
|
||||
margin: 1px 0;
|
||||
padding: .125em .25em;
|
||||
text-align: left;
|
||||
white-space: nowrap;
|
||||
display: block;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.p-multiselect-panel .p-multiselect-item .p-checkbox {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.p-multiselect-panel .p-multiselect-item label {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.p-multiselect-header {
|
||||
margin-bottom: 0.3em;
|
||||
padding: .25em;
|
||||
position: relative;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.p-multiselect-header .p-checkbox {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
cursor:pointer;
|
||||
}
|
||||
|
||||
.p-multiselect-header .p-multiselect-filter-container {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
width: 65%;
|
||||
}
|
||||
|
||||
.p-multiselect-header .p-multiselect-filter-container .p-multiselect-filter-icon {
|
||||
position: absolute;
|
||||
top: .25em;
|
||||
left: .125em;
|
||||
}
|
||||
|
||||
.p-multiselect-header .p-inputtext {
|
||||
padding: .125em .125em .125em 1.25em;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.p-multiselect-header .p-multiselect-close {
|
||||
position: absolute;
|
||||
right: .375em;
|
||||
top: .375em;
|
||||
display: block;
|
||||
border: 0 none;
|
||||
}
|
||||
|
||||
.p-multiselect-header a.p-multiselect-all,
|
||||
.p-multiselect-header a.p-multiselect-none {
|
||||
float:left;
|
||||
margin-right: 10px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.p-multiselect-header .p-multiselect-close.p-state-hover {
|
||||
padding:0px;
|
||||
}
|
||||
|
||||
.p-fluid .p-multiselect {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
|
@ -0,0 +1,188 @@
|
|||
<template>
|
||||
<div :class="containerClass" @click="onClick">
|
||||
<div class="p-hidden-accessible">
|
||||
<input ref="focusInput" type="text" role="listbox" readonly :disabled="disabled" @focus="onFocus" @blur="onBlur" @keydown="onKeyDown" :tabindex="tabindex"/>
|
||||
</div>
|
||||
<div class="p-multiselect-label-container">
|
||||
<label :class="labelClass">{{label}}</label>
|
||||
</div>
|
||||
<div class="p-multiselect-trigger">
|
||||
<span class="p-multiselect-trigger-icon pi pi-chevron-down p-c"></span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
value: null,
|
||||
options: Array,
|
||||
dataKey: null,
|
||||
filter: Boolean,
|
||||
optionLabel: null,
|
||||
optionValue: null,
|
||||
optionDisabled: null,
|
||||
disabled: Boolean,
|
||||
tabindex: String,
|
||||
editable: Boolean,
|
||||
placeholder: String,
|
||||
scrollHeight: {
|
||||
type: String,
|
||||
default: '200px'
|
||||
},
|
||||
filterPlaceholder: String
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
focused: false,
|
||||
filterValue: null,
|
||||
overlayVisible: false
|
||||
};
|
||||
},
|
||||
outsideClickListener: null,
|
||||
beforeDestroy() {
|
||||
this.unbindOutsideClickListener();
|
||||
},
|
||||
updated() {
|
||||
if (this.overlayVisible && this.filterValue) {
|
||||
this.alignOverlay();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getOptionLabel(option) {
|
||||
return ObjectUtils.resolveFieldData(option, this.optionLabel);
|
||||
},
|
||||
getOptionValue(option) {
|
||||
return this.optionValue ? ObjectUtils.resolveFieldData(option, this.optionValue) : option;
|
||||
},
|
||||
isOptionDisabled(option) {
|
||||
return this.optionDisabled ? ObjectUtils.resolveFieldData(option, this.optionDisabled) : false;
|
||||
},
|
||||
onFocus() {
|
||||
this.focused = true;
|
||||
},
|
||||
onBlur() {
|
||||
this.focused = false;
|
||||
},
|
||||
onClick() {
|
||||
|
||||
},
|
||||
onKeyDown(event) {
|
||||
switch(event.which) {
|
||||
//down
|
||||
case 40:
|
||||
if (this.visibleOptions && this.overlayVisible && event.altKey) {
|
||||
this.overlayVisible = true;
|
||||
}
|
||||
break;
|
||||
|
||||
//space
|
||||
case 32:
|
||||
if (!this.overlayVisible) {
|
||||
this.overlayVisible = true;
|
||||
event.preventDefault();
|
||||
}
|
||||
break;
|
||||
|
||||
//enter and escape
|
||||
case 13:
|
||||
case 27:
|
||||
if (this.overlayVisible) {
|
||||
this.hideOverlay();
|
||||
event.preventDefault();
|
||||
}
|
||||
break;
|
||||
|
||||
//tab
|
||||
case 9:
|
||||
this.hideOverlay();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
},
|
||||
bindOutsideClickListener() {
|
||||
if (!this.outsideClickListener) {
|
||||
this.outsideClickListener = (event) => {
|
||||
if (this.$refs.overlay && !this.$refs.overlay.contains(event.target)) {
|
||||
this.hideOverlay();
|
||||
}
|
||||
};
|
||||
document.addEventListener('click', this.outsideClickListener);
|
||||
}
|
||||
},
|
||||
unbindOutsideClickListener() {
|
||||
if (this.outsideClickListener) {
|
||||
document.removeEventListener('click', this.outsideClickListener);
|
||||
this.outsideClickListener = null;
|
||||
}
|
||||
},
|
||||
hideOverlay() {
|
||||
this.overlayVisible = false;
|
||||
this.unbindOutsideClickListener();
|
||||
},
|
||||
getLabelByValue(val) {
|
||||
let label = null;
|
||||
|
||||
if (this.options) {
|
||||
for (let option of this.options) {
|
||||
let optionValue = this.getOptionValue(option);
|
||||
|
||||
if(ObjectUtils.equals(optionValue, val, this.dataKey)) {
|
||||
label = this.getOptionLabel(option);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return label;
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
visibleOptions() {
|
||||
if (this.filterValue)
|
||||
return this.options.filter(option => this.getOptionLabel(option).toLowerCase().indexOf(this.filterValue.toLowerCase()) > -1);
|
||||
else
|
||||
return this.options;
|
||||
},
|
||||
containerClass() {
|
||||
return [
|
||||
'p-multiselect p-component p-unselectable-text',
|
||||
{
|
||||
'p-disabled': this.disabled,
|
||||
'p-focus': this.focused
|
||||
}
|
||||
];
|
||||
},
|
||||
labelClass() {
|
||||
return [
|
||||
'p-multiselect-label',
|
||||
{
|
||||
'p-placeholder': this.label == null && this.placeholder,
|
||||
'p-multiselect-label-empty': !this.placeholder
|
||||
}
|
||||
];
|
||||
},
|
||||
label() {
|
||||
let label;
|
||||
|
||||
if (this.value && this.value.length) {
|
||||
label = '';
|
||||
for(let i = 0; i < this.value.length; i++) {
|
||||
if(i !== 0) {
|
||||
label += ',';
|
||||
}
|
||||
|
||||
label += this.findLabelByValue(this.value[i]);
|
||||
}
|
||||
}
|
||||
else {
|
||||
label = this.placeholder || 'p-multiselect';
|
||||
}
|
||||
|
||||
return label;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -12,6 +12,7 @@ import Editor from './components/editor/Editor';
|
|||
import InputSwitch from './components/inputswitch/InputSwitch';
|
||||
import InputText from './components/inputtext/InputText';
|
||||
import Fieldset from './components/fieldset/Fieldset';
|
||||
import MultiSelect from './components/multiselect/MultiSelect';
|
||||
import Listbox from './components/listbox/Listbox';
|
||||
import Panel from './components/panel/Panel';
|
||||
import Password from './components/password/Password';
|
||||
|
@ -46,6 +47,7 @@ Vue.component('p-inputSwitch', InputSwitch);
|
|||
Vue.component('p-inputtext', InputText);
|
||||
Vue.component('p-listbox', Listbox);
|
||||
Vue.component('p-fieldset', Fieldset);
|
||||
Vue.component('p-multiSelect', MultiSelect);
|
||||
Vue.component('p-panel', Panel);
|
||||
Vue.component('p-password', Password);
|
||||
Vue.component('p-progressBar', ProgressBar);
|
||||
|
|
|
@ -71,6 +71,11 @@ export default new Router({
|
|||
name: 'listbox',
|
||||
component: () => import('./views/listbox/ListboxDemo.vue')
|
||||
},
|
||||
{
|
||||
path: '/multiselect',
|
||||
name: 'multiselect',
|
||||
component: () => import('./views/multiselect/MultiSelectDemo.vue')
|
||||
},
|
||||
{
|
||||
path: '/panel',
|
||||
name: 'panel',
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
<template>
|
||||
<div>
|
||||
<div class="content-section introduction">
|
||||
<div class="feature-intro">
|
||||
<h1>MultiSelect</h1>
|
||||
<p>MultiSelect is used to multiple values from a list of options.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="content-section implementation">
|
||||
<h3 class="first">Basic</h3>
|
||||
<p-multiSelect v-model="selectedCars1" :options="cars" optionLabel="brand" placeholder="Select Brands" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
selectedCars1: null,
|
||||
selectedCars2: null,
|
||||
cars: [
|
||||
{brand: 'Audi', value: 'Audi'},
|
||||
{brand: 'Bmw', value: 'Bmw'},
|
||||
{brand: 'Fiat', value: 'Fiat'},
|
||||
{brand: 'Honda', value: 'Honda'},
|
||||
{brand: 'Jaguar', value: 'Jaguar'},
|
||||
{brand: 'Mercedes', value: 'Mercedes'},
|
||||
{brand: 'Renault', value: 'Renault'},
|
||||
{brand: 'Volkswagen', value: 'Volkswagen'},
|
||||
{brand: 'Volvo', value: 'Volvo'}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.p-multiselect {
|
||||
min-width: 12em;
|
||||
}
|
||||
|
||||
.p-multiselect-car-option {
|
||||
img {
|
||||
vertical-align: middle;
|
||||
margin-right: .5em;
|
||||
width: 24px;
|
||||
}
|
||||
|
||||
span {
|
||||
margin-top: .125em;
|
||||
}
|
||||
}
|
||||
</style>
|
Loading…
Reference in New Issue