Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
251e839
TextField: Implemented masking
lambertwang-zz Jan 24, 2018
71cea3f
Changed example
lambertwang-zz Jan 24, 2018
4bf0059
Change file
lambertwang-zz Jan 24, 2018
ab1c2c7
Moved functions to util. Added tests
lambertwang-zz Jan 24, 2018
cfd5e0a
Added selection deletion tests
lambertwang-zz Jan 24, 2018
c61c77c
Refactored textfield into separate components
lambertwang-zz Jan 26, 2018
b932927
Merge branch 'master' of github.com:OfficeDev/office-ui-fabric-react …
lambertwang-zz Jan 26, 2018
e2462f0
Merge branch 'master' of github.com:OfficeDev/office-ui-fabric-react …
lambertwang-zz Jan 30, 2018
257ea8a
Merge branch 'master' of github.com:lambertwang/office-ui-fabric-reac…
lambertwang-zz Feb 21, 2018
86e3260
Deleted base and default textfields
lambertwang-zz Feb 21, 2018
76c3d1b
Revert additional changes
lambertwang-zz Feb 21, 2018
322141d
Fixed refs
lambertwang-zz Feb 21, 2018
7ae09a0
Merge branch 'master' of https://github.com/officedev/office-ui-fabri…
dzearing Mar 10, 2018
794d948
Update magellan-textFieldMasking_2018-01-24-01-35.json
dzearing Mar 13, 2018
2ac854f
Merge branch 'master' of github.com:lambertwang/office-ui-fabric-reac…
lambertwang-zz Mar 26, 2018
17cff11
Merge branch 'magellan/textFieldMasking' of github.com:lambertwang/of…
lambertwang-zz Mar 26, 2018
b66bdb9
Added enzyme and snapshot tests for the component
lambertwang-zz Mar 27, 2018
3ea706d
Fixed typo
lambertwang-zz Mar 27, 2018
218637f
Added character overflow test
lambertwang-zz Mar 27, 2018
fc57283
Undo changes to textfield
lambertwang-zz Mar 27, 2018
ed138ae
Merge branch 'master' of github.com:OfficeDev/office-ui-fabric-react …
lambertwang-zz Mar 27, 2018
f47a481
Fixed linting error
lambertwang-zz Mar 27, 2018
1cfbdf7
Update TextField.Basic.Example.tsx
lambertwang Mar 28, 2018
7060aee
Added comments to inputMask.ts
lambertwang Mar 28, 2018
5eb7615
Removed trailing whitespace
lambertwang Mar 28, 2018
7776a30
Merge branch 'master' of github.com:OfficeDev/office-ui-fabric-react …
lambertwang-zz Apr 18, 2018
ade5b57
Fix build errors for Lambert
cliffkoh Apr 19, 2018
41353cd
Update jest snapshot
cliffkoh Apr 19, 2018
ef1e721
Merge pull request #1 from cliffkoh/lambertwang-magellan/textFieldMas…
lambertwang Apr 19, 2018
ed03b12
Merge branch 'master' of github.com:OfficeDev/office-ui-fabric-react …
lambertwang-zz Apr 19, 2018
5087641
Fix build errors
lambertwang-zz Apr 19, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"changes": [
{
"packageName": "office-ui-fabric-react",
"comment": "TextField: Implemented input masking.",
"type": "minor"
}
],
"packageName": "office-ui-fabric-react",
"email": "[email protected]"
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,15 @@ export class LayoutGroupBasicExample extends React.Component<{}, {}> {
}
/>
<LayoutGroup layoutGap={ 20 } direction='horizontal' justify='fill'>
<TextField label='TextField with a placeholder' placeholder='Now I am a Placeholder' ariaLabel='Please enter text here' />
<TextField label='TextField with an icon' iconProps={ { iconName: 'Calendar' } } />
<TextField
label='TextField with a placeholder'
placeholder='Now I am a Placeholder'
ariaLabel='Please enter text here'
/>
<TextField
label='TextField with an icon'
iconProps={ { iconName: 'Calendar' } }
/>
</LayoutGroup>

<LayoutGroup layoutGap={ 20 } direction='horizontal' justify='fill'>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,333 @@
import * as React from 'react';
import * as ReactTestUtils from 'react-dom/test-utils';
import * as renderer from 'react-test-renderer';
import { mount } from 'enzyme';
import {
KeyCodes
} from '../../../Utilities';

import { MaskedTextField } from './MaskedTextField';

describe('MaskedTextField', () => {
function mockEvent(targetValue: string = ''): ReactTestUtils.SyntheticEventData {
const target: EventTarget = { value: targetValue } as HTMLInputElement;
const event: ReactTestUtils.SyntheticEventData = { target };

return event;
}

it('renders TextField correctly', () => {
const component = renderer.create(
<MaskedTextField
label='With input mask'
mask='m\ask: (999) 999 - 9999'
/>
);
const tree = component.toJSON();
expect(tree).toMatchSnapshot();
});

it('Moves caret on focus', () => {
const component = mount(
<MaskedTextField
label='With input mask'
mask='m\ask: (999) 999 - 9999'
/>
);

const input = component.find('input');
input.simulate('focus');
expect((input.getDOMNode() as HTMLInputElement).selectionStart).toEqual(7);
});

it('can change single character', () => {
const component = mount(
<MaskedTextField
label='With input mask'
mask='m\ask: (999) 999 - 9999'
/>
);

const input = component.find('input'),
inputDOM = input.getDOMNode() as HTMLInputElement;
input.simulate('focus');

// Simulate pressing the '1' key
input.simulate('keyDown', { keyCode: KeyCodes.one });
inputDOM.setSelectionRange(8, 8);
input.simulate('change', mockEvent('mask: (1___) ___ - ____'));
expect(inputDOM.value).toEqual('mask: (1__) ___ - ____');

// Simulate pressing the '2' key
input.simulate('keyDown', { keyCode: KeyCodes.two });
inputDOM.setSelectionRange(9, 9);
input.simulate('change', mockEvent('mask: (12__) ___ - ____'));
expect(inputDOM.value).toEqual('mask: (12_) ___ - ____');
});

it('can replace single character', () => {
const component = mount(
<MaskedTextField
label='With input mask'
mask='m\ask: (999) 999 - 9999'
/>
);

const input = component.find('input'),
inputDOM = input.getDOMNode() as HTMLInputElement;
input.simulate('focus');

// Simulate pressing the '1' key
input.simulate('keyDown', { keyCode: KeyCodes.one });
inputDOM.setSelectionRange(8, 8);
input.simulate('change', mockEvent('mask: (1___) ___ - ____'));
expect(inputDOM.value).toEqual('mask: (1__) ___ - ____');

// Replacing a character
input.simulate('keyDown', { keyCode: KeyCodes.two });
inputDOM.setSelectionRange(8, 8);
input.simulate('change', mockEvent('mask: (21__) ___ - ____'));
expect(inputDOM.value).toEqual('mask: (2__) ___ - ____');
});

it('should ignore incorrect format characters', () => {
const component = mount(
<MaskedTextField
label='With input mask'
mask='m\ask: (999) 999 - 9999'
/>
);

const input = component.find('input'),
inputDOM = input.getDOMNode() as HTMLInputElement;
input.simulate('focus');

// Simulate pressing the '1' key
input.simulate('keyDown', { keyCode: KeyCodes.one });
inputDOM.setSelectionRange(8, 8);
input.simulate('change', mockEvent('mask: (1___) ___ - ____'));
expect(inputDOM.value).toEqual('mask: (1__) ___ - ____');

// Simulate pressing the 'a' key
input.simulate('keyDown', { keyCode: KeyCodes.a });
inputDOM.setSelectionRange(9, 9);
input.simulate('change', mockEvent('mask: (1a__) ___ - ____'));
expect(inputDOM.value).toEqual('mask: (1__) ___ - ____');
});

it('should backspace', () => {
const component = mount(
<MaskedTextField
label='With input mask'
mask='m\ask: (999) 999 - 9999'
value='123-456-7890'
/>
);

const input = component.find('input'),
inputDOM = input.getDOMNode() as HTMLInputElement;
input.simulate('focus');

// Simulate backspacing the '2'
inputDOM.setSelectionRange(9, 9);
input.simulate('keyDown', { keyCode: KeyCodes.backspace });
input.simulate('change', mockEvent('mask: (13) 456 - 7890'));
expect(inputDOM.value).toEqual('mask: (1_3) 456 - 7890');
});

it('should delete', () => {
const component = mount(
<MaskedTextField
label='With input mask'
mask='m\ask: (999) 999 - 9999'
value='123-456-7890'
/>
);

const input = component.find('input'),
inputDOM = input.getDOMNode() as HTMLInputElement;
input.simulate('focus');

// Simulate deleting the '3'
inputDOM.setSelectionRange(9, 9);
input.simulate('keyDown', { keyCode: KeyCodes.del });
input.simulate('change', mockEvent('mask: (12) 456 - 7890'));
expect(inputDOM.value).toEqual('mask: (12_) 456 - 7890');
});

it('should ctrl backspace', () => {
const component = mount(
<MaskedTextField
label='With input mask'
mask='m\ask: (999) 999 - 9999'
value='123-456-7890'
/>
);

const input = component.find('input'),
inputDOM = input.getDOMNode() as HTMLInputElement;
input.simulate('focus');

// Simulate backspacing the '123'
inputDOM.setSelectionRange(10, 10);
input.simulate('keyDown', { keyCode: KeyCodes.backspace, ctrlKey: true });
inputDOM.setSelectionRange(7, 7);
input.simulate('change', mockEvent('mask: () 456 - 7890'));
expect(inputDOM.value).toEqual('mask: (___) 456 - 7890');
});

it('should ctrl delete', () => {
const component = mount(
<MaskedTextField
label='With input mask'
mask='m\ask: (999) 999 - 9999'
value='123-456-7890'
/>
);

const input = component.find('input'),
inputDOM = input.getDOMNode() as HTMLInputElement;
input.simulate('focus');

// Simulate deleting the '123'
inputDOM.setSelectionRange(7, 7);
input.simulate('keyDown', { keyCode: KeyCodes.del, ctrlKey: true });
input.simulate('change', mockEvent('mask: () 456 - 7890'));
expect(inputDOM.value).toEqual('mask: (___) 456 - 7890');
});

it('should backspace and delete selections', () => {
const component = mount(
<MaskedTextField
label='With input mask'
mask='m\ask: (999) 999 - 9999'
value='123-456-7890'
/>
);

const input = component.find('input'),
inputDOM = input.getDOMNode() as HTMLInputElement;
input.simulate('focus');

// Simulate selecting and backspacing the '123'
// Also select the preceding '('
inputDOM.setSelectionRange(6, 10);
input.simulate('keyDown', { keyCode: KeyCodes.backspace });
input.simulate('change', mockEvent('mask: 456 - 7890'));
expect(inputDOM.value).toEqual('mask: (___) 456 - 7890');

// Simulate selecting and deleting the '456'
// also select the proceding ' '
inputDOM.setSelectionRange(12, 16);
input.simulate('keyDown', { keyCode: KeyCodes.del });
input.simulate('change', mockEvent('mask: (___) - 7890'));
expect(inputDOM.value).toEqual('mask: (___) ___ - 7890');
});

it('should paste characters', () => {
const component = mount(
<MaskedTextField
label='With input mask'
mask='m\ask: (999) 999 - 9999'
value='123-456-7890'
/>
);

const input = component.find('input'),
inputDOM = input.getDOMNode() as HTMLInputElement;
input.simulate('focus');

// Paste a 7777 into the start of the input
inputDOM.setSelectionRange(0, 0);
input.simulate('paste');
input.simulate('change', mockEvent('7777mask: (123) 456 - 7890'));
expect(inputDOM.value).toEqual('mask: (777) 756 - 7890');

// Paste a 9999 into the end
inputDOM.setSelectionRange(22, 22);
input.simulate('paste');
input.simulate('change', mockEvent('mask: (777) 756 - 78909999'));
expect(inputDOM.value).toEqual('mask: (777) 756 - 7890');

// Paste invalid characters mixed with valid characters
inputDOM.setSelectionRange(0, 0);
input.simulate('paste');
input.simulate('change', mockEvent('1a2b3cmask: (777) 756 - 7890'));
expect(inputDOM.value).toEqual('mask: (123) 756 - 7890');
});

it('should paste over selected characters', () => {
const component = mount(
<MaskedTextField
label='With input mask'
mask='m\ask: (999) 999 - 9999'
value='123-456-7890'
/>
);

const input = component.find('input'),
inputDOM = input.getDOMNode() as HTMLInputElement;
input.simulate('focus');

// Paste a 000 over the '123'
inputDOM.setSelectionRange(7, 10);
input.simulate('paste');
input.simulate('change', mockEvent('mask: (000) 456 - 7890'));
expect(inputDOM.value).toEqual('mask: (000) 456 - 7890');

// Replace all characters with a paste
inputDOM.setSelectionRange(0, 22);
input.simulate('paste');
input.simulate('change', mockEvent('98765'));
expect(inputDOM.value).toEqual('mask: (987) 65_ - ____');
});

it('should replace selected text a char added', () => {
const component = mount(
<MaskedTextField
label='With input mask'
mask='m\ask: (999) 999 - 9999'
value='123-456-7890'
/>
);

const input = component.find('input'),
inputDOM = input.getDOMNode() as HTMLInputElement;
input.simulate('focus');

// Replace '23) 45' text with '6'
inputDOM.setSelectionRange(8, 14);
input.simulate('keyDown', { keyCode: KeyCodes.six });
inputDOM.setSelectionRange(9, 9);
input.simulate('change', mockEvent('mask: (166 - 7890'));
expect(inputDOM.value).toEqual('mask: (16_) __6 - 7890');

// Replace all text with '9'
inputDOM.setSelectionRange(0, 22);
input.simulate('keyDown', { keyCode: KeyCodes.nine });
inputDOM.setSelectionRange(1, 1);
input.simulate('change', mockEvent('9'));
expect(inputDOM.value).toEqual('mask: (9__) ___ - ____');
});

it('should ignore overflowed characters', () => {
const component = mount(
<MaskedTextField
label='With input mask'
mask='m\ask: (999) 999 - 9999'
value='123-456-7890'
/>
);

const input = component.find('input'),
inputDOM = input.getDOMNode() as HTMLInputElement;
input.simulate('focus');

// Add '1' to the end
inputDOM.setSelectionRange(22, 22);
input.simulate('keyDown', { keyCode: KeyCodes.one });
inputDOM.setSelectionRange(23, 23);
input.simulate('change', mockEvent('mask: (123) 456 - 78901'));
expect(inputDOM.value).toEqual('mask: (123) 456 - 7890');
});
});
Loading