Skip to content
This repository was archived by the owner on May 5, 2021. It is now read-only.

Commit ada7909

Browse files
SORMAS-Foundation#2963: Allow resetting OptionGroup fields to null
1 parent 8e77121 commit ada7909

43 files changed

Lines changed: 375 additions & 232 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

sormas-app/app/src/main/java/de/symeda/sormas/app/component/controls/ControlSwitchField.java

Lines changed: 29 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ public class ControlSwitchField extends ControlPropertyEditField<Object> {
5151
// Constants
5252

5353
private static final String RADIO_BUTTON_FONT_FAMILY = "sans-serif-medium";
54+
private Object valueBeforeChange = null;
5455

5556
// Views
5657

@@ -60,6 +61,7 @@ public class ControlSwitchField extends ControlPropertyEditField<Object> {
6061

6162
private boolean useAbbreviations;
6263
private boolean useBoolean;
64+
private boolean nullable;
6365
private Drawable background;
6466
private ColorStateList textColor;
6567

@@ -198,7 +200,7 @@ private RadioButton createRadioButton(int index, int lastIndex, Item item) {
198200
button.setText(btnKey);
199201
}
200202

201-
setUpOnClickListener(button);
203+
setUpOnClickListener(button, this);
202204

203205
return button;
204206
}
@@ -211,20 +213,21 @@ private Drawable getButtonDrawable(boolean lastButton, boolean hasError) {
211213
.build();
212214
}
213215

214-
private void setUpOnClickListener(RadioButton button) {
215-
button.setOnClickListener(new OnClickListener() {
216+
private void setUpOnClickListener(RadioButton button, ControlSwitchField field) {
217+
button.setOnClickListener(v -> {
218+
if (!v.isEnabled()) {
219+
return;
220+
}
216221

217-
@Override
218-
public void onClick(View v) {
219-
if (!v.isEnabled()) {
220-
return;
221-
}
222+
if (nullable && (valueBeforeChange == getValue() || (valueBeforeChange != null && valueBeforeChange.equals(getValue())))) {
223+
setValue(null);
224+
}
225+
valueBeforeChange = getValue();
222226

223-
showOrHideNotifications(v.hasFocus());
227+
showOrHideNotifications(v.hasFocus());
224228

225-
input.requestFocus();
226-
input.requestFocusFromTouch();
227-
}
229+
input.requestFocus();
230+
input.requestFocusFromTouch();
228231
});
229232
}
230233

@@ -238,6 +241,7 @@ protected void initialize(Context context, AttributeSet attrs, int defStyle) {
238241
try {
239242
useAbbreviations = a.getBoolean(R.styleable.ControlSwitchField_useAbbreviations, isSlim());
240243
useBoolean = a.getBoolean(R.styleable.ControlSwitchField_useBoolean, false);
244+
nullable = a.getBoolean(R.styleable.ControlSwitchField_nullable, true);
241245
} finally {
242246
a.recycle();
243247
}
@@ -275,23 +279,19 @@ protected void onFinishInflate() {
275279
setEnumClass(YesNoUnknown.class);
276280
}
277281

278-
input.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
279-
280-
@Override
281-
public void onCheckedChanged(RadioGroup radioGroup, int i) {
282-
if (inverseBindingListener != null) {
283-
inverseBindingListener.onChange();
284-
}
282+
input.setOnCheckedChangeListener((radioGroup, i) -> {
283+
if (inverseBindingListener != null) {
284+
inverseBindingListener.onChange();
285+
}
285286

286-
// on checked changed is also called when other button is deselected before new button is selected
287-
RadioButton radioButton = (RadioButton) radioGroup.getChildAt(i);
288-
if (radioButton == null || radioButton.isChecked()) {
289-
onValueChanged();
290-
}
287+
// on checked changed is also called when other button is deselected before new button is selected
288+
RadioButton radioButton = (RadioButton) radioGroup.getChildAt(i);
289+
if (radioButton == null || radioButton.isChecked()) {
290+
onValueChanged();
291+
}
291292

292-
if (onCheckedChangeListener != null && !suppressListeners) {
293-
onCheckedChangeListener.onCheckedChanged(radioGroup, i);
294-
}
293+
if (onCheckedChangeListener != null && !suppressListeners) {
294+
onCheckedChangeListener.onCheckedChanged(radioGroup, i);
295295
}
296296
});
297297
}
@@ -315,6 +315,8 @@ protected Object getFieldValue() {
315315

316316
@Override
317317
protected void setFieldValue(Object value) {
318+
valueBeforeChange = value;
319+
318320
if (value == null) {
319321
input.clearCheck();
320322
} else {

sormas-app/app/src/main/res/layout/fragment_case_edit_health_conditions_layout.xml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
<?xml version="1.0" encoding="utf-8"?>
2-
<!--
1+
<?xml version="1.0" encoding="utf-8"?><!--
32
~ SORMAS® - Surveillance Outbreak Response Management & Analysis System
43
~ Copyright © 2016-2018 Helmholtz-Zentrum für Infektionsforschung GmbH (HZI)
54
~
@@ -23,9 +22,12 @@
2322
android:id="@+id/base_layout">
2423

2524
<data>
25+
2626
<import type="de.symeda.sormas.api.utils.YesNoUnknown" />
2727

28-
<variable name="data" type="de.symeda.sormas.app.backend.clinicalcourse.HealthConditions" />
28+
<variable
29+
name="data"
30+
type="de.symeda.sormas.app.backend.clinicalcourse.HealthConditions" />
2931
</data>
3032

3133
<ScrollView

sormas-app/app/src/main/res/layout/fragment_case_new_layout.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
android:id="@+id/caseData_caseOrigin"
5151
style="@style/ControlSingleColumnStyle"
5252
app:enumClass="@{caseOriginClass}"
53+
app:nullable="false"
5354
app:required="true"
5455
app:value="@={data.caseOrigin}" />
5556

sormas-app/app/src/main/res/layout/fragment_report_weekly_layout.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
android:layout_width="match_parent"
6060
android:layout_height="wrap_content"
6161
app:enumClass="@{reportFilterOptionClass}"
62+
app:nullable="false"
6263
app:showCaption="false" />
6364

6465
<LinearLayout

sormas-app/app/src/main/res/layout/fragment_reports_aggregate_layout.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
android:layout_width="match_parent"
6060
android:layout_height="wrap_content"
6161
app:enumClass="@{reportFilterOptionClass}"
62+
app:nullable="false"
6263
app:showCaption="false" />
6364

6465
<LinearLayout

sormas-app/app/src/main/res/values/attrs.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@
7272
<attr name="includeUnknown" format="reference|boolean" />
7373
<attr name="useAbbreviations" format="boolean" />
7474
<attr name="useBoolean" format="boolean" />
75+
<attr name="nullable" format="boolean" />
7576

7677
<attr name="value" format="string" />
7778
<attr name="valueFormat" format="reference" />
@@ -168,6 +169,7 @@
168169
<declare-styleable name="ControlSwitchField">
169170
<attr name="useAbbreviations" />
170171
<attr name="useBoolean" />
172+
<attr name="nullable" />
171173
</declare-styleable>
172174

173175

sormas-ui/src/main/java/de/symeda/sormas/ui/action/ActionEditForm.java

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525

2626
import com.vaadin.v7.ui.ComboBox;
2727
import com.vaadin.v7.ui.Label;
28-
import com.vaadin.v7.ui.OptionGroup;
2928
import com.vaadin.v7.ui.RichTextArea;
3029
import com.vaadin.v7.ui.TextField;
3130

@@ -40,6 +39,7 @@
4039
import de.symeda.sormas.ui.utils.DateFormatHelper;
4140
import de.symeda.sormas.ui.utils.DateTimeField;
4241
import de.symeda.sormas.ui.utils.FieldHelper;
42+
import de.symeda.sormas.ui.utils.NullableOptionGroup;
4343

4444
public class ActionEditForm extends AbstractEditForm<ActionDto> {
4545

@@ -87,8 +87,8 @@ protected void addFields() {
8787
DateTimeField date = addDateField(ActionDto.DATE, DateTimeField.class, -1);
8888
date.setImmediate(true);
8989
addField(ActionDto.PRIORITY, ComboBox.class);
90-
addField(ActionDto.ACTION_STATUS, OptionGroup.class);
91-
OptionGroup actionContext = addField(ActionDto.ACTION_CONTEXT, OptionGroup.class);
90+
addField(ActionDto.ACTION_STATUS, NullableOptionGroup.class);
91+
NullableOptionGroup actionContext = addField(ActionDto.ACTION_CONTEXT, NullableOptionGroup.class);
9292
actionContext.setImmediate(true);
9393
actionContext.addValueChangeListener(event -> updateByActionContext());
9494
// XXX: set visible when other contexts will be managed
@@ -109,7 +109,8 @@ protected void addFields() {
109109

110110
private void updateReplyInfo() {
111111
if (getValue().getReplyingUser() != null && getValue().getChangeDate() != null) {
112-
Label replyLabel = new Label(String.format(
112+
Label replyLabel = new Label(
113+
String.format(
113114
I18nProperties.getCaption(Captions.actionReplyingLabel),
114115
DateFormatHelper.formatDate(getValue().getChangeDate()),
115116
getValue().getReplyingUser().getCaption()));
@@ -120,7 +121,8 @@ private void updateReplyInfo() {
120121

121122
private void updateStatusChangeInfo() {
122123
if (getValue().getStatusChangeDate() != null) {
123-
Label statusChangeLabel = new Label(String.format(
124+
Label statusChangeLabel = new Label(
125+
String.format(
124126
I18nProperties.getCaption(Captions.actionStatusChangeDate),
125127
DateFormatHelper.formatDate(getValue().getStatusChangeDate())));
126128
statusChangeLabel.addStyleNames(CssStyles.LABEL_ITALIC);
@@ -129,7 +131,8 @@ private void updateStatusChangeInfo() {
129131
}
130132

131133
private void updateCreationInfo() {
132-
Label creationLabel = new Label(String.format(
134+
Label creationLabel = new Label(
135+
String.format(
133136
I18nProperties.getCaption(Captions.actionCreatingLabel),
134137
DateFormatHelper.formatDate(getValue().getCreationDate()),
135138
getValue().getCreatorUser().getCaption()));
@@ -172,7 +175,7 @@ private void updateByActionContext() {
172175
}
173176
} else {
174177
FieldHelper.setFirstVisibleClearOthers(null, eventField);
175-
FieldHelper.setFirstRequired(null, eventField);
178+
FieldHelper.setFirstRequired(null, eventField);
176179
}
177180
}
178181

sormas-ui/src/main/java/de/symeda/sormas/ui/campaign/campaigndata/CampaignFormBuilder.java

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@
1515

1616
package de.symeda.sormas.ui.campaign.campaigndata;
1717

18-
import static com.vaadin.server.Sizeable.Unit;
19-
2018
import java.util.ArrayList;
2119
import java.util.Arrays;
2220
import java.util.HashMap;
@@ -36,7 +34,6 @@
3634
import com.vaadin.v7.shared.ui.label.ContentMode;
3735
import com.vaadin.v7.ui.Field;
3836
import com.vaadin.v7.ui.Label;
39-
import com.vaadin.v7.ui.OptionGroup;
4037
import com.vaadin.v7.ui.TextField;
4138

4239
import de.symeda.sormas.api.campaign.data.CampaignFormDataEntry;
@@ -49,18 +46,11 @@
4946
import de.symeda.sormas.api.i18n.Validations;
5047
import de.symeda.sormas.api.utils.fieldvisibility.FieldVisibilityCheckers;
5148
import de.symeda.sormas.ui.utils.CssStyles;
49+
import de.symeda.sormas.ui.utils.NullableOptionGroup;
5250
import de.symeda.sormas.ui.utils.NumberValidator;
5351
import de.symeda.sormas.ui.utils.SormasFieldGroupFieldFactory;
5452
import de.symeda.sormas.ui.utils.UiFieldAccessCheckers;
5553

56-
import java.util.ArrayList;
57-
import java.util.Arrays;
58-
import java.util.HashMap;
59-
import java.util.List;
60-
import java.util.Locale;
61-
import java.util.Map;
62-
import java.util.stream.Collectors;
63-
6454
public class CampaignFormBuilder {
6555

6656
private final List<CampaignFormElement> formElements;
@@ -197,7 +187,7 @@ private <T extends Field<?>> T createField(String fieldId, String caption, Campa
197187

198188
T field;
199189
if (type == CampaignFormElementType.YES_NO) {
200-
field = fieldFactory.createField(Boolean.class, (Class<T>) OptionGroup.class);
190+
field = fieldFactory.createField(Boolean.class, (Class<T>) NullableOptionGroup.class);
201191
} else if (type == CampaignFormElementType.TEXT || type == CampaignFormElementType.NUMBER) {
202192
field = fieldFactory.createField(String.class, (Class<T>) TextField.class);
203193
} else {
@@ -281,10 +271,10 @@ private float calculateComponentWidth(CampaignFormElementType type, List<Campaig
281271
private <T extends Field<?>> void setFieldValue(T field, CampaignFormElementType type, Object value) {
282272
switch (type) {
283273
case YES_NO:
284-
((OptionGroup) field).setValue(value instanceof Boolean ? (Boolean) value : null);
274+
((NullableOptionGroup) field).setValue(value instanceof Boolean ? (Boolean) value : null);
285275
break;
286276
case TEXT:
287-
case NUMBER:
277+
case NUMBER:
288278
((TextField) field).setValue(value != null ? value.toString() : null);
289279
break;
290280
default:
@@ -318,7 +308,7 @@ private boolean fieldValueMatchesDependingOnValues(Field<?> dependingOnField, Li
318308
return false;
319309
}
320310

321-
if (dependingOnField instanceof OptionGroup) {
311+
if (dependingOnField instanceof NullableOptionGroup) {
322312
String booleanValue = Boolean.TRUE.equals(dependingOnField.getValue()) ? "true" : "false";
323313
String stringValue = Boolean.TRUE.equals(dependingOnField.getValue()) ? "yes" : "no";
324314

sormas-ui/src/main/java/de/symeda/sormas/ui/caze/BulkCaseDataForm.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030

3131
import com.vaadin.v7.ui.CheckBox;
3232
import com.vaadin.v7.ui.ComboBox;
33-
import com.vaadin.v7.ui.OptionGroup;
3433
import com.vaadin.v7.ui.TextField;
3534

3635
import de.symeda.sormas.api.Disease;
@@ -48,6 +47,7 @@
4847
import de.symeda.sormas.api.user.UserRole;
4948
import de.symeda.sormas.ui.utils.AbstractEditForm;
5049
import de.symeda.sormas.ui.utils.FieldHelper;
50+
import de.symeda.sormas.ui.utils.NullableOptionGroup;
5151

5252
public class BulkCaseDataForm extends AbstractEditForm<CaseBulkEditData> {
5353

@@ -123,9 +123,9 @@ protected void addFields() {
123123
ComboBox disease = addDiseaseField(CaseDataDto.DISEASE, false);
124124
disease.setEnabled(false);
125125
addField(CaseDataDto.DISEASE_DETAILS, TextField.class);
126-
addField(CaseDataDto.PLAGUE_TYPE, OptionGroup.class);
127-
addField(CaseDataDto.DENGUE_FEVER_TYPE, OptionGroup.class);
128-
addField(CaseDataDto.RABIES_TYPE, OptionGroup.class);
126+
addField(CaseDataDto.PLAGUE_TYPE, NullableOptionGroup.class);
127+
addField(CaseDataDto.DENGUE_FEVER_TYPE, NullableOptionGroup.class);
128+
addField(CaseDataDto.RABIES_TYPE, NullableOptionGroup.class);
129129

130130
if (isVisibleAllowed(CaseDataDto.DISEASE_DETAILS)) {
131131
FieldHelper
@@ -156,11 +156,11 @@ protected void addFields() {
156156
getContent().addComponent(investigationStatusCheckBox, INVESTIGATION_STATUS_CHECKBOX);
157157
outcomeCheckBox = new CheckBox(I18nProperties.getCaption(Captions.bulkCaseOutcome));
158158
getContent().addComponent(outcomeCheckBox, OUTCOME_CHECKBOX);
159-
OptionGroup caseClassification = addField(CaseBulkEditData.CASE_CLASSIFICATION, OptionGroup.class);
159+
NullableOptionGroup caseClassification = addField(CaseBulkEditData.CASE_CLASSIFICATION, NullableOptionGroup.class);
160160
caseClassification.setEnabled(false);
161-
OptionGroup investigationStatus = addField(CaseBulkEditData.INVESTIGATION_STATUS, OptionGroup.class);
161+
NullableOptionGroup investigationStatus = addField(CaseBulkEditData.INVESTIGATION_STATUS, NullableOptionGroup.class);
162162
investigationStatus.setEnabled(false);
163-
OptionGroup outcome = addField(CaseBulkEditData.OUTCOME, OptionGroup.class);
163+
NullableOptionGroup outcome = addField(CaseBulkEditData.OUTCOME, NullableOptionGroup.class);
164164
outcome.setEnabled(false);
165165

166166
if (singleSelectedDistrict != null) {

0 commit comments

Comments
 (0)