mirror of https://github.com/rancher/dashboard.git
175 lines
3.8 KiB
JavaScript
175 lines
3.8 KiB
JavaScript
<script>
|
|
import LabeledFormElement from '@/mixins/labeled-form-element';
|
|
import { findBy } from '@/utils/array';
|
|
import { get } from '@/utils/object';
|
|
|
|
export default {
|
|
mixins: [LabeledFormElement],
|
|
|
|
props: {
|
|
options: {
|
|
type: Array,
|
|
default: null,
|
|
},
|
|
grouped: {
|
|
type: Boolean,
|
|
default: false,
|
|
},
|
|
disabled: {
|
|
type: Boolean,
|
|
default: false
|
|
},
|
|
multiple: {
|
|
type: Boolean,
|
|
default: false
|
|
},
|
|
optionLabel: {
|
|
type: String,
|
|
default: 'label'
|
|
}
|
|
},
|
|
data() {
|
|
return { selectedDisplay: 'block' };
|
|
},
|
|
computed: {
|
|
currentLabel() {
|
|
let entry;
|
|
|
|
if ( this.grouped ) {
|
|
for ( let i = 0 ; i < this.options.length && !entry ; i++ ) {
|
|
entry = findBy(this.options[i].items || [], 'value', this.value);
|
|
}
|
|
} else {
|
|
entry = findBy(this.options || [], 'value', this.value);
|
|
}
|
|
|
|
if ( entry ) {
|
|
return entry.label;
|
|
}
|
|
|
|
return this.getOptionLabel(this.value);
|
|
},
|
|
shownValue() {
|
|
return this.value ? this.value : ' ';
|
|
}
|
|
},
|
|
|
|
methods: {
|
|
onFocus() {
|
|
this.onFocusLabeled();
|
|
if ( this.$refs.input ) {
|
|
this.$refs.input.placeholder = this.placeholder;
|
|
}
|
|
},
|
|
|
|
onBlur() {
|
|
this.onBlurLabeled();
|
|
if ( this.$refs.input ) {
|
|
this.$refs.input.placeholder = '';
|
|
}
|
|
},
|
|
|
|
searchFocus() {
|
|
this.selectedDisplay = 'none';
|
|
},
|
|
|
|
searchBlur() {
|
|
this.selectedDisplay = 'block';
|
|
},
|
|
|
|
getOptionLabel(option) {
|
|
if (get(option, this.optionLabel)) {
|
|
return get(option, this.optionLabel);
|
|
} else {
|
|
return option;
|
|
}
|
|
},
|
|
get
|
|
},
|
|
};
|
|
</script>
|
|
|
|
<template>
|
|
<div>
|
|
<div v-if="isView">
|
|
<div :class="{'labeled-input': true, raised, focused, empty, [mode]: true}">
|
|
<label>
|
|
{{ label }}
|
|
<span v-if="required && !value" class="required">*</span>
|
|
</label>
|
|
<label class="corner">
|
|
<slot name="corner" />
|
|
</label>
|
|
<div class="selected" :class="{'no-label':!label}" :style="{display:selectedDisplay}">
|
|
{{ currentLabel }}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<v-select
|
|
v-else
|
|
ref="input"
|
|
class="inline"
|
|
v-bind="$attrs"
|
|
:disabled="isView || disabled"
|
|
:value="shownValue"
|
|
:options="options"
|
|
:multiple="multiple"
|
|
:get-option-label="opt=>getOptionLabel(opt)"
|
|
:get-option-key="opt=>optionKey ? get(opt, optionKey) : getOptionLabel(opt)"
|
|
:label="optionLabel"
|
|
@input="e=>e.value ? $emit('input', e.value) : $emit('input', e) "
|
|
@search:focus="searchFocus"
|
|
@search:blur="searchBlur"
|
|
@focus="onFocus"
|
|
@blur="onBlur"
|
|
>
|
|
<template v-slot:selected-option-container>
|
|
<div :class="{'labeled-input': true, raised, focused, empty, [mode]: true}" :style="{border:'none'}">
|
|
<label>
|
|
{{ label }}
|
|
<span v-if="required && !value" class="required">*</span>
|
|
</label>
|
|
<label class="corner">
|
|
<slot name="corner" />
|
|
</label>
|
|
<div v-if="isView">
|
|
{{ currentLabel }}
|
|
</div>
|
|
<div v-else class="selected" :class="{'no-label':!label}" :style="{display:selectedDisplay}">
|
|
{{ currentLabel }}
|
|
</div>
|
|
</div>
|
|
</template>
|
|
</v-select>
|
|
</div>
|
|
</template>
|
|
|
|
<style lang='scss'>
|
|
.v-select.inline {
|
|
|
|
& .labeled-input {
|
|
background-color: rgba(0,0,0,0);
|
|
padding-right:0;
|
|
display: flex;
|
|
flex-direction: column;
|
|
|
|
& *{
|
|
background-color: rgba(0,0,0,0);
|
|
}
|
|
}
|
|
|
|
& .vs__search {
|
|
background-color: none;
|
|
padding: 3px 10px 0px 10px;
|
|
}
|
|
|
|
& .selected{
|
|
position:relative;
|
|
top: 1.4em;
|
|
&.no-label{
|
|
top:7px;
|
|
}
|
|
}
|
|
}
|
|
</style>
|