@@ -28,8 +28,8 @@ import androidx.appcompat.app.AppCompatActivity
28
28
import androidx.core.view.children
29
29
import androidx.core.view.get
30
30
import androidx.core.view.isEmpty
31
+ import androidx.core.widget.addTextChangedListener
31
32
import androidx.lifecycle.lifecycleScope
32
- import com.google.android.fhir.datacapture.CustomCallback
33
33
import com.google.android.fhir.datacapture.R
34
34
import com.google.android.fhir.datacapture.extensions.displayString
35
35
import com.google.android.fhir.datacapture.extensions.identifierString
@@ -58,14 +58,11 @@ internal object AutoCompleteViewHolderFactory :
58
58
private lateinit var autoCompleteTextView: MaterialAutoCompleteTextView
59
59
private lateinit var chipContainer: ChipGroup
60
60
private lateinit var textInputLayout: TextInputLayout
61
- private lateinit var adapter: ArrayAdapter < AutoCompleteViewAnswerOption >
61
+ private lateinit var adapter: AutoCompleteArrayAdapter
62
62
63
63
private val canHaveMultipleAnswers
64
64
get() = questionnaireViewItem.questionnaireItem.repeats
65
65
66
- private val callback: CustomCallback <* >?
67
- get() = questionnaireViewItem.callback
68
-
69
66
override lateinit var questionnaireViewItem: QuestionnaireViewItem
70
67
private lateinit var errorTextView: TextView
71
68
@@ -82,30 +79,50 @@ internal object AutoCompleteViewHolderFactory :
82
79
override fun bind (questionnaireViewItem : QuestionnaireViewItem ) {
83
80
header.bind(questionnaireViewItem)
84
81
header.showRequiredOrOptionalTextInHeaderView(questionnaireViewItem)
85
- val suggestions = mutableListOf<AutoCompleteViewAnswerOption >()
86
82
val answerOptionValues =
87
83
questionnaireViewItem.enabledAnswerOptions.map {
88
84
AutoCompleteViewAnswerOption (
89
85
answerId = it.value.identifierString(header.context),
90
86
answerDisplay = it.value.displayString(header.context),
91
87
)
92
88
}
93
- suggestions.addAll(answerOptionValues)
94
89
adapter =
95
90
AutoCompleteArrayAdapter (
96
91
context = header.context,
97
92
resource = R .layout.drop_down_list_item,
98
93
textViewResourceId = R .id.answer_option_textview,
99
94
objects = answerOptionValues,
100
- callback = callback,
101
- answerValueSet = questionnaireViewItem.questionnaireItem.answerValueSet,
102
95
)
103
96
autoCompleteTextView.setAdapter(adapter)
104
97
// Remove chips if any from the last bindView call on this VH.
105
98
chipContainer.removeAllViews()
106
99
presetValuesIfAny()
107
100
108
101
displayValidationResult(questionnaireViewItem.validationResult)
102
+
103
+ val serverSideFiltering =
104
+ questionnaireViewItem.questionnaireItem.answerValueSet != null &&
105
+ answerOptionValues.isEmpty()
106
+
107
+ autoCompleteTextView.addTextChangedListener { text ->
108
+ if (serverSideFiltering) {
109
+ questionnaireViewItem.autoCompleteAnswerOptionResolver(
110
+ text.toString(),
111
+ questionnaireViewItem.questionnaireItem.answerValueSet,
112
+ ) { response ->
113
+ val items =
114
+ response.map {
115
+ AutoCompleteViewAnswerOption (
116
+ answerId = it.code,
117
+ answerDisplay = it.display,
118
+ )
119
+ }
120
+ adapter.updateData(items)
121
+ }
122
+ } else {
123
+ adapter.clientSideFilter(text.toString())
124
+ }
125
+ }
109
126
}
110
127
111
128
override fun setReadOnly (isReadOnly : Boolean ) {
@@ -272,7 +289,7 @@ internal object AutoCompleteViewHolderFactory :
272
289
* An answer option that would show up as a dropdown item in an [AutoCompleteViewHolderFactory]
273
290
* textview
274
291
*/
275
- data class AutoCompleteViewAnswerOption (val answerId : String , val answerDisplay : String ) {
292
+ internal data class AutoCompleteViewAnswerOption (val answerId : String , val answerDisplay : String ) {
276
293
override fun toString (): String {
277
294
return this .answerDisplay
278
295
}
@@ -283,8 +300,6 @@ internal class AutoCompleteArrayAdapter(
283
300
val resource : Int ,
284
301
val textViewResourceId : Int ,
285
302
private val objects : List <AutoCompleteViewAnswerOption >,
286
- private val callback : CustomCallback <* >? = null ,
287
- private val answerValueSet : String? = null ,
288
303
) : ArrayAdapter<AutoCompleteViewAnswerOption>(context, resource, textViewResourceId, objects) {
289
304
290
305
private var items = listOf<AutoCompleteViewAnswerOption >()
@@ -303,6 +318,11 @@ internal class AutoCompleteArrayAdapter(
303
318
notifyDataSetChanged()
304
319
}
305
320
321
+ fun clientSideFilter (query : String ) {
322
+ items = objects.filter { it.answerDisplay.contains(query, ignoreCase = true ) }
323
+ notifyDataSetChanged()
324
+ }
325
+
306
326
override fun getDropDownView (position : Int , convertView : View ? , parent : ViewGroup ): View {
307
327
return getView(position, convertView, parent)
308
328
}
@@ -312,21 +332,12 @@ internal class AutoCompleteArrayAdapter(
312
332
@Suppress(" UNCHECKED_CAST" )
313
333
override fun getFilter (): Filter {
314
334
return object : Filter () {
335
+
315
336
override fun performFiltering (constraint : CharSequence? ): FilterResults {
316
- val query = (constraint?.toString() ? : " " ).trim()
317
- val filteredResults: List <AutoCompleteViewAnswerOption > =
318
- if (callback != null && answerValueSet != null && objects.isEmpty()) {
319
- (callback as ? CustomCallback <AutoCompleteViewAnswerOption >)?.invoke(
320
- query,
321
- answerValueSet,
322
- )
323
- ? : emptyList()
324
- } else {
325
- objects.filter { it.answerDisplay.contains(query, ignoreCase = true ) }
326
- }
337
+ // Prevent default filtering behaviour
327
338
return FilterResults ().apply {
328
- values = filteredResults
329
- count = filteredResults .size
339
+ values = items
340
+ count = items .size
330
341
}
331
342
}
332
343
0 commit comments