Categories
BootstrapVue

BootstrapVue — Jumbotrons and Layouts

To make good looking Vue apps, we need to style our components. To make our lives easier, we can use components with styles built-in. In this article, we’ll look at how to add jumbotrons. We also look at how to create basic layouts.

Customizing Jumbotrons

We can add HTML content into a jumbotron by populating slots.

For example, we can write:

<template>
  <div id="app">
    <b-jumbotron>
      <template v-slot:header>Hello</template>

      <template v-slot:lead>Lead</template>

      <p>World</p>
      <b-button variant="primary" href="#">Go Somewhere</b-button>
    </b-jumbotron>
  </div>
</template>
<script>
export default {
  name: "App"
};
</script>

We added the template tags.

And we have the v-slot directives to populate different slots.

header lets us set the header contents.

lead lets us set the lead content, which is displayed below the header .

Header and Lead Tags

We can change the header and lead tags with the header-tag and lead-tag props.

For instance, we can write:

<template>
  <div id="app">
    <b-jumbotron header="Hello" lead="Lead" header-tag="h2" lead-tag="p">
      <p>World</p>
      <b-button variant="primary" href="#">Go Somewhere</b-button>
    </b-jumbotron>
  </div>
</template>
<script>
export default {
  name: "App"
};
</script>

Now we set the header and lead tags to h2 and p respectively.

Styling Variants

We can change the styling by using the bg-variant prop to change the background.

It can take the values info , danger , warning , light and dark .

The border can set with the border-variant prop. And the text style can ve set with the text-variant prop.

For instance, we can write:

<template>
  <div id="app">
    <b-jumbotron text-variant='light' bg-variant="info" header="Hello" lead="Lead">
      <p>World</p>
      <b-button variant="primary" href="#">Go Somewhere</b-button>
    </b-jumbotron>
  </div>
</template>
<script>
export default {
  name: "App"
};
</script>

Then we get white text on a green background.

Layout and Grid System

BootstrapVue has its own layout and grid components.

It comes with the b-container , b-row , and b-col components.

For example, we can write:

<template>
  <div id="app">
    <b-container>
      <b-row>
        <b-col>1</b-col>
        <b-col>2</b-col>
        <b-col>3</b-col>
      </b-row>
    </b-container>
  </div>
</template>
<script>
export default {
  name: "App"
};
</script>

We used the b-container component to contain a b-row , and that contains 3 b-col components.

b-row is a row and b-col is a column.

We can make it responsive with the fluid prop.

Responsive Fluid Containers

The fluid prop can take on a size value that indicates on what screen size it’s 100% wide.

For instance, we can write:

<b-container fluid="sm">
  hello
</b-container>

so it’s 100% wide until the app hits the small breakpoint.

Likewise, 'md' is 100% wide until the medium breakpoint.

'lg' is 100% wide until the large breakpoint.

'xl' is 100% wide until the extra-large breakpoint.

Rows

The b-row and b-form-row components let us add rows.

b-form-row is different from b-row in that the margins of b-form-row are smaller.

Columns

We can create columns with equal without any props and the b-col component.

We can write:

<template>
  <div id="app">
    <b-container>
      <b-row>
        <b-col>1</b-col>
        <b-col>2</b-col>
        <b-col>3</b-col>
      </b-row>
    </b-container>
  </div>
</template>
<script>
export default {
  name: "App"
};
</script>

to create them.

We can also create equal width multiline columns by adding a div with class w-100 between the columns.

For instance, if we have:

<template>
  <div id="app">
    <b-container>
      <b-row>
        <b-col>1</b-col>
        <b-col>2</b-col>
        <div class="w-100"></div>
        <b-col>3</b-col>
        <b-col>4</b-col>
      </b-row>
    </b-container>
  </div>
</template>
<script>
export default {
  name: "App"
};
</script>

Then we have 2 columns on top and 2 below them.

Setting One Column Width

We can change the column width the cols prop.

For example, we can write:

<template>
  <div id="app">
    <b-container>
      <b-row>
        <b-col>1</b-col>
        <b-col cols="8">2</b-col>
        <b-col>3</b-col>
      </b-row>
    </b-container>
  </div>
</template>
<script>
export default {
  name: "App"
};
</script>

We have cols set to 8 so that the column takes 8 / 12 of the screens’ width.

A grid is divided into 12 columns.

The other columns will fill the remaining space evenly.

Conclusion

We can add columns and rows to create responsive rows and columns.

Jumbotrons can be used to display attention-grabbing text.

Categories
BootstrapVue

BootstrapVue — Form Tags

To make good looking Vue apps, we need to style our components.

To make our lives easier, we can use components with styles built-in.

In this article, we’ll look at how to add form tags to our forms.

Form Tags

Form tags are custom tagged input form control.

We can customize it and allow duplicate tag selection and tag validation.

To add it, we can use the b-form-tags component.

For instance, we can write:

<template>
  <div id="app">
    <b-form-tags v-model="value"></b-form-tags>
    <p>Value: {{ value }}</p>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {
      value: ["banana", "grape"]
    };
  }
};
</script>

to display an input that lets us enter tags.

v-model will bind the inputted values to an array as we can see from the p element.

When we press Enter, we’ll add the value.

We can add the no-add-on-enter prop to disable adding a new tag on entering.

And we can add tags on change with the add-on-change prop.

Tag Creation with Separators

Tag creation can be added with separators.

We can add the separator tag with all the separators we want to let users use.

For instance, we can write:

<template>
  <div id="app">
    <b-form-tags v-model="value" separator=" ,"></b-form-tags>
    <p>Value: {{ value }}</p>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {
      value: ["banana", "grape"]
    };
  }
};
</script>

Then we can use the space and the comma as separators.

When we type them, we’ll see a new tag.

Last Tag Removal with Backspace

By default, the b-form-tags component doesn’t remove tags when we press backspace.

To let users press backspace to remove the last tag, we can use the remove-on-delete prop.

For example, we can write:

<template>
  <div id="app">
    <b-form-tags v-model="value" remove-on-delete></b-form-tags>
    <p>Value: {{ value }}</p>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {
      value: ["banana", "grape"]
    };
  }
};
</script>

Then we can remove the last item with backspace.

Styling

We can style the tags with various props.

tag-pills renders the tags with the appearance of the pill.

tag-variant applies the styling variants built into Bootstrap.

size sets the size of the component’s appearance.

placeholder lets us set placeholder text for the input element.

state lets us set the validation state. We set it to true for valid, false for invalid or null .

disabld lets us disable the input.

For instance, we can write:

<template>
  <div id="app">
    <b-form-tags v-model="value" tag-pills size="lg"></b-form-tags>
    <p>Value: {{ value }}</p>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {
      value: ["banana", "grape"]
    };
  }
};
</script>

Then the tags are more rounded and the size is bigger.

Tag Validation

We can use the tag-validator to validate the tags.

For instance, we can write:

<template>
  <div id="app">
    <b-form-tags v-model="value" :tag-validator="tagValidator"></b-form-tags>
    <p>Value: {{ value }}</p>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {
      value: ["banana", "grape"]
    };
  },
  methods: {
    tagValidator(tag) {
      return tag.length > 2;
    }
  }
};
</script>

We have the tag-validator prop set to the tagValidator method.

We check that if the tag’s length is bigger than 2.

We’ll see an error message if the tag doesn’t meet that condition.

Detect New, Invalid and Duplicate Tags

We can listen to the tag-state event.

It’s emitted whenever new tags are entered into the new tag input element.

When tags don’t pass validation or duplicate tags are detected then this will also be emitted.

For instance, we can write:

<template>
  <div id="app">
    <b-form-tags v-model="tags" :tag-validator="validator" @tag-state="onTagState"></b-form-tags>
    <p>Value: {{ tags }}</p>
    <p>Invalid: {{ invalidTags }}</p>
    <p>Duplicate: {{ duplicateTags }}</p>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {
      tags: [],
      validTags: [],
      invalidTags: [],
      duplicateTags: []
    };
  },
  methods: {
    onTagState(valid, invalid, duplicate) {
      this.validTags = valid;
      this.invalidTags = invalid;
      this.duplicateTags = duplicate;
    },
    validator(tag) {
      return tag.length > 2 && tag.length < 6;
    }
  }
};
</script>

We have the onTagState method that’s set as the value of the tag-state event handler.

Also, we have the validator method to set the tag-validator prop.

v-model is used to bind the inputted values to tags .

We display invalid and duplicate tags.

Then when we enter invalid or duplicate tags, they’ll be displayed in the p elements.

Conclusion

We can add the b-form-tags component to add a tags input.

It has features for validation and checking for duplicates.

Categories
BootstrapVue

BootstrapVue — Text Inputs

To make good looking Vue apps, we need to style our components. To make our lives easier, we can use components with styles built-in.

In this article, we’ll look at how to add text input boxes.

Text Inputs

We can create inputs with text or other values with text, password, number, url, email, search, range, date and more.

For instance, we can add one with the b-form-input component by writing:

<template>
  <div id="app">
    <b-form-input v-model="text" placeholder="Enter your name"></b-form-input>
    <div>{{ text }}</div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      text: ""
    };
  }
};
</script>

v-model binds the text state to the inputted value.

Then we display the text value below it.

When we type something, we’ll see it displayed below it.

Input Types

We can set it to different types.

We can set the type prop to the following values:

  • text
  • password
  • number
  • url
  • email
  • search
  • range
  • date
  • color

For instance, we can write:

<template>
  <div id="app">
    <b-form-input v-model="color" placeholder="Enter color" type="color"></b-form-input>
    <div>{{ color }}</div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      color: ""
    };
  }
};
</script>

Then we click the input box, we see a native color picker where we can choose the color. After we pick the color, it’ll be displayed.

v-model.lazy isn’t supported by b-form-input. Instead, we should use the lazy prop for lazy evaluation.

date and time are native browser types. They aren’t customizable date pickers.

Range Type Input

We can set the type prop to range to get a slider.

For instance, we can write:

<template>
  <div id="app">
    <b-form-input v-model="value" type="range" min="0" max="5"></b-form-input>
    <div>Value: {{ value }}</div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      value: 0
    };
  }
};
</script>

to get a slider.

When we slide it then value is updated because of the v-model directive. We can set the steps prop to change the increment or decrement value when we slide.

For example, we can write:

<template>
  <div id="app">
    <b-form-input  v-model="value" type="range" step="0.5" min="0" max="5"></b-form-input>
    <div>Value: {{ value }}</div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      value: 0
    };
  }
};
</script>

Control Sizing

We can change the sizing of the controls with the size prop. The value can be sm or lg.

For instance, we can write:

<template>
  <div id="app">
    <b-form-input size="sm" placeholder="enter your name"></b-form-input>
  </div>
</template>

<script>
export default {};
</script>

Then we get an extra small input box.

Validation States

We can display green if the input value is valid. Otherwise, we can display red.

We can write:

<template>
  <div id="app">
    <b-form-input :state="valid" v-model="name" placeholder="name"></b-form-input>
  </div>
</template>

<script>
export default {
  computed: {
    valid() {
      return this.name.length > 0;
    }
  },
  data() {
    return {
      name: ""
    };
  }
};
</script>

to display a red border when the input value is empty.

Otherwise, we display a green border. The state prop is the validation state.

Formatter

We can add a formatted function to format the input value the way we want.

For instance, we can write:

<template>
  <div id="app">
    <b-form-input :formatter="formatter" v-model="value" placeholder="enter some text"></b-form-input>
    <p>{{value}}</p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      value: ""
    };
  },
  methods: {
    formatter(value) {
      return value.toLowerCase();
    }
  }
};
</script>

We added the formatter prop set to the formatter function. Inside it, we return the value state converted to lower case.

Then when we enter upper case text, it’ll be converted to lower case.

Read-Only Input

We can make the input read-only with the readonly prop.

Disabling Mouse Wheel Events on Numeric-Like Inputs

The no-wheel prop can be set to true to disable mouse wheel events on these inputs.

Datalist

We can add an autocomplete list with the datalist element.

For instance, we can write:

<template>
  <div id="app">
    <b-form-input list="fruits" name="fruit"></b-form-input>
    <datalist id="fruits">
      <option>apple</option>
      <option>orange</option>
      <option>grape</option>
    </datalist>
  </div>
</template>

<script>
export default {};
</script>

The list attribute of the b-form-input component and the id has to be the same.

Debounce

We can add a debounce prop to delay the registering of the input value.

So we can add:

<b-form-input v-model="value" type="text" debounce="500"></b-form-input>

Conclusion

We can add many kinds of text inputs with the b-form-input component.

The value can be formatted and delayed.

Categories
BootstrapVue

BootstrapVue — Spin Button Customization

To make good looking Vue apps, we need to style our components.

To make our lives easier, we can use components with styles built-in.

In this article, we’ll look at how to customize a spin button.

What’s a Spin Button?

A spin button is a numerical range form control.

We can include it with the b-form-spinbutton component.

For example, we can write:

<b-form-spinbutton v-model="value" min="1" max="100"></b-form-spinbutton>

We set the minimum and maximum allowed values with the min and max props.

v-model binds the inputted value to value .

Then we see a form control with a minus button on the left and a plus button on the right.

The number entered will be shown in the middle.

Make it Disabled

We can make the spin button disabled, which means that it’s non-interactive.

For instance. we can write:

<template>  
  <div id="app">  
    <b-form-spinbutton disabled v-model="value" min="1" max="100"></b-form-spinbutton>  
    <p>Value: {{ value }}</p>  
  </div>  
</template>  
<script>  
export default {  
  name: "App",  
  data() {  
    return {  
      value: 0  
    };  
  }  
};  
</script>

We added the disabled prop to make it non-interactive.

Read Only

We can set it to read-only as well.

This means that we can focus on it, but we can’t select a value.

For instance, we can do this with the readonly prop:

<template>  
  <div id="app">  
    <b-form-spinbutton readonly v-model="value" min="1" max="100"></b-form-spinbutton>  
    <p>Value: {{ value }}</p>  
  </div>  
</template>  
<script>  
export default {  
  name: "App",  
  data() {  
    return {  
      value: 0  
    };  
  }  
};  
</script>

Validation States

We can display the validation state.

To do this, we set the state prop.

For instance, we can write:

<template>  
  <div id="app">  
    <b-form-spinbutton :state='isValid' v-model="value" min="1" max="10"></b-form-spinbutton>  
    <p>Value: {{ value }}</p>  
  </div>  
</template>  
<script>  
export default {  
  name: "App",  
  data() {  
    return {  
      value: 0  
    };  
  },  
  computed: {  
    isValid(){  
      return !!this.value;  
    }  
  }  
};  
</script>

We set the state prop to the computed isValid property.

Then everything is green when we set a number.

Otherwise, everything is red.

Events

The b-form-spinbutton component emits a few events.

It emits the change event when the user released the mouse button when pressing the increment or decrement buttons.

For instance, we can write:

<template>  
  <div id="app">  
    <b-form-spinbutton wrap @change="value2 = $event" v-model="value" min="1" max="10"></b-form-spinbutton>  
    <p>Value 1: {{ value }}</p>  
    <p>Value 2: {{ value2 }}</p>  
  </div>  
</template>  
<script>  
export default {  
  name: "App",  
  data() {  
    return {  
      value: 0,  
      value2: 0  
    };  
  }  
};  
</script>

The $event variable has the value of the selected number.

We assigned that to value2 so we can display it in the bottom p element.

Conclusion

We can listen to events emitted by b-form-spinbutton and do something with the emitted value.

Also, we can make the form control disabled or read-only.

Read-only means we can focus but can’t do anything.

Disabled means that it’s not interactive at all.

We can also display the validation state of the control with the state prop.

Categories
BootstrapVue

BootstrapVue — Lazy Load Images and Input Groups

To make good looking Vue apps, we need to style our components. To make our lives easier, we can use components with styles built-in.

In this article, we’ll look at how to add images that only load when we see them. We also look at how to add input groups.

Lazy Loaded Images

Lazy loading images is more efficient since we don’t have to load all the images upfront.

To do that, we can use the b-image-lazy component.

For instance, we can write:

<template>
  <div id="app">
    <b-img-lazy src="http://placekitten.com/200/200" alt="kitten"></b-img-lazy>
  </div>
</template>

<script>
export default {
  name: "App"
};
</script>

Now our app will only load the image when it’s shown on the screen.

Input Groups

We can create input groups, which lets us group inputs with other components together.

To add an input group, we use the b-input-group component.

For instance, we can write:

<template>
  <div id="app">
    <b-input-group size="lg" prepend="$" append=".00">
      <b-form-input></b-form-input>
    </b-input-group>
  </div>
</template>

<script>
export default {
  name: "App"
};
</script>

We change the size of the group to be large with size="lg" .

prepend lets us add something to the left the input.

append lets us add something to the right of the input.

So we should see the dollar sign on the left and .00 on the right. To customize the input group more, we can put code into slots.

For example, we can write:

<template>
  <div id="app">
    <b-input-group>
      <template v-slot:append>
        <b-input-group-text>
          <strong class="text-success">!</strong>
        </b-input-group-text>
      </template>
      <b-form-input></b-form-input>
    </b-input-group>
  </div>
</template>

<script>
export default {
  name: "App"
};
</script>

Then we can add an exclamation mark with that’s green on the right.

Sub-Components

We can add subcomponents into the b-input-group-prepend and b-input-group-append components to add anything we want to the right.

For example, we can write:

<template>
  <div id="app">
    <b-input-group>
      <b-input-group-prepend>
        <b-button variant="primary">left button</b-button>
      </b-input-group-prepend>

      <b-form-input type="text"></b-form-input>

      <b-input-group-append>
        <b-button variant="outline-secondary">right button</b-button>
      </b-input-group-append>
    </b-input-group>
  </div>
</template>

<script>
export default {
  name: "App"
};
</script>

We have the b-input-group-prepend and b-input-group-append components inside the b-input-group component.

This lets us add things that we can’t add with the prepend and append props.

In the example above, we added buttons inside each component.

Support Form Control Inside Input Groups

We can add the following components inside the b-input-group component:

  • <b-form-input>
  • <b-form-textarea>
  • <b-form-select>
  • <b-form-file>
  • <b-form-rating>
  • <b-form-tags>
  • <b-form-spinbutton>
  • <b-form-datepicker>
  • <b-form-timepicker>

Check and Radio Buttons

We can add checkboxes and radio buttons inside the b-input-group-prepend and b-input-group-append components.

For example, we can write:

<template>
  <div id="app">
    <b-input-group>
      <b-input-group-prepend is-text>
        <input type="checkbox">
      </b-input-group-prepend>
      <b-form-input></b-form-input>
    </b-input-group>
  </div>
</template>

<script>
export default {
  name: "App"
};
</script>

We nest a checkbox inside the b-input-geoup-prepend component.

is-text applies the proper content for textual content.

We can also write the following to add a radio button the same way:

<template>
  <div id="app">
    <b-input-group>
      <b-input-group-prepend is-text>
        <input type="radio">
      </b-input-group-prepend>
      <b-form-input></b-form-input>
    </b-input-group>
  </div>
</template>

<script>
export default {
  name: "App"
};
</script>

Custom Radio Button, Checkbox or Switch

The examples above added native radio buttons and checkboxes.

We can also add Bootstrap style radio button, checkbox or switch components.

For example, we can write:

<template>
  <div id="app">
    <b-input-group>
      <b-input-group-prepend is-text>
        <b-form-checkbox></b-form-checkbox>
      </b-input-group-prepend>
      <b-form-input></b-form-input>
    </b-input-group>
  </div>
</template>

<script>
export default {
  name: "App"
};
</script>

to add a b-form-checkbox inside the b-input-group-prepend component.

Other components can be added the same way.

Conclusion

We can add lazy loading images with the b-img-lazy component.

Also, we can add input groups to add components on the left and right of input boxes.