31
31
import com .vijay .jsonwizard .presenters .JsonFormFragmentPresenter ;
32
32
import com .vijay .jsonwizard .task .AttachRepeatingGroupTask ;
33
33
import com .vijay .jsonwizard .utils .FormUtils ;
34
+ import com .vijay .jsonwizard .utils .ValidationStatus ;
34
35
import com .vijay .jsonwizard .validators .edittext .MaxNumericValidator ;
35
36
import com .vijay .jsonwizard .validators .edittext .MinNumericValidator ;
36
37
import com .vijay .jsonwizard .validators .edittext .RequiredValidator ;
51
52
52
53
import static com .vijay .jsonwizard .constants .JsonFormConstants .FIELDS ;
53
54
import static com .vijay .jsonwizard .constants .JsonFormConstants .KEY ;
55
+ import static com .vijay .jsonwizard .constants .JsonFormConstants .OPENMRS_ENTITY ;
56
+ import static com .vijay .jsonwizard .constants .JsonFormConstants .OPENMRS_ENTITY_ID ;
57
+ import static com .vijay .jsonwizard .constants .JsonFormConstants .OPENMRS_ENTITY_PARENT ;
58
+ import static com .vijay .jsonwizard .constants .JsonFormConstants .TEXT ;
59
+ import static com .vijay .jsonwizard .constants .JsonFormConstants .TYPE ;
54
60
import static com .vijay .jsonwizard .constants .JsonFormConstants .VALUE ;
55
61
56
62
/**
59
65
public class RepeatingGroupFactory implements FormWidgetFactory {
60
66
61
67
private static Map <Integer , String > repeatingGroupLayouts = new HashMap <>();
62
- private final String REFERENCE_EDIT_TEXT_HINT = "reference_edit_text_hint" ;
68
+ public static final String REFERENCE_EDIT_TEXT_HINT = "reference_edit_text_hint" ;
63
69
private final String REPEATING_GROUP_LABEL = "repeating_group_label" ;
64
70
private final String REFERENCE_EDIT_TEXT = "reference_edit_text" ;
65
71
private final String REPEATING_GROUP_MAX = "repeating_group_max" ;
66
72
private final String REPEATING_GROUP_MIN = "repeating_group_min" ;
67
73
protected int MAX_NUM_REPEATING_GROUPS = 35 ;
68
74
protected int MIN_NUM_REPEATING_GROUPS = 0 ;
69
- private ImageButton doneButton ;
70
- private WidgetArgs widgetArgs ;
75
+
71
76
72
77
@ Override
73
78
public List <View > getViewsFromJson (final String stepName , final Context context , final JsonFormFragment formFragment , final JSONObject jsonObject , final CommonListener listener , final boolean popup ) throws Exception {
74
79
List <View > views = new ArrayList <>(1 );
75
80
LinearLayout rootLayout = getRootLayout (context );
76
81
77
82
final int rootLayoutId = View .generateViewId ();
78
- doneButton = rootLayout .findViewById (R .id .btn_repeating_group_done );
79
83
80
84
rootLayout .setId (rootLayoutId );
81
85
views .add (rootLayout );
82
86
83
87
JSONArray repeatingGroupLayout = jsonObject .getJSONArray (VALUE );
84
88
repeatingGroupLayouts .put (rootLayoutId , repeatingGroupLayout .toString ());
85
89
86
- this . widgetArgs = new WidgetArgs ()
90
+ final WidgetArgs widgetArgs = new WidgetArgs ()
87
91
.withStepName (stepName )
88
92
.withContext (context )
89
93
.withFormFragment (formFragment )
@@ -92,15 +96,19 @@ public List<View> getViewsFromJson(final String stepName, final Context context,
92
96
.withPopup (popup );
93
97
94
98
final MaterialEditText referenceEditText = rootLayout .findViewById (R .id .reference_edit_text );
99
+ final ImageButton doneButton = rootLayout .findViewById (R .id .btn_repeating_group_done );
100
+
95
101
final String referenceEditTextHint = jsonObject .optString (REFERENCE_EDIT_TEXT_HINT , context .getString (R .string .enter_number_of_repeating_group_items ));
96
102
final String repeatingGroupLabel = jsonObject .optString (REPEATING_GROUP_LABEL , context .getString (R .string .repeating_group_item ));
97
103
String remoteReferenceEditText = jsonObject .optString (REFERENCE_EDIT_TEXT );
98
104
99
- setRepeatingGroupNumLimits ();
105
+ setRepeatingGroupNumLimits (widgetArgs );
100
106
101
107
// Enables us to fetch this value from a previous edit_text & disable this one
102
- retrieveRepeatingGroupCountFromRemoteReferenceEditText (rootLayout , (JsonApi ) context , referenceEditText , remoteReferenceEditText );
103
- setUpReferenceEditText (referenceEditText , referenceEditTextHint , repeatingGroupLabel );
108
+ retrieveRepeatingGroupCountFromRemoteReferenceEditText (rootLayout , getJsonApi (widgetArgs ),
109
+ referenceEditText , remoteReferenceEditText , doneButton , widgetArgs );
110
+ setUpReferenceEditText (doneButton , referenceEditText , referenceEditTextHint ,
111
+ repeatingGroupLabel , getRepeatingGroupCountObj (widgetArgs ), widgetArgs );
104
112
105
113
// Disable the done button if the reference edit text being used is remote & has a valid value
106
114
if (isRemoteReferenceValueUsed (referenceEditText )) {
@@ -109,18 +117,46 @@ public List<View> getViewsFromJson(final String stepName, final Context context,
109
117
doneButton .setOnClickListener (new View .OnClickListener () {
110
118
@ Override
111
119
public void onClick (View v ) {
112
- addOnDoneAction (referenceEditText );
120
+ addOnDoneAction (referenceEditText , doneButton , widgetArgs );
113
121
}
114
122
});
115
123
}
116
124
117
125
((JsonApi ) context ).addFormDataView (referenceEditText );
118
- setViewTags (rootLayout );
119
- prepareViewChecks (rootLayout , context );
126
+ setViewTags (rootLayout , widgetArgs );
127
+ prepareViewChecks (rootLayout , context , widgetArgs );
120
128
121
129
return views ;
122
130
}
123
131
132
+ /**
133
+ * Returns the object that holds the repeating group count
134
+ *
135
+ * @return
136
+ * @throws JSONException
137
+ */
138
+ private JSONObject getRepeatingGroupCountObj (WidgetArgs widgetArgs ) throws JSONException {
139
+
140
+ String repeatingGroupCountObjKey = widgetArgs .getJsonObject ().get (KEY ) + "_count" ;
141
+ JSONArray stepFields = getStepFields (getJsonApi (widgetArgs ).getStep (widgetArgs .getStepName ()));
142
+ JSONObject repeatingGroupCountObj = FormUtils .getFieldJSONObject (stepFields , repeatingGroupCountObjKey );
143
+ // prevents re-adding the count object during form traversals
144
+ if (repeatingGroupCountObj != null ) {
145
+ return repeatingGroupCountObj ;
146
+ }
147
+
148
+ repeatingGroupCountObj = new JSONObject ();
149
+ repeatingGroupCountObj .put (KEY , repeatingGroupCountObjKey );
150
+ repeatingGroupCountObj .put (OPENMRS_ENTITY_PARENT , "" );
151
+ repeatingGroupCountObj .put (OPENMRS_ENTITY , "" );
152
+ repeatingGroupCountObj .put (OPENMRS_ENTITY_ID , "" );
153
+ repeatingGroupCountObj .put (TYPE , "" );
154
+ repeatingGroupCountObj .put (TEXT , widgetArgs .getJsonObject ().get (REFERENCE_EDIT_TEXT_HINT ));
155
+ stepFields .put (repeatingGroupCountObj );
156
+
157
+ return repeatingGroupCountObj ;
158
+ }
159
+
124
160
@ Override
125
161
public List <View > getViewsFromJson (final String stepName , Context context , JsonFormFragment formFragment , JSONObject jsonObject , CommonListener listener ) throws Exception {
126
162
return getViewsFromJson (stepName , context , formFragment , jsonObject , listener , false );
@@ -139,7 +175,7 @@ protected LinearLayout getRootLayout(Context context) {
139
175
/**
140
176
* Sets min and max number of repeating groups
141
177
*/
142
- private void setRepeatingGroupNumLimits () {
178
+ private void setRepeatingGroupNumLimits (WidgetArgs widgetArgs ) {
143
179
try {
144
180
MIN_NUM_REPEATING_GROUPS = widgetArgs .getJsonObject ().optInt (REPEATING_GROUP_MIN , MIN_NUM_REPEATING_GROUPS );
145
181
MAX_NUM_REPEATING_GROUPS = widgetArgs .getJsonObject ().optInt (REPEATING_GROUP_MAX , MAX_NUM_REPEATING_GROUPS );
@@ -148,7 +184,7 @@ private void setRepeatingGroupNumLimits() {
148
184
}
149
185
}
150
186
151
- private void setViewTags (@ NonNull LinearLayout rootLayout ) {
187
+ private void setViewTags (@ NonNull LinearLayout rootLayout , WidgetArgs widgetArgs ) {
152
188
JSONArray canvasIds = new JSONArray ();
153
189
canvasIds .put (rootLayout .getId ());
154
190
rootLayout .setTag (R .id .canvas_ids , canvasIds .toString ());
@@ -158,7 +194,7 @@ private void setViewTags(@NonNull LinearLayout rootLayout) {
158
194
rootLayout .setTag (R .id .address , widgetArgs .getStepName () + ":" + widgetArgs .getJsonObject ().optString (KEY ));
159
195
}
160
196
161
- private void prepareViewChecks (@ NonNull LinearLayout view , @ NonNull Context context ) {
197
+ private void prepareViewChecks (@ NonNull LinearLayout view , @ NonNull Context context , WidgetArgs widgetArgs ) {
162
198
String relevance = widgetArgs .getJsonObject ().optString (JsonFormConstants .RELEVANCE );
163
199
String constraints = widgetArgs .getJsonObject ().optString (JsonFormConstants .CONSTRAINTS );
164
200
String calculation = widgetArgs .getJsonObject ().optString (JsonFormConstants .CALCULATION );
@@ -179,7 +215,13 @@ private void prepareViewChecks(@NonNull LinearLayout view, @NonNull Context cont
179
215
}
180
216
}
181
217
182
- private void retrieveRepeatingGroupCountFromRemoteReferenceEditText (final @ NonNull View rootLayout , @ NonNull JsonApi context , @ NonNull final MaterialEditText referenceEditText , @ Nullable String remoteReferenceEditTextAddress ) throws JSONException {
218
+ private void retrieveRepeatingGroupCountFromRemoteReferenceEditText (final @ NonNull View rootLayout ,
219
+ @ NonNull JsonApi context ,
220
+ @ NonNull final MaterialEditText referenceEditText ,
221
+ @ Nullable String remoteReferenceEditTextAddress ,
222
+ @ NonNull final ImageButton doneButton ,
223
+ @ NonNull final WidgetArgs widgetArgs ) throws JSONException {
224
+
183
225
if (!TextUtils .isEmpty (remoteReferenceEditTextAddress ) && remoteReferenceEditTextAddress .contains (":" )) {
184
226
String finalRemoteReferenceEditTextAddress = remoteReferenceEditTextAddress .trim ();
185
227
String [] addressSections = finalRemoteReferenceEditTextAddress .split (":" );
@@ -190,7 +232,7 @@ private void retrieveRepeatingGroupCountFromRemoteReferenceEditText(final @NonNu
190
232
JSONObject stepJsonObject = context .getmJSONObject ().optJSONObject (remoteReferenceEditTextStep );
191
233
192
234
if (stepJsonObject != null ) {
193
- JSONArray fields = stepJsonObject . optJSONArray ( FIELDS );
235
+ JSONArray fields = getStepFields ( stepJsonObject );
194
236
195
237
for (int i = 0 ; i < fields .length (); i ++) {
196
238
JSONObject stepField = fields .optJSONObject (i );
@@ -205,9 +247,11 @@ private void retrieveRepeatingGroupCountFromRemoteReferenceEditText(final @NonNu
205
247
// Start the repeating groups
206
248
Object visibilityTag = rootLayout .getTag (R .id .relevance_decided );
207
249
if (visibilityTag != null && (boolean ) visibilityTag ) {
208
- attachRepeatingGroup (referenceEditText .getParent ().getParent (), remoteReferenceValue );
250
+ attachRepeatingGroup (referenceEditText .getParent ().getParent (),
251
+ remoteReferenceValue , doneButton , widgetArgs );
209
252
} else {
210
- setGlobalLayoutListener (rootLayout , referenceEditText , remoteReferenceValue );
253
+ setGlobalLayoutListener (rootLayout , referenceEditText ,
254
+ remoteReferenceValue , doneButton , widgetArgs );
211
255
}
212
256
} catch (NumberFormatException ex ) {
213
257
Timber .e (ex );
@@ -221,22 +265,33 @@ private void retrieveRepeatingGroupCountFromRemoteReferenceEditText(final @NonNu
221
265
}
222
266
223
267
@ VisibleForTesting
224
- protected void setGlobalLayoutListener (@ NonNull final View rootLayout , @ NonNull final MaterialEditText referenceEditText , final int remoteReferenceValue ) {
268
+ protected void setGlobalLayoutListener (@ NonNull final View rootLayout ,
269
+ @ NonNull final MaterialEditText referenceEditText ,
270
+ @ NonNull final int remoteReferenceValue ,
271
+ @ NonNull final ImageButton doneButton ,
272
+ @ NonNull final WidgetArgs widgetArgs ) {
273
+
225
274
rootLayout .getViewTreeObserver ().addOnGlobalLayoutListener (new ViewTreeObserver .OnGlobalLayoutListener () {
226
275
227
276
@ Override
228
277
public void onGlobalLayout () {
229
278
Object visibilityTag = rootLayout .getTag (R .id .relevance_decided );
230
279
if (visibilityTag != null && (boolean ) visibilityTag ) {
231
- attachRepeatingGroup (referenceEditText .getParent ().getParent (), remoteReferenceValue );
280
+ attachRepeatingGroup (referenceEditText .getParent ().getParent (),
281
+ remoteReferenceValue , doneButton , widgetArgs );
232
282
233
283
rootLayout .getViewTreeObserver ().removeOnGlobalLayoutListener (this );
234
284
}
235
285
}
236
286
});
237
287
}
238
288
239
- private void setUpReferenceEditText (final MaterialEditText referenceEditText , String referenceEditTextHint , String repeatingGroupLabel ) throws JSONException {
289
+ private void setUpReferenceEditText (final ImageButton doneButton ,
290
+ final MaterialEditText referenceEditText ,
291
+ final String referenceEditTextHint ,
292
+ final String repeatingGroupLabel ,
293
+ final JSONObject repeatingGroupCount ,
294
+ final WidgetArgs widgetArgs ) throws JSONException {
240
295
// We should disable this edit_text if another referenced edit text is being used
241
296
Context context = widgetArgs .getContext ();
242
297
if (isRemoteReferenceValueUsed (referenceEditText )) {
@@ -246,7 +301,7 @@ private void setUpReferenceEditText(final MaterialEditText referenceEditText, St
246
301
@ Override
247
302
public boolean onEditorAction (TextView focusTextView , int actionId , KeyEvent event ) {
248
303
if (actionId == EditorInfo .IME_ACTION_DONE ) {
249
- addOnDoneAction (focusTextView );
304
+ addOnDoneAction (focusTextView , doneButton , widgetArgs );
250
305
return true ;
251
306
}
252
307
return false ;
@@ -255,7 +310,7 @@ public boolean onEditorAction(TextView focusTextView, int actionId, KeyEvent eve
255
310
}
256
311
257
312
referenceEditText .setTag (R .id .address , widgetArgs .getStepName () + ":" + widgetArgs .getJsonObject ().getString (KEY ));
258
- attachTextChangedListener (referenceEditText );
313
+ attachTextChangedListener (referenceEditText , doneButton , repeatingGroupCount , widgetArgs );
259
314
referenceEditText .setHint (referenceEditTextHint );
260
315
referenceEditText .setTag (R .id .repeating_group_label , repeatingGroupLabel );
261
316
referenceEditText .setTag (R .id .extraPopup , false );
@@ -274,7 +329,11 @@ public boolean onEditorAction(TextView focusTextView, int actionId, KeyEvent eve
274
329
}
275
330
}
276
331
277
- private void attachTextChangedListener (final MaterialEditText referenceEditText ) {
332
+ private void attachTextChangedListener (final MaterialEditText referenceEditText ,
333
+ final ImageButton doneButton ,
334
+ final JSONObject repeatingGroupCount ,
335
+ final WidgetArgs widgetArgs ) {
336
+
278
337
referenceEditText .addTextChangedListener (new TextWatcher () {
279
338
@ Override
280
339
public void beforeTextChanged (CharSequence s , int start , int count , int after ) {
@@ -289,11 +348,23 @@ public void onTextChanged(CharSequence s, int start, int before, int count) {
289
348
@ Override
290
349
public void afterTextChanged (Editable s ) {
291
350
doneButton .setImageResource (R .drawable .ic_done_grey );
292
- JsonFormFragmentPresenter .validate (widgetArgs .getFormFragment (), referenceEditText , false );
351
+ ValidationStatus validationStatus = JsonFormFragmentPresenter
352
+ .validate (widgetArgs .getFormFragment (), referenceEditText , false );
353
+ if (validationStatus .isValid ()) {
354
+ writeJsonObjectValue (repeatingGroupCount , s .toString ());
355
+ }
293
356
}
294
357
});
295
358
}
296
359
360
+ private void writeJsonObjectValue (JSONObject jsonObject , String value ) {
361
+ try {
362
+ jsonObject .put (VALUE , value );
363
+ } catch (JSONException e ) {
364
+ Timber .e (e );
365
+ }
366
+ }
367
+
297
368
private void addRequiredValidator (JSONObject jsonObject , MaterialEditText editText ) throws JSONException {
298
369
JSONObject requiredObject = jsonObject .optJSONObject (JsonFormConstants .V_REQUIRED );
299
370
if (requiredObject != null ) {
@@ -305,23 +376,26 @@ private void addRequiredValidator(JSONObject jsonObject, MaterialEditText editTe
305
376
}
306
377
}
307
378
308
- protected void addOnDoneAction (TextView textView ) {
379
+ protected void addOnDoneAction (final TextView textView , final ImageButton doneButton , final WidgetArgs widgetArgs ) {
309
380
try {
310
381
InputMethodManager inputMethodManager = (InputMethodManager ) widgetArgs .getFormFragment ().getContext ().getSystemService (Context .INPUT_METHOD_SERVICE );
311
382
inputMethodManager .hideSoftInputFromWindow (textView .getWindowToken (), 0 );
312
383
textView .clearFocus ();
313
- attachRepeatingGroup (textView .getParent ().getParent (), Integer .parseInt (textView .getText ().toString ()));
384
+ attachRepeatingGroup (textView .getParent ().getParent (),
385
+ Integer .parseInt (textView .getText ().toString ()), doneButton , widgetArgs );
314
386
} catch (Exception e ) {
315
387
Timber .e (e );
316
388
}
317
389
}
318
390
319
- private void attachRepeatingGroup (final ViewParent parent , final int numRepeatingGroups ) {
391
+ private void attachRepeatingGroup (final ViewParent parent , final int numRepeatingGroups ,
392
+ final ImageButton doneButton , final WidgetArgs widgetArgs ) {
320
393
if (numRepeatingGroups > MAX_NUM_REPEATING_GROUPS ) {
321
394
return ;
322
395
}
323
396
324
- new AttachRepeatingGroupTask (parent , numRepeatingGroups , repeatingGroupLayouts , widgetArgs , doneButton ).execute ();
397
+ new AttachRepeatingGroupTask (parent , numRepeatingGroups , repeatingGroupLayouts ,
398
+ widgetArgs , doneButton ).execute ();
325
399
}
326
400
327
401
protected int getLayout () {
@@ -337,4 +411,13 @@ public int remoteReferenceValue(@NonNull View referenceEditText) {
337
411
Object tagValue = referenceEditText .getTag (R .id .repeating_group_remote_reference_value );
338
412
return tagValue instanceof Integer ? (int ) tagValue : 0 ;
339
413
}
414
+
415
+ private JsonApi getJsonApi (WidgetArgs widgetArgs ) {
416
+ Context context = widgetArgs .getContext ();
417
+ return context instanceof JsonApi ? (JsonApi ) context : null ;
418
+ }
419
+
420
+ private JSONArray getStepFields (JSONObject step ) {
421
+ return step .optJSONArray (FIELDS );
422
+ }
340
423
}
0 commit comments