Permalink
Browse files

feat(form-input): emit input event when lazy-formatter is true (#1086)

* feat(form-input): fire input event when lazy-formatter is true

Trigger `input` event event when lazy-formatter is set to true.

Also adds proper styling to color and range inputs

* ESLint

* Update README.md

* Add supported input types

* Update README.md

* Update demo.html
  • Loading branch information...
tmorehouse committed Sep 20, 2017
1 parent cd29b7a commit 016591c805fadc842df00366e491ad952b3f6cfa
Showing with 87 additions and 54 deletions.
  1. +40 −26 docs/components/form-input/README.md
  2. +44 −7 lib/components/form-input.vue
  3. +3 −21 tests/fixtures/form-input/demo.html
@@ -1,4 +1,4 @@
# Textual inputs
# Textual and Value inputs
> Create various text style inputs such as: `text`, `password`, `number`, `url`,
`email`, `search`, and more.
@@ -26,37 +26,47 @@
## Input type
`<b-form-input>` defaults to a `text` input, but you can set it to any other text-like
type, such as `password`, `number`, `url`, `email`, etc, by setting the `type` prop to the
appropriate value.
`<b-form-input>` defaults to a `text` input, but you can set teh `type` prop to one
of the supported types: `text`, `password`, `email`, `number`, `url`, `tel`, `search`,
`date`, `datetime`, `datetime-local`, `month`, `week`, `time`,`range`, or `color`.
```html
<b-container fluid>
<b-row class="my-1">
<b-col sm="3"><label for="input-text">Type Text:</label></b-col>
<b-col sm="9"><b-form-input id="input-text" type="text"></b-form-input></b-col>
</b-row>
<b-row class="my-1">
<b-col sm="3"><label for="input-passwd">Type Password:</label></b-col>
<b-col sm="9"><b-form-input id="input-passwd" type="password"></b-form-input></b-col>
</b-row>
<b-row class="my-1">
<b-col sm="3"><label for="input-email">Type Number:</label></b-col>
<b-col sm="9"><b-form-input id="input-email" type="email"></b-form-input></b-col>
</b-row>
<b-row class="my-1">
<b-col sm="3"><label for="input-number">Type Number:</label></b-col>
<b-col sm="9"><b-form-input id="input-number" type="number"></b-form-input></b-col>
</b-row>
<b-row class="my-1">
<b-col sm="3"><label for="input-url">Type URL:</label></b-col>
<b-col sm="9"><b-form-input id="input-url" type="url"></b-form-input></b-col>
</b-row>
</b-container>
<template>
<b-container fluid>
<b-row class="my-1" v-for="type in types" :key="type">
<b-col sm="3"><label :for="`type-${type}`">Type {{ type }}:</label></b-col>
<b-col sm="9"><b-form-input :id="`type-${type}`" :type="type"></b-form-input></b-col>
</b-row>
</b-container>
</template>
<script>
export default {
data: {
types: [
'text', 'password', 'email', 'number', 'url',
'tel', 'date', `time`, 'range', 'color'
]
}
}
</script>
<!-- form-input-types.vue -->
```
If prop `type` is set to an unsupported value, a `text` input will be rendered.
Not all browsers support all types, nor do some types render in the same format across
browser types/version. Browsers that do not support a particular type will fall back to
a `text` input type.
Chrome lost support for `datetime` in version 26, Opera in version 15, and Safari in iOS 7.
Instead of using `datetime`, since support should be deprecated, use `date` and `time`
as two separate input types.
For date an time style input, when supported, the displayed value in the GUI may be different
than what is return by it's value.
## Control sizing
@@ -253,6 +263,10 @@ No formatting occurs if a `formatter` is not provided.
<!-- form-input-formatter.vue -->
```
**Note:** When using a non-text-like input (i.e. `color`, `range`, `date`, etc),
ensure that your formatter function returns the value in the expected format
for the input type. The formatter **must** return the value as a string.
## Readonly plain text
@@ -15,8 +15,44 @@
@change="onChange($event.target.value, $event)"/>
</template>
<style>
/* Special styling for type=range and color input */
input.form-control[type="range"],
input.form-control[type="color"] {
height: 36px;
height: 2.25rem;
}
input.form-control.form-control-sm[type="range"],
input.form-control.form-control-sm[type="color"] {
height: 31px;
height: 1.9375rem;
}
input.form-control.form-control-lg[type="range"],
input.form-control.form-control-lg[type="color"] {
height: 48px;
height: 3rem;
}
/* Less padding on type=color */
input.form-control[type="color"] {
padding: 8px 8px;
padding: 0.25rem 0.25rem;
}
input.form-control.form-control-sm[type="color"] {
padding: 4px 5px;
padding: 0.125rem 0.125rem;
}
</style>
<script>
import { idMixin, formMixin, formSizeMixin, formStateMixin } from '../mixins';
import { arrayIncludes } from '../utils/array';
// Valid input types
const TYPES = [
'text', 'password', 'email', 'number', 'url', 'tel', 'search', 'range', 'color',
`date`, `time`, `datetime`, `datetime-local`, `month`, `week`
];
export default {
mixins: [idMixin, formMixin, formSizeMixin, formStateMixin],
data() {
@@ -30,7 +66,8 @@
},
type: {
type: String,
default: 'text'
default: 'text',
validator: (type) => arrayIncludes(TYPES, type)
},
ariaInvalid: {
type: [Boolean, String],
@@ -62,11 +99,8 @@
},
computed: {
localType() {
if (this.type === 'radio' || this.type === 'checkbox') {
// This component doesn't support radio or checkbox
return 'text';
}
return this.type || 'text';
// We only allow certain types
return arrayIncludes(TYPES, this.type) ? this.type : 'text';
},
inputClass() {
return [
@@ -111,7 +145,10 @@
return value;
},
onInput(value, e) {
if (!this.lazyFormatter) {
if (this.lazyFormatter) {
// Update the model with the current unformated value
this.localValue = value;
} else {
this.localValue = this.format(value, e);
}
},
@@ -1,31 +1,13 @@
<div id="app">
<b-form-input v-model="text" placeholder="Enter your name"></b-form-input>
<br><br>
<b-form-input v-model="textformatter" placeholder="Enter your name" :formatter="format"></b-form-input>
<small class="text-muted">We will convert your name to lowercase instantly</small>
<br><br>
<b-form-input v-model="textlazy" type="text" placeholder="Enter your name" :formatter="format" lazy-formatter></b-form-input>
<small class="text-muted">We will convert your name to lowercase on change</small>
<br><br>
<b-form-input state="valid" v-model="text" placeholder="valid"></b-form-input>
<br><br>
<b-form-input v-model="text" state="valid" placeholder="valid"></b-form-input>
<b-form-input state="invalid" v-model="text" placeholder="invalid"></b-form-input>
<br><br>
<b-form-input v-model="text" state="invalid" placeholder="invalid"></b-form-input>
<b-form-input type="password" v-model="text" placeholder="password"></b-form-input>
<br><br>
<!-- This one should render as a text input -->
<b-form-input type="radio" v-model="radio"></b-form-input>
<br><br>
<!-- This one should render as a text input -->
<b-form-input type="checkbox" v-model="check"></b-form-input>
<br><br>
<p>Value: {{text}}</p>
<b-form-input v-model="text" type="password" placeholder="password"></b-form-input>
</div>

0 comments on commit 016591c

Please sign in to comment.