Flexible UI components
for scheduling, planning and resource management
Built for growth companies to mature organizations who are looking for solid tools instead of opinionated libraries, that play well with their stack
Built for growth companies to mature organizations who are looking for solid tools instead of opinionated libraries, that play well with their stack
Many HR tools rely on solid scheduling and calendaring mechanics. Both product companies and internal teams use Mobiscroll to build their UI from rota planing and staffing to leave and employee event calendars.
The timeline for managing tens, hundreds or event thousand of resources and the scheduler for having a Google calendar-like experience supporting single & multi-resource views with great performance.
Because building things internally is time-consuming, requires continuous maintenance, and demands unnecessary effort.
Compared to other vendors, developers using Mobiscroll can achieve outcomes more aligned with their product team's vision, as they are not constrained by the mindset of "that's just how things are supposed to work".
Scheduling plays a crucial role in daily tasks across various industries and sectors, fundamentally involving the planning of tasks, work orders, meetings, and appointments across multiple dimensions and timeframes.
The timeline is ideal for planning and gaining a clear overview of multiple resources across different time spans, with the flexibility to zoom in and out. Meanwhile, the scheduler offers a highly customizable, Google Calendar-like experience. Both tools come equipped with essential features for displaying multiple layers of information, enabling developers to create insightful and user-friendly views.
Instead of a one-size-fits-all approach with rigid, opinionated features, we offer a versatile toolset that empowers teams to leverage various capabilities, enabling users to make informed decisions in real-time.
The flexibility to layer multiple data points onto the timeline or scheduler allows designers and developers to get creative and refine the user experience to fit their needs.
In resource management, flexibility and performance are key. The ability to quickly view a few resources or thousands across different timeframes is essential. With templating capabilities, users can access all relevant information at a glance—whether it's tasks assigned to assets, jobs, accommodation reservations, or vehicle fleets with routes, you can display crucial data, buffers, and more to enhance decision-making.
With built-in virtualization, advanced data loading mechanics, and deep customization options, the timeline view provides a powerful way to get both a high-level overview of resources and detailed single-resource views across multiple dimensions.
Optimized for both touch and desktop, with exceptional scrolling and loading performance, these versatile components provide all the tools needed to craft bespoke resource management experiences.
Project management can quickly become complex, involving dependencies, work estimation across various resources, and multiple stages. The more moving parts there are, the harder it is to keep everything aligned.
The timeline view simplifies this process by allowing you to easily configure short- or long-term views, adjust time granularity, and manage anything from a few to thousands of resources along with their tasks and dependencies.
If a full-fledged Gantt chart isn't necessary, but you still need Gantt-like features—such as dependencies, visual progress tracking, combined with advanced resource and task management, the timeline is the perfect solution.
With Mobiscroll's flexibility, developers have the tools to create custom views that help customers stay organized and keep projects on track.
Build responsive scheduling, appointment management for single or multiple resources, with deep view configuration and customization through templating and custom renderers.
Fine-grain control over drag & drop, validation along with external event drag, ship great scheduling experiences.
mobisroll.eventcalendar('#demo', {
view: {
schedule: {
type: 'week',
startTime: "08:00",
endTime: "17:00",
}
}
})
$('#demo').mobiscroll().eventcalendar({
view: {
schedule: {
type: 'week',
startTime: "08:00",
endTime: "17:00",
}
}
})
<mbsc-eventcalendar [view]="myView"></mbsc-eventcalendar>
public myView: MbscEventcalendarView = {
schedule: {
type: 'week',
startTime: "08:00",
endTime: "17:00",
}
};
function (props) {
const myView = {
schedule: {
type: 'week',
startTime: "08:00",
endTime: "17:00",
}
}
return <>
<Eventcalendar view={myView} />
</>
}
<script setup>
const myView = {
schedule: {
type: 'week',
startTime: "08:00",
endTime: "17:00",
}
}
</script>
<template>
<MbscEventcalendar :view="myView" />
</template>
#demo .mbsc-schedule-header-dayname,
#demo .mbsc-schedule-header-day,
#demo .mbsc-schedule-all-day-text,
#demo .mbsc-schedule-time {
font-weight: bold;
color: #000;
}
mobisroll.eventcalendar('#demo', {
renderScheduleEvent: function (data) {
return (
'<div class="my-event-class">' + data.title + '</div>'
);
},
})
$('#demo').mobiscroll().eventcalendar({
renderScheduleEvent: function (data) {
return (
'<div class="my-event-class">' + data.title + '</div>'
);
},
})
<mbsc-eventcalendar
[scheduleEventTemplate]="eventTemplate"
>
<ng-template #eventTemplate let-data>
<div class="my-custom-class">{{data.title}}</div>
</ng-template>
</mbsc-eventcalendar>
function (props) {
const customEventRenderer = (data) => (
<div className="my-custom-event">{data.title}</div>
);
return <>
<Eventcalendar
renderScheduleEvent={customEventRenderer}
/>
</>
}
<template>
<MbscEventcalendar>
<template #scheduleEvent="data">
<div class="my-custom-event">{{ data.title }}</div>
</template>
</MbscEventcalendar>
</template>
mobisroll.eventcalendar('#demo', {
onEventClick: function() {
mobiscroll.toast({ message: "Event clicked" });
},
onEventCreated: function() {
mobiscroll.toast({ message: "Event created" });
},
});
$('#demo').mobiscroll().eventcalendar({
onEventClick: function() {
mobiscroll.toast({ message: "Event clicked" });
},
onEventCreated: function() {
mobiscroll.toast({ message: "Event created" });
},
});
<mbsc-eventcalendar
(onEventClick)="eventClick()"
(onEventCreated)="eventCreated()"
></mbsc-eventcalendar>
import { Notifications } from '@mobiscroll/angular';
// ...
constructor(private notify: Notifications) {}
public eventClick: function() {
this.notify.toast({ message: "Event clicked" });
}
public eventCreated: function() {
this.notify.toast({ message: "Event created" });
}
function (props) {
const [isToastOpen, setToastOpen] = useState(false);
const closeMessage = () => setToastOpen(false);
const [message, setMessage] = useState('');
return <>
<Eventcalendar
onEventClick={showToast.bind(null, 'Event clicked')}
onEventCreated={showToast.bind(null, 'Event created')}
/>
<Toast
isOpen={isToastOpen}
onClose={closeMessage}
message={message}
/>
</>
function showToast(mess) {
setMessage(mess);
setToastOpen(true)
}
}
<template>
<MbscToast :message="message" :isOpen="isToastOpen" @close="isToastOpen = false" />
<MbscEventcalendar
@event-click="() => showMessage('Event clicked')"
@event-created="() => showMessage('Event created')"
>
</MbscEventcalendar>
</template>
<script setup>
import { ref } from 'vue';
import { MbscToast, MbscEventcalendar } from '@mobiscroll/vue';
const isToastOpen = ref(false);
const message = ref('');
function showMessage(mess) {
message.value = mess;
isToastOpen.value = true;
}
</script>
Use the calendar view to display events for one or more resources and from multiple sources as labels or lists. Month view by default, but can be configured as single or multiple week view, multi-month view, quarter view or year view.
Flexible in styling and customizable through theming and custom renderers.
#demo .mbsc-calendar-week-day,
#demo .mbsc-calendar-cell-text,
#demo .mbsc-calendar-label-text,
#demo .mbsc-calendar-button.mbsc-ios {
font-weight: bold;
color: #000;
}
mobisroll.eventcalendar('#demo', {
renderLabel: function (data) {
return (
'<div style="background:' + data.original.color + '">' + data.original.title + '</div>'
);
},
})
$('#demo').mobiscroll().eventcalendar({
renderLabel: function (data) {
return (
'<div style="background:' + data.original.color + '">' + data.original.title + '</div>'
);
},
})
<mbsc-eventcalendar
[labelTemplate]="myLabelTemplate"
>
<ng-template #myLabelTemplate let-data>
<div [ngStyle]="{color: '#000'}">{{data.original.title}}</div>
</ng-template>
</mbsc-eventcalendar>
function (props) {
const labelRenderer = (data) => (
<div className="my-custom-event">{data.original.title}</div>
);
return <>
<Eventcalendar
renderLabel={labelRenderer}
/>
</>
}
<template>
<MbscEventcalendar>
<template #label="data">
<div class="my-custom-event">{{ data.original.title }}</div>
</template>
</MbscEventcalendar>
</template>
mobisroll.eventcalendar('#demo', {
onEventClick: function() {
mobiscroll.toast({ message: "Event clicked" });
},
onEventCreated: function() {
mobiscroll.toast({ message: "Event created" });
},
});
$('#demo').mobiscroll().eventcalendar({
onEventClick: function() {
mobiscroll.toast({ message: "Event clicked" });
},
onEventCreated: function() {
mobiscroll.toast({ message: "Event created" });
},
});
<mbsc-eventcalendar
(onEventClick)="eventClick()"
(onEventCreated)="eventCreated()"
></mbsc-eventcalendar>
import { Notifications } from '@mobiscroll/angular';
// ...
constructor(private notify: Notifications) {}
public eventClick: function() {
this.notify.toast({ message: "Event clicked" });
}
public eventCreated: function() {
this.notify.toast({ message: "Event created" });
}
function (props) {
const [isToastOpen, setToastOpen] = useState(false);
const closeMessage = () => setToastOpen(false);
const [message, setMessage] = useState('');
return <>
<Eventcalendar
onEventClick={showToast.bind(null, 'Event clicked')}
onEventCreated={showToast.bind(null, 'Event created')}
/>
<Toast
isOpen={isToastOpen}
onClose={closeMessage}
message={message}
/>
</>
function showToast(mess) {
setMessage(mess);
setToastOpen(true)
}
}
<template>
<MbscToast :message="message" :isOpen="isToastOpen" @close="isToastOpen = false" />
<MbscEventcalendar
@event-click="() => showMessage('Event clicked')"
@event-created="() => showMessage('Event created')"
>
</MbscEventcalendar>
</template>
<script setup>
import { ref } from 'vue';
import { MbscToast, MbscEventcalendar } from '@mobiscroll/vue';
const isToastOpen = ref(false);
const message = ref('');
function showMessage(mess) {
message.value = mess;
isToastOpen.value = true;
}
</script>
mobisroll.eventcalendar('#demo', {
clickToCreate: true,
dragToCreate: true,
dragToMove: true,
dragToResize: true,
eventDelete: true,
});
$('#demo').mobiscroll().eventcalendar({
clickToCreate: true,
dragToCreate: true,
dragToMove: true,
dragToResize: true,
eventDelete: true,
});
<mbsc-eventcalendar
[clickToCreate]="true"
[dragToCreate]="true"
[dragToMove]="true"
[dragToResize]="true"
[eventDelete]="true"
></mbsc-eventcalendar>
<Eventcalendar
clickToCreate={true}
dragToCreate={true}
dragToMove={true}
dragToResize={true}
eventDelete={true}
/>
<MbscEventcalendar
:clickToCreate="true"
:dragToCreate="true"
:dragToMove="true"
:dragToResize="true"
:eventDelete="true"
>
</MbscEventcalendar>
Use the timeline view with Gantt-like features for smoothly managing anything between a couple to thousands of resources across virtually any period of time. With built-in virtualization, advanced templating capabilities, great performance, touch support and super flexibility, the timeline view is your go-to tool for asset-, resource-, workforce- or project-management.
Pair that with your vision for what a tailored user experience means for your customers and users.
mobisroll.eventcalendar('#demo', {
view: {
timeline: {
type: 'month',
startTime: "08:00",
endTime: "17:00",
}
}
})
$('#demo').mobiscroll().eventcalendar({
view: {
timeline: {
type: 'month',
startTime: "08:00",
endTime: "17:00",
}
}
})
<mbsc-eventcalendar [view]="myView"></mbsc-eventcalendar>
public class MyComponent {
public myView: MbscEventcalendarView = {
timeline: {
type: 'month',
startTime: "08:00",
endTime: "17:00",
}
};
function (props) {
const myView = {
timeline: {
type: 'month',
startTime: "08:00",
endTime: "17:00",
}
}
return <>
<Eventcalendar view={myView} />
</>
}
<script setup>
const myView = {
timeline: {
type: 'month',
startTime: "08:00",
endTime: "17:00",
}
}
</script>
<template>
<MbscEventcalendar :view="myView" />
</template>
#demo .mbsc-timeline-header-active,
#demo .mbsc-timeline-header-date,
#demo .mbsc-timeline-header-column {
font-weight: bold;
color: #000;
}
mobisroll.eventcalendar('#demo', {
renderScheduleEvent: function (data) {
return (
'<div class="my-event-class">' + data.title + '</div>'
);
},
})
$('#demo').mobiscroll().eventcalendar({
renderScheduleEvent: function (data) {
return (
'<div class="my-event-class">' + data.title + '</div>'
);
},
})
<mbsc-eventcalendar
[scheduleEventTemplate]="eventTemplate"
>
<ng-template #eventTemplate let-data>
<div class="my-custom-class">{{data.title}}</div>
</ng-template>
</mbsc-eventcalendar>
function (props) {
const customEventRenderer = (data) => (
<div className="my-custom-event">{data.title}</div>
);
return <>
<Eventcalendar
renderScheduleEvent={customEventRenderer}
/>
</>
}
<template>
<MbscEventcalendar>
<template #scheduleEvent="data">
<div class="my-custom-event">{{ data.title }}</div>
</template>
</MbscEventcalendar>
</template>
mobisroll.eventcalendar('#demo', {
resources: [{
id: 'unassigned_tickets',
name: "Unassigned Tickets",
color: "#c8cdcf",
fixed: true,
}, /* ... */],
})
$('#demo').mobiscroll().eventcalendar({
resources: [{
id: 'unassigned_tickets',
name: "Unassigned Tickets",
color: "#c8cdcf",
fixed: true,
}, /* ... */],
})
<mbsc-eventcalendar [resources]="myResources"></mbsc-eventcalendar>
public class MyComponent {
public myResources: MbscResource[] = [{
id: 'unassigned_tickets',
name: "Unassigned Tickets",
color: "#c8cdcf",
fixed: true,
}, /* ... */]
function (props) {
const [resources, setResources] = useState([{
id: 'unassigned_tickets',
name: "Unassigned Tickets",
color: "#c8cdcf",
fixed: true,
}, /* ... */])
return <>
<Eventcalendar resources={resources} />
</>
}
<script setup>
import { ref } from 'vue';
import { MbscEventcalendar } from '@mobiscroll/vue';
const resources = ref([{
id: 'unassigned_tickets',
name: "Unassigned Tickets",
color: "#c8cdcf",
fixed: true,
}, /* ... */]);
</script>
<template>
<MbscEventcalendar
:resources="resources"
>
</MbscEventcalendar>
</template>
mobisroll.eventcalendar('#demo', {
dragInTime: false,
dragToResize: false,
dragToCreate: true,
});
$('#demo').mobiscroll().eventcalendar({
dragInTime: false,
dragToResize: false,
dragToCreate: true,
});
<mbsc-eventcalendar
[dragInTime]="false",
[dragToResize]="false",
[dragToCreate]="true",
></mbsc-eventcalendar>
<Eventcalendar
dragInTime={false},
dragToResize={false},
dragToCreate={true},
/>
<MbscEventcalendar
:dragInTime="false", // [!code highlight]
:dragToResize="false",
:dragToCreate="true",
>
</MbscEventcalendar>
List out events events grouped by day with sticky headers. Set it up as a daily, weekly, monthly agenda or configure a custom range for the event list.
Customize the look & feel through templating and custom renderers and use it on its own or combine it with a calendar or date picker.
mobisroll.eventcalendar('#demo', {
view: {
agenda: { type: 'week' },
calendar: { type: 'week' },
}
})
$('#demo').mobiscroll().eventcalendar({
view: {
agenda: { type: 'week' },
calendar: { type: 'week' },
}
})
<mbsc-eventcalendar [view]="myView"></mbsc-eventcalendar>
public class MyComponent {
public myView: MbscEventcalendarView = {
agenda: { type: 'week' },
calendar: { type: 'week' },
};
function (props) {
const myView = {
agenda: { type: 'week' },
calendar: { type: 'week' },
}
return <>
<Eventcalendar view={myView} />
</>
}
<script setup>
const myView = {
agenda: { type: 'week' },
calendar: { type: 'week' },
}
</script>
<template>
<MbscEventcalendar :view="myView" />
</template>
#demo .mbsc-calendar-week-day,
#demo .mbsc-calendar-cell-text,
#demo .mbsc-calendar-label-text {
font-weight: bold;
color: #000;
}
mobisroll.eventcalendar('#demo', {
renderEvent: function (data) {
return (
'<div style="background:' + data.original.color + '">' + data.original.title + '</div>'
);
},
})
$('#demo').mobiscroll().eventcalendar({
renderEvent: function (data) {
return (
'<div style="background:' + data.original.color + '">' + data.original.title + '</div>'
);
},
})
<mbsc-eventcalendar
[eventTemplate]="myEventTemplate"
>
<ng-template #myEventTemplate let-data>
<div [ngStyle]="{color: '#000'}">{{data.original.title}}</div>
</ng-template>
</mbsc-eventcalendar>
function (props) {
const eventRenderer = (data) => (
<div className="my-custom-event">{data.original.title}</div>
);
return <>
<Eventcalendar
renderEvent={eventRenderer}
/>
</>
}
<template>
<MbscEventcalendar>
<template #event="data">
<div class="my-custom-event">{{ data.original.title }}</div>
</template>
</MbscEventcalendar>
</template>
mobisroll.eventcalendar('#demo', {
onEventClick: function() {
mobiscroll.toast({ message: "Event clicked" });
},
onEventDeleted: function() {
mobiscroll.toast({ message: "Event deleted" });
},
});
$('#demo').mobiscroll().eventcalendar({
onEventClick: function() {
mobiscroll.toast({ message: "Event clicked" });
},
onEventDeleted: function() {
mobiscroll.toast({ message: "Event deleted" });
},
});
<mbsc-eventcalendar
(onEventClick)="eventClick()"
(onEventDeleted)="eventCreated()"
></mbsc-eventcalendar>
import { Notifications } from '@mobiscroll/angular';
// ...
constructor(private notify: Notifications) {}
public eventClick: function() {
this.notify.toast({ message: "Event clicked" });
}
public eventCreated: function() {
this.notify.toast({ message: "Event deleted" });
}
function (props) {
const [isToastOpen, setToastOpen] = useState(false);
const closeMessage = () => setToastOpen(false);
const [message, setMessage] = useState('');
return <>
<Eventcalendar
onEventClick={showToast.bind(null, 'Event clicked')}
onEventDeleted={showToast.bind(null, 'Event deleted')}
/>
<Toast
isOpen={isToastOpen}
onClose={closeMessage}
message={message}
/>
</>
function showToast(mess) {
setMessage(mess);
setToastOpen(true)
}
}
<template>
<MbscToast :message="message" :isOpen="isToastOpen" @close="isToastOpen = false" />
<MbscEventcalendar
@event-click="() => showMessage('Event clicked')"
@event-deleted="() => showMessage('Event deleted')"
>
</MbscEventcalendar>
</template>
<script setup>
import { ref } from 'vue';
import { MbscToast, MbscEventcalendar } from '@mobiscroll/vue';
const isToastOpen = ref(false);
const message = ref('');
function showMessage(mess) {
message.value = mess;
isToastOpen.value = true;
}
</script>
Use it wherever JavaScript runs, framework agnostic components for the modern developers.
Get started with JavaScriptUse it with Angular, Ionic, Remix or any development framework based on Angular.
Get started with AngularUse it with React, Ionic, Next.js or any development framework based on React.
Get started with ReactUse it with Vue, Ionic, Nuxt or any development framework based on Vue.
Get started with VueUse it with jQuery-based projects to enhance interactivity, simplify DOM manipulation and improve cross-browser compatibility.
Get started with jQueryStanding on a solid foundation, our toolset based approach doesn't outgrow you. We build to face new requirements.
Why development loves itThe reality is that every product is a bit different. We focus on flexibility rather than opinionated and stiff solutions.
Why product loves itWith a great track record, you can count on us. Future-proof your team and let us help you check all the boxes.
Why leadership loves itYou have signed in on a different machine. To keep everything in sync, you have been signed out of this session.
If you need to invite team members, manage seats and accounts you can do it from the licenses page.
We noticed you are logged in on a different machine and have closed your old session.
If you need to invite team members, manage seats and accounts you can do it from the licenses page.