Skip to content

Commit 8eba853

Browse files
authored
Allow for questions to be defined as components (#161)
1 parent ca4d4e9 commit 8eba853

File tree

4 files changed

+435
-332
lines changed

4 files changed

+435
-332
lines changed

src/components/FlowForm.vue

Lines changed: 100 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
v-bind:reverse="reverse"
1717
/>
1818

19+
<slot></slot>
20+
1921
<!-- Complete/Submit screen slots -->
2022
<div v-if="isOnLastStep" class="vff-animate f-fade-in-up field-submittype">
2123
<slot name="complete">
@@ -127,8 +129,8 @@
127129
https://www.ditdot.hr/en
128130
*/
129131
130-
import FlowFormQuestion from './Question.vue'
131-
import QuestionModel from '../models/QuestionModel'
132+
import FlowFormQuestion from './FlowFormQuestion.vue'
133+
import QuestionModel, { ChoiceOption, LinkOption, QuestionType } from '../models/QuestionModel'
132134
import LanguageModel from '../models/LanguageModel'
133135
import { IsMobile } from '../mixins/IsMobile'
134136
@@ -139,7 +141,7 @@
139141
},
140142
141143
props: {
142-
questions:{
144+
questions: {
143145
type: Array,
144146
validator: value => value.every(q => q instanceof QuestionModel)
145147
},
@@ -212,7 +214,7 @@
212214
},
213215
214216
activeQuestionId() {
215-
const question = this.questions[this.activeQuestionIndex]
217+
const question = this.questionModels[this.activeQuestionIndex]
216218
217219
if (this.isOnLastStep) {
218220
return '_submit'
@@ -271,6 +273,93 @@
271273
}
272274
273275
return false
276+
},
277+
278+
questionModels: {
279+
cache: false,
280+
281+
get() {
282+
if (this.questions && this.questions.length) {
283+
return this.questions
284+
}
285+
286+
const questions = []
287+
288+
if (!this.questions) {
289+
const classMap = {
290+
'options': ChoiceOption,
291+
'descriptionLink': LinkOption
292+
}
293+
294+
this
295+
.$slots
296+
.default
297+
.filter(q => q.tag && q.tag.indexOf('Question') !== -1)
298+
.forEach(q => {
299+
const attrs = q.data.attrs
300+
let model = new QuestionModel()
301+
302+
if (q.componentInstance.question !== null) {
303+
model = q.componentInstance.question
304+
}
305+
306+
if (q.data.model) {
307+
model.answer = q.data.model.value
308+
}
309+
310+
Object.keys(model).forEach(key => {
311+
if (attrs[key] !== undefined) {
312+
if (typeof model[key] === 'boolean') {
313+
model[key] = attrs[key] !== false
314+
} else if (key in classMap) {
315+
const
316+
classReference = classMap[key],
317+
options = []
318+
319+
attrs[key].forEach(option => {
320+
const instance = new classReference()
321+
322+
Object.keys(instance).forEach(instanceKey => {
323+
if (option[instanceKey] !== undefined) {
324+
instance[instanceKey] = option[instanceKey]
325+
}
326+
})
327+
328+
options.push(instance)
329+
})
330+
331+
model[key] = options
332+
} else {
333+
switch(key) {
334+
case 'type':
335+
if (Object.values(QuestionType).indexOf(attrs[key]) !== -1) {
336+
model[key] = attrs[key]
337+
} else {
338+
for (const questionTypeKey in QuestionType) {
339+
if (questionTypeKey.toLowerCase() === attrs[key].toLowerCase()) {
340+
model[key] = QuestionType[questionTypeKey]
341+
break
342+
}
343+
}
344+
}
345+
break
346+
347+
default:
348+
model[key] = attrs[key]
349+
break
350+
}
351+
}
352+
}
353+
})
354+
355+
q.componentInstance.question = model
356+
357+
questions.push(model)
358+
})
359+
}
360+
361+
return questions
362+
}
274363
}
275364
},
276365
@@ -298,7 +387,7 @@
298387
setQuestionListActivePath() {
299388
const questions = []
300389
301-
if (!this.questions.length) {
390+
if (!this.questionModels.length) {
302391
return
303392
}
304393
@@ -308,7 +397,7 @@
308397
nextId
309398
310399
do {
311-
let question = this.questions[index]
400+
let question = this.questionModels[index]
312401
313402
question.setIndex(serialIndex)
314403
question.language = this.language
@@ -321,10 +410,10 @@
321410
nextId = question.getJumpId()
322411
if (nextId) {
323412
if (nextId === '_submit') {
324-
index = this.questions.length
413+
index = this.questionModels.length
325414
} else {
326-
for (let i = 0; i < this.questions.length; i++) {
327-
if (this.questions[i].id === nextId) {
415+
for (let i = 0; i < this.questionModels.length; i++) {
416+
if (this.questionModels[i].id === nextId) {
328417
index = i
329418
break
330419
}
@@ -334,11 +423,11 @@
334423
++index
335424
}
336425
} else {
337-
index = this.questions.length
426+
index = this.questionModels.length
338427
}
339428
340429
++serialIndex
341-
} while (index < this.questions.length)
430+
} while (index < this.questionModels.length)
342431
343432
this.questionListActivePath = questions
344433
},

0 commit comments

Comments
 (0)