Categories
BootstrapVue

BootstrapVue — Tooltips

In this article, we look at how to use the v-b-tooltip directive to add tooltips.

Tooltips

We can add tooltips with the v-b-tooltip directive.

For example, we can write:

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

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

We have the v-b-tooltip directive on our button.

title has the content of the tooltip.

The hover modifier makes the tooltip open on hover.

A tooltip on a disabled element must be triggered by its wrapper element.

Positioning

We can change the position that the tooltip is displayed with modifiers.

For example, we can write:

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

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

We have the bottomright modifier to display the tooltip on the bottom right.

Other possible choices include top, topleft, topright, right, righttop, rightbottom, bottom, bottomleft, bottomright, left, lefttop, and leftbottom .

Triggers

We can change how the tooltip is triggered by some modifiers.

We can have no modifier, which means it’s opened when an element is hovered or focused.

hover means the tooltip opens on hover.

click means the tooltip opens on click.

focus means the tooltip opens on focus.

We can write:

<template>
  <div id="app">
    <b-button v-b-tooltip.click title="Tooltip">Hover Me</b-button>
  </div>
</template>

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

Now the tooltip opens on click because of the click modifier.

Disabled Elements

We have to trigger the tooltip on a wrapper if we want to open a tooltip on a disabled element.

For example, we can write:

<template>
  <div id="app">
    <span v-b-tooltip title="Disabled tooltip">
      <b-button variant="primary" disabled>Disabled</b-button>
    </span>
  </div>
</template>

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

We put the v-b-tooltip on the span instead of the disabled button.

The result is still having the tooltip disabled on hover or focus.

Focus and Button

Since b-button is rendered as a tag if we add the focus trigger.

We need to add the tabindex='0' attribute.

For instance, we can write:

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

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

Dismiss on Next Click

We need to add the click and blur modifiers to add a tooltip that only opens when the element is clicked and closed when anything in the document is clicked or receives focus.

For example, we write:

<template>
  <div id="app">
    <b-button v-b-tooltip.click.blur title="Tooltip">Link</b-button>
  </div>
</template>

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

Title

We can set the value of the v-b-tooltip directive to an object to set the options for the tooltip.

The object can have the title property to set the title.

For example, we can write:

<template>
  <div id="app">
    <b-button v-b-tooltip="options">Link</b-button>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {
      options: {
        title: "hello <strong>world</strong>",
        html: true
      }
    };
  }
};
</script>

We have the title property with some HTML inside.

html is set to true so that the HTML is rendered.

Variants

To change the style, we can add the variant property to the object.

For example, we can write:

<template>
  <div id="app">
    <b-button v-b-tooltip="options">Link</b-button>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {
      options: {
        title: "hello <strong>world</strong>",
        html: true,
        variant: "info"
      }
    };
  }
};
</script>

Then variant is 'info' , so the background will be green.

Other possible values include, 'primary' , 'secondary' , 'warning' , 'success' , etc.

Make the Tooltip Non-Interactive

We can make a tooltip non-interactive with the noninteractive prop.

Hiding and Showing Tooltips via $root Events

To show a tooltip, we can write:

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

to show a tooltip that’s added to the element with ID trigger-button-id .

To hide all tooltips, we can write:

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

this is the component.

Disabling and Enabling Tooltips via $root Events

We can disable all tooltips by writing:

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

to disable a tooltip by element ID, we can write:

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

and to enable a tooltip by ID, we can write:

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

Conclusion

We can add a tooltip to an element with the v-b-tooltip directive.

The content can be plain text or HTML.

Categories
BootstrapVue

BootstrapVue — Reacting on Visibility

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-visible directive to run something when something becomes visible or not.

Directive Syntax

We can use the v-b-visible directive, by writing:

<div v-b-visible.[mod1].[mod2]="callback">content</div>

mod1 and mod2 are modifiers.

callback is a function that runs when the visibility status changes.

It has a parameter to indicate visibility.

The parameter can be true or false .

The callback will be run each time the element’s visibility changes except when the once modifier is used.

All modifiers are optional.

Example

We can use it by writing:

<template>
  <div v-b-visible="visibleHandler">...</div>
</template>

<script>
export default {
  methods: {
    visibleHandler(isVisible) {
      if (isVisible) {
        // Do something
      } else {
        // Do something else
      }
    }
  }
};
</script>

We have the visibleHandler function.

isVisible indicates whether the div is visible or not.

Then we can do something according to the visibility status.

Use v-b-visible with the once Modifier

We can use the once modifier with v-b-visible .

For example, we can write:

<template>
  <div v-b-visible.once="visibleHandler"> ... </div>
</template>

<script>
export default {
  methods: {
    visibleHandler(isVisible) {
      if (isVisible) {
        // ...
      } else {
        // ...
      }
    }
  }
}
</script>

Then visibleHandler is only called once.

So isVisible can be true once when the element becomes visible for the first time.

isVisible can be false for zero or more times.

It’ll never be false after the element has become visible.

Use with once and Offset Modifiers

We can also add an offset modifier.

For instance, we can write:

<template>
  <div v-b-visible.once.350="visibleHandler">...</div>
</template>
<script>
export default {
  methods: {
    visibleHandler(isVisible) {
      if (isVisible) {
        //...
      } else {
        //...
      }
    }
  }
};
</script>

The offset is the number of pixels away from the edge of the viewport to determine when the element is considered to be in the viewport.

Therefore, it’ll be considered to be in the viewport if it’s within 350px of the viewport.

For example, we write:

<template>
  <div
    v-b-visible.once.350="visibleHandler"
    :class="[isVisible ? 'bg-info' : 'bg-light', 'text-center']"
  >
    <p v-for="n in 100" :key="n">{{n}}</p>
    <b-badge v-b-visible="visibleHandler">Element with v-b-visible directive</b-badge>
    <p v-for="n in 100" :key="n">{{n}}</p>
  </div>
</template>
<script>
export default {
  data() {
    return {
      isVisible: false
    };
  },
  methods: {
    visibleHandler(isVisible) {
      this.isVisible = isVisible;
    }
  }
};
</script>

We’ll see the background in green if we see the badge.

Otherwise, we’ll see a light-colored background.

This is because we added the v-b-visible directive to the b-badge .

The visibilityHandler is run when the badge becomes visible or not as we scroll.

The class prop on the div will change the class according to the isVisible state, which we update in visibleHandler .

CSS Display Visibility Detection

We can detect visibility with CSS.

For instance, we can write:

<template>
  <div>
    <b-button @click="show = !show">Toggle display</b-button>
    <p>Visible: {{ isVisible }}</p>
    <div class="border p-3">
      <div v-show="show" class="bg-info p-3">
        <b-badge v-b-visible="handleVisibility">Element with v-b-visible directive</b-badge>
      </div>
    </div>
  </div>
</template>
<script>
export default {
  data() {
    return {
      show: false,
      isVisible: false
    };
  },
  methods: {
    handleVisibility(isVisible) {
      this.isVisible = isVisible;
    }
  }
};
</script>

v-show shows and hides elements and components with CSS.

When it’s shown or hidden, handleVisibility will be triggered.

Therefore, the isVisible will be triggered at the same time as show .

Conclusion

We can use the v-b-visible directive to detect visibility changes of elements or components.

Then we can run callbacks to do something when the visibility of something changes.

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.