Skip to content

Commit 2c9ee17

Browse files
committed
Added generic error handler.
1 parent c8861f2 commit 2c9ee17

File tree

10 files changed

+278
-217
lines changed

10 files changed

+278
-217
lines changed

app/src/main/java/ext/sample/SimpleFormFragment.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import android.view.ViewGroup;
99
import android.widget.EditText;
1010
import android.widget.RadioGroup;
11+
import android.widget.TextView;
1112

1213
import org.joda.time.DateTime;
1314

@@ -19,10 +20,11 @@
1920
import ext.extensions.forms.Condition;
2021
import ext.extensions.forms.DateMultiInput;
2122
import ext.extensions.forms.Form;
22-
import ext.extensions.forms.Forms.FormBuilder;
23+
import ext.extensions.forms.FormBuilder;
2324
import ext.extensions.forms.Mapping;
2425
import ext.extensions.forms.StringInput;
2526
import ext.extensions.forms.ValidationException;
27+
import ext.extensions.forms.ViewErrorHandler;
2628
import ext.sample.SimpleFormFragment.User.Gender;
2729

2830

@@ -53,7 +55,7 @@ public void onViewCreated(View view, Bundle savedInstanceState) {
5355
@Override
5456
public boolean verify(DateTime value) {
5557
// at least 18
56-
return value.isAfter(DateTime.now().minusYears(18));
58+
return value.isBefore(DateTime.now().minusYears(18));
5759
}
5860
}, R.string.birthday_error));
5961
builder.addViewAndInput((RadioGroup) view.findViewById(R.id.gender),
@@ -76,6 +78,7 @@ public String unbind(Gender value) {
7678
return value.name();
7779
}
7880
}));
81+
builder.addErrorHandler(new ViewErrorHandler((TextView) view.findViewById(R.id.birthday_error)), "birthday");
7982

8083
mForm = builder.build(new Mapping<Map<String, Object>, User>() {
8184
@Override

app/src/main/res/layout/fragment_simple_form.xml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,16 @@
7070

7171
</LinearLayout>
7272

73+
<ext.TextView
74+
android:id="@+id/birthday_error"
75+
android:layout_width="match_parent"
76+
android:layout_height="wrap_content"
77+
android:layout_marginTop="8dp"
78+
android:background="@color/error"
79+
android:textColor="@android:color/white"
80+
android:textSize="12sp"
81+
android:visibility="gone"/>
82+
7383
<ext.Button
7484
android:id="@+id/submit"
7585
android:layout_width="wrap_content"
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package ext.extensions.forms;
2+
3+
import android.widget.EditText;
4+
5+
/**
6+
* Created by evelina on 21/09/14.
7+
*/
8+
public class EditTextErrorHandler implements ErrorHandler {
9+
10+
public final EditText view;
11+
12+
public EditTextErrorHandler(EditText view) {
13+
this.view = view;
14+
}
15+
16+
@Override
17+
public void onError(ValidationFailure[] failures) {
18+
view.setError(failures[0].getMessage(view.getContext()));
19+
}
20+
}

lib/src/main/java/ext/extensions/forms/Form.java

Lines changed: 14 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@
99
import java.util.Map;
1010
import java.util.Map.Entry;
1111

12-
import ext.extensions.forms.Forms.ViewExtractor;
13-
1412
import static android.text.TextUtils.*;
1513

1614
/**
@@ -20,10 +18,12 @@ public abstract class Form<T> {
2018

2119
public final Input<?>[] inputs;
2220
public final Map<String, ViewPair<?>> views;
21+
public final Map<String, ErrorHandler[]> errorHandlers;
2322

24-
protected Form(Input<?>[] inputs, Map<String, ViewPair<?>> views) {
23+
protected Form(Input<?>[] inputs, Map<String, ViewPair<?>> views, Map<String, ErrorHandler[]> errorHandlers) {
2524
this.inputs = inputs;
2625
this.views = views;
26+
this.errorHandlers = errorHandlers;
2727
}
2828

2929
public T bind() throws ValidationException {
@@ -51,9 +51,11 @@ private void onValidationError(ValidationException e) {
5151
for (Entry<String, List<ValidationFailure>> entry : failureMap.entrySet()) {
5252
String key = entry.getKey();
5353
if (!isEmpty(key)) {
54-
ViewPair<?> viewPair = views.get(key);
55-
if (viewPair != null) {
56-
viewPair.onError(entry.getValue());
54+
ErrorHandler[] handlers = errorHandlers.get(key);
55+
if (handlers != null) {
56+
for (ErrorHandler h : handlers) {
57+
h.onError(entry.getValue().toArray(new ValidationFailure[entry.getValue().size()]));
58+
}
5759
}
5860
}
5961
}
@@ -62,24 +64,10 @@ private void onValidationError(ValidationException e) {
6264
public abstract T bind(Map<String, String> data) throws ValidationException;
6365
}
6466

65-
class SingleForm<T> extends Form<T> {
66-
67-
SingleForm(final Input<T> input, final ViewPair<?> view) {
68-
super(new Input[]{input}, new HashMap<String, ViewPair<?>>() {{
69-
put(input.key, view);
70-
}});
71-
}
72-
73-
@Override
74-
public T bind(Map<String, String> data) throws ValidationException {
75-
return (T) data.get(inputs[0].key);
76-
}
77-
}
78-
7967
class MapForm extends Form<Map<String, Object>> {
8068

81-
MapForm(Input<?>[] inputs, Map<String, ViewPair<?>> views) {
82-
super(inputs, views);
69+
MapForm(Input<?>[] inputs, Map<String, ViewPair<?>> views, Map<String, ErrorHandler[]> errorHandlers) {
70+
super(inputs, views, errorHandlers);
8371
}
8472

8573
@Override
@@ -102,10 +90,10 @@ class ObjectForm<T> extends Form<T> {
10290
public final Mapping<Map<String, Object>, T> mapping;
10391
private final MapForm mMapForm;
10492

105-
ObjectForm(Mapping<Map<String, Object>, T> mapping, Input<?>[] inputs, Map<String, ViewPair<?>> views) {
106-
super(inputs, views);
93+
ObjectForm(Mapping<Map<String, Object>, T> mapping, Input<?>[] inputs, Map<String, ViewPair<?>> views, Map<String, ErrorHandler[]> errorHandlers) {
94+
super(inputs, views, errorHandlers);
10795
this.mapping = mapping;
108-
mMapForm = new MapForm(inputs, views);
96+
mMapForm = new MapForm(inputs, views, errorHandlers);
10997
}
11098

11199
@Override
@@ -117,19 +105,13 @@ public T bind(Map<String, String> data) throws ValidationException {
117105
class ViewPair<V extends View> {
118106
public final V view;
119107
public final ViewExtractor<? super V> extractor;
120-
public final ViewErrorHandler<? super V> errorHandler;
121108

122-
ViewPair(V view, ViewExtractor<? super V> extractor, ViewErrorHandler<? super V> errorHandler) {
109+
ViewPair(V view, ViewExtractor<? super V> extractor) {
123110
this.view = view;
124111
this.extractor = extractor;
125-
this.errorHandler = errorHandler;
126112
}
127113

128114
public String get() {
129115
return extractor.get(view);
130116
}
131-
132-
public void onError(List<ValidationFailure> failures) {
133-
errorHandler.onError(view, failures.toArray(new ValidationFailure[failures.size()]));
134-
}
135117
}
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
package ext.extensions.forms;
2+
3+
import android.view.View;
4+
import android.widget.CompoundButton;
5+
import android.widget.EditText;
6+
import android.widget.RadioGroup;
7+
import android.widget.TextView;
8+
9+
import java.util.ArrayList;
10+
import java.util.HashMap;
11+
import java.util.HashSet;
12+
import java.util.List;
13+
import java.util.Map;
14+
import java.util.Map.Entry;
15+
import java.util.Set;
16+
17+
import static ext.extensions.forms.ViewExtractor.*;
18+
19+
/**
20+
* Created by evelina on 21/09/14.
21+
*/
22+
public class FormBuilder {
23+
24+
private Set<Input<?>> mInputs = new HashSet<>();
25+
private Map<String, ViewPair<?>> mViewMap = new HashMap<>();
26+
private Map<String, List<ErrorHandler>> mErrorHandlers = new HashMap<>();
27+
28+
private Input<?>[] toArray() {
29+
return mInputs.toArray(new Input<?>[mInputs.size()]);
30+
}
31+
32+
private Map<String, ErrorHandler[]> toErrorHandlerArray() {
33+
Map<String, ErrorHandler[]> map = new HashMap<>();
34+
for (Entry<String, List<ErrorHandler>> entry : mErrorHandlers.entrySet()) {
35+
List<ErrorHandler> v = entry.getValue();
36+
map.put(entry.getKey(), v.toArray(new ErrorHandler[v.size()]));
37+
}
38+
return map;
39+
}
40+
41+
public synchronized FormBuilder addInput(Input<?> input) {
42+
mInputs.add(input);
43+
return this;
44+
}
45+
46+
public synchronized <V extends View> FormBuilder addView(String key, V view, ViewExtractor<? super V> extractor, ErrorHandler errorHandler) {
47+
mViewMap.put(key, new ViewPair<V>(view, extractor));
48+
addErrorHandler(errorHandler, key);
49+
return this;
50+
}
51+
52+
public synchronized FormBuilder addView(String key, TextView view) {
53+
return addView(key, view, TEXT_VIEW_EXTRACTOR, new TextErrorHandler(view));
54+
}
55+
56+
public synchronized FormBuilder addView(String key, EditText view) {
57+
return addView(key, view, TEXT_VIEW_EXTRACTOR, new EditTextErrorHandler(view));
58+
}
59+
60+
public synchronized FormBuilder addView(String key, RadioGroup view) {
61+
return addView(key, view, RADIO_GROUP_EXTRACTOR, new RadioGroupErrorHandler(view));
62+
}
63+
64+
public synchronized FormBuilder addView(String key, CompoundButton view) {
65+
return addView(key, view, COMPOUND_BUTTON_EXTRACTOR, new TextErrorHandler(view));
66+
}
67+
68+
public synchronized <V extends View> FormBuilder addViewAndInput(V view, ViewExtractor<? super V> extractor, ErrorHandler errorHandler, Input<?> input) {
69+
addView(input.key, view, extractor, errorHandler);
70+
return addInput(input);
71+
}
72+
73+
public synchronized FormBuilder addViewAndInput(TextView view, Input<?> input) {
74+
addInput(input);
75+
return addView(input.key, view);
76+
}
77+
78+
public synchronized FormBuilder addViewAndInput(EditText view, Input<?> input) {
79+
addInput(input);
80+
return addView(input.key, view);
81+
}
82+
83+
public synchronized FormBuilder addViewAndInput(RadioGroup view, Input<?> input) {
84+
addInput(input);
85+
return addView(input.key, view);
86+
}
87+
88+
public synchronized FormBuilder addViewAndInput(CompoundButton view, Input<?> input) {
89+
addInput(input);
90+
return addView(input.key, view);
91+
}
92+
93+
public synchronized FormBuilder addErrorHandler(ErrorHandler errorHandler, String key, String... keys) {
94+
if (!mErrorHandlers.containsKey(key)) {
95+
mErrorHandlers.put(key, new ArrayList<ErrorHandler>());
96+
}
97+
mErrorHandlers.get(key).add(errorHandler);
98+
if (keys != null) {
99+
for (String k : keys) {
100+
if (!mErrorHandlers.containsKey(k)) {
101+
mErrorHandlers.put(k, new ArrayList<ErrorHandler>());
102+
}
103+
mErrorHandlers.get(k).add(errorHandler);
104+
}
105+
}
106+
return this;
107+
}
108+
109+
public synchronized Form<Map<String, Object>> build() {
110+
return new MapForm(toArray(), mViewMap, toErrorHandlerArray());
111+
}
112+
113+
public synchronized <T> Form<T> build(Mapping<Map<String, Object>, T> mapping) {
114+
return new ObjectForm(mapping, toArray(), mViewMap, toErrorHandlerArray());
115+
}
116+
}

0 commit comments

Comments
 (0)