Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 0 additions & 13 deletions src/components/FlowForm.vue
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,6 @@
window.addEventListener('beforeunload', this.onBeforeUnload)

this.setQuestions()
this.focusActiveQuestion()
},
beforeDestroy() {
document.removeEventListener('keyup', this.onKeyListener, true)
Expand Down Expand Up @@ -394,8 +393,6 @@

if (this.activeQuestionIndex > 0) {
--this.activeQuestionIndex

this.focusActiveQuestion()
}

this.reverse = true
Expand All @@ -414,16 +411,6 @@
this.reverse = false
},

focusActiveQuestion() {
this.$nextTick(() => {
const q = this.activeQuestionComponent()

if (q) {
q.focusField()
}
})
},

/**
* Removes focus from the currently focused DOM element.
*/
Expand Down
28 changes: 17 additions & 11 deletions src/components/Question.vue
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// Single question template and logic

<template>
<div class="animate q-form" v-bind:class="mainClasses">
<div class="q-inner" ref="qinner">
<div class="animate q-form" v-bind:class="mainClasses" ref="qanimate">
<div class="q-inner">
<div v-bind:class="{'section-wrap': question.type === QuestionType.SectionBreak}">
<div v-bind:class="{'fh2': question.type !== QuestionType.SectionBreak}">
<span class="f-title" v-if="question.tagline">{{ question.tagline }}</span>
Expand Down Expand Up @@ -31,7 +31,7 @@
<span class="f-sub" v-if="question.subtitle || question.type === QuestionType.LongText || question.multiple">
<span v-if="question.subtitle">{{ question.subtitle }}</span>

<span class="f-help" v-if="question.type === QuestionType.LongText">{{ question.helpText || language.longTextHelpText }}</span>
<span class="f-help" v-if="question.type === QuestionType.LongText && !isMobile">{{ question.helpText || language.longTextHelpText }}</span>

<span class="f-help" v-if="question.multiple">{{ question.helpText || language.multipleChoiceHelpText }}</span>
</span>
Expand Down Expand Up @@ -65,7 +65,7 @@
<span v-else>{{ language.ok }}</span>
</div>

<span class="f-enter-desc">{{ language.pressEnter }}</span>
<span class="f-enter-desc" v-if="question.type !== QuestionType.LongText || !isMobile">{{ language.pressEnter }}</span>
</a>

<div v-if="showInvalid()" class="f-invalid" role="alert" aria-live="assertive">{{ language.invalidPrompt }}</div>
Expand All @@ -91,6 +91,7 @@
import FlowFormSectionBreakType from './QuestionTypes/SectionBreakType.vue'
import FlowFormTextType from './QuestionTypes/TextType.vue'
import FlowFormUrlType from './QuestionTypes/UrlType.vue'
import { IsMobile } from '../mixins/IsMobile'

export default {
name: 'FlowFormQuestion',
Expand Down Expand Up @@ -119,6 +120,9 @@
default: false
}
},
mixins: [
IsMobile
],
data() {
return {
QuestionType: QuestionType,
Expand All @@ -129,33 +133,35 @@
this.focusField()
this.dataValue = this.question.answer

this.$refs.qinner.addEventListener('transitionend', this.onTransitionEnd)
this.$refs.qanimate.addEventListener('animationend', this.onAnimationEnd)
},
beforeDestroy() {
this.$refs.qinner.removeEventListener('transitionend', this.onTransitionEnd)
this.$refs.qanimate.removeEventListener('animationend', this.onAnimationEnd)
},
methods: {
/**
* Autofocus the input box of the current question
*/
focusField() {
let el = this.$refs.questionComponent
const el = this.$refs.questionComponent

el && el.focus()
},

onTransitionEnd() {
this.enterPressed = false
onAnimationEnd() {
this.focusField()
},

/**
* Emits "answer" event and calls "onEnter" method on Enter press
*/
onEnter() {
onEnter($event) {
const q = this.$refs.questionComponent

if (q) {
this.$emit('answer', q)
if (!q.focused) {
this.$emit('answer', q)
}
q.onEnter()
}
},
Expand Down
44 changes: 34 additions & 10 deletions src/components/QuestionTypes/BaseType.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import QuestionModel, { QuestionType } from '../../models/QuestionModel'
import LanguageModel from '../../models/LanguageModel'
import { IsMobile } from '../../mixins/IsMobile'

export default {
name: 'FlowFormBaseType',
Expand All @@ -17,14 +18,18 @@
active: Boolean,
value: [String, Array]
},
mixins: [
IsMobile
],
data() {
return {
dirty: false,
dataValue: '',
answer: null,
enterPressed: false,
allowedChars: null,
alwaysAllowedKeys: ['ArrowLeft', 'ArrowRight', 'Delete', 'Backspace']
alwaysAllowedKeys: ['ArrowLeft', 'ArrowRight', 'Delete', 'Backspace'],
focused: false
}
},
mounted() {
Expand Down Expand Up @@ -52,6 +57,15 @@
return el
},

setFocus() {
this.focused = true
},

// eslint-disable-next-line no-unused-vars
unsetFocus($event) {
this.focused = false
},

focus() {
const el = this.getElement()

Expand All @@ -68,11 +82,17 @@
this.enterPressed = false
clearTimeout(this.timeoutId)

if ($event && this.allowedChars !== null) {
// Check if the entered character is allowed.
// We always allow keys from the alwaysAllowedKeys array.
if (this.alwaysAllowedKeys.indexOf($event.key) === -1 && this.allowedChars.indexOf($event.key) === -1) {
$event.preventDefault()
if ($event) {
if ($event.key === 'Enter') {
this.unsetFocus()
}

if (this.allowedChars !== null) {
// Check if the entered character is allowed.
// We always allow keys from the alwaysAllowedKeys array.
if (this.alwaysAllowedKeys.indexOf($event.key) === -1 && this.allowedChars.indexOf($event.key) === -1) {
$event.preventDefault()
}
}
}
},
Expand All @@ -86,11 +106,11 @@
},

onEnter() {
this.enterPressed = true
this._onEnter()
},

if (this.question.type === QuestionType.SectionBreak) {
this.dirty = true
}
_onEnter() {
this.enterPressed = true

this.dataValue = this.fixAnswer(this.dataValue)
this.setAnswer(this.dataValue)
Expand Down Expand Up @@ -133,6 +153,10 @@
}
},
computed: {
editingFinished() {
return true
},

placeholder() {
return this.question.placeholder || this.language.placeholder
},
Expand Down
27 changes: 26 additions & 1 deletion src/components/QuestionTypes/LongTextType.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@
v-bind:required="question.required"
v-on:keydown.native="onKeyDown"
v-on:keyup.native="onChange"
v-on:keydown.enter.exact.prevent.native
v-on:keydown.enter.exact.native="onEnterDown"
v-on:keyup.enter.exact.prevent.native="onEnter"
v-on:keyup.tab.prevent.native="onEnter"
v-on:focus.native="setFocus"
v-on:blur.native="unsetFocus"
v-bind:placeholder="placeholder"
/>
</span>
Expand Down Expand Up @@ -41,6 +43,29 @@
methods: {
onResizeListener() {
this.$refs.input.resize()
},

unsetFocus($event) {
if ($event || !this.isMobile) {
this.focused = false
}
},

onEnterDown($event) {
if (!this.isMobile) {
$event.preventDefault()
}
},

onEnter() {
if (!this.isMobile) {
this._onEnter()
}
}
},
computed: {
editingFinished() {
return !this.isMobile
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions src/components/QuestionTypes/PhoneType.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
v-bind:placeholder="placeholder"
v-on:keydown.native="onKeyDown"
v-on:keyup.native="onChange"
v-on:focus.native="setFocus"
v-on:blur.native="unsetFocus"
v-on:keyup.native.enter.prevent="onEnter"
v-on:keyup.native.tab.prevent="onEnter"
/>
Expand Down
6 changes: 6 additions & 0 deletions src/components/QuestionTypes/SectionBreakType.vue
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@
extends: BaseType,
name: QuestionType.SectionBreak,
methods: {
onEnter() {
this.dirty = true

this._onEnter()
},

isValid() {
return true
}
Expand Down
2 changes: 2 additions & 0 deletions src/components/QuestionTypes/TextType.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
v-on:keyup="onChange"
v-on:keyup.enter.prevent="onEnter"
v-on:keyup.tab.prevent="onEnter"
v-on:focus="setFocus"
v-on:blur="unsetFocus"
v-bind:placeholder="placeholder"
/>
</template>
Expand Down
7 changes: 7 additions & 0 deletions src/mixins/IsMobile.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export const IsMobile = {
data() {
return {
isMobile: !!navigator.userAgent.match(/android|iphone|ipad|ipod/i)
}
}
}