1
0
Fork 0
mirror of https://gitlab.com/bramw/baserow.git synced 2025-04-24 05:03:02 +00:00
bramw_baserow/web-frontend/components/Editable.vue
2019-08-26 19:41:00 +02:00

103 lines
2.3 KiB
Vue

<template>
<span
ref="editable"
:contenteditable="editing"
@input="update"
@keydown="keydown"
@focusout="change"
@paste="paste"
></span>
</template>
<script>
import { focusEnd } from '@/utils/dom'
export default {
name: 'Editable',
props: {
value: {
type: String,
required: true
}
},
data() {
return {
editing: false,
oldValue: '',
newValue: ''
}
},
mounted() {
this.set(this.value)
},
methods: {
/**
* This method must be called when the is going to be edited. It will enable the
* contenteditable state and will focus the element.
*/
edit() {
this.editing = true
this.$nextTick(() => {
focusEnd(this.$refs.editable)
})
},
/**
* This method is called when the value has changed and needs to be saved. It will
* change the editing state and will emit a change event if the new value has
* changed.
*/
change() {
this.editing = false
if (this.oldValue === this.newValue) {
return
}
this.$emit('change', {
oldValue: this.value,
value: this.newValue
})
this.oldValue = this.newValue
},
/**
* Everytime a key is pressed inside the editable this event will be trigger which
* will update the new value.
*/
update(event) {
const target = event.target
const text = target.textContent
this.newValue = text
},
/**
* When someone pastes something we want to only insert the plain text instead of
* the styled content.
*/
paste(event) {
event.preventDefault()
const text = (event.originalEvent || event).clipboardData.getData(
'text/plain'
)
document.execCommand('insertHTML', false, text)
},
/**
* If a key is pressed and it is an enter or esc key the change event will be called
* to end the editing and save the value.
*/
keydown(event) {
if (event.keyCode === 13 || event.keyCode === 27) {
event.preventDefault()
this.change()
return false
}
},
/**
*
*/
set(value) {
this.oldValue = this.value
this.newValue = this.value
this.$refs.editable.innerText = this.value
}
}
}
</script>