ditdot-dev/vue-flow-form

Way to restore state from previously started form

fabrahaingo opened this issue ยท 3 comments

Problem

Currently, there is no way to restore the previous state of a form that has been started by a returning user.
If the user doesn't submit the form and goes away, his progress is lost.

Current workaround

We can implement a way to save answers from the user with the onAnswer event. This is useful when the user only forgets to submit the form. If he leaves in the middle of the form, there seems to be no way to bring him back to his last unanswered question.

In order to restore user progress, we need 3 things:

  1. know what his previous answers were and fill them back in
  2. know if the question was answered of not (so the progress bar displays the right percentage)
  3. know at which question index the user has left

How to do it:

  1. There's already answer in QuestionModel
  2. There's already answered in QuestionModel
  3. I suggest adding a prop called activeQuestion on FlowForm component in order to be able to automatically go to a specific question

Here's what I suggest doing in FlowForm.vue from line 206 (woking on my project)

    timerStartStep: [String, Number],
    timerStopStep: [String, Number],
    // new prop, default to 0 if not provided 
    activeQuestion: {
      type: Number,
      default: 0
    }
  },

  mixins: [IsMobile, ComponentInstance],

  data() {
    return {
      questionRefs: [],
      completed: false,
      submitted: false,
      // Instead of hardcoding 0, previsouly defined prop could be used
      activeQuestionIndex: this.$props.activeQuestion,
      questionList: [],
      questionListActivePath: [],
spinn commented

Hi @fabrahaingo,

thank you for the detailed featured request and explanation. We like the solution you proposed but it has a potential issue where you'd be able to skip questions that weren't already answered which could completely break the form.

But we added an API function in the meantime which will let you accomplish what you want, goToQuestion(index). You can use it by storing a ref to Flow Form in your parent component and calling it, something like this:

<template>
  <flow-form
    ref="flowform"
    v-bind:questions="questions"
    v-bind:standalone="true"
  >
  </flow-form>
</template>

<script>
  export default {
    name: 'example',

    components: {
      FlowForm
    },

    data() {
      return {
        questions: [
          ...
        ]
      }
    }

    mounted() {
      this.$refs.flowform.goToQuestion(3)
      // You can also jump by question ID:
      // this.$refs.flowform.goToQuestion('question_id')
    }
  }
</script>

The goToQuestion function checks if it's possible to jump to the selected question which should ensure that the form logic does not break.

Hi !
I'm trying to figure out how to use goToQuestion(index) method, and specially what are the conditions for this to work. I use this form (the first questions of your example) :

questions: [
        new QuestionModel({
          id: 'first_name',
          tagline: 'Hi! Welcome to our demo survey ๐Ÿ˜Š',
          title: 'What is your first name?',
          type: QuestionType.Text,
          required: false,
          answer: 'coucou',
          placeholder: 'Start typing here...'
        }),
        new QuestionModel({
          id: 'email',
          tagline: "Nice to meet you ๐Ÿ‘€, let's continue",
          title: 'Provide an example email.',
          type: QuestionType.Email,
          required: false,
          answer: 'coucou@fzef.com',
          placeholder: 'Start typing here...'
        }),
        new QuestionModel({
          id: 'phone',
          title: 'Doing great! ๐Ÿ‘ Go ahead and try with a phone number.',
          type: QuestionType.Phone,
          required: false,
          mask: '(###) ###-####'
        }),
        new QuestionModel({
          id: 'movies',
          title: 'List your favorite movies. ๐Ÿฟ',
          type: QuestionType.LongText,
          required: false,
          placeholder: 'Start typing here...'
        })
      ]

and a call like this :

mounted() {
    this.$refs.flowform.goToQuestion(2)
  },

but it starts at the first question.

spinn commented

Hi @jetownfeve21,

if you set answered to true in your QuestionModel it should work. But to simplify things, we'll automatically set answered to true if an answer argument is defined in the next update.