Skip to content

Commit

Permalink
feat(Input): support froze value on input, close #389
Browse files Browse the repository at this point in the history
  • Loading branch information
Javey committed Nov 14, 2019
1 parent 4ad619f commit d93d6ce
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 5 deletions.
45 changes: 45 additions & 0 deletions components/input/demos/frozen.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
---
title: 输入过程中禁止更新
order: 7
---

默认情况下`value`变化,就会更新视图的`value`值,但这会打断用户的输入,当添加`frozenOnInput`属性时,组件的`value`
在输入的过程中被冻结,输入完成后,组件才会更新最新的`value`到视图

```vdt
import {Input} from 'kpc/components/input';
<div>
<Input value={{ self.get('value') }} ev-input={{ self._onInput }} />
<br />
<Input frozenOnInput value={{ self.get('value') }} ev-input={{ self._onInput }} />
</div>
```

```styl
.k-input
margin 5px
```

```js
import tinycolor from 'tinycolor2';

export default class extends Intact {
@Intact.template()
static template = template;

defaults() {
return {
value: '#ddd'
};
}

_onInput(e) {
const value = e.target.value.trim();
const color = tinycolor(value);
if (color.isValid()) {
this.set('value', color.toHexString());
}
}
}
```
17 changes: 16 additions & 1 deletion components/input/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export default class Input extends Intact {
autocomplete: String,
nativeProps: Object,
stackClearIcon: Boolean,
frozenOnInput: Boolean,
};

defaults() {
Expand All @@ -52,8 +53,11 @@ export default class Input extends Intact {
autocomplete: undefined,
nativeProps: undefined,
stackClearIcon: false,
frozenOnInput: false,

_width: 1,
_inputing: false,
_originalValue: '',
}
}

Expand Down Expand Up @@ -92,8 +96,19 @@ export default class Input extends Intact {
this.refs.input.blur();
}

_startInput(e) {
this.set({_inputing: true, _originalValue: e.target.value});
this.trigger('focus', e);
}

_endInput(e) {
this.set({_inputing: false});
this.trigger('blur', e);
}

_onInput(e) {
this.set('value', e.target.value);
const value = e.target.value;
this.set({value, _originalValue: value});
this.trigger('input', e);
}

Expand Down
1 change: 1 addition & 0 deletions components/input/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ sidebar: doc
| autocomplete | 原生`autocomplete`属性 | `String` | `undefined` |
| nativeProps | 原生`input``textarea`上的属性 | `Object` | `undefined` |
| stackClearIcon | 是否将清空按钮覆盖在`suffix`按钮上展示来节省空间 | `Boolean` | `false` |
| frozenOnInput | 是否在输入的过程中冻结`value`更新到视图 | `Boolean` | `false` |


## Search
Expand Down
16 changes: 16 additions & 0 deletions components/input/index.spec.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import BasicDemo from '~/components/input/demos/basic';
import {mount, unmount, dispatchEvent} from 'test/utils';
import SearchDemo from '~/components/input/demos/search';
import FrozenDemo from '~/components/input/demos/frozen';

describe('Input', () => {
let instance;
Expand Down Expand Up @@ -49,4 +50,19 @@ describe('Input', () => {
document.body.click();
expect(instance.element.innerHTML).to.matchSnapshot();
});

it('should frozen value on input', () => {
instance = mount(FrozenDemo);

const [input1, input2] = instance.element.querySelectorAll('input');
dispatchEvent(input2, 'focusin');
input2.value = '#123';
dispatchEvent(input2, 'input');

expect(input1.value).to.eql('#112233');
expect(input2.value).to.eql('#123');

dispatchEvent(input2, 'focusout');
expect(input2.value).to.eql('#112233');
});
});
14 changes: 10 additions & 4 deletions components/input/index.vdt
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@ const {
readonly, clearable, disabled, size, nativeProps,
rows, spellcheck, defaultValue, style, _width,
className, autoWidth, fluid, width, autocomplete,
stackClearIcon,
stackClearIcon, frozenOnInput, _inputing, _originalValue
} = self.get();

const inputValue = frozenOnInput && _inputing ? _originalValue : value;

const classNameObj = {
'k-input': true,
[`k-${size}`]: size !== 'default',
Expand All @@ -25,7 +27,7 @@ const classNameObj = {

const events = [
'keydown', 'keyup', 'change',
'keypress', 'focus', 'blur', /* 'input' */
'keypress', /* 'focus', 'blur', */ /* 'input' */
].reduce((memo, name) => {
memo[`ev-${name}`] = self._proxyEvent.bind(self, name);
return memo;
Expand Down Expand Up @@ -63,7 +65,9 @@ const wrapperEvents = [
class="k-inner"
type={{ type }}
name={{ name }}
value={{ value }}
value={{ inputValue }}
ev-focus={{ self._startInput }}
ev-blur={{ self._endInput }}
ev-input={{ self._onInput }}
defaultValue={{ defaultValue }}
readOnly={{ readonly }}
Expand All @@ -78,7 +82,9 @@ const wrapperEvents = [
<textarea v-else
{{ ...(nativeProps || {}) }}
class="k-inner k-textarea"
value={{ value }}
value={{ inputValue }}
ev-focus={{ self._startInput }}
ev-blur={{ self._endInput }}
ev-input={{ self._onInput }}
defaultValue={{ defaultValue }}
name={{ name }}
Expand Down

0 comments on commit d93d6ce

Please sign in to comment.