Skip to content

Commit

Permalink
don't drop keystrokes after backspace
Browse files Browse the repository at this point in the history
  • Loading branch information
dbachelder committed Aug 22, 2015
1 parent 7ba8eab commit 25a0b89
Show file tree
Hide file tree
Showing 8 changed files with 112 additions and 69 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -42,37 +42,7 @@ void init() {
public void afterTextChanged(Editable s) {
String number = s.toString();
if (number.length() >= CreditCardUtil.CC_LEN_FOR_TYPE) {
CardType type = CreditCardUtil.findCardType(number);

if (type.equals(CardType.INVALID)) {
setValid(false);
delegate.onBadInput(this);
return;
}

if (this.type != type) {
delegate.onCardTypeChange(type);
}
this.type = type;

String formatted = CreditCardUtil.formatForViewing(number, type);
if (!number.equalsIgnoreCase(formatted)) {
this.removeTextChangedListener(this);
this.setText(formatted);
this.setSelection(formatted.length());
this.addTextChangedListener(this);
}

if (formatted.length() >= CreditCardUtil.lengthOfFormattedStringForType(type)) {
if (CreditCardUtil.isValidNumber(formatted)) {
setValid(true);
delegate.onCreditCardNumberValid();
} else {
setValid(false);
delegate.onBadInput(this);
}
}

formatAndSetText(number);
} else {
if (this.type != null) {
this.type = null;
Expand All @@ -81,6 +51,45 @@ public void afterTextChanged(Editable s) {
}
}

@Override
public void formatAndSetText(String number) {
CardType type = CreditCardUtil.findCardType(number);

if (type.equals(CardType.INVALID)) {
setValid(false);
delegate.onBadInput(this);
return;
}

if (this.type != type) {
delegate.onCardTypeChange(type);
}
this.type = type;

String formatted = CreditCardUtil.formatForViewing(number, type);
if (!number.equalsIgnoreCase(formatted)) {
this.removeTextChangedListener(this);
this.setText(formatted);
this.setSelection(formatted.length());
this.addTextChangedListener(this);
}

if (formatted.length() >= CreditCardUtil.lengthOfFormattedStringForType(type)) {

String remainder = null;
if (number.startsWith(formatted)) {
remainder = number.replace(formatted, "");
}
if (CreditCardUtil.isValidNumber(formatted)) {
setValid(true);
delegate.onCreditCardNumberValid(remainder);
} else {
setValid(false);
delegate.onBadInput(this);
}
}
}

public CardType getType() {
return type;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ public void onTextChanged(CharSequence s, int start, int before, int end) {
}
}

public abstract void formatAndSetText(String updatedString);

@Override public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
@Override public void afterTextChanged(Editable s) {}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,22 +41,30 @@ public void afterTextChanged(Editable s) {

// if delete occurred do not format
if (updatedString.length() > previousString.length()) {
this.removeTextChangedListener(this);
String formatted = CreditCardUtil.formatExpirationDate(s.toString());
this.setText(formatted);
this.setSelection(formatted.length());
this.addTextChangedListener(this);

if(formatted.length() == 5) {
setValid(true);
delegate.onExpirationDateValid();
} else if(formatted.length() < updatedString.length()) {
setValid(false);
delegate.onBadInput(this);
}
formatAndSetText(updatedString);
}
}

public void formatAndSetText(String updatedString) {
this.removeTextChangedListener(this);
String formatted = CreditCardUtil.formatExpirationDate(updatedString);
this.setText(formatted);
this.setSelection(formatted.length());
this.addTextChangedListener(this);

if(formatted.length() == 5) {
setValid(true);
String remainder = null;
if(updatedString.startsWith(formatted)) {
remainder = updatedString.replace(formatted, "");
}
delegate.onExpirationDateValid(remainder);
} else if(formatted.length() < updatedString.length()) {
setValid(false);
delegate.onBadInput(this);
}
}

@Override
public String helperText() {
return context.getString(R.string.ExpirationDateHelp);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import android.content.Context;
import android.text.Editable;
import android.text.InputFilter;
import android.util.AttributeSet;

import com.devmarvel.creditcardentry.R;
Expand Down Expand Up @@ -37,6 +36,7 @@ void init() {

/* TextWatcher Implementation Methods */
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}

public void afterTextChanged(Editable s) {
if(type == null) {
this.removeTextChangedListener(this);
Expand All @@ -45,11 +45,20 @@ public void afterTextChanged(Editable s) {
}
}

public void formatAndSetText(String s) {
setText(s);
}

public void textChanged(CharSequence s, int start, int before, int count) {
if (type != null) {
if (s.length() == length) {
if (s.length() >= length) {
setValid(true);
delegate.onSecurityCodeValid();
String remainder = null;
if(s.length() > length()) remainder = String.valueOf(s).substring(length);
this.removeTextChangedListener(this);
setText(String.valueOf(s).substring(0, length));
this.addTextChangedListener(this);
delegate.onSecurityCodeValid(remainder);
} else {
setValid(false);
}
Expand All @@ -64,8 +73,6 @@ public CardType getType() {
public void setType(CardType type) {
this.type = type;
this.length = CreditCardUtil.securityCodeValid(type);

setFilters(new InputFilter[]{new InputFilter.LengthFilter(length)});
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,10 @@ public void textChanged(CharSequence s, int start, int before, int end) {
setValid(false);
}
}

public void formatAndSetText(String text) {
this.removeTextChangedListener(this);
this.setText(text);
this.addTextChangedListener(this);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ public CreditCardEntry(Context context, boolean includeExp, boolean includeSecur
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (EditorInfo.IME_ACTION_DONE == actionId) {
onSecurityCodeValid();
onSecurityCodeValid("");
return true;
}
return false;
Expand Down Expand Up @@ -205,26 +205,26 @@ public void onCardTypeChange(CardType type) {
}

@Override
public void onCreditCardNumberValid() {
nextField(this.creditCardText);
public void onCreditCardNumberValid(String remainder) {
nextField(this.creditCardText, remainder);

updateLast4();
}

@Override
public void onExpirationDateValid() {
nextField(this.expDateText);
public void onExpirationDateValid(String remainder) {
nextField(this.expDateText, remainder);
}

@Override
public void onSecurityCodeValid() {
nextField(securityCodeText);
public void onSecurityCodeValid(String remainder) {
nextField(securityCodeText, remainder);
updateCardImage(false);
}

@Override
public void onZipCodeValid() {
nextField(zipCodeText);
nextField(zipCodeText, null);
}

@Override
Expand Down Expand Up @@ -282,8 +282,11 @@ public void setOnFocusChangeListener(OnFocusChangeListener l) {
zipCodeText.setOnFocusChangeListener(l);
}

@Override
public void focusOnField(final CreditEntryFieldBase field) {
focusOnField(field, null);
}

public void focusOnField(final CreditEntryFieldBase field, String initialFieldValue) {
field.requestFocus();
if(!scrolling) {
scrolling = true;
Expand All @@ -302,6 +305,10 @@ public void run() {
});
}

if(initialFieldValue != null && initialFieldValue.length() > 0) {
field.formatAndSetText(initialFieldValue);
}

if (this.textHelper != null) {
this.textHelper.setText(field.helperText());
}
Expand All @@ -312,6 +319,7 @@ public void run() {
} else {
updateCardImage(false);
}
field.setSelection(field.getText().length());
}

private void scrollToTarget(int target, final Runnable after) {
Expand Down Expand Up @@ -427,7 +435,7 @@ public void onCardTypeChange(CardType type) {
}

@Override
public void onCreditCardNumberValid() {
public void onCreditCardNumberValid(String remainder) {
updateLast4();
}

Expand All @@ -436,10 +444,10 @@ public void onBadInput(EditText field) {
delegate.onBadInput(field);
}

@Override public void onExpirationDateValid() {}
@Override public void onSecurityCodeValid() {}
@Override public void onExpirationDateValid(String remainder) {}
@Override public void onSecurityCodeValid(String remainder) {}
@Override public void onZipCodeValid() { }
@Override public void focusOnField(CreditEntryFieldBase field) { }
@Override public void focusOnField(CreditEntryFieldBase field, String initialValue) { }
@Override public void focusOnPreviousField(CreditEntryFieldBase field) { }
};
}
Expand Down Expand Up @@ -504,12 +512,12 @@ private void updateLast4() {
textFourDigits.setText(digits);
}

private void nextField(CreditEntryFieldBase currentField) {
private void nextField(CreditEntryFieldBase currentField, String initialFieldValue) {
CreditEntryFieldBase next = nextFocusField.get(currentField);
if (next == null) {
entryComplete(currentField);
} else {
focusOnField(next);
focusOnField(next, initialFieldValue);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,18 @@ public interface CreditCardFieldDelegate {
// When the card type is identified
void onCardTypeChange(CardType type);

void onCreditCardNumberValid();
void onCreditCardNumberValid(String remainder);

void onExpirationDateValid();
void onExpirationDateValid(String remainder);

// Image should flip to back for security code
void onSecurityCodeValid();
void onSecurityCodeValid(String remainder);

void onZipCodeValid();

void onBadInput(EditText field);

void focusOnField(CreditEntryFieldBase field);
void focusOnField(CreditEntryFieldBase field, String initialValue);

void focusOnPreviousField(CreditEntryFieldBase field);
}
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ Add the project to your `dependencies`
...
compile 'com.github.dbachelder:CreditCardEntry:1.4.3'
compile 'com.github.dbachelder:CreditCardEntry:1.4.4'
}
```

Expand Down Expand Up @@ -114,6 +114,9 @@ In code:

# Version History

###8/21/2015
- don't drop key strokes after backspace

###8/21/2015
- focus change behavior can now keep up with very fast typing
- several minor performance tweaks
Expand Down

0 comments on commit 25a0b89

Please sign in to comment.