| CARVIEW |
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
Trusted by amazing internal and product teams
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.
Why Mobiscroll?
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.
Why Mobiscroll?
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.
Why Mobiscroll?
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.
Why Mobiscroll?
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.
Scheduler for day, week, month or any custom range for one or more resources
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.
How is the Scheduler made?
- Configured the view from 8AM to 5PM Learn moreIt's very simple to set up a recurring start and end time for the day along with configuring what days to show and more.
- Overridden the default colors, font weight Learn moreYou can easily customize the look and feel of the scheduler by adjusting colors, font weights, and other styles using CSS to ensure it matches your design requirements.
- Implemented custom templates Learn moreCustom templates allow you to fully control how events, headers, resources and time slots are displayed, making it possible to create a highly personalized scheduling experience.
- Used lifecycle events to handle interactions Learn moreBy leveraging lifecycle events, you can react to user interaction such as event clicks, drags, drops, enabling dynamic updates and seamless user 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",
}
}
})Template
<mbsc-eventcalendar [view]="myView"></mbsc-eventcalendar> TypeScript
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>'
);
},
})Template
<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" });
},
});Template
<mbsc-eventcalendar
(onEventClick)="eventClick()"
(onEventCreated)="eventCreated()"
></mbsc-eventcalendar> TypeScript
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(message) {
setMessage(message);
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> Responsive event calendar with mobile & desktop mode
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.
How is the Calendar made?
- Overridden the default colors, font weight Learn moreYou can easily customize the look and feel of the calendar by adjusting colors, font weights, and other styles using CSS to ensure it matches your design requirements.
- Implemented custom templates Learn moreCustom templates allow you to fully control how events show up as labels and in popover listing, making it possible to show relevant information that your users will actually enjoy.
- Used lifecycle events to handle interactions Learn moreBy leveraging lifecycle events, you can react to user interaction such as event clicks, drags, drops, enabling dynamic updates and seamless user experiences.
- Configured event actions Learn moreWith fine-grain control over drag & drop, event creation, resize and delete, you can dynamically switch between presets based on roles or whatever makes sense.
#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>'
);
},
})Template
<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" });
},
});Template
<mbsc-eventcalendar
(onEventClick)="eventClick()"
(onEventCreated)="eventCreated()"
></mbsc-eventcalendar> TypeScript
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(message) {
setMessage(message);
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,
});Template
<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> Timeline for advanced resource management across variable time ranges
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.
How is this Timeline made?
- Configured the view from 8AM to 5PM Learn moreIt's very simple to set up a recurring start and end time for the day along with configuring what days to show and more.
- Overridden the default colors, font weight Learn moreYou can easily customize the look and feel of the timeline by adjusting colors, font weights, and other styles using CSS to ensure it matches your design requirements.
- Implemented custom templates Learn moreCustom templates allow you to fully control how events, headers, resources and time slots are displayed, making it possible to create a highly personalized scheduling experience.
- Fixed the unassigned tickets row at the topYou can easily mark one or more resource rows sticky at the top, which grants them constant visibility.
- Fixed events in time to only allow reassignmentWith fine-grain control over the allowed drag & drop interaction, you can fix scheduled tasks in time and only allow reassignments.
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",
}
}
})Template
<mbsc-eventcalendar [view]="myView"></mbsc-eventcalendar> TypeScript
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>'
);
},
})Template
<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,
}, /* ... */],
})Template
<mbsc-eventcalendar [resources]="myResources"></mbsc-eventcalendar> TypeScript
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,
});Template
<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> Agenda with event listing for a customizable range
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.
How is the Agenda made?
- Combined the agenda with a week calendar Learn moreMix & match the views so that they make sense for your users. Weekly calendar + weekly agenda, or monthly calendar and daily agenda below?
- Overridden the default colors, font weight Learn moreYou can easily customize the look and feel of the agenda by adjusting colors, font weights, and other styles using CSS to ensure it matches your design requirements.
- Implemented custom templates Learn moreCustom templates allow you to fully control how events look, making it possible to display relevant information that your users will actually enjoy.
- Used lifecycle events to handle interactions Learn moreBy leveraging lifecycle events, you can react to user interaction such as event clicks, selection, delete and much more.
mobisroll.eventcalendar('#demo', {
view: {
agenda: { type: 'week' },
calendar: { type: 'week' },
}
})$('#demo').mobiscroll().eventcalendar({
view: {
agenda: { type: 'week' },
calendar: { type: 'week' },
}
})Template
<mbsc-eventcalendar [view]="myView"></mbsc-eventcalendar> TypeScript
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>'
);
},
})Template
<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" });
},
});Template
<mbsc-eventcalendar
(onEventClick)="eventClick()"
(onEventDeleted)="eventCreated()"
></mbsc-eventcalendar> TypeScript
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(message) {
setMessage(message);
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> For plain JavaScript
Use it wherever JavaScript runs, framework agnostic components for the modern developers.
Get started with JavaScriptFor Angular
Use it with Angular, Ionic, Remix or any development framework based on Angular.
Get started with AngularFor React
Use it with React, Ionic, Next.js or any development framework based on React.
Get started with ReactFor Vue
Use it with Vue, Ionic, Nuxt or any development framework based on Vue.
Get started with VueFor jQuery
Use it with jQuery-based projects to enhance interactivity, simplify DOM manipulation and improve cross-browser compatibility.
Get started with jQueryBuilt to scale
Standing on a solid foundation, our toolset based approach doesn't outgrow you. We build to face new requirements.
Why development loves itFlexibility on the output
The reality is that every product is a bit different. We focus on flexibility rather than opinionated and stiff solutions.
Why product loves itPeace of mind
With 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 itand get $50 cash
Duplicate Session
You 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.
Duplicate Session
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.