Uncategorised

How to Create a Spinner With Bootstrap Vue

A spinner is used to indicate an ongoing process to the user. They are suitable for operations that don’t take very long to complete, and they help to enhance the responsiveness of an application. Read on to learn more about the Vue Bootstrap spinner component and the various customization options it provides.

The Boostrap Vue Spinner Component (b-spinner)

Boostrap Vue provides the b-spinner component for creating spinners. It starts spinning as soon as it has been rendered on the page.

<template>
  <div
    id="app"
    class="text-center"
  >
    <b-spinner></b-spinner>
  </div>
</template>
The Bootstrap Vue Spinner component (b-spinner)

Border spinner

We can use the type prop to display a particular type of spinner. By default the type is set to border, which makes the spinner transparent and gives it a thick circle border.

<template>
  <div
    id="app"
    class="text-center"
  >
    <b-spinner type="border"></b-spinner>
  </div>
</template>
A border spinner in Bootstrap Vue

Grow spinner

Alternatively, we can set type to grow to make the spinner repeatedly grow into view and fade out.

<template>
  <div
    id="app"
    class="text-center"
  >
    <b-spinner type="grow"></b-spinner>
  </div>
</template>
A grow spinner in Bootstrap Vue

Spinner colors

b-spinner comes with a variant prop that lets us customize the color of the spinner. There are a bunch of values it can take, including primary, secondary, danger, warning, success, and info.

Here we create multiple border spinners with many different colors:

<template>
  <div
    id="app"
    class="text-center d-flex justify-content-between"
  >
    <b-spinner
      v-for="variant in variants"
      :key="variant"
      :variant="variant"
    ></b-spinner>
  </div>
</template>

<script>
export default {
  data() {
    return {
      variants: [
        'primary',
        'secondary',
        'danger',
        'warning',
        'success',
        'info',
      ],
    };
  },
};
</script>
Border spinner components with different color variants.

We can also customize the color of grow spinners with the variant prop:

<template>
  <div
    id="app"
    class="text-center d-flex justify-content-between"
  >
    <b-spinner
      v-for="variant in variants"
      :key="variant"
      :variant="variant"
      type="grow"
    ></b-spinner>
  </div>
</template>

<script>
export default {
  data() {
    return {
      variants: [
        'primary',
        'secondary',
        'danger',
        'warning',
        'success',
        'info',
      ],
    };
  },
};
</script>
Grow spinner components with different color variants.

For more color customization options we can set the color CSS property using inline styles.

<template>
  <div
    id="app"
    class="text-center m-3 d-flex justify-content-between"
  >
    <b-spinner style="color: orange"></b-spinner>
    <b-spinner style="color: blue"></b-spinner>
    <b-spinner style="color: #800080"></b-spinner>
    <b-spinner style="color: green"></b-spinner>
    <b-spinner style="color: red"></b-spinner>
    <b-spinner style="color: #424242"></b-spinner>
  </div>
</template>
Customizing spinner colors with inline CSS.

Spinner size

Setting the small prop to true on the b-spinner creates a spinner of a smaller size.

<template>
  <div
    id="app"
    class="text-center"
  >
    <b-spinner small></b-spinner>
    <b-spinner
      type="grow"
      small
    ></b-spinner>
  </div>
</template>
Using the small prop of the Bootstrap Vue spinner component

For more size customization options, we can add some inline styles to customize the width and height CSS properties.

<template>
  <div
    id="app"
    class="text-center"
  >
    <b-spinner
      style="width: 50px; height: 50px"
    ></b-spinner>
    <b-spinner
      type="grow"
      style="width: 50px; height: 50px"
    ></b-spinner>
  </div>
</template>
Customizing the size of the spinner with inline styles.

Spinner margin

We can add any of the Bootstrap Vue margin utility classes to a b-spinner to adjust its spacing. Here we use the ms-4 class from Bootstrap to add a left margin to the second spinner:

<template>
  <div
    id="app"
    class="text-center"
  >
    <b-spinner></b-spinner>
    <b-spinner
      type="grow"
      class="ms-4"
    ></b-spinner>
  </div>
</template>
Adjusting spinner margin.

Spinner in button

One good use for a spinner is within a button, to indicate that an action is currently taking place.

<template>
  <div
    id="app"
    class="text-center"
  >
    <b-button variant="primary">
      <b-spinner small></b-spinner>
      Loading...
    </b-button>
  </div>
</template>
Using the Boostrap Vue spinner component in a button.

Here’s a more practical example of using spinners within buttons. When the button is clicked to save, it changes its text and shows the spinner to indicate the ongoing save operation (simulated with a timeout). Then it hides the spinner and changes the text again after the save.

<template>
  <div
    id="app"
    class="text-center m-3"
  >
    <b-button
      variant="primary"
      @click="save"
    >
      <b-spinner
        small
        v-if="status === 'saving'"
      ></b-spinner>
      {{ buttonText }}
    </b-button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      status: 'unsaved',
    };
  },
  computed: {
    buttonText() {
      if (this.status === 'unsaved') return 'Save';
      else if (this.status === 'saving') return 'Saving';
      else return 'Saved';
    },
  },
  methods: {
    save() {
      this.status = 'saving';
      setTimeout(() => {
        this.status = 'saved';
      }, 2000);
    },
  },
};
</script>

We use the status data property to track the current save state, and we create a buttonText computed property to determine what the button label should be from status.

Using a spinner in a button.

Conclusion

A spinner is useful for indicating app operations in the process of being completed. In this article, we learned how to use the spinner component from Bootstrap Vue (b-spinner) to easily create and customize spinners.

How to Check if a String Contains Only Numbers in JavaScript

To check if a string contains only numbers in JavaScript, call the test() method on this regular expression: ^\d+$. The test() method will return true if the string contains only numbers. Otherwise, it will return false.

For example:

function containsOnlyNumbers(str) {
  return /^\d+$/.test(str);
}

console.log(containsOnlyNumbers('HTML5')); // false
console.log(containsOnlyNumbers('1234')); // true
console.log(containsOnlyNumbers('3 bananas')); // false

The RegExp test() method searches for a match between a regular expression and a string.

The / and / characters are used to start and end a regular expression.

The ^ character marks the beginning of the string input, and the $ character marks the end of it.

The \d pattern matches any digit (09) in the string.

Adding the + character after the \d makes the regex match one or more occurrences of the \d pattern.

So the regex matches a string that starts and ends with a consecutive sequence of digits.

We can use the [0-9] pattern to match digits. This pattern matches any number character between 0 and 9.

function containsOnlyNumbers(str) {
  return /^[0-9]+$/.test(str);
}

console.log(containsOnlyNumbers('HTML5')); // false
console.log(containsOnlyNumbers('1234')); // true
console.log(containsOnlyNumbers('3 bananas')); // false

You might find [0-9] to be more readable than \d, especially if you’re not very familiar with special characters in regular expressions.

Match a string that contains numbers separated by a character

Sometimes we would like to match strings where the numbers might be separated by a particular character, such as a space or comma.

function containsOnlyNumbers(str) {
  return /^(\d+,)*(\d+)$/.test(str);
}

console.log(containsOnlyNumbers('123456789')); // true (separator not required)
console.log(containsOnlyNumbers('123,456,789')); // true
console.log(containsOnlyNumbers('123-456-789')); // false

We do this using a regular expression of this format: ^(\d+{ch})*(\d+)$, where {ch} is the character separating the numbers.

So we can use a very similar regex to match a string that contains only numbers separated with hyphens:

function containsOnlyNumbers(str) {
  return /^(\d+-)*(\d+)$/.test(str);
}

console.log(containsOnlyNumbers('123456789')); // true
console.log(containsOnlyNumbers('123,456,789')); // false
console.log(containsOnlyNumbers('123-456-789')); // true

Or spaces:

function containsOnlyNumbers(str) {
  return /^(\d+ )*(\d+)$/.test(str);
}

console.log(containsOnlyNumbers('123456789')); // true
console.log(containsOnlyNumbers('123 456 789')); // true
console.log(containsOnlyNumbers('123-456-789')); // false

Tip: If you ever come across a regular expression with a pattern you find hard to understand, this regular expression cheat sheet from the MDN docs may help.

Like before, we could use [0-9] in place of \d for the regular expression:

function containsOnlyNumbers(str) {
  return /^([0-9]+-)*([0-9]+)$/.test(str);
}

console.log(containsOnlyNumbers('123456789')); // true
console.log(containsOnlyNumbers('123,456,789')); // false
console.log(containsOnlyNumbers('123-456-789')); // true

How to Check if a String Contains Numbers in JavaScript

To check if a string contains numbers in JavaScript, call the test() method on this regex: /\d/. test() will return true if the string contains numbers. Otherwise, it will return false.

For example:

function containsNumbers(str) {
  return /\d/.test(str);
}

console.log(containsNumbers('hello123')); // true
console.log(containsNumbers('javascript')); // false
console.log(containsNumbers('3 apples')); // true

The RegExp test() method searches for a match between a regular expression and a string.

The / and / characters are used to start and end the regular expression.

The \d metacharacter matches any digit (09) in the string.

You can also use the [0-9] to match digits. This pattern matches any number character between 0 and 9.

function containsNumbers(str) {
  return /[0-9]/.test(str);
}

console.log(containsNumbers('hello123')); // true
console.log(containsNumbers('javascript')); // false
console.log(containsNumbers('3 apples')); // true

You might find [0-9] to be more readable than using \d, especially if you’re not very familiar with special characters in regular expressions.

Check if string contains only numbers

To check if the string contains only numbers, we’ll have to use a different regular expression – ^\d+$:

function containsOnlyNumbers(str) {
  return /^\d+$/.test(str);
}

console.log(containsOnlyNumbers('hello123')); // false
console.log(containsOnlyNumbers('3453')); // true
console.log(containsOnlyNumbers('3 apples')); // false

The ^ character marks the beginning of the string input, and the $ character marks the end of it.

Adding the + character after the \d makes regex match one or more occurrences of the \d pattern.

So the regex matches a string starting and ending with a consecutive sequence of digits.

As we did before, we could replace \d with [0-9] here:

function containsOnlyNumbers(str) {
  return /^[0-9]+$/.test(str);
}

console.log(containsOnlyNumbers('hello123')); // false
console.log(containsOnlyNumbers('3453')); // true
console.log(containsOnlyNumbers('3 apples')); // false

The String match() method

We can use the String match() method in place of RegExp test() to check if a string contains numbers

function containsNumbers(str) {
  return Boolean(str.match(/\d/));
}

console.log(containsNumbers('hello123')); // true
console.log(containsNumbers('javascript')); // false
console.log(containsNumbers('3 apples')); // true

The String match() method returns an array of all the matches of a regular expression in a string. If there are no matches, it returns null.

function containsNumbers(str) {
  return str.match(/\d/);
}

console.log(containsNumbers('hello123'));
// [ '1', index: 5, input: 'hello123', groups: undefined ]

console.log(containsNumbers('javascript')); // null

console.log(containsNumbers('3 apples'));
// [ '3', index: 0, input: '3 apples', groups: undefined ]

We pass the result of match() to the Boolean() constructor to convert it to a Boolean value. Boolean() converts truthy values to true, and falsy values to false.

In JavaScript, there are six falsy values: undefinednullNaN0'' (empty string), and false. Every other value is truthy.

console.log(Boolean(undefined)); // false
console.log(Boolean(['number60'])); // true
console.log(Boolean(null)); // false
console.log(Boolean(5)); // true

How to Use a Button as a Link in Vue

To use a button as a link in Vue, you can wrap the button in an anchor (<a>) element. Clicking a link button makes the browser navigate to the specified URL.

<template>
  <div>
    <a href="/posts">
      <button>Posts</button>
    </a>
  </div>
</template>
Clicking the link button to navigate to another page.
Clicking the link button to navigate to another page.

When working with Vue Router, you can make a button serve as a router link using the navigate function provided by the router-link default slot.

<template>
  <div>
    <router-link
      to="/posts"
      custom
      v-slot="{ navigate }"
    >
      <button
        @click="navigate"
        role="link"
      >
        Posts
      </button>
    </router-link>
  </div>
</template>
Navigating to the "/posts" route without refreshing the page.
Navigating to the /posts route without refreshing the page.

We use navigate as a handler for the click event, so it is called when the button is clicked, making the browser navigate to the specified route without refreshing the page.

The above method only works for Vue 3.x though. If working with Vue 2.x, you can use a button as a router link by setting the tag prop to the name of the button component, and setting the to prop to the specific route.

<template>
  <div>
    <router-link to="/posts" tag="button">Posts</router-link>
  </div>
</template>

The $router.push() method

Alternatively, we can use a button as a Vue router link by calling the push() method on the $router variable made available by Vue Router.

<template>
  <div>
    <button @click="$router.push('/posts')">Posts</button>
  </div>
</template>

The $router variable represents the router instance, and can be used for programmatic navigation.

When working with the Vuetify framework, we can use the button component as a link by setting the v-btn href prop.

<template>
  <div>
    <v-btn
      href="/posts"
      color="primary"
      dark
    >
      Posts
    </v-btn>
  </div>
</template>

When using Vue Router with Vuetify, we can use the button component as a router link by setting the v-btn to prop.

<template>
  <div>
    <v-btn
      to="/posts"
      color="primary"
      dark
    >
      Posts
    </v-btn>
  </div>
</template>

If you’re working with the Vue Bootstrap framework, you can use the href to turn the button component into a link.

<template>
  <div>
    <b-button
      href="/posts"
      variant="primary"
    >
      Posts
    </b-button>
  </div>
</template>

We can set the b-button to prop to use the Vue Bootstrap button component as a Vue Router link.

<template>
  <div>
    <b-button
      to="/posts"
      variant="success"
    >
      Posts
    </b-button>
  </div>
</template>

How to Add an Element to an Array in Vue

Add Element to Array With push() Method

To add an element to an array in Vue, call the push() method in the array with the element as an argument. The push() method will add the element to the end of the array.

For example:

<template>
  <div id="app">
    <button @click="addFruit">Add fruit</button>
    <ul>
      <h2
        v-for="(fruit, i) in fruits"
        :key="i"
      >
        {{ fruit }}
      </h2>
    </ul>
  </div>
</template>

<script>
export default {
  data() {
    return {
      fruits: ['Orange', 'Apple'],
    };
  },
  methods: {
    addFruit() {
      this.fruits.push('Banana');
    },
  },
};
</script>
Clicking the button adds a new fruit element.
Clicking the button adds a new fruit element.

The Array push() method adds one or more elements to the end of an array and returns the length of the array.

We use the v-for Vue directive to display the elements in the array. These rendered elements are automatically updated in the view when the array is modified with push().

Add Object Element to Array in Vue

We can use the same approach to add an object to an array and display more complex data. We just have to make sure that we render the properties of each object in the array, not the object itself.

<template>
  <div id="app">
    <button @click="addFruit">Add fruit</button>
    <ul>
      <h2
        v-for="(fruit, i) in fruits"
        :key="i"
      >
        <!-- Render "name" and "amount" properties -->
        {{ fruit.name }} ({{ fruit.amount }})
      </h2>
    </ul>
  </div>
</template>

<script>
export default {
  data() {
    return {
      fruits: [
        { name: 'Orange', amount: 3 },
        { name: 'Apple', amount: 5 },
      ],
    };
  },
  methods: {
    addFruit() {
      // Add object element to array
      this.fruits.push({ name: 'Banana', amount: 4 });
    },
  },
};
</script>
Clicking the button adds a new fruit item with a certain amount.
Clicking the button adds a new fruit element with a certain amount.

Like before, the list automatically updates in the view when a new object element is added to the array.