Permalink
Browse files

fix(forms): Adjustments to form-textarea and form-input (#880)

* feat(id): safe client side ID generation

If no ID provided, generates one client side during mount (after SSR rehydration)

* fix(form-textarea): prevent prop mutaion console errors in dev mode

* [form-textarea] meta.json update

* [form-textarea] docs update

* Update form-input.vue

* [form-input] meta docs update

* [form-input] docs update

* Update index.js
  • Loading branch information...
tmorehouse committed Aug 18, 2017
1 parent 2448666 commit 79a7aa8fdc5d5bb13b4bc5adaa7c4322e628a386
@@ -8,7 +8,7 @@
```html
<template>
<div>
<h5>Text input with formatter</h5>
<h5>Text input with formatter (on input)</h5>
<b-form-input v-model="text1"
type="text"
placeholder="Enter your name"
@@ -34,7 +34,7 @@
text2: ''
},
methods: {
format(value, el) {
format(value, event) {
return value.toLowerCase();
}
}
@@ -47,7 +47,7 @@
## 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`, etc, by setting the `type` prop to the
type, such as `password`, `number`, `url`, `email`, etc, by setting the `type` prop to the
appropriate value.

### Readonly plain text
@@ -65,8 +65,10 @@ By default, formatting occurs when the control's native `input` event fires. You
use the boolean prop `lazy-formatter` to restrict the formatter function to being
called on the control's native `change` event (which usually occurs on blur).

The `formatter` function receives two arguments (the raw value of the input, and
teh native event object) and should return the formatted value (as a string).
The `formatter` function receives two arguments: the raw `value` of the input element,
and the native `event` object.

The `formatter` function should return the formatted value (as a string).

No formatting occurs if a `formatter` is not provided.

@@ -76,6 +78,25 @@ Set heights using the `size` prop to `sm` or `lg` for small or large respectivel

To control width, place the input inside standard Bootstrap grid column.

```html
<template>
<div>
<label>Small:</label>
<b-form-input size="sm" type="text" placeholder="Enter your name"></b-form-input>
<label class="mt-3">Default:</label>
<b-form-input type="text" placeholder="Enter your name"></b-form-input>
<label class="mt-3">Large:</label>
<b-form-input size="lg" type="text" placeholder="Enter your name"></b-form-input>
</div>
</template>

<script>
export default { }
</script>

<!-- form-input-size-1.vue -->
```

## Contextual States

Bootstrap includes validation styles for `valid` and `invalid` states
@@ -9,10 +9,6 @@
{
"arg": "value",
"description": "current value of the input"
},
{
"arg": "event",
"description": "Native event object"
}
]
},
@@ -23,10 +19,6 @@
{
"arg": "value",
"description": "current value of the input"
},
{
"arg": "event",
"description": "Native event object"
}
]
}
@@ -5,12 +5,15 @@ and maximum number of rows, and contextual states.
```html
<template>
<b-form-textarea id="textarea1"
:value="text"
placeholder="Enter something"
:rows="3"
:max-rows="5">
</b-form-textarea>
<div>
<b-form-textarea id="textarea1"
v-model="text"
placeholder="Enter something"
:rows="3"
:max-rows="6">
</b-form-textarea>
<pre class="mt-3">{{ text }}</pre>
</div>
</template>

<script>
@@ -30,7 +33,7 @@ and maximum number of rows, and contextual states.
<template>
<b-form-textarea id="textarea2"
state="invalid"
:value="text"
v-model.trim="text"
placeholder="Enter something"
:rows="3"></b-form-textarea>
</template>
@@ -9,24 +9,6 @@
{
"arg": "value",
"description": "current value of the textarea"
},
{
"arg": "event",
"description": "native event object"
}
]
},
{
"event": "change",
"description": "Emitted when the textarea value changes.",
"args": [
{
"arg": "value",
"description": "current value of the textarea"
},
{
"arg": "event",
"description": "native event object"
}
]
}
@@ -2,7 +2,7 @@
<input :id="id || null"
:class="inputClass"
:name="name"
:value="value"
v-model="localValue"
:type="localType"
:disabled="disabled"
:required="required"
@@ -19,6 +19,11 @@
import { formMixin } from '../mixins';
export default {
mixins: [formMixin],
data() {
return {
localValue: this.value
}
},
props: {
value: {
default: null
@@ -95,7 +100,12 @@
watch:{
value(newVal, oldVal) {
if (newVal !== oldVal){
this.$el.value = newVal;
this.localValue = newVal;
}
},
localValue(newVal, oldVal) {
if (newVal !== oldVal){
this.$emit('input', newVal);
}
}
},
@@ -104,23 +114,19 @@
if (this.formatter) {
const formattedValue = this.formatter(value, e);
if (formattedValue !== value) {
this.$el.value = formattedValue;
return formattedValue;
}
}
return value;
},
onInput(value, e) {
let formattedValue = value;
if (!this.lazyFormatter) {
formattedValue = this.format(value, e);
this.localValue = this.format(value, e);
}
this.$emit('input', formattedValue, e);
},
onChange(value, e) {
const formattedValue = this.format(value, e);
this.$emit('input', formattedValue, e);
this.$emit('change', formattedValue, e);
this.localValue = this.format(value, e);
this.$emit('change', this.localValue);
},
focus() {
if(!this.disabled) {
@@ -1,5 +1,5 @@
<template>
<textarea v-model="value"
<textarea v-model="localValue"
:class="inputClass"
:id="id || null"
:name="name"
@@ -12,15 +12,18 @@
:wrap="wrap || null"
:aria-required="required ? 'true' : null"
:aria-invalid="computedAriaInvalid"
@input="onInput($event.target.value, $event)"
@change="onChange($event.target.value, $event)"
></textarea>
</template>

<script>
import { formMixin } from '../mixins';
export default {
mixins: [formMixin],
data() {
return {
localValue: this.value
};
},
props: {
value: {
type: String,
@@ -95,14 +98,21 @@
return this.ariaInvalid;
}
},
methods: {
onInput(value, e) {
this.$emit('input', value, e);
},
onChange(value, e) {
this.$emit('input', value, e);
this.$emit('change', value, e);
watch: {
value(newVal, oldVal) {
// Update our localValue
if (newVal !== oldVal) {
this.localvalue = newVal;
}
},
localValue(newVal, oldVal) {
// update Parent value
if (newVal !== oldVal) {
this.$emit('input', newVal);
}
}
},
methods: {
focus() {
// For external handler that may want a focus method
if(!this.disabled) {
@@ -0,0 +1,28 @@
/*
* SSR Safe Client Side ID attribute generation
*
*/

export default {
props: {
id: {
typ: String,
default: null
}
},
data() {
return {
localId_: null
}
},
mounted() {
if (!this.$isServer && !this.id && this._uid) {
this.localId_ = `__BV__${this._uid}_`;
}
},
computed: {
safeId() {
return this.id || this.localId_ || null;
}
}
};
@@ -5,6 +5,7 @@ import formMixin from "./form";
import formCheckBoxMixin from "./form-checkbox";
import formCustomMixin from "./form-custom";
import formOptionsMixin from "./form-options";
import idMixin from "./id";
import linkMixin from "./link";
import listenOnRootMixin from "./listen-on-root";
import popoverMixin from "./popover";
@@ -17,6 +18,7 @@ export {
formCheckBoxMixin,
formCustomMixin,
formOptionsMixin,
idMixin,
linkMixin,
listenOnRootMixin,
popoverMixin

0 comments on commit 79a7aa8

Please sign in to comment.