· 6 years ago · Sep 03, 2019, 11:56 AM
1class FormFragment : Fragment(), FormSection {
2
3 private val section by lazy { arguments!!.getParcelable<Section>(SECTION) }
4 private val fieldInputs = mutableListOf<FieldInput>()
5
6 override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
7 val view = inflater.inflate(R.layout.form_section_fragment, container, false)
8 return view
9 }
10
11 override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
12 super.onViewCreated(view, savedInstanceState)
13 renderFields(view)
14 }
15
16 //Added function
17 override fun onUserSubmitSection() {
18 if (fieldInputs.validate()) {
19 val answers = mutableListOf<Answer>()
20 fieldInputs.forEach {
21 answers.add(it.key, it.getValue())
22 }
23 (context as SectionSubmittedListener).onSectionSubmittedWithValidAnswers(answers)
24 }
25
26 }
27
28 // This is the method which does the magic
29 private fun renderFields(view: View) {
30 val formContainer = view.findViewById<LinearLayout>(R.id.formContainer)
31
32 //We iterate through each field and decide which component it corresponds to.
33 //All of these components created by ourselves must follow the same interface, which is FieldInput<T>
34 section.fields.forEach {
35 val fieldInput: FieldInput = when(it.type) {
36 FieldType.TEXT -> { TextInput(requireContext()) }
37 FieldType.DATE -> { DateInput(requireContext()) }
38 else -> {
39 throw IllegalStateException("unknown type")
40 }
41 }
42
43 //we must set a key to each field so we send it back to the api as a map of the key and the value inserted
44 fieldInput.apply {
45 key = it.key
46 setLabel(it.label)
47 }
48
49 //Then we add this field to the list of the fields, so we can validate all of them and get their values
50 fieldInputs.add(fieldInput)
51
52 //Our view only as a linear layout to hold the fields and place them one on each line
53 formContainer.addView(fieldInput as View)
54 }
55 }
56
57 companion object {
58 const val SECTION = "section"
59
60 fun newInstance(section: Section): FormFragment {
61 val fragment = FormFragment()
62 val bundle = Bundle().apply {
63 putParcelable(SECTION, section)
64 }
65 fragment.arguments = bundle
66 return fragment
67 }
68 }
69}
70
71//Added class to hold the answers
72data class Answer(val key: String, val value: String)