UNPKG

bootstrap-vue

Version:

With more than 85 components, over 45 available plugins, several directives, and 1000+ icons, BootstrapVue provides one of the most comprehensive implementations of the Bootstrap v4 component and grid system available for Vue.js v2.6, complete with extens

412 lines (328 loc) 12.1 kB
# Form Spinbutton > Spin buttons are a BootstrapVue custom numerical range form control. Spin buttons allow for > incrementing or decrementing a numerical value within a range of a minimum and maximum number, > with optional step value. ## Overview The component `<b-form-spinbutton>` is [WAI-ARIA compliant](https://www.w3.org/TR/wai-aria-practices-1.2/#spinbutton), allowing for [keyboard control](#accessibility), and supports both horizontal (default) and vertical layout. Similar to [range type inputs](/docs/components/form-input#range-type-input), BootstrapVue's `<b-form-spinbutton>` _does not_ allow the user to type in a value. ```html <template> <div> <label for="demo-sb">Spin Button</label> <b-form-spinbutton id="demo-sb" v-model="value" min="1" max="100"></b-form-spinbutton> <p>Value: {{ value }}</p> </div> </template> <script> export default { data() { return { value: 50 } } } </script> <!-- b-form-spinbutton-demo.vue --> ``` The <kbd>ArrowUp</kbd> and <kbd>ArrowDown</kbd> keys can be used to increment or decrement the value. To be submitted via native browser form submits, the spinbutton must have a name set via the `name` prop. This will create a hidden input containing the current value of the spinbutton. If the spinbutton does not have a value, the hidden input's value will be an empty string. ## `v-model` value The `v-model` always returns the value as a number. The `v-model` can be `null` if no initial value is set. If the initial value is `null` no value will be displayed in the spinbutton. Use the `placeholder` prop to show a string when the spinbutton has no value (i.e. `placeholder="--"`). ## Min, max, and step Spinbuttons have a default range from `1` to `100`, which can be changed by setting the `min` and `max` props. The default step increment is `1`, and can be changed via the `step` prop (decimal values allowed). When `step` is set, the value will always be a multiple of the step size plus the minimum value. ```html <template> <div> <label for="sb-step">Spin button with step of 0.25</label> <b-form-spinbutton id="sb-step" v-model="value" min="0" max="10" step="0.25" ></b-form-spinbutton> </div> </template> <script> export default { data() { return { value: 0 } } } </script> <!-- b-form-spinbutton-step.vue --> ``` ## Number wrapping By default, when the value is increased to the `max` value, it pressing the increment button will have no effect. Similarly when the value is as the `min` value, pressing the decrement button will have no effect. To allow the spin button to wrap from max to min when incrementing (or min to max when decrementing), set the `wrap` prop to `true`. ```html <template> <div> <label for="sb-wrap">Wrapping value spin button</label> <b-form-spinbutton id="sb-wrap" wrap min="1" max="25" placeholder="--"></b-form-spinbutton> </div> </template> <!-- b-form-spinbutton-wrap.vue --> ``` ## Styling ### Size As with other form controls, `<b-form-spinbutton>` supports small and large sizing via setting the `size` prop to either `'sm'` or `'lg'`, respectively. ```html <template> <div> <label for="sb-small">Spin button - Small size</label> <b-form-spinbutton id="sb-small" size="sm" placeholder="--" class="mb-2"></b-form-spinbutton> <label for="sb-default">Spin button - Default size</label> <b-form-spinbutton id="sb-default" placeholder="--" class="mb-2"></b-form-spinbutton> <label for="sb-large">Spin button - Large size</label> <b-form-spinbutton id="sb-large" size="lg" placeholder="--" class="mb-2"></b-form-spinbutton> </div> </template> <!-- b-form-spinbutton-size.vue --> ``` ### Inline ```html <template> <div> <label for="sb-inline">Inline spin button</label> <b-form-spinbutton id="sb-inline" v-model="value" inline></b-form-spinbutton> </div> </template> <script> export default { data() { return { value: 50 } } } </script> <!-- b-form-spinbutton-inline.vue --> ``` The spin button will automatically adjust it's width to fit the displayed value. See the [Width section](#width) below for details on controlling or setting the width. ### Vertical Spinbuttons can be oriented in vertical mode: ```html <template> <div> <label for="sb-vertical">Vertical spin button</label><br> <b-form-spinbutton id="sb-vertical" v-model="value" vertical></b-form-spinbutton> </div> </template> <script> export default { data() { return { value: 50 } } } </script> <!-- b-form-spinbutton-vertical.vue --> ``` Vertical spin buttons can also be sized using the [`size` prop](#size). When in vertical mode, the spin button is rendered as an inline element. The spin button will automatically adjust it's width to fit the displayed value. See the [Width section](#width) below for details on controlling or setting the width. ### Width The control (when not `vertical` or `inline`) will expand to the maximum width of the parent container You can control width via utility classes such as `w-25`, `w-50`, `w-75`, or use styles to set the width. When either `vertical` or `inline` is set, the control will adjust its width based on the displayed value. You can use css style to control the overall width of the control (i.e. `style="width: 10rem;`). ### Number formatting and locale By default `<b-form-spinbutton>` will format the displayed number in the users browser default locale. You can change the localized formatting by specifying a locale (or array of locales) via the `locale` prop. Number format localization is performed via [`Intl.NumberFormat`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NumberFormat). The locales available will be dependent on the browser implementation. Localization only controls the presentation of the value to the user, and does not affect the `v-model`. ```html <template> <div> <label for="sb-locales">Locale</label> <b-form-select id="sb-locales" v-model="locale" :options="locales"></b-form-select> <label for="sb-local" class="mt-2">Spin button with locale</label> <b-form-spinbutton id="sb-locale" v-model="value" :locale="locale" min="0" max="10" step="0.125" ></b-form-spinbutton> <p>Value: {{ value }}</p> </div> </template> <script> export default { data() { return { value: 0, locale: 'fr-CA', locales: [ { value: 'en', text: 'English' }, { value: 'de', text: 'German' }, { value: 'fr-CA', text: 'French (Canadian)' }, { value: 'fa', text: 'Persian' }, { value: 'ar-EG', text: 'Arabic (Egyptian)' } ] } } } </script> <!-- b-form-spinbutton-locale.vue --> ``` Alternatively, you can provide your own number formatter function to format the value displayed. This is useful for displaying text instead of a number, or if you want to implement different features of `Intl.NumberFormat`. To provide a formatter function, set the prop `formatter-fn` to a method reference. The formatter is passed a single argument which is the current value. Note the formatter only affects the value displayed to the user and does not affect the `v-model`. ```html <template> <div> <label for="sb-days" class="mt-2">Spin button with formatter</label> <b-form-spinbutton id="sb-days" v-model="value" :formatter-fn="dayFormatter" min="0" max="6" wrap ></b-form-spinbutton> <p>Value: {{ value }}</p> </div> </template> <script> export default { data() { return { value: 0, days: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'] } }, methods: { dayFormatter(value) { return this.days[value] } } } </script> <!-- b-form-spinbutton-formatter.vue --> ``` ## Disabled and readonly states Setting the prop `disabled` places the component in a disabled, non-interactive state. The `readonly` prop places the component in a readonly state (focusable, but the value cannot be changed by the user). ```html <template> <b-row> <b-col md="6" class="mb-2"> <label for="sb-disabled">Disabled spin button</label> <b-form-spinbutton id="sb-disabled" v-model="value" disabled></b-form-spinbutton> </b-col> <b-col md="6" class="mb-2"> <label for="sb-readonly" class="">Readonly spin button</label> <b-form-spinbutton id="sb-readonly" v-model="value" readonly></b-form-spinbutton> </b-col> </b-row> </template> <script> export default { data() { return { value: 50 } } } </script> <!-- b-form-spinbutton-disabled-readonly.vue --> ``` Disabled spinbuttons will not be submitted during native browser form submission, while a readonly spinbutton will be submitted (as long as a name has been set via the `name` prop). ## Validation states When you default to a `null` value, and the user has not selected a value, you can use the `state` prop to apply one of the contextual validation styles to the component. - `true` applies the valid styling to the component - `false` applies the invalid styling to the component - `null` applies no contextual styling (the default) ### Required prop Note that the required prop only generates the `aria-required="true"` attribute on the component, and does not perform any validation on form submit. You must validate the `v-model` in your application logic. Note that if the prop `required` is set, and the `v-model` is `null`, the attribute `aria-invalid="true"` will be rendered on the component. ## Events The `input` event is used to update the `v-model` and is emitted any time the value changes. The `change` event is emitted once the user releases the mouse button (when pressing the increment or decrement buttons) or when the user releases the <kbd>ArrowDown</kbd> or <kbd>ArrowUp</kbd> key. This can be handy when you need to debounce the input. The following example illustrates the difference between the `input` and `change` events. Click and hold the increment or decrement button (or use the up/down arrow keys). ```html <template> <div> <label for="sb-input">Spin button - input and change events</label> <b-form-spinbutton id="sb-input" v-model="value1" @change="value2 = $event" wrap ></b-form-spinbutton> <p>Input event: {{ value1 }}</p> <p>Change event: {{ value2 }}</p> </div> </template> <script> export default { data() { return { value1: 0, value2: null } } } </script> <!-- b-form-spinbutton-events.vue --> ``` ## Accessibility The following keyboard controls are available when the spin button is focused: - <kbd>Home</kbd> Sets the value to the `min` value - <kbd>End</kbd> Sets the value to the `max` value - <kbd>ArrowUp</kbd> Increases the value by the step amount - <kbd>ArrowDown</kbd> Decreases the value by the step amount - <kbd>PageUp</kbd> Increases the value by the step amount times the `repeat-step-multiplier` amount - <kbd>PageDown</kbd> Decreases the value by the step amount times the `repeat-step-multiplier` amount Pressing an holding the <kbd>ArrowUp</kbd>, <kbd>ArrowDown</kbd>, <kbd>PageUp</kbd>, or <kbd>PageDown</kbd> keys will auto-repeat the increment or decrement (after an initial delay). Holding down the <kbd>ArrowUp</kbd> or <kbd>ArrowDown</kbd> keys for an extended period will multiply the increment or decrement amount by the `repeat-step-multiplier` amount. Note the the `repeat-delay`, `repeat-threshold` and `repeat-interval` only applies to the <kbd>ArrowUp</kbd> or <kbd>ArrowDown</kbd> keys. ## Implementation notes `<b-form-spinbutton>` uses a mixture of Bootstrap v4 utility classes (border, alignment, flex), form-control and button classes, along with additional custom BootstrapVue SCSS/CSS. ## See also - [Range type input](/docs/components/form-input#range-type-input)