Categories
BootstrapVue

BootstrapVue — Scrollspys and Toggles

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 look at how to customize scrollspys. Also, we look at how to use toggles.

Scrollspys and List Groups

Scrollspys works with list groups. So it can highlight the element with the ID that’s shown.

For example, we can write:

<template>
  <div id="app">
    <b-container fluid>
      <b-row>
        <b-col cols="4">
          <b-list-group v-b-scrollspy:listgroup>
            <b-list-group-item href="#list-item-1">Item 1</b-list-group-item>
            <b-list-group-item href="#list-item-2">Item2</b-list-group-item>
            <b-list-group-item href="#list-item-3">Item 3</b-list-group-item>
            <b-list-group-item href="#list-item-4">Item 4</b-list-group-item>
            <b-list-group-item href="#list-item-5">Item 5</b-list-group-item>
          </b-list-group>
        </b-col>

<b-col cols="8">
          <div id="listgroup" style="position:relative; overflow-y:auto; height:300px">
            <h4 id="list-item-1">Item 1</h4>
            <p>{{ text }}</p>
            <h4 id="list-item-2">Item 2</h4>
            <p>{{ text }}</p>
            <h4 id="list-item-3">Item 3</h4>
            <p>{{ text }}</p>
            <h4 id="list-item-4">Item 4</h4>
            <p>{{ text }}</p>
            <h4 id="list-item-5">Item 5</h4>
            <p>{{ text }}</p>
          </div>
        </b-col>
      </b-row>
    </b-container>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {
      text: "lorem ipsum"
    };
  }
};
</script>

We have the b-list-group component that has the v-b-scrollspy directive with the listgroup modifier. That’s the same as the ID of the div that the scrollspy is watching. Therefore, when we scroll up and down, we’ll see the link for the div with the given ID highlighted.

Scrollspy on Components with the to Prop

Scrollspys also works with Vue Router and Nuxt’s router.

For example, we can write:

<b-nav-item to="#id">link</b-nav-item>

or:

<b-nav-item :to="{ hash: '#id' }">link</b-nav-item>

They both link to some element with the given ID, so it’ll work.

Scrollspy Events

We can watch for events emitted by the v-b-scrollspy directive with the thus.$root.$on method.

For example, we can write:

const app = new Vue({
  el: '#app',
  created() {
    this.$root.$on('bv::scrollspy::activate', this.onActivate)
  },
  methods: {
    onActivate(target) {
      console.log(target)
    }
  }
})

Now we watch the activate event emitted by the scrollspy. target has the target element for the scrollspy, which is the element with the ID that is visible.

Toggle

v-b-toggle is a lightweight directive for toggling the visibility of collapses and sidebars.

For instance, we can use it by writing:

<template>
  <div id="app">
    <b-button v-b-toggle.collapse>toggle</b-button>

    <b-collapse id="collapse">
      <b-card title="Collapsible card">hello!</b-card>
    </b-collapse>
  </div>
</template>

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

We have a b-button with the v-b-toggle directive. It also has the collapse modifier. The modifier name matches the id value of the b-collapse component. Therefore, it’ll toggle the b-collapse component on and off. Likewise, we can toggle the sidebar on and off with the v-b-toggle directive.

For example, we can write:

<template>
  <div id="app">
    <b-button v-b-toggle.sidebar>toggle</b-button>

    <b-sidebar id="sidebar" title="Sidebar" shadow>
      <div class="px-3 py-2">
        lorem ipsum
      </div>
    </b-sidebar>
  </div>
</template>

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

We have the b-sidebar component which has the id set to sidebar . This matches the modifier name, so it’ll toggle on and off the sidebar.

Hiding and Showing Content in the Toggle Trigger Element

The when-open and when-close classes will be added to the button that toggles the collapse or sidebar. Therefore, we can use it to hide and show content depending on the toggle status of those components.

For example, we can write:

<template>
  <div id="app">
    <b-button v-b-toggle.collapse>
      <span class="when-open">close</span>
      <span class="when-closed">open</span>
      collapse
    </b-button>

<b-collapse id="collapse">collapse</b-collapse>
  </div>
</template>

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

<style>
.collapsed > .when-open,
.not-collapsed > .when-closed {
  display: none;
}
</style>

When the collapse is open, we see ‘close collapse’. Otherwise, we see ‘open collapse’.

This is because we hide content if we have .collapsed > .when-open or the .not-collapsed > .when-closed selectors.

Conclusion

We can use scrollspys to highlight links in list groups. Also, we can use toggles to toggle collapses and sidebars on and off.

Categories
BootstrapVue

BootstrapVue — Customize Popover and Scrollspys

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 look at how to customize the v-b-popover directives.

Also, we look at how to add a scrollspy to highlight the link of the element with the given ID that’s in the viewport.

Variants and Custom Class

We can use the variant prop to change the styling variant.

For example, we can write:

<template>
  <div id="app">
    <b-button v-b-popover="options">Hover Me</b-button>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {
      options: {
        title: "This is the <b>title</b>",
        content: "This is the <i>content<i>",
        html: true,
        variant: 'info'
      }
    };
  }
};
</script>

Now the popover has a green background since we set the variant property to 'info' .

ScrollSpy

A scrollspy is a directive that updates the value of the navigation according to the location of the page the user is in.

To add a scrollspy, we can use the v-b-scrollspy directive.

For example, we can write:

<template>
  <div id="app">
    <b-card no-body>
      <b-nav pills card-header slot="header" v-b-scrollspy:nav-scroller>
        <b-nav-item href="#foo">foo</b-nav-item>
        <b-nav-item-dropdown text="dropdown" right-alignment>
          <b-dropdown-item href="#one">one</b-dropdown-item>
          <b-dropdown-item href="#two">two</b-dropdown-item>
          <b-dropdown-divider></b-dropdown-divider>
          <b-dropdown-item href="#three">three</b-dropdown-item>
        </b-nav-item-dropdown>
        <b-nav-item href="#bar">bar</b-nav-item>
      </b-nav>

<b-card-body
        id="nav-scroller"
        ref="content"
        style="position:relative; height:300px; overflow-y:scroll;"
      >
        <p>{{ text }}</p>
        <h4 id="foo">foo</h4>
        <p v-for="i in 3" :key="i">{{ text }}</p>
        <h4 id="one">one</h4>
        <p v-for="i in 2" :key="i">{{ text }}</p>
        <h4 id="two">two</h4>
        <p>{{ text }}</p>
        <h4 id="three">three</h4>
        <p v-for="i in 2" :key="i">{{ text }}</p>
        <h4 id="bar">bar</h4>
        <p v-for="i in 3" :key="i">{{ text }}</p>
      </b-card-body>
    </b-card>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {
      text: "lorem ipsum"
    };
  }
};
</script>

We have the v-b-scrollspy directive.

It has the nav-scroller modifier added to it to make it watch the nav-scroller component, which is set as the ID of the b-card-body .

Therefore, it’ll watch the card body.

The item is identified by ID since the href attributes are set to something that starts with a hash, which indicates that we navigate to something with the given ID.

The link watched by the scrollspy can be inside a dropdown.

Now when we scroll up and down, we’ll see the link that goes to the element with the given ID highlighted.

Nested Navs

Scrollspys can be used with nested navs.

For example, we can write:

<template>
  <div id="app">
    <b-container fluid>
      <b-row>
        <b-col cols="4">
          <b-navbar v-b-scrollspy:nav-scroller>
            <b-nav pills vertical>
              <b-nav-item href="#foo">foo</b-nav-item>
              <b-nav pills vertical>
                <b-nav-item class="ml-3 my-1" href="#one">one</b-nav-item>
                <b-nav-item class="ml-3 my-1" href="#two">two</b-nav-item>
                <b-nav-item class="ml-3 my-1" href="#three">three</b-nav-item>
              </b-nav>
              <b-nav-item href="#bar">bar</b-nav-item>
            </b-nav>
          </b-navbar>
        </b-col>

<b-col
          cols="8"
          id="nav-scroller"
          ref="content"
          style="position:relative; height:300px; overflow-y:scroll;"
        >
          <p>{{ text }}</p>
          <h4 id="foo">foo</h4>
          <p v-for="i in 3" :key="i">{{ text }}</p>
          <h4 id="one">one</h4>
          <p v-for="i in 2" :key="i">{{ text }}</p>
          <h4 id="two">two</h4>
          <p>{{ text }}</p>
          <h4 id="three">three</h4>
          <p v-for="i in 2" :key="i">{{ text }}</p>
          <h4 id="bar">bar</h4>
          <p v-for="i in 3" :key="i">{{ text }}</p>
        </b-col>
      </b-row>
    </b-container>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {
      text: "lorem ipsum"
    };
  }
};
</script>

We added the indentation with the class=”ml-3 my-1" attribute.

Also, we have a b-navbar , which we nested b-nav components inside.

We have v-b-scrollspy:nav-scroller to watch the scroll position of the the b-col with the ID nav-scroller .

Now when we scroll, we’ll see the links highlighted as we scroll to them.

Conclusion

We can use a scrollspy to highlight the item with the ID that’s in the viewport.

Popovers can be styled with the variant property.

Categories
BootstrapVue

BootstrapVue — Tooltips and Popover Directives

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 look at how to use the v-b-tooltip and v-b-popover directives.

v-b-tooltip Directive

We can use the html modifier to make the v-b-tooltip directive render HTML.

For example, we can write:

<template>
  <div id="app">
    <b-button v-b-tooltip.html title="Hello <b>World!</b>">html tooltip</b-button>
  </div>
</template>

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

We have the b-button component with the v-b-tooltip directive.

It has the html modifier added to it so that we can render HTML that’s set as the value of title .

Hiding and Showing Tooltip with $root Events

We can hide and show all tooltips by emitting events on this.$root .

For example, we can write:

this.$root.$emit('bv::hide::tooltip')

to hide a tooltip.

Also, we can write:

this.$root.$emit('bv::hide::tooltip', 'trigger-button-id')

to hide a tooltip by its ID.

To show a tooltip, we can write:

this.$root.$emit('bv::show::tooltip', 'trigger-button-id')

to show a tooltip by ID.

Disabling and Enabling Tooltip with $root Events

Likewise, we can disable or enable tooltips with $root events.

For example, we can write:

this.$root.$emit('bv::disable::tooltip')

to disable all tooltips.

Also, we can write:

this.$root.$emit('bv::disable::tooltip', 'trigger-button-id')

to disable a tooltip with a particular ID.

To enable it, we can write:

this.$root.$emit('bv::enable::tooltip', 'trigger-button-id')

Listening to Tooltip Changes with $root Events

We can listen to tooltip events if we add a listener in the mounted hook.

For example, we can write:

export default {
  mounted() {
    this.$root.$on('bv::tooltip::show', bvEvent => {
      console.log('bvEvent:', bvEvent)
    })
  }
}

Hover

We can use the v-b-hover directive to run a callback on hover.

For example, we can write:

<div v-b-hover="callback">content</div>

Then the callback is run when we hover over the div.

We can write a callback as follows:

<template>
  <div id="app">
    <div v-b-hover="callback">content</div>
  </div>
</template>

<script>
export default {
  name: "App",
  methods: {
    callback(hovered){
      console.log(hovered)
    }
  }
};
</script>

The callback takes a hovered parameter, which is true when we hover over the div and false otherwise.

Popovers

We can add a popover to our app with the v-b-popover directive.

For example, we can write:

<template>
  <div id="app">
    <b-button v-b-popover.hover="'popover content'" title="Popover">Hover Me</b-button>
  </div>
</template>

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

We set the title prop to set the title.

The content is the value of the v-b-popover directive.

The hover modifier makes it show when we hover over the button.

Popover Positioning

We can change the positioning of the popover.

The possible values for positioning are top, topleft, topright, right, righttop, rightbottom, bottom, bottomleft, bottomright, left, lefttop, and leftbottom .

For example, we can write:

<template>
  <div id="app">
    <b-button v-b-popover.hover.bottomright="'popover content'" title="Popover">Hover Me</b-button>
  </div>
</template>

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

Then the popover will be shown on the bottom right because of the bottomright modifier.

Triggers

We can trigger the showing of the popover on events other than hover.

We can show it on click, hover, or focus,

To change the event that triggers the display of the popover, we can change the modifier of v-b-popover .

For example, we can write:

<template>
  <div id="app">
    <b-button v-b-popover.click="'popover content'" title="Popover">Click Me</b-button>
  </div>
</template>

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

Now the popover is displayed when we click the button because of the click modifier.

Dismiss Popover on Next Click

We can add the blur and click modifiers to dismiss the popover on the next click.

For example, we can write:

<template>
  <div id="app">
    <b-button v-b-popover.click.blur="'popover content'" title="Popover">Click Me</b-button>
  </div>
</template>

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

Now when we click the Click Me button, the popover will toggle on and off.

Heading and Content

We can change the heading and content with an object we set as the value of v-b-popover .

For example, we can write:

<template>
  <div id="app">
    <b-button v-b-popover="options">Hover Me</b-button>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {
      options: {
        title: "This is the <b>title</b>",
        content: "This is the <i>content<i>",
        html: true
      }
    };
  }
};
</script>

The title and content are set in the options object instead of in the props.

html lets us display HTML content.

Conclusion

We can trigger root events to enable/disable or toggle on and off tooltips.

Also, we can add popovers to display messages.

Categories
BootstrapVue

BootstrapVue — Time Picker Internationalization and Toasts

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 look at how to set the time picker’s locale.

We also look at how to display toasts.

Time Picker Internationalization

We can set the locale of the time picker with the locale prop.

For example, we can write:

<template>
  <div id="app">
    <b-time v-model="value" locale="de" v-bind="labels"></b-time>
    <p>{{value}}</p>
  </div>
</template>
<script>
export default {
  name: "App",
  data() {
    return {
      value: "",
      labels: {
        labelHours: "Stunden",
        labelMinutes: "Minuten",
        labelSeconds: "Sekunden",
        labelIncrement: "Erhöhen",
        labelDecrement: "Verringern",
        labelSelected: "Ausgewählte Zeit",
        labelNoTimeSelected: "Keine Zeit ausgewählt"
      }
    };
  }
};
</script>

We set the locale to 'de' for German.

Then we set the props for the labels with v-bind='labels' .

Now we see German labels for all the time picker controls.

Hours Cycle

The hours cycle may differ between locales.

h12 is an hours system using 1 to 12 for hours.

h23 is an hours system using 0 to 23 for hours.

h11 is an hours system using 0 to 11 for hours.

h24 is an hours system using 1 24 for hours.

Force 12 or 24 Hours Interface

We can set hour12 to true to force the time picker to display 12 hours.

If it’s false it’ll display 24 hours.

Whether it starts with 0 or 1 depends on the locale.

We can write:

<template>
  <div id="app">
    <b-time v-model="value" hour12></b-time>
    <p>{{value}}</p>
  </div>
</template>
<script>
export default {
  name: "App",
  data() {
    return {
      value: ""
    };
  }
};
</script>

to force the hours selector to have 12 hours.

Toasts

We can display push notifications with the b-toast component.

For example, we can write:

<template>
  <div id="app">
    <b-button variant="primary" @click="$bvToast.show('toast')">Show toast</b-button>
    <b-toast id='toast' title="Hello">Hello.</b-toast>
  </div>
</template>
<script>
export default {
  name: "App"
};
</script>

We create a button that calls $bvToast.show(‘toast’) to open a toast.

The argument is the ID value of the toast.

The toast is created with the b-toast method.

The title prop is the content for the title.

The content between the tags is the toast’s content.

Titles are optional but should be included.

There’s also a close button on the top right to close the toast.

We can disable that with the no-close-button prop.

The title bar is shown unless we give it no title and set the no-close-button prop.

Auto-hide can be enabled.

The countdown will pause when we hover over the text.

We can disable that with the no-hover-pause prop set to true .

Transparency can be disabled by setting the solid prop to true .

Toasts on Demand

We can create a toast with the this.$bvToast.toast method.

For example, we can write:

<template>
  <div id="app">
    <b-button @click="makeToast()">Show toast</b-button>
    <b-button @click="makeToast(true)">Show appended toast</b-button>
  </div>
</template>
<script>
export default {
  name: "App",
  methods: {
    makeToast(append = false) {
      this.$bvToast.toast(`hello`, {
        title: `toast ${append ? "appended": ''}`,
        autoHideDelay: 5000,
        appendToast: append
      });
    }
  }
};
</script>

We can create a toast by using the this.$bvToast.toast method.

The first argument is the content of the toast.

The 2nd is an object with various options.

The title property sets the title.

autoHideDelay sets the duration that the toast will show in milliseconds.

appendToast will display the toast below the other ones if it’s true .

Options

Toasts can have many options.

The title prop lets us change the title.

The solid prop lets us change the transparency. There’s no transparency if this is true .

The variant prop lets us change the style of the prop.

For example, we can write:

<template>
  <div id="app">
    <b-button @click="makeToast()">Show toast</b-button>
  </div>
</template>
<script>
export default {
  name: "App",
  methods: {
    makeToast() {
      this.$bvToast.toast(`hello`, {
        title: 'toast',
        autoHideDelay: 5000,
        variant: 'success'
      });
    }
  }
};
</script>

Then the background of the toast will be green since we set variant to 'success' .

Other possible values for variant include 'primary' , 'secondary' , 'danger' , 'warning' , and 'info' .

Conclusion

The locale and labels for the time picker can be changed.

The hours selector can have 12 or 24 hours depending on our choice.

Toasts are easy to add with built-in methods.

Categories
BootstrapVue

BootstrapVue — Customizing Tooltips

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 look at how to customize tooltips.

Positioning

We can change the positing with modifiers for the v-b-tooltip to change the placement.

For example, we can write:

<template>
  <div id="app">
    <b-button v-b-tooltip.hover.bottomright title="Tooltip title">hover</b-button>
  </div>
</template>

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

<style>
#app {
  height: 100vh;
  width: 100vw;
  margin: 50vw 50vh;
}
</style>

We have the bottomright prop so that the tooltip is placed to the bottom right of the button.

Focus Trigger

The focus trigger renders the a tag rather than the button tag.

So tabindex='0' must be included.

Therefore, we’ve to write:

<template>
  <div id="app">
    <b-button href="#" tabindex="0" v-b-tooltip.focus title="Tooltip">Link button</b-button>
  </div>
</template>

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

Disabled Elements

We can trigger a tooltip from a disable button by trigger it from its wrapper element instead.

For example, we can write:

<template>
  <div id="app">
    <span id="disabled" tabindex="0">
      <b-button disabled>Disabled button</b-button>
    </span>
    <b-tooltip target="disabled">Disabled</b-tooltip>
  </div>
</template>

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

We put the id on the span instead of the b-button , so we can trigger the tooltip when we hover over the button.

b-tooltip Component Usage

We can style the content inside a tooltip if we use the b-tooltip component.

For example, we can write:

<template>
  <div id="app">
    <b-button id="tooltip">button</b-button>
    <b-tooltip target="tooltip">Hello
      <b>World</b>
    </b-tooltip>
  </div>
</template>

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

We made the word ‘World’ bold with the b tag.

Variants and Custom Class

b-tooltip takes the variant prop to let us change the variant.

For example, we can write:

<template>
  <div id="app">
    <b-button id="tooltip">button</b-button>
    <b-tooltip target="tooltip" variant="info">hello</b-tooltip>
  </div>
</template>

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

We set the variant to 'info' , so the tooltip is green.

Also, we can add the custom-class prop to set a custom class.

For instance, we can write:

<template>
  <div id="app">
    <b-button id="tooltip">button</b-button>
    <b-tooltip target="tooltip" custom-class="tooltip">hello</b-tooltip>
  </div>
</template>

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

<style>
.tooltip {
  font-weight: bold;
}
</style>

Then the text in the tooltip is bold since we set the custom-class to 'tooltip' .

Show and Hide Tooltips Programmatically

We can set the show prop to show and hide a tooltip programmatically.

For example, we can write:

<template>
  <div id="app">
    <b-button @click="show = !show">button</b-button>
    <b-button id="tooltip">button with tooltip</b-button>
    <b-tooltip :show='show' target="tooltip" custom-class="tooltip">hello</b-tooltip>
  </div>
</template>

<script>
export default {
  name: "App",
  data(){
    return {
      show: false
    }
  }
};
</script>

We have a button that toggles the show value.

The show prop is added to the b-tooltip so we can see the tooltip when show is true .

We can also submit the 'open' and 'close' events to open and close the tooltip.

For example, we can write:

<template>
  <div id="app">
    <b-button @click="open">open</b-button>
    <b-button @click="close">close</b-button>
    <b-button id="tooltip">tooltip button</b-button>
    <b-tooltip target="tooltip" ref="tooltip">hello</b-tooltip>
  </div>
</template>

<script>
export default {
  name: "App",
  methods: {
    open() {
      this.$refs.tooltip.$emit("open");
    },
    close() {
      this.$refs.tooltip.$emit("close");
    }
  }
};
</script>

We assigned a ref to the b-tooltip component.

Also, we added the open and close method to emit the open and close events respectively.

That will open or close the tooltip.

Then when we click the open button, the tooltip will open beside the ‘tooltip button’ button.

When we click close, we close the tooltip.

Disable a Tooltip Programmatically

We can disable a tooltip with a prop or a ref event.

For example, we can write:

<template>
  <div id="app">
    <b-button id="tooltip">tooltip button</b-button>
    <b-tooltip target="tooltip" disabled>hello</b-tooltip>
  </div>
</template>

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

to disable the tooltip with the disable prop.

We can also disable a tooltip with the ref.

For example, we can write:

<template>
  <div id="app">
    <b-button [@click](http://twitter.com/click "Twitter profile for @click")="toggleDisable">toggle disable</b-button>
    <b-button id="tooltip">tooltip button</b-button>
    <b-tooltip ref="tooltip" target="tooltip">hello</b-tooltip>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {
      disabled: false
    };
  },
  methods: {
    toggleDisable() {
      this.disabled = !this.disabled;
      if (this.disabled) {
        this.$refs.tooltip.$emit("disable");
      } else {
        this.$refs.tooltip.$emit("enable");
      }
    }
  }
};
</script>

We can disable or enable the tooltip with the this.$refs.tooltip.$emit(“disable”); and this.$refs.tooltip.$emit(“enable”); calls respectively.

Therefore, the ‘toggle disable’ button will toggle the disabled status of the tooltip.

Conclusion

We can enable or disable a tooltip programmatically.

To do that, we can emit events or set props.

The positioning of the tooltip can also be changed.