added FormWrapper and form field validation
This commit is contained in:
parent
0569a1e769
commit
8850a1fbe3
|
@ -2,6 +2,7 @@ package eu.siacs.conversations.ui.forms;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.widget.CheckBox;
|
import android.widget.CheckBox;
|
||||||
|
import android.widget.CompoundButton;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -16,6 +17,13 @@ public class FormBooleanFieldWrapper extends FormFieldWrapper {
|
||||||
protected FormBooleanFieldWrapper(Context context, Field field) {
|
protected FormBooleanFieldWrapper(Context context, Field field) {
|
||||||
super(context, field);
|
super(context, field);
|
||||||
checkBox = (CheckBox) view.findViewById(R.id.field);
|
checkBox = (CheckBox) view.findViewById(R.id.field);
|
||||||
|
checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
||||||
|
@Override
|
||||||
|
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
||||||
|
checkBox.setError(null);
|
||||||
|
invokeOnFormFieldValuesEdited();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -33,7 +41,22 @@ public class FormBooleanFieldWrapper extends FormFieldWrapper {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean validates() {
|
public boolean validates() {
|
||||||
return checkBox.isChecked() || !field.isRequired();
|
if (checkBox.isChecked() || !field.isRequired()) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
checkBox.setError(context.getString(R.string.this_field_is_required));
|
||||||
|
checkBox.requestFocus();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean edited() {
|
||||||
|
if (field.getValues().size() == 0) {
|
||||||
|
return checkBox.isChecked();
|
||||||
|
} else {
|
||||||
|
return super.edited();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -20,7 +20,7 @@ public class FormFieldFactory {
|
||||||
typeTable.put("boolean", FormBooleanFieldWrapper.class);
|
typeTable.put("boolean", FormBooleanFieldWrapper.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static FormFieldWrapper createFromField(Context context, Field field) {
|
protected static FormFieldWrapper createFromField(Context context, Field field) {
|
||||||
Class clazz = typeTable.get(field.getType());
|
Class clazz = typeTable.get(field.getType());
|
||||||
if (clazz == null) {
|
if (clazz == null) {
|
||||||
clazz = FormTextFieldWrapper.class;
|
clazz = FormTextFieldWrapper.class;
|
||||||
|
|
|
@ -4,11 +4,13 @@ import android.content.Context;
|
||||||
import android.text.SpannableString;
|
import android.text.SpannableString;
|
||||||
import android.text.style.ForegroundColorSpan;
|
import android.text.style.ForegroundColorSpan;
|
||||||
import android.text.style.StyleSpan;
|
import android.text.style.StyleSpan;
|
||||||
|
import android.util.Log;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import eu.siacs.conversations.Config;
|
||||||
import eu.siacs.conversations.R;
|
import eu.siacs.conversations.R;
|
||||||
import eu.siacs.conversations.xmpp.forms.Field;
|
import eu.siacs.conversations.xmpp.forms.Field;
|
||||||
|
|
||||||
|
@ -17,6 +19,7 @@ public abstract class FormFieldWrapper {
|
||||||
protected final Context context;
|
protected final Context context;
|
||||||
protected final Field field;
|
protected final Field field;
|
||||||
protected final View view;
|
protected final View view;
|
||||||
|
protected OnFormFieldValuesEdited onFormFieldValuesEditedListener;
|
||||||
|
|
||||||
protected FormFieldWrapper(Context context, Field field) {
|
protected FormFieldWrapper(Context context, Field field) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
|
@ -57,6 +60,23 @@ public abstract class FormFieldWrapper {
|
||||||
return spannableString;
|
return spannableString;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void invokeOnFormFieldValuesEdited() {
|
||||||
|
Log.d(Config.LOGTAG, "invoke on form field values edited");
|
||||||
|
if (this.onFormFieldValuesEditedListener != null) {
|
||||||
|
this.onFormFieldValuesEditedListener.onFormFieldValuesEdited();
|
||||||
|
} else {
|
||||||
|
Log.d(Config.LOGTAG,"listener is null");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean edited() {
|
||||||
|
return !field.getValues().equals(getValues());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOnFormFieldValuesEditedListener(OnFormFieldValuesEdited listener) {
|
||||||
|
this.onFormFieldValuesEditedListener = listener;
|
||||||
|
}
|
||||||
|
|
||||||
protected static <F extends FormFieldWrapper> FormFieldWrapper createFromField(Class<F> c, Context context, Field field) {
|
protected static <F extends FormFieldWrapper> FormFieldWrapper createFromField(Class<F> c, Context context, Field field) {
|
||||||
try {
|
try {
|
||||||
return c.getDeclaredConstructor(Context.class, Field.class).newInstance(context,field);
|
return c.getDeclaredConstructor(Context.class, Field.class).newInstance(context,field);
|
||||||
|
@ -65,4 +85,8 @@ public abstract class FormFieldWrapper {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public interface OnFormFieldValuesEdited {
|
||||||
|
void onFormFieldValuesEdited();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,8 @@ public class FormJidSingleFieldWrapper extends FormTextFieldWrapper {
|
||||||
try {
|
try {
|
||||||
Jid.fromString(value);
|
Jid.fromString(value);
|
||||||
} catch (InvalidJidException e) {
|
} catch (InvalidJidException e) {
|
||||||
|
editText.setError(context.getString(R.string.invalid_jid));
|
||||||
|
editText.requestFocus();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
package eu.siacs.conversations.ui.forms;
|
package eu.siacs.conversations.ui.forms;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.text.Editable;
|
||||||
import android.text.InputType;
|
import android.text.InputType;
|
||||||
|
import android.text.TextWatcher;
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
@ -22,6 +24,21 @@ public class FormTextFieldWrapper extends FormFieldWrapper {
|
||||||
if ("text-private".equals(field.getType())) {
|
if ("text-private".equals(field.getType())) {
|
||||||
editText.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
|
editText.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
|
||||||
}
|
}
|
||||||
|
editText.addTextChangedListener(new TextWatcher() {
|
||||||
|
@Override
|
||||||
|
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||||
|
editText.setError(null);
|
||||||
|
invokeOnFormFieldValuesEdited();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterTextChanged(Editable s) {
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -38,14 +55,22 @@ public class FormTextFieldWrapper extends FormFieldWrapper {
|
||||||
public List<String> getValues() {
|
public List<String> getValues() {
|
||||||
List<String> values = new ArrayList<>();
|
List<String> values = new ArrayList<>();
|
||||||
for (String line : getValue().split("\\n")) {
|
for (String line : getValue().split("\\n")) {
|
||||||
values.add(line);
|
if (line.length() > 0) {
|
||||||
|
values.add(line);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return values;
|
return values;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean validates() {
|
public boolean validates() {
|
||||||
return getValue().trim().length() > 0 || !field.isRequired();
|
if (getValue().trim().length() > 0 || !field.isRequired()) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
editText.setError(context.getString(R.string.this_field_is_required));
|
||||||
|
editText.requestFocus();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -0,0 +1,66 @@
|
||||||
|
package eu.siacs.conversations.ui.forms;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import eu.siacs.conversations.xmpp.forms.Data;
|
||||||
|
import eu.siacs.conversations.xmpp.forms.Field;
|
||||||
|
|
||||||
|
public class FormWrapper {
|
||||||
|
|
||||||
|
private final LinearLayout layout;
|
||||||
|
|
||||||
|
private final Data form;
|
||||||
|
|
||||||
|
private final List<FormFieldWrapper> fieldWrappers = new ArrayList<>();
|
||||||
|
|
||||||
|
private FormWrapper(Context context, LinearLayout linearLayout, Data form) {
|
||||||
|
this.form = form;
|
||||||
|
this.layout = linearLayout;
|
||||||
|
this.layout.removeAllViews();
|
||||||
|
for(Field field : form.getFields()) {
|
||||||
|
FormFieldWrapper fieldWrapper = FormFieldFactory.createFromField(context,field);
|
||||||
|
if (fieldWrapper != null) {
|
||||||
|
layout.addView(fieldWrapper.getView());
|
||||||
|
fieldWrappers.add(fieldWrapper);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Data submit() {
|
||||||
|
for(FormFieldWrapper fieldWrapper : fieldWrappers) {
|
||||||
|
fieldWrapper.submit();
|
||||||
|
}
|
||||||
|
this.form.submit();
|
||||||
|
return this.form;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean validates() {
|
||||||
|
boolean validates = true;
|
||||||
|
for(FormFieldWrapper fieldWrapper : fieldWrappers) {
|
||||||
|
validates &= fieldWrapper.validates();
|
||||||
|
}
|
||||||
|
return validates;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOnFormFieldValuesEditedListener(FormFieldWrapper.OnFormFieldValuesEdited listener) {
|
||||||
|
for(FormFieldWrapper fieldWrapper : fieldWrappers) {
|
||||||
|
fieldWrapper.setOnFormFieldValuesEditedListener(listener);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean edited() {
|
||||||
|
boolean edited = false;
|
||||||
|
for(FormFieldWrapper fieldWrapper : fieldWrappers) {
|
||||||
|
edited |= fieldWrapper.edited();
|
||||||
|
}
|
||||||
|
return edited;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static FormWrapper createInLayout(Context context, LinearLayout layout, Data form) {
|
||||||
|
return new FormWrapper(context, layout, form);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,7 +1,9 @@
|
||||||
package eu.siacs.conversations.xmpp.forms;
|
package eu.siacs.conversations.xmpp.forms;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import eu.siacs.conversations.xml.Element;
|
import eu.siacs.conversations.xml.Element;
|
||||||
|
|
||||||
|
@ -52,6 +54,19 @@ public class Field extends Element {
|
||||||
return findChildContent("value");
|
return findChildContent("value");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<String> getValues() {
|
||||||
|
List<String> values = new ArrayList<>();
|
||||||
|
for(Element child : getChildren()) {
|
||||||
|
if ("value".equals(child.getName())) {
|
||||||
|
String content = child.getContent();
|
||||||
|
if (content != null) {
|
||||||
|
values.add(content);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
|
||||||
public String getLabel() {
|
public String getLabel() {
|
||||||
return getAttribute("label");
|
return getAttribute("label");
|
||||||
}
|
}
|
||||||
|
|
|
@ -581,4 +581,5 @@
|
||||||
<string name="disable">Disable</string>
|
<string name="disable">Disable</string>
|
||||||
<string name="selection_too_large">The selected area is too large</string>
|
<string name="selection_too_large">The selected area is too large</string>
|
||||||
<string name="no_accounts">(No activated accounts)</string>
|
<string name="no_accounts">(No activated accounts)</string>
|
||||||
|
<string name="this_field_is_required">This field is required</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
Loading…
Reference in New Issue