Skip to content

Commit

Permalink
Merge pull request #86 from huttneab/libaddressinput
Browse files Browse the repository at this point in the history
Add zip code validation and formatter
  • Loading branch information
huttneab authored Aug 27, 2016
2 parents 6ca57f5 + 27e150f commit 94d6c11
Show file tree
Hide file tree
Showing 10 changed files with 91 additions and 104 deletions.
2 changes: 1 addition & 1 deletion app/build.gradle
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Manifest version information!
def versionMajor = 1
def versionMinor = 0
def versionPatch = 8
def versionPatch = 9
def versionBuild = 0 // bump for dogfood builds, public betas, etc.

apply plugin: 'com.android.application'
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

<application
android:name=".GrommetApp"
android:allowBackup="true"
android:allowBackup="false"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="false"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,29 +8,20 @@
import android.widget.CheckBox;

import com.f2prateek.rx.preferences.Preference;
import com.jakewharton.rxbinding.widget.RxCompoundButton;
import com.mobsandgeeks.saripaar.annotation.Checked;
import com.rockthevote.grommet.R;
import com.rockthevote.grommet.data.db.model.RockyRequest;
import com.rockthevote.grommet.data.db.model.VoterClassification;
import com.rockthevote.grommet.data.prefs.CurrentRockyRequestId;
import com.rockthevote.grommet.ui.misc.ObservableValidator;
import com.rockthevote.grommet.ui.views.AddressView;
import com.squareup.sqlbrite.BriteDatabase;

import java.util.concurrent.TimeUnit;

import javax.inject.Inject;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnCheckedChanged;
import rx.Observable;
import rx.schedulers.Schedulers;
import rx.subscriptions.CompositeSubscription;

import static com.rockthevote.grommet.data.db.Db.DEBOUNCE;
import static com.rockthevote.grommet.data.db.model.VoterClassification.Type.SEND_COPY_IN_MAIL;


public class PersonalInfoFragment extends BaseRegistrationFragment {
Expand All @@ -48,18 +39,14 @@ public class PersonalInfoFragment extends BaseRegistrationFragment {

@BindView(R.id.address_changed) CheckBox addressChanged;

@BindView(R.id.mailing_address_divider) View maillingDivider;
@BindView(R.id.mailing_address_divider) View mailingDivider;

@BindView(R.id.previous_address_divider) View prevDivider;

@BindView(R.id.send_copy_in_mail) CheckBox sendCopyInMail;

@Inject @CurrentRockyRequestId Preference<Long> rockyRequestRowId;

@Inject BriteDatabase db;

private CompositeSubscription subscriptions;

private ObservableValidator validator;

@Nullable
Expand All @@ -76,34 +63,10 @@ public void onViewCreated(View view, Bundle savedInstanceState) {
validator = new ObservableValidator(this, getActivity());
}

@Override
public void onResume() {
super.onResume();
subscriptions = new CompositeSubscription();

// try to use debounce when possible to reduce DB churn
subscriptions.add(RxCompoundButton.checkedChanges(sendCopyInMail)
.observeOn(Schedulers.io())
.debounce(DEBOUNCE, TimeUnit.MILLISECONDS)
.skip(1)
.subscribe(checked -> {
VoterClassification.insertOrUpdate(db, rockyRequestRowId.get(), SEND_COPY_IN_MAIL,
new VoterClassification.Builder()
.assertion(checked)
.build());
}));
}

@Override
public void onPause() {
super.onPause();
subscriptions.unsubscribe();
}

@OnCheckedChanged(R.id.mailing_address_is_different)
public void onMailingAddressDifferentChecked(boolean checked) {
mailingAddress.setVisibility(checked ? View.VISIBLE : View.GONE);
maillingDivider.setVisibility(checked ? View.VISIBLE : View.GONE);
mailingDivider.setVisibility(checked ? View.VISIBLE : View.GONE);

db.update(RockyRequest.TABLE,
new RockyRequest.Builder()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@

import com.f2prateek.rx.preferences.Preference;
import com.jakewharton.rxbinding.widget.RxTextView;
import com.mobsandgeeks.saripaar.annotation.Length;
import com.mobsandgeeks.saripaar.annotation.NotEmpty;
import com.mobsandgeeks.saripaar.annotation.Pattern;
import com.rockthevote.grommet.R;
import com.rockthevote.grommet.data.Injector;
import com.rockthevote.grommet.data.db.model.Address;
Expand All @@ -25,6 +25,7 @@
import com.rockthevote.grommet.ui.misc.ChildrenViewStateHelper;
import com.rockthevote.grommet.ui.misc.ObservableValidator;
import com.rockthevote.grommet.util.Strings;
import com.rockthevote.grommet.util.ZipTextWatcher;
import com.squareup.sqlbrite.BriteDatabase;

import java.util.concurrent.TimeUnit;
Expand Down Expand Up @@ -62,7 +63,7 @@ public class AddressView extends FrameLayout {

@BindView(R.id.spinner_state) BetterSpinner stateSpinner;

@Length(min = 5, max = 10)
@Pattern(regex = "^[0-9]{5}(?:-[0-9]{4})?$", messageResId = R.string.zip_code_error)
@BindView(R.id.til_zip_code) TextInputLayout zipTIL;
@BindView(R.id.zip) EditText zipEditText;

Expand All @@ -74,15 +75,14 @@ public class AddressView extends FrameLayout {

@Inject BriteDatabase db;

ObservableValidator validator;
private ObservableValidator validator;

private ArrayAdapter<CharSequence> countyAdapter;

private ArrayAdapter<CharSequence> stateAdapter;

private Address.Type type;

private CompositeSubscription subscriptions = new CompositeSubscription();
private ZipTextWatcher zipTextWatcher = new ZipTextWatcher();

public AddressView(Context context) {
this(context, null);
Expand Down Expand Up @@ -182,13 +182,16 @@ protected void onFinishInflate() {
if (Strings.isBlank(stateSpinner.getEditText().getEditableText().toString())) {
stateSpinner.getEditText().setText(stateAdapter.getItem(stateAdapter.getPosition(PA_ABREV)));
}

}
}

@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
if (!isInEditMode()) {
zipEditText.addTextChangedListener(zipTextWatcher);

subscriptions.add(Observable.combineLatest(RxTextView.afterTextChangeEvents(streetEditText),
RxTextView.afterTextChangeEvents(unitEditText),
RxTextView.afterTextChangeEvents(cityEditText),
Expand All @@ -215,6 +218,7 @@ protected void onAttachedToWindow() {
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
subscriptions.unsubscribe();
zipEditText.removeTextChangedListener(zipTextWatcher);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
import android.widget.TextView;

import com.f2prateek.rx.preferences.Preference;
import com.mobsandgeeks.saripaar.annotation.Length;
import com.mobsandgeeks.saripaar.annotation.Pattern;
import com.rockthevote.grommet.R;
import com.rockthevote.grommet.data.Injector;
import com.rockthevote.grommet.data.api.RockyService;
Expand All @@ -25,7 +25,9 @@
import com.rockthevote.grommet.data.prefs.PartnerId;
import com.rockthevote.grommet.data.prefs.PartnerName;
import com.rockthevote.grommet.ui.misc.BetterViewAnimator;
import com.rockthevote.grommet.ui.misc.ObservableValidator;
import com.rockthevote.grommet.util.Strings;
import com.rockthevote.grommet.util.ZipTextWatcher;

import java.util.List;
import java.util.concurrent.TimeUnit;
Expand All @@ -39,6 +41,8 @@
import rx.schedulers.Schedulers;
import rx.subscriptions.CompositeSubscription;

import static com.rockthevote.grommet.ui.views.EditableActionView.EditableActionViewListener;

public class EventDetails extends FrameLayout {

static final ButterKnife.Setter<View, Boolean> ENABLED =
Expand All @@ -47,46 +51,35 @@ public class EventDetails extends FrameLayout {
@BindViews({R.id.ede_til_canvasser_name, R.id.ede_til_event_name,
R.id.ede_til_event_zip, R.id.ede_til_partner_id})
List<TextInputLayout> editableViews;

@BindView(R.id.ed_animator) BetterViewAnimator viewAnimator;

@BindView(R.id.ed_canvasser_name) TextView edCanvasserName;

@BindView(R.id.ed_event_name) TextView edEventName;

@BindView(R.id.ed_event_zip) TextView edEventZip;

@BindView(R.id.ed_partner_name) TextView edPartnerName;

@BindView(R.id.ede_canvasser_name) EditText edeCanvasserName;

@BindView(R.id.ede_event_name) EditText edeEventName;

@Pattern(regex = "^[0-9]{5}(?:-[0-9]{4})?$", messageResId = R.string.zip_code_error)
@BindView(R.id.ede_til_event_zip) TextInputLayout edeEventZipTIL;
@BindView(R.id.ede_event_zip) EditText edeEventZip;

@BindView(R.id.ede_til_partner_id) TextInputLayout edePartnerIdTIL;

@BindView(R.id.ede_partner_id) EditText edePartnerId;

@Inject @EventRegTotal Preference<Integer> eventRegTotalPref;

@Inject @CanvasserName Preference<String> canvasserNamePref;

@Inject @EventName Preference<String> eventNamePref;

@Inject @EventZip Preference<String> eventZipPref;

@Inject @PartnerId Preference<String> partnerIdPref;

@Inject @PartnerName Preference<String> partnerNamePref;

@Inject RockyService rockyService;

private CompositeSubscription subscriptions = new CompositeSubscription();

private EditableActionView.EditableActionViewListener listener;

private EditableActionView editableActionView;
private ZipTextWatcher zipTextWatcher = new ZipTextWatcher();
private ObservableValidator validator;

public EventDetails(Context context) {
this(context, null);
Expand All @@ -109,13 +102,18 @@ public EventDetails(Context context, AttributeSet attrs, int defStyleAttr) {
@Override
protected void onFinishInflate() {
super.onFinishInflate();
ButterKnife.bind(this);
if (!isInEditMode()) {
ButterKnife.bind(this);
validator = new ObservableValidator(this, getContext());
}
}

@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
if (!isInEditMode()) {
edeEventZip.addTextChangedListener(zipTextWatcher);

subscriptions.add(canvasserNamePref.asObservable()
.subscribe(name -> edCanvasserName.setText(name)));

Expand All @@ -132,7 +130,7 @@ protected void onAttachedToWindow() {

public void setEditableActionView(EditableActionView view) {
editableActionView = view;
listener = new EditableActionView.EditableActionViewListener() {
editableActionView.setListener(new EditableActionViewListener() {
@Override
public void onEdit() {
enableEditMode(true);
Expand All @@ -147,41 +145,41 @@ public void onCancel() {
public void onSave() {

// allow the user to not set a partner ID
if (Strings.isBlank(edePartnerId.getText().toString())) {
setPartnerName("");
} else if (edePartnerId.getText().toString().equals(partnerIdPref.get())) {
setPartnerName(partnerNamePref.get());
} else {
rockyService.getPartnerName(edePartnerId.getText().toString())
.subscribeOn(Schedulers.io())
.delay(500, TimeUnit.MILLISECONDS)
.observeOn(AndroidSchedulers.mainThread())
.doOnSubscribe(() -> {
editableActionView.showSpinner();
ButterKnife.apply(editableViews, ENABLED, false);
})
.doOnCompleted(() -> ButterKnife.apply(editableViews, ENABLED, true))
.subscribe(result -> {
if (!result.isError() && result.response().isSuccessful()) {
PartnerNameResponse partnerNameResponse = result.response().body();
if (partnerNameResponse.isValid()) {
setPartnerName(partnerNameResponse.partnerName());
if (validator.validate().toBlocking().single()) {
if (Strings.isBlank(edePartnerId.getText().toString())) {
setPartnerName("");
} else if (edePartnerId.getText().toString().equals(partnerIdPref.get())) {
setPartnerName(partnerNamePref.get());
} else {
rockyService.getPartnerName(edePartnerId.getText().toString())
.subscribeOn(Schedulers.io())
.delay(500, TimeUnit.MILLISECONDS)
.observeOn(AndroidSchedulers.mainThread())
.doOnSubscribe(() -> {
editableActionView.showSpinner();
ButterKnife.apply(editableViews, ENABLED, false);
})
.doOnCompleted(() -> ButterKnife.apply(editableViews, ENABLED, true))
.subscribe(result -> {
if (!result.isError() && result.response().isSuccessful()) {
PartnerNameResponse partnerNameResponse = result.response().body();
if (partnerNameResponse.isValid()) {
setPartnerName(partnerNameResponse.partnerName());
} else {
edePartnerIdTIL.setError(
getContext().getString(R.string.error_partner_id));
editableActionView.showSaveCancel();
}
} else {
edePartnerIdTIL.setError(
getContext().getString(R.string.error_partner_id));
editableActionView.showSaveCancel();
}
} else {
edePartnerIdTIL.setError(
getContext().getString(R.string.error_partner_id));
editableActionView.showSaveCancel();
}
});
});
}
}
}
};

editableActionView.setListener(listener);
});
}

private void setPartnerName(String name) {
Expand Down
27 changes: 27 additions & 0 deletions app/src/main/java/com/rockthevote/grommet/util/ZipTextWatcher.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.rockthevote.grommet.util;

import android.text.Editable;
import android.text.TextWatcher;

public class ZipTextWatcher implements 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) {

}

@Override
public void afterTextChanged(Editable s) {
if (!s.toString().contains("-") && s.length() > 5) {
s.insert(5, "-");
} else if( s.toString().contains("-") && s.length() < 7){
int dashIndex = s.toString().indexOf("-");
s.delete(dashIndex, s.length());
}
}
}
3 changes: 2 additions & 1 deletion app/src/main/res/layout/event_details_editable.xml
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@
style="@android:style/TextAppearance.Material.Subhead"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="number"
android:inputType="phone"
android:maxLength="10"
android:maxLines="1"
/>

Expand Down
Loading

0 comments on commit 94d6c11

Please sign in to comment.