summaryrefslogtreecommitdiffstats
path: root/webapp/src/components/SelectBox.vue
diff options
context:
space:
mode:
authorUdo Walter2019-02-25 07:54:40 +0100
committerUdo Walter2019-02-25 07:54:40 +0100
commit484f76be15caf517ced58930bf950ffe0d049e36 (patch)
tree139d45121ec57150e846d3987ebd486afcbe9805 /webapp/src/components/SelectBox.vue
parentMerge (diff)
downloadbas-484f76be15caf517ced58930bf950ffe0d049e36.tar.gz
bas-484f76be15caf517ced58930bf950ffe0d049e36.tar.xz
bas-484f76be15caf517ced58930bf950ffe0d049e36.zip
[webapp/selectbox] new selectbox component
Diffstat (limited to 'webapp/src/components/SelectBox.vue')
-rw-r--r--webapp/src/components/SelectBox.vue170
1 files changed, 170 insertions, 0 deletions
diff --git a/webapp/src/components/SelectBox.vue b/webapp/src/components/SelectBox.vue
new file mode 100644
index 0000000..89afc5b
--- /dev/null
+++ b/webapp/src/components/SelectBox.vue
@@ -0,0 +1,170 @@
+<i18n>
+{
+ "en": {
+ "name": "Name",
+ "more": "more"
+ },
+ "de": {
+ "name": "Name",
+ "more": "mehr"
+ }
+}
+</i18n>
+
+<template>
+ <v-menu v-model="menu" offset-y :close-on-content-click="false" lazy class="select-menu non-selectable">
+ <v-input class="v-text-field primary--text select-input" :class="{ 'v-input--is-focused': menu }" slot="activator"
+ hide-details
+ label="asdf"
+ >
+ <div class="select-input-content">
+ <div class="select-input-chips">
+ <v-chip
+ class="item-chip"
+ :style="{ width: 'calc(' + (100 / maxColumns) + '% - 8px)' }"
+ v-for="(item, index) in value"
+ :key="item[idKey]"
+ v-if="index < maxShow"
+ small
+ label
+ close
+ @input="removeItem(index)"
+ >
+ <div style="overflow: hidden; text-overflow: ellipsis;">{{ item.name || item.id }}</div>
+ </v-chip>
+ <span v-if="value.length > maxShow" class="and-more">+ {{ value.length - maxShow }} {{ $t('more') }}</span>
+ </div>
+ <v-icon :class="{ 'expand-arrow-flipped': menu }" :color="menu ? 'primary' : ''" style="margin-top: 4px">arrow_drop_down</v-icon>
+ </div>
+ </v-input>
+
+ <v-card>
+ <data-table :value="value" @input="$emit('input', $event)" :headers="headers" :items="items" slim :row-count="6"></data-table>
+ </v-card>
+ </v-menu>
+</template>
+
+<script>
+import DataTable from '@/components/DataTable'
+
+export default {
+ name: 'SelectBox',
+ components: {
+ DataTable
+ },
+ props: {
+ value: {
+ type: Array,
+ default: []
+ },
+ items: {
+ type: Array,
+ default: []
+ },
+ idKey: {
+ type: String,
+ default: 'id'
+ },
+ textKey: {
+ type: String,
+ default: 'name'
+ },
+ textHeading: {
+ type: String
+ },
+ maxColumns: {
+ type: Number,
+ default: 2
+ },
+ maxRows: {
+ type: Number,
+ default: 3
+ }
+ },
+ data () {
+ return {
+ menu: false
+ }
+ },
+ computed: {
+ maxShow () {
+ return this.maxColumns * this.maxRows - 1
+ },
+ computedTextHeading () {
+ return this.textHeading === undefined ? this.$t('name') : this.textHeading
+ },
+ headers () {
+ return [
+ { key: this.textKey, text: this.computedTextHeading }
+ ]
+ }
+ },
+ watch: {
+ value () {
+ window.dispatchEvent(new Event('resize'))
+ }
+ },
+ methods: {
+ removeItem (index) {
+ const newValue = this.value.slice(0)
+ newValue.splice(index, 1)
+ this.$emit('input', newValue)
+ },
+ test () {
+ console.log('asdf')
+ }
+ }
+}
+</script>
+
+<!-- Add "scoped" attribute to limit CSS to this component only -->
+<style scoped>
+.select-menu {
+ width: 100%;
+ overflow: hidden;
+}
+
+.select-input {
+ margin: 0;
+ padding: 0;
+ padding-bottom: 1px;
+}
+
+.select-input-content {
+ width: 100%;
+ display: flex;
+ align-items: flex-start;
+}
+
+.select-input-chips {
+ display: flex;
+ flex-wrap: wrap;
+ text-transform: none;
+ min-height: 34px;
+ flex: 1;
+}
+
+.item-chip >>> .v-chip__content {
+ width: 100%;
+ cursor: pointer;
+}
+
+.expand-arrow-flipped {
+ transform: rotate(180deg);
+}
+
+.and-more {
+ font-size: 13px;
+ display: flex;
+ align-items: center;
+ margin: 4px 17px;
+}
+
+.theme--dark .and-more {
+ color: rgb(255, 255, 255);
+}
+
+.theme--light .and-more {
+ color: rgba(0, 0, 0, 0.87);
+}
+</style>