Skip to content

Instantly share code, notes, and snippets.

@SharpSeeEr
Created August 21, 2018 15:51
Show Gist options
  • Save SharpSeeEr/f6b67c99f84d4cd6ccac7851485422b6 to your computer and use it in GitHub Desktop.
Save SharpSeeEr/f6b67c99f84d4cd6ccac7851485422b6 to your computer and use it in GitHub Desktop.
Mixin Example
// Mixins providing different address formatting functions.
// This allows address display to be consistent across the entire app.
export const AddressMixin = {
methods: {
formatAddress (address) {
let text = ''
if (address !== null) {
if (address.streetAddress) text += address.streetAddress + '<br />'
if (address.city) text += address.city
if (address.state) {
if (address.city) text += ', '
text += address.state
}
if (address.zip) {
if (address.city || address.state) text += ' '
text += address.zip
}
}
return text
},
formatStreetAddress (address) {
let text = ''
if (address !== null) {
if (address.streetAddress1) text += address.streetAddress1
if (address.streetAddress2) {
if (address.streetAddress1) text += '<br />'
text += address.streetAddress2
}
}
return text
},
formatCityStateZip (address) {
let text = ''
if (address !== null) {
if (address.city) text += address.city
if (address.state) {
if (address.city) text += ', '
text += address.state
}
if (address.zip) {
text += ' ' + address.zip
}
}
return text.trim()
},
formatAddressSingleLine (address) {
return this.formatAddress(address).replace('<br />', ', ')
}
},
filters: {
formattedAddress (address) {
return this.formatAddress(address)
}
}
}
export default AddressMixin
<template>
<v-layout >
<v-flex>
<v-menu :max-height="height" v-model="showSuggestions" :full-width="true" :open-on-click="false">
<div slot="activator">
<v-text-field
:label="label"
v-model="text"
:hint="hint"
:persistent-hint="true"
@focus="onFocus"
@blur="onBlur"
:disabled="disabled"
:error="error"
:error-messages="errorMessages"
@input="onUpdate"
></v-text-field><!-- v-if="showSuggestions" -->
<v-btn v-if="showAddBtn"
fab dark small absolute bottom right
@click.stop="create"
class="pink"
style="top:28px; z-index: 6;"
>
<v-icon>add</v-icon>
</v-btn>
</div>
<v-list three-line class="suggestions">
<v-list-tile v-if="loading && suggestions.length === 0">
<v-list-tile-content class="text-xs-center">
<v-progress-circular indeterminate></v-progress-circular>
</v-list-tile-content>
</v-list-tile>
<div v-for="(item, index) in suggestions" :key="item.id">
<v-divider v-if="index > 0"></v-divider>
<v-list-tile @click="select(item)">
<v-list-tile-content>
<v-list-tile-title>{{ item.firstName }} {{ item.lastName }}</v-list-tile-title>
<v-list-tile-sub-title v-if="item.employment && item.employment.length > 0">{{ item.employment[0].company }}</v-list-tile-sub-title>
<v-list-tile-sub-title class="nowrap" v-html="formatAddress(firstOrDefault(item.addresses)) || 'No Address Available'"></v-list-tile-sub-title>
</v-list-tile-content>
</v-list-tile>
</div>
<v-list-tile tag="div" v-if="suggestions.length === 0">
<v-list-tile-content>
No matches found
</v-list-tile-content>
</v-list-tile>
</v-list>
</v-menu>
</v-flex>
<v-flex style="flex: 0 0 auto;" v-if="!noViewButton">
<v-btn v-show="value" small @click.stop="view" style="margin-top: 16px;">View</v-btn>
</v-flex>
<contact-modal v-if="!noViewButton"
:value="modalContact"
:editing="startInEditMode"
:show="showModal"
@input="onModalInput"
@close="modalClose"
@cancel="modalClose"></contact-modal>
</v-layout>
</template>
<script>
import _ from 'lodash'
import apiClient from '../../store/httpConfig'
import { AddressMixin } from '../../mixins'
import { Contact } from '../../models'
export default {
mixins: [
AddressMixin
],
data () {
return {
text: '',
showSuggestions: false,
suggestions: [],
modalContact: null,
showModal: false,
startInEditMode: false,
unwatchModalContact: null,
loading: false
}
},
props: {
value: { required: true },
label: String,
disabled: Boolean,
clear: Boolean,
error: Boolean,
errorMessages: { default: () => [] },
height: { type: Number, default: 500 },
noViewButton: { type: Boolean, default: false }
},
computed: {
hint () {
if (this.disabled || this.value) return ''
return 'Select Contact'
},
showAddBtn () {
return this.showSuggestions || this.value === null
}
},
created () {
if (this.value) {
this.text = this.getSelectedDisplay(this.value)
}
},
watch: {
value (newValue) {
if (newValue) this.text = this.getSelectedDisplay(newValue)
else this.text = ''
},
showModal (newValue) {
if (newValue !== true) {
}
}
},
methods: {
firstOrDefault (ary, defaultValue) {
if (typeof defaultValue === 'undefined') defaultValue = null
if (!ary || ary.length === 0) return defaultValue
return ary[0]
},
onFocus (e) {
if (this.value !== null) {
e.target.select()
} else if (this.text !== '') {
this.showSuggestions = true
}
this.$emit('focus', e)
},
onBlur (e) {
this.$emit('blur', e)
if (this.value === null && this.clear) this.text = ''
},
getSelectedDisplay (value) {
return `${value.firstName} ${value.lastName}`.trim()
},
debouncedOnUpdate: _.debounce(function (text) {
// console.log('debouncedOnUpdate() text: ' + text);
this.loading = true
if (text === '') {
// console.log('search text is empty');
this.selections = []
this.showSuggestions = false
} else {
// console.log('itemWasJustSelected is false');
// console.log('fetching suggestions');
this.fetchSuggestions(text)
}
}, 400),
onUpdate (text) {
if (this.value) this.$emit('input', null)
this.debouncedOnUpdate(text)
},
select (item) {
this.$emit('input', item)
// this.text = this.getSelectedDisplay(item);
this.text = ''
this.showSuggestions = false
this.suggestions = []
},
fetchSuggestions (text) {
apiClient.get('/api/contacts/lookup/' + text).then(res => {
this.suggestions = res.data || []
this.showSuggestions = true
this.loading = false
}).catch(res => {
console.error('Error fetching lookup results for Contacts: ', res)
this.$store.commit('showMessage', 'Error fetching lookup results for Contacts', 'error', Infinity)
this.showSuggestions = true
this.loading = false
})
},
view () {
this.showSuggestions = false
this.modalContact = this.value
this.startInEditMode = false
this.showModal = true
// this.watchModalContact(newValue => {
// this.$emit('input', newValue)
// });
},
create () {
this.showSuggestions = false
this.modalContact = new Contact()
this.startInEditMode = true
this.showModal = true
// this.watchModalContact(newValue => {
// this.$emit('input', newValue);
// this.modalClose();
// });
},
onModalInput (newValue) {
this.text = ''
if (this.startInEditMode) {
this.modalContact = null
} else this.modalContact = newValue
this.$emit('input', newValue)
},
watchModalContact (cb) {
if (this.unwatchModalContact) this.unwatchModalContact()
this.unwatchModalContact = this.$watch('modalContact', cb)
},
modalClose () {
this.showModal = false
// if (this.unwatchModalContact) {
// this.unwatchModalContact();
// this.unwatchModalContact = null;
// }
}
}
}
</script>
<style>
</style>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment