summaryrefslogblamecommitdiffstats
path: root/webapp/src/components/SelectBox.vue
blob: 89afc5bc638b3b911a18accb77a2c5d6b45590d7 (plain) (tree)









































































































































































                                                                                                                                         
<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>