Categories
Buefy

Buefy — Numeric Slider

Buefy is a UI framework that’s based on Bulma.

In this article, we’ll look at how to use Buefy in our Vue app.

Numeric Slider

We can add a slider to set a numeric value with the b-slider component.

For example, we can write:

<template>
  <section>
    <b-field label="number">
      <b-slider v-model="value"></b-slider>
    </b-field>
  </section>
</template>

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

We add v-model to bind the value to a state.

We can disable it with the disabled prop.

The size can be changed with the size prop:

<template>
  <section>
    <b-field label="number">
      <b-slider size="is-large" :value="20"></b-slider>
    </b-field>
  </section>
</template>

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

The style can be changed with the type prop:

<template>
  <section>
    <b-field label="number">
      <b-slider type="is-success" :value="20"></b-slider>
    </b-field>
  </section>
</template>

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

We can customize the label with the custom-formatter prop:

<template>
  <section>
    <b-field label="number">
      <b-slider type="is-success" :custom-formatter="val => `${val}%`"></b-slider>
    </b-field>
  </section>
</template>

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

now the tooltip shows the % symbol after the number since we set the custom-formatter prop to our own function.

Tick and Label

We can add ticks by populating the default slot with the b-slider-tick component:

<template>
  <section>
    <b-field label="Custom tick and label">
      <b-slider size="is-medium" :min="0" :max="10">
        <template v-for="val in [2,4,6,8]">
          <b-slider-tick :value="val" :key="val">{{ val }}</b-slider-tick>
        </template>
      </b-slider>
    </b-field>
  </section>
</template>

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

Range Slider

We can add a range slider with the min and max props to restrict the range that we can select.

Then the value we bound to v-model would be an array with the min and max values:

<template>
  <section>
    <b-field>
      <b-slider v-model="numbers" :min="0" :max="15" :step="0.5"></b-slider>
    </b-field>
  </section>
</template>

<script>
export default {
  data() {
    return {
      numbers: [1, 5]
    };
  }
};
</script>

Lazy Update

We can add the lazy prop to update the v-model value only when dragging is done:

<template>
  <section>
    <b-field>
      <b-slider v-model="value" lazy></b-slider>
    </b-field>
    {{value}}
  </section>
</template>

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

Conclusion

Buefy’s b-slider component is a useful slider component for Vue.

Categories
Buefy

Buefy — Dropdowns

Buefy is a UI framework that’s based on Bulma.

In this article, we’ll look at how to use Buefy in our Vue app.

Select Dropdown

We can add a select dropdown with the b-select component.

For example, we can write:

<template>
  <section>
    <b-field label="Simple">
      <b-select placeholder="Select a fruit">
        <option v-for="option in data" :value="option.id" :key="option.id">{{ option.name }}</option>
      </b-select>
    </b-field>
  </section>
</template>

<script>
export default {
  data() {
    return {
      data: [
        { id: 1, name: "apple" },
        { id: 2, name: "orange" },
        { id: 3, name: "grape" }
      ]
    };
  }
};
</script>

to add it.

We can use v-model to bind the selected value to a state:

<template>
  <section>
    <b-field label="Simple">
      <b-select placeholder="Select a fruit" v-model="val">
        <option v-for="option in data" :value="option.id" :key="option.id">{{ option.name }}</option>
      </b-select>
      {{val}}
    </b-field>
  </section>
</template>

<script>
export default {
  data() {
    return {
      val: 0,
      data: [
        { id: 1, name: "apple" },
        { id: 2, name: "orange" },
        { id: 3, name: "grape" }
      ]
    };
  }
};
</script>

Also, we can set the type and message props to set the style and add a message:

<template>
  <section>
    <b-field label="Simple" type="is-danger" message="error">
      <b-select placeholder="Select a fruit" v-model="val">
        <option v-for="option in data" :value="option.id" :key="option.id">{{ option.name }}</option>
      </b-select>
    </b-field>
  </section>
</template>

<script>
export default {
  data() {
    return {
      val: 0,
      data: [
        { id: 1, name: "apple" },
        { id: 2, name: "orange" },
        { id: 3, name: "grape" }
      ]
    };
  }
};
</script>

type is the type, and message is displayed below the dropdown.

The loading prop shows a loading indicator.

And disabled prop disables the dropdown.

We add them both to the b-select component.

Multiple Selection

Also, we can enable multiple selection with the multiple prop:

<template>
  <section>
    <b-field>
      <b-select multiple placeholder="Select fruits" v-model="fruits">
        <option v-for="option in data" :value="option.id" :key="option.id">{{ option.name }}</option>
      </b-select>
    </b-field>
    {{fruits}}
  </section>
</template>

<script>
export default {
  data() {
    return {
      fruits: 0,
      data: [
        { id: 1, name: "apple" },
        { id: 2, name: "orange" },
        { id: 3, name: "grape" }
      ]
    };
  }
};
</script>

We see the selected values in an array.

Icons

We can add an icon on the left side of the dropdown by wrting:

<template>
  <section>
    <b-field>
      <b-select placeholder="Country" icon="address-book" icon-pack="fa">
        <option value="1">Option 1</option>
        <option value="2">Option 2</option>
      </b-select>
    </b-field>
  </section>
</template>

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

The icon-pack prop sets the icon library to use.

fa stands for Font Awesome.

icon has the name of the icon from the library we want to add.

To add Font Awesome 4.7.0, we add:

<link
      rel="stylesheet"
      href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css"
      integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN"
      crossorigin="anonymous"
    />

in the head tag of public/index.html .

Sizes

We can change the size with the size prop:

<template>
  <section>
    <b-field>
      <b-select placeholder="Country" size="is-large">
        <option value="1">Option 1</option>
        <option value="2">Option 2</option>
      </b-select>
    </b-field>
  </section>
</template>

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

Conclusion

We add the dropdowns with Buefy into our Vue app.

Categories
Vue

Adding a Simple Calendar to Our Vue App with vue-simple-calendar

Adding a calendar widget by hand is very painful.

Therefore, many calendar component libraries are created.

vue-simple-calendar is one library.

In this article, we’ll look at how to add a calendar with the vue-simple-calendar library.

Getting Started

We add our library by installing it with NPM.

To do that, we run:

npm i vue-simple-calendar

Add a Simple Calendar

We can add a simple calendar with the calendar-view component.

To add it, we write:

<template>
  <div id="app">
    <calendar-view
      :show-date="showDate"
      class="theme-default holiday-us-traditional holiday-us-official"
    >
      <calendar-view-header
        slot="header"
        slot-scope="t"
        :header-props="t.headerProps"
        @input="setShowDate"
      />
    </calendar-view>
  </div>
</template>
<script>
import { CalendarView, CalendarViewHeader } from "vue-simple-calendar";
import "vue-simple-calendar/static/css/default.css";
import "vue-simple-calendar/static/css/holidays-us.css";

export default {
  name: "app",
  data() {
    return { showDate: new Date() };
  },
  components: {
    CalendarView,
    CalendarViewHeader
  },
  methods: {
    setShowDate(d) {
      this.showDate = d;
    }
  }
};
</script>

We import the CSS and register the components within our component.

The showDate prop has the date object which controls the month to be shown.

The calendar-view-header component has the header that lets us navigate through the months.

When we choose a month on the header, the input event is emitted.

Adding Calendar Events

We can set the events prop to populate the calendar with events.

For example, we can write:

<template>
  <div id="app">
    <calendar-view
      :show-date="showDate"
      :events="events"
      class="theme-default holiday-us-traditional holiday-us-official"
      @click-date="onClickDate"
    >
      <calendar-view-header
        slot="header"
        slot-scope="t"
        :header-props="t.headerProps"
        @input="setShowDate"
      />
    </calendar-view>
  </div>
</template>
<script>
import { CalendarView, CalendarViewHeader } from "vue-simple-calendar";
import "vue-simple-calendar/static/css/default.css";
import "vue-simple-calendar/static/css/holidays-us.css";

export default {
  name: "app",
  data() {
    return {
      showDate: new Date(),
      events: [
        {
          id: 1,
          startDate: "2020-10-19",
          endDate: "2020-10-19",
          title: "Sample event 1"
        },
        {
          id: 2,
          startDate: "2020-10-06",
          endDate: "2020-10-13",
          title: "Sample event 2"
        }
      ]
    };
  },
  components: {
    CalendarView,
    CalendarViewHeader
  },
  methods: {
    setShowDate(d) {
      this.showDate = d;
    },
    onClickDate(...params) {
      console.log(params);
    }
  }
};
</script>

We have the events array which we set as the value of the events prop.

Each entry has the id with the unique ID.

startDate has the start date of the event.

endDate has the end date of the event.

title has the title of the event.

id and startDate are required.

title defaults to 'untitled' .

It also emits events that we can listen to.

For example, we can listen to the click-date event which has the date that we clicked on and the mouse events as parameters.

The events will be shown on the calendar.

Slots

vue-simple-calendar can be customized by populating various slots.

periodStart lets us customize the first date of the display period.

periodEnd lets us customize the last date of the display period.

displayLocale lets us show the locale setting for the calendar.

monthNames sets the month names.

There’re many more slots listed at https://github.com/richardtallent/vue-simple-calendar#slots.

Conclusion

vue-simple-calendar is a simple library for adding a calendar to our Vue app.

Categories
Vue

Adding a Simple Calendar to Our Vue App with vue2-event-calendar

Adding a calendar widget by hand is very painful.

Therefore, many calendar component libraries are created.

vue-event-calendar is one library.

In this article, we’ll look at how to add a calendar with the vue-event-calendar library.

Getting Started

We add our library by installing it with NPM.

To do that, we run:

npm i vue-event-calendar

Adding the Calendar

We can use the component by registering the plugin.

First, we register it by writing:

import Vue from "vue";
import App from "./App.vue";
import "vue-event-calendar/dist/style.css";
import vueEventCalendar from "vue-event-calendar";

Vue.use(vueEventCalendar, { locale: "en" });
Vue.config.productionTip = false;

new Vue({
  render: (h) => h(App)
}).$mount("#app");

We import the CSS and then register the plugin to make it available throughout our Vue app.

Also, we set the locale with the options.

Then in our component, we add:

<template>
  <vue-event-calendar :events="events"></vue-event-calendar>
</template>

<script>
export default {
  data() {
    return {
      events: [
        {
          date: "2020/09/12",
          title: "special event"
        },
        {
          date: "2020/09/15",
          title: "party",
          desc: "go to a party",
          customClass: "highlight"
        }
      ]
    };
  }
};
</script>

to show the calendar component with the events.

vue-event-calendar has the calendar.

events has the events that we want to display.

Once we click on the day, we see the events displayed.

The event template can be changed by populating the default slot.

For example, we can write:

<template>
  <vue-event-calendar :events="events">
    <template scope="props">
      <div :key="index" v-for="(event, index) in props.showEvents" class="event-item">{{event}}</div>
    </template>
  </vue-event-calendar>
</template>

<script>
export default {
  data() {
    return {
      events: [
        {
          date: "2020/09/12",
          title: "special event"
        },
        {
          date: "2020/09/15",
          title: "party",
          desc: "go to a party",
          customClass: "highlight"
        }
      ]
    };
  }
};
</script>

We loop through the prop.showEvents array to render the events.

It has the whole event object.

Component Events

The vue-event-calendar emits the day-changed and month-changed events when we navigate through the calendar.

For example, we can write:

<template>
  <vue-event-calendar
    :events="events"
    @day-changed="handleDayChanged"
    @month-changed="handleMonthChanged"
  ></vue-event-calendar>
</template>

<script>
export default {
  data() {
    return {
      events: [
        {
          date: "2020/09/12",
          title: "special event"
        },
        {
          date: "2020/09/15",
          title: "party",
          desc: "go to a party",
          customClass: "highlight"
        }
      ]
    };
  },
  methods: {
    handleDayChanged(ev) {
      console.log(ev);
    },
    handleMonthChanged(ev) {
      console.log(ev);
    }
  }
};
</script>

We listen to the events with our own methods.

The event object parameter for the handleDayChanged method has the date and the events array with the events for the day.

The event object parameter for the handleMonthChanged method has the month string in MM/YYYY format.

We can also navigate the months programmatically with a few methods.

this.$EventCalendar.nextMonth() goes to the next month.

this.$EventCalendar.preMonth() goes to the previous month.

this.$EventCalendar.toDate(‘2020/11/12’) goes to the given date.

Conclusion

vue-event-calendar is a very useful library for displaying a calendar with events in a Vue app.

Categories
Vue

Adding a Simple Calendar to Our Vue App with vue2-simple-calendar

Adding a calendar widget by hand is very painful.

Therefore, many calendar component libraries are created.

vue2-simple-calendar is one library.

In this article, we’ll look at how to add a calendar with the vue2-simple-calendar library.

Getting Started

We add our library by installing it with NPM.

To do that, we run:

npm i vue2-simple-calendar

Using the Calendar Component

We can ad the calendar component by adding the CSS code.

Create a file called vue2-simple-calendar.css and add:

.vue-calendar {
  display: grid;
  grid-template-rows: 10% 90%;
  background: #fff;
  margin: 0 auto;
}
.calendar-header {
  align-items: center;
}
.header-left,
.header-right {
  flex: 1;
}
.header-center {
  flex: 3;
  text-align: center;
}
.title {
  margin: 0 5px;
}
.next-month,
.prev-month {
  cursor: pointer;
}
.calendar-body {
  display: grid;
  grid-template-rows: 5% 95%;
}
.days-header {
  display: grid;
  grid-auto-columns: 14.25%;
  grid-template-areas: "a a a a a a a";
  border-top: 1px solid #e0e0e0;
  border-left: 1px solid #e0e0e0;
  border-bottom: 1px solid #e0e0e0;
}
.days-body {
  display: grid;
  grid-template-rows: auto;
}
.day-number {
  text-align: right;
  margin-right: 10px;
}
.day-label {
  text-align: center;
  border-right: 1px solid #e0e0e0;
}
.week-row {
  display: grid;
  grid-template-areas: "a a a a a a a";
  grid-row-gap: 5px;
  grid-auto-columns: 14.25%;
  border-left: 1px solid #e0e0e0;
}
.week-day {
  padding: 4px;
  border-right: 1px solid #e0e0e0;
  border-bottom: 1px solid #e0e0e0;
}
.week-day.disabled {
  background-color: #f5f5f5;
}
.week-day.not-current > .day-number {
  color: #c3c3c3;
}
.week-day.today > .day-number {
  font-weight: 700;
  color: red;
}
.events {
  font-size: 12px;
  cursor: pointer;
  padding: 0 0 0 4px;
}
.events .event {
  height: 18px;
  line-height: 18px;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  margin: 0 4px 2px 0;
  color: rgba(0, 0, 0, 0.87);
  background-color: #d4dcec;
}
.events .more-link {
  color: rgba(0, 0, 0, 0.38);
}

This is the same code like the example at https://codesandbox.io/s/93pjr734r4?file=/src/assets/vue2-simple-calendar.css:0-1549.

It doesn’t come with any styles, so we’ve to add them ourselves.

Then in main.js , we add:

import Vue from "vue";
import App from "./App.vue";
import vueCalendar from "vue2-simple-calendar";
import "./assets/vue2-simple-calendar.css";

Vue.use(vueCalendar, {});
Vue.config.productionTip = false;

new Vue({
  render: (h) => h(App)
}).$mount("#app");

to register the plugin.

Then in our component, we write:

<template>
  <vue-calendar
    :show-limit="3"
    :events="events"
    @show-all="showAll"
    @day-clicked="dayClicked"
    @event-clicked="eventClicked"
    @month-changed="monthChanged"
  ></vue-calendar>
</template>

<script>
export default {
  methods: {
    showAll(events) {
      console.log(events);
    },
    dayClicked(day) {
      console.log(day);
    },
    eventClicked(event) {
      console.log(event);
    },
    monthChanged(start, end) {
      console.log(start, end);
    },
    highlightDays(days) {
      console.log(days);
    }
  },
  created() {
    this.$calendar.eventBus.$on("show-all", events => this.showAll(events));
    this.$calendar.eventBus.$on("day-clicked", day => this.dayClicked(day));
    this.$calendar.eventBus.$on("event-clicked", event =>
      this.eventClicked(event)
    );
    this.$calendar.eventBus.$on("month-changed", (start, end) =>
      this.monthChanged(start, end)
    );
  }
};
</script>

The vue-calendar component renders the calendar.

It renders various events.

show-all is emitted when we show the days.

day-clicked is emitted when we click on a day.

event-clicked is emitted when we click on an event.

month-changed is emitted when we change the month on the calendar.

Conclusion

We can add a simple calendar component with the vue2-simple-calendar component.