Skip to content

Commit

Permalink
fix(input): mark ion-input touched on blur instead of changed (#12812)
Browse files Browse the repository at this point in the history
fixes #12102
  • Loading branch information
kensodemann authored Sep 11, 2017
1 parent f5ef1ca commit d0cad6b
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 9 deletions.
2 changes: 1 addition & 1 deletion src/components/checkbox/checkbox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ export class Checkbox extends BaseInput<boolean> implements IonicTapInput, OnDes
ev.preventDefault();
ev.stopPropagation();
this.value = !this.value;
this._fireTouched();
}

/**
Expand All @@ -141,5 +142,4 @@ export class Checkbox extends BaseInput<boolean> implements IonicTapInput, OnDes
_inputUpdated() {
this._item && this._item.setElementClass('item-checkbox-checked', this._value);
}

}
7 changes: 4 additions & 3 deletions src/components/segment/segment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,10 @@ export class Segment extends BaseInput<string> implements AfterContentInit {
ngAfterContentInit() {
this._initialize();
this._buttons.forEach(button => {
button.ionSelect.subscribe((selectedButton: any) => this.value = selectedButton.value);
button.ionSelect.subscribe((selectedButton: any) => {
this.value = selectedButton.value;
this._fireTouched();
});
});
}

Expand All @@ -109,6 +112,4 @@ export class Segment extends BaseInput<string> implements AfterContentInit {
button.isActive = (button.value === value);
}
}


}
11 changes: 9 additions & 2 deletions src/util/base-input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { AfterContentInit, ElementRef, EventEmitter, Input, NgZone, Output, Rend
import { ControlValueAccessor } from '@angular/forms';
import { NgControl } from '@angular/forms';

import { assert, deepCopy, isArray, isPresent, isString, isTrueProperty, isUndefined } from './util';
import { assert, deepCopy, isArray, isPresent, isString, isTrueProperty, isUndefined } from './util';
import { IonicFormInput } from './form';
import { Ion } from '../components/ion';
import { Config } from '../config/config';
Expand Down Expand Up @@ -228,9 +228,17 @@ export class BaseInput<T> extends Ion implements CommonInput<T> {

this._form && this._form.unsetAsFocused(this);
this._setFocus(false);
this._fireTouched();
this.ionBlur.emit(this);
}

/**
* @hidden
*/
_fireTouched() {
this._onTouched && this._onTouched();
}

/**
* @hidden
*/
Expand All @@ -253,7 +261,6 @@ export class BaseInput<T> extends Ion implements CommonInput<T> {
*/
private onChange() {
this._onChanged && this._onChanged(this._inputNgModelEvent());
this._onTouched && this._onTouched();
}

/**
Expand Down
17 changes: 14 additions & 3 deletions src/util/input-tester.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ function testState<T>(input: BaseInput<T>, config: TestConfig, isInit: boolean)
if (isInit) {
let blurCount = 0;
let focusCount = 0;
let onTouchedCalled = 0;
const subBlur = input.ionBlur.subscribe((ev: any) => {
assertEqual(ev, input, 'ionBlur argument is wrong');
blurCount++;
Expand All @@ -121,6 +122,15 @@ function testState<T>(input: BaseInput<T>, config: TestConfig, isInit: boolean)
assert(false, 'onFocusChange test failed');
}
});
input.registerOnTouched(() => {
assertEqual(onTouchedCalled, 0, 'registerOnTouched: internal error');
onTouchedCalled++;
});

input._fireBlur();
assertEqual(blurCount, 0, 'blur should not have been emitted');
assertEqual(onTouchedCalled, 0, 'touched should not have been called');

input._fireFocus();
assertEqual(input._isFocus, true, 'should be focus');
assertEqual(input.isFocus(), true, 'should be focus');
Expand All @@ -129,6 +139,7 @@ function testState<T>(input: BaseInput<T>, config: TestConfig, isInit: boolean)
input._fireBlur();
assertEqual(input._isFocus, false, 'should be not focus');
assertEqual(input.isFocus(), false, 'should be not focus');
assertEqual(onTouchedCalled, 1, 'touched should have been called');
input._fireBlur(); // it should not crash

assertEqual(focusCount, 1, 'ionFocus was not called correctly');
Expand Down Expand Up @@ -166,7 +177,7 @@ function testWriteValue<T>(input: BaseInput<T>, config: TestConfig, isInit: bool
OnChangeCalled++;
});

// Test registerOnChange
// Test registerOnTouched
input.registerOnTouched(() => {
assertEqual(OnTouchedCalled, 0, 'registerOnTouched: internal error');

Expand All @@ -187,7 +198,7 @@ function testWriteValue<T>(input: BaseInput<T>, config: TestConfig, isInit: bool
assertEqual(ionChangeCalled, 0, 'loop: ionChange error');
}
assertEqual(OnChangeCalled, 1, 'loop: OnChangeCalled was not called');
assertEqual(OnTouchedCalled, 1, 'loop: OnTouchedCalled was not called');
assertEqual(OnTouchedCalled, 0, 'loop: OnTouchedCalled was called');

OnTouchedCalled = OnChangeCalled = ionChangeCalled = 0;

Expand All @@ -212,7 +223,7 @@ function testWriteValue<T>(input: BaseInput<T>, config: TestConfig, isInit: bool
input.value = null;
assertEqual(input.value, config.defaultValue, 'null: wrong default value');
assertEqual(OnChangeCalled, 1, 'null: OnChangeCalled was not called');
assertEqual(OnTouchedCalled, 1, 'null: OnTouchedCalled was not called');
assertEqual(OnTouchedCalled, 0, 'null: OnTouchedCalled was called');


input.registerOnChange(null);
Expand Down

0 comments on commit d0cad6b

Please sign in to comment.