---
title: "JQuery Timeline Resource Hover Tooltip Example | Mobiscroll"
component: "Timeline"
framework: "jQuery"
library_version: "6.1.5"
url: "https://demo.mobiscroll.com/jquery/timeline/display-resource-information-on-hover"
---

# Resource Hover Tooltip - jQuery Timeline demo

Hover over a resource row in the JQuery Timeline to open a tooltip popup with scheduled hours — keeps the timeline view clean.

- [Live demo](https://demo.mobiscroll.com/jquery/timeline/display-resource-information-on-hover)
- [View code on GitHub](https://github.com/acidb/mobiscroll-demos-jquery/tree/main/src/demos/eventcalendar/timeline/display-resource-information-on-hover)
- This demo in other frameworks: [JavaScript](https://demo.mobiscroll.com/javascript/timeline/display-resource-information-on-hover.md), [Angular](https://demo.mobiscroll.com/angular/timeline/display-resource-information-on-hover.md), [React](https://demo.mobiscroll.com/react/timeline/display-resource-information-on-hover.md), [Vue](https://demo.mobiscroll.com/vue/timeline/display-resource-information-on-hover.md)

## Description

Displaying information in a tooltip can come in handy when space is tight but information matters. When hovering over a resource cell, the [`onResourceHoverIn`](https://mobiscroll.com/docs/jquery/eventcalendar/api#event-onResourceHoverIn) and [`onResourceHoverOut`](https://mobiscroll.com/docs/jquery/eventcalendar/api#event-onResourceHoverOut) [lifecycle events](https://demo.mobiscroll.com/jquery/timeline/event-hooks) are triggered, which can be used to show/hide rich tooltips. Information and actions shown here won't clutter the main view, keep the timeline clean while still giving quick access to content that helps.

**Do you want to learn more about customizing the resource header?** [Take a look at this example →](https://demo.mobiscroll.com/jquery/scheduler/custom-resource-header-template)

## What this demo shows

- A desktop resource timeline with hours arranged horizontally and worker resources listed as rows on the left.
- **Header navigation** The month and year label opens date navigation, the previous and next arrows move between days, and the Today button returns to the current date.
- **Day view** The day strip shows the selected day, with the current date highlighted. The timeline displays hourly columns from 7 AM to 10 PM.
- **Resources** Each worker appears as a separate resource row with an avatar, name, and profession in the resource column.
- **Resource hover** Hovering over a resource row opens a custom popup with additional worker details.
- **Resource popup** The popup shows the worker avatar, name, hourly rate, scheduled hours for the selected day, estimated earnings, and a Pay action button.
- **Current time** A vertical blue line with a time label marks the current time.
- **Hover behavior** Hovering over the time grid shows a time indicator that follows the cursor in 15-minute increments.
- **Event cards** Events are shown as colored cards with a left color stripe, a bold title, and the exact start and end time below the title.
- **Date positioning** Events are positioned by their assigned resource and exact date and time range.
- **Event interaction** Events highlight on hover and show drag and resize handles for repositioning or changing duration.
- **Event selection** Clicking an event selects and highlights it.
- **Event creation** New events can be created by double-clicking the timeline or by clicking and dragging across a time range.
- **Scrolling** The timeline supports horizontal and vertical scrolling for navigating through time and resources.

## Best for

- **Workforce management** Showing employee schedules together with role, cost, and daily workload details.
- **Field service scheduling** Reviewing technician assignments while keeping profile details and pay-related actions close to the schedule.
- **Construction and maintenance planning** Coordinating resource-based work across a day timeline with quick access to worker information.
- **Healthcare staffing** Comparing staff assignments by time and resource while showing contextual staff details only when needed.
- **Payroll-aware scheduling** Displaying scheduled hours, hourly rates, estimated earnings, and payment actions alongside planned work.
- **Resource-heavy operations** Keeping the timeline readable while making worker metadata available from the resource column.

## API used in this demo

- [`theme`](https://mobiscroll.com/docs/jquery/eventcalendar/api#opt-theme) - option
- [`themeVariant`](https://mobiscroll.com/docs/jquery/eventcalendar/api#opt-themeVariant) - option
- [`getEvents`](https://mobiscroll.com/docs/jquery/eventcalendar/api#method-getEvents) - method
- [`position`](https://mobiscroll.com/docs/jquery/popup/api#method-position) - method
- [`open`](https://mobiscroll.com/docs/jquery/popup/api#method-open) - method
- [`close`](https://mobiscroll.com/docs/jquery/popup/api#method-close) - method
- [`clickToCreate`](https://mobiscroll.com/docs/jquery/eventcalendar/api#opt-clickToCreate) - option
- [`dragToCreate`](https://mobiscroll.com/docs/jquery/eventcalendar/api#opt-dragToCreate) - option
- [`dragToMove`](https://mobiscroll.com/docs/jquery/eventcalendar/api#opt-dragToMove) - option
- [`dragToResize`](https://mobiscroll.com/docs/jquery/eventcalendar/api#opt-dragToResize) - option
- [`eventDelete`](https://mobiscroll.com/docs/jquery/eventcalendar/api#opt-eventDelete) - option
- [`view`](https://mobiscroll.com/docs/jquery/eventcalendar/api#opt-view) - option
- [`data`](https://mobiscroll.com/docs/jquery/eventcalendar/api#opt-data) - option
- [`resources`](https://mobiscroll.com/docs/jquery/eventcalendar/api#opt-resources) - option
- [`renderResource`](https://mobiscroll.com/docs/jquery/eventcalendar/api#renderer-renderResource) - renderer
- [`onResourceHoverIn`](https://mobiscroll.com/docs/jquery/eventcalendar/api#event-onResourceHoverIn) - event
- [`onResourceHoverOut`](https://mobiscroll.com/docs/jquery/eventcalendar/api#event-onResourceHoverOut) - event
- [`onPageChange`](https://mobiscroll.com/docs/jquery/eventcalendar/api#event-onPageChange) - event
- [`display`](https://mobiscroll.com/docs/jquery/popup/api#opt-display) - option
- [`showOverlay`](https://mobiscroll.com/docs/jquery/popup/api#opt-showOverlay) - option
- [`touchUi`](https://mobiscroll.com/docs/jquery/popup/api#opt-touchUi) - option
- [`width`](https://mobiscroll.com/docs/jquery/popup/api#opt-width) - option
- [`onPosition`](https://mobiscroll.com/docs/jquery/popup/api#event-onPosition) - event

## Code

### JS

```js
mobiscroll.setOptions({
  theme: 'ios',
  themeVariant: 'light',
});

$(function () {
  var $tooltip = $('#demo-resource-info-popup');
  var $resourceAvatar = $('#demo-resource-info-avatar');
  var $resourceName = $('#demo-resource-info-name');
  var $resourceCost = $('#demo-resource-info-cost');
  var $resourceDate = $('#demo-resource-info-date');
  var $resourceTotal = $('#demo-resource-info-total');
  var $payButton = $('#demo-resource-info-pay');

  var $hoveredResourceElm = null;
  var currentResource = null;
  var selectedDate = new Date();
  var openTimer;
  var closeTimer;

  function getTotalHoursForResource(events, resourceId) {
    return events
      .filter(function (e) {
        return e.resource === resourceId;
      })
      .reduce(function (sum, e) {
        var start = new Date(e.start);
        var end = new Date(e.end);
        var hours = (end - start) / (1000 * 60 * 60);
        return sum + hours;
      }, 0);
  }

  function openTooltip(resource, target) {
    clearTimeout(closeTimer);
    clearTimeout(openTimer);

    // Delay opening the tooltip to avoid flickering
    openTimer = setTimeout(function () {
      var events = calendar.getEvents();
      var totalHours = getTotalHoursForResource(events, resource.id);

      currentResource = resource;
      $hoveredResourceElm = target;

      // Update popup content
      $resourceAvatar.attr('src', resource.avatar);
      $resourceName.text(resource.name);
      $resourceCost.text('$' + resource.cost);
      $resourceDate.text(mobiscroll.formatDate('D DDD MMM YYYY', selectedDate));
      $resourceTotal.text(totalHours + 'h, $' + totalHours * resource.cost);
      $(target).addClass('mds-resource-info-hover');

      tooltip.position();
      tooltip.open();

      openTimer = null;
    }, 100);
  }

  // Close the tooltip with a delay to allow hover interactions
  function closeTooltip() {
    clearTimeout(openTimer);
    clearTimeout(closeTimer);
    closeTimer = setTimeout(function () {
      tooltip.close();
      closeTimer = null;
    }, 200);
  }

  var calendar = $('#demo-display-resource-information-on-hover')
    .mobiscroll()
    .eventcalendar({
      clickToCreate: true,
      dragToCreate: true,
      dragToMove: true,
      dragToResize: true,
      eventDelete: true
      view: {
        timeline: {
          type: 'day',
          startTime: '07:00',
          endTime: '22:00',
        },
      },
      data: [
        {
          start: '2026-10-24T12:00',
          end: '2026-10-24T15:00',
          title: 'Repoint Brick Facade',
          resource: 'res1',
        },
        {
          start: '2026-10-24T09:00',
          end: '2026-10-24T12:00',
          title: 'Install Custom Wood Trim',
          resource: 'res3',
        },
        {
          start: '2026-10-24T14:00',
          end: '2026-10-24T18:00',
          title: 'Repair Steel Stair Treads',
          resource: 'res4',
        },
        {
          start: '2026-10-24T10:00',
          end: '2026-10-24T13:00',
          title: 'Pour and Finish Driveway Slab',
          resource: 'res6',
        },
        {
          start: '2026-10-24T11:00',
          end: '2026-10-24T16:00',
          title: 'Paint Interior Drywall',
          resource: 'res8',
        },
        {
          start: '2026-10-25T08:00',
          end: '2026-10-25T11:00',
          title: 'Block Wall Construction',
          resource: 'res1',
        },
        {
          start: '2026-10-25T14:00',
          end: '2026-10-25T16:00',
          title: 'Task 2',
          resource: 'Paver Installation',
        },
        {
          start: '2026-10-25T12:00',
          end: '2026-10-25T17:00',
          title: 'Install ceiling fan',
          resource: 'res2',
        },
        {
          start: '2026-10-25T10:00',
          end: '2026-10-25T14:00',
          title: 'Roof Beam Replacement',
          resource: 'res3',
        },
        {
          start: '2026-10-25T07:00',
          end: '2026-10-25T12:00',
          title: 'Custom Metalworks Creation',
          resource: 'res4',
        },
        {
          start: '2026-10-25T14:00',
          end: '2026-10-25T17:00',
          title: 'Pipe Welding',
          resource: 'res4',
        },
        {
          start: '2026-10-10T08:00',
          end: '2026-10-11T20:00',
          title: 'Leak Detection & Repair',
          resource: 'res5',
        },
        {
          start: '2026-10-25T13:00',
          end: '2026-10-25T17:00',
          title: 'Faucet & Sink Fitting',
          resource: 'res5',
        },
        {
          start: '2026-10-25T18:00',
          end: '2026-10-25T20:00',
          title: 'Drainage System Setup',
          resource: 'res5',
        },
        {
          start: '2026-10-25T09:00',
          end: '2026-10-25T13:00',
          title: 'Surface Polishing',
          resource: 'res6',
        },
        {
          start: '2026-10-25T08:00',
          end: '2026-10-25T10:00',
          title: 'Structural Steel Inspections',
          resource: 'res7',
        },
        {
          start: '2026-10-25T13:00',
          end: '2026-10-25T16:00',
          title: 'Metal Structure Assembly',
          resource: 'res7',
        },
        {
          start: '2026-10-25T17:00',
          end: '2026-10-25T19:00',
          title: 'Heavy Steel Beam Placement',
          resource: 'res7',
        },
        {
          start: '2026-10-25T09:00',
          end: '2026-10-25T12:00',
          title: 'Exterior House Painting',
          resource: 'res8',
        },
        {
          start: '2026-10-25T15:00',
          end: '2026-10-25T18:00',
          title: 'Deck Staining & Sealing',
          resource: 'res8',
        },
        {
          start: '2026-10-26T12:00',
          end: '2026-10-26T15:00',
          title: 'Troubleshoot Faulty Breaker',
          resource: 'res2',
        },
        {
          start: '2026-10-26T10:00',
          end: '2026-10-26T13:00',
          title: 'Frame Interior Partitions',
          resource: 'res3',
        },
        {
          start: '2026-10-26T16:00',
          end: '2026-10-26T20:00',
          title: 'Weld Structural Beam Connections',
          resource: 'res4',
        },
        {
          start: '2026-10-26T12:00',
          end: '2026-10-26T16:00',
          title: 'Apply Smooth Trowel Finish to Basement Floor',
          resource: 'res6',
        },
      ],
      resources: [
        {
          id: 'res1',
          name: 'Adam Miller',
          color: '#F39C12',
          profession: 'Mason',
          avatar: 'https://img.mobiscroll.com/demos/m1.png',
          cost: '15',
        },
        {
          id: 'res2',
          name: 'Emily Carter',
          color: '#76e083',
          profession: 'Electrician',
          avatar: 'https://img.mobiscroll.com/demos/f1.png',
          cost: '20',
        },
        {
          id: 'res3',
          name: 'James Brown',
          color: '#b13f49',
          profession: 'Carpenter',
          avatar: 'https://img.mobiscroll.com/demos/m2.png',
          cost: '18',
        },
        {
          id: 'res4',
          name: 'Daniel Wilson',
          color: '#e25dd2',
          profession: 'Welder',
          avatar: 'https://img.mobiscroll.com/demos/m3.png',
          cost: '22',
        },
        {
          id: 'res5',
          name: 'Benjamin Harris',
          color: '#7056ff',
          profession: 'Plumber',
          avatar: 'https://img.mobiscroll.com/demos/m4.png',
          cost: '20',
        },
        {
          id: 'res6',
          name: 'Olivia Anderson',
          color: '#56aaff',
          profession: 'Concrete Finisher',
          avatar: 'https://img.mobiscroll.com/demos/f2.png',
          cost: '15',
        },
        {
          id: 'res7',
          name: 'Emma Thompson',
          color: '#84852f',
          profession: 'Steelworker',
          avatar: 'https://img.mobiscroll.com/demos/f3.png',
          cost: '18',
        },
        {
          id: 'res8',
          name: 'Natalie Roberts',
          color: '#ff6e56',
          profession: 'Painter',
          avatar: 'https://img.mobiscroll.com/demos/f4.png',
          cost: '25',
        },
      ],
      renderResource: function (res) {
        return (
          '<div class="mbsc-flex">' +
          '<img class="mds-resource-info-avatar" src="' +
          res.avatar +
          '"/>' +
          '<div class="mds-resource-info-details">' +
          '<div class="mds-resource-info-title">' +
          res.name +
          '</div>' +
          '<div class="mds-resource-info-profession">' +
          res.profession +
          '</div>' +
          '</div>' +
          '</div>'
        );
      },
      onResourceHoverIn: function (args) {
        openTooltip(args.resource, args.target);
      },
      onResourceHoverOut: function (args) {
        $(args.target).removeClass('mds-resource-info-hover');
        closeTooltip();
      },
      onPageChange: function (args) {
        selectedDate = args.firstDay;
      },
    })
    .mobiscroll('getInst');

  var tooltip = $tooltip
    .mobiscroll()
    .popup({
      display: 'anchored',
      showOverlay: false,
      touchUi: false,
      width: 280,
      onPosition: function (args, inst) {
        var $popupElm = $(args.target).children('.mbsc-popup');
        var rect = $hoveredResourceElm.getBoundingClientRect();

        $popupElm[0].style.top = rect.top - 10 + 'px';

        if (inst.s.rtl) {
          $popupElm[0].style.right = window.innerWidth - rect.left + 10 + 'px';
        } else {
          $popupElm[0].style.left = rect.right + 10 + 'px';
        }
        return false; // Prevent default positioning
      },
    })
    .mobiscroll('getInst');

  $tooltip
    .on('mouseenter', function () {
      clearTimeout(closeTimer);
    })
    .on('mouseleave', function () {
      closeTooltip();
    });

  $payButton.on('click', function () {
    tooltip.close();
    mobiscroll.toast({
      message: currentResource.name + ' paid',
    });
  });
});
```

### HTML

```html
<div id="demo-resource-info-popup" style="display: none;">
  <div class="mbsc-flex mbsc-align-items-center mds-resource-info-header">
    <img id="demo-resource-info-avatar" class="mds-resource-info-avatar" />
    <div id="demo-resource-info-name" class="mds-resource-info-name mbsc-flex-1-0"></div>
    <button id="demo-resource-info-pay" mbsc-button data-color="success" data-variant="outline" class="mds-resource-info-pay mbsc-button-xs">
      Pay
    </button>
  </div>
  <div class="mds-resource-info-cont">
    <div>
      <span class="mbsc-txt-muted">Hourly rate </span>
      <span id="demo-resource-info-cost" class="mds-resource-info-detail"></span>
    </div>
    <div>
      <span id="demo-resource-info-date" class="mbsc-txt-muted"></span>
      <span id="demo-resource-info-total" class="mds-resource-info-detail"></span>
    </div>
  </div>
</div>
<div id="demo-display-resource-information-on-hover"></div>
```

### CSS

```css
.mds-resource-info-avatar {
  width: 40px;
  height: 40px;
}
.mds-resource-info-details {
  margin: 0 8px;
}
.mds-resource-info-title {
  line-height: 24px;
}
.mds-resource-info-profession {
  font-size: 12px;
  opacity: .5;
  line-height: 18px;
}
.mds-resource-info-hover.mbsc-timeline-resource {
  text-decoration: underline;
}
.mds-resource-info-header {
  height: 35px;
}
.mds-resource-info-name {
  font-size: 18px;
  padding: 16px 10px;
}
.mds-resource-info-pay.mbsc-button {
  margin: 0;
  line-height: 24px;
  padding: 0 10px;
  will-change: opacity;
}
.mds-resource-info-pay .mbsc-button-txt {
  font-size: 12px;
}
.mds-resource-info-cont {
  font-size: 14px;
  line-height: 22px;
  padding-top: 23px;
}
.mbsc-ltr .mds-resource-info-detail {
  float: right;
}
.mbsc-rtl .mds-resource-info-detail {
  float: left;
}
```

## Implementation notes

- Use `timeline: { type: 'day', startTime: '07:00', endTime: '22:00' }` - a single-day view showing 7am-10pm.
- Define 8 worker resources, each with `id`, `name`, `color`, `profession`, `avatar` (image URL), and `cost` ($/hour).
- Add ~24 task events across yesterday/today/tomorrow with `dyndatetime` offsets and hourly start/end times.
- **Custom resource row** (`renderResource` / `resourceTemplate` / `resource` slot): renders the worker's avatar image alongside their name and profession.
- **Hover tooltip** - implemented with debounced open/close timers to avoid flickering and to allow the cursor to travel from the resource row into the popup without dismissal:
  - `onResourceHoverIn`: cancel both timers, start a 100ms open timer. When it fires: compute total scheduled hours for the resource (see below), add a CSS highlight class (`mds-resource-info-hover`) to `args.target`, populate tooltip state (avatar, name, hourly rate, formatted date, total hours + total cost), call `popupRef.position()`, then open the popup.
  - `onResourceHoverOut`: remove the highlight class from `args.target`, cancel the open timer, start a 200ms close timer.
  - On the popup's wrapping element: `onMouseEnter` cancels the close timer (keeps popup open); `onMouseLeave` starts the close timer again.
- **Popup**: `display: 'anchored'`, `showOverlay: false`, `touchUi: false`, `width: 280`. Content: avatar + name + a "Pay" button (outline/success) in the header row; below that, hourly rate and a line showing the current day's total hours and total cost (`hours * rate`).
- **Custom popup positioning** (`onPosition`): read the hovered resource element's `getBoundingClientRect()`, set the popup 10px to the right of the element (`rect.right + 10`) and aligned to its top (`rect.top - 10`). For RTL, use `window.innerWidth - rect.left + 10` for the right offset. Return `false` to suppress Mobiscroll's default positioning.
- **Total hours**: use `calRef.getEvents()`, filter by resource id, sum `(end - start) / (1000 * 60 * 60)` across all events visible on the current day.
- **Date display**: track the visible date via `onPageChange` (`args.firstDay`); format it with `formatDate('D DDD MMM YYYY', date)` for the tooltip.
- **"Pay" button**: closes the tooltip and shows a `Toast` with `"<name> paid"`.

## Run it in your project

1. If not signed up yet, or don't own a license, you can [start a free trial](https://mobiscroll.com/starttrial).

2. Clone the repository:

   ```
   git clone https://github.com/acidb/mobiscroll-demos-jquery.git
   ```

3. If not installed yet, install the Mobiscroll CLI from NPM:

   ```
   npm install -g @mobiscroll/cli
   ```

4. Config Mobiscroll - open a terminal window in the root directory and run:

   ```
   mobiscroll config jquery
   ```

5. Install dependencies - open a terminal window in the root directory and run:

   ```
   npm install
   ```

6. Run the project:

   ```
   npm run dev
   ```

On a trial, add `--trial` to the config command: `mobiscroll config jquery --trial`.

Running a demo locally requires a Mobiscroll trial or a license; setup is per framework at https://mobiscroll.com/docs/jquery/getting-started/installation

## Related demos

- Previous: [Resource Properties](https://demo.mobiscroll.com/jquery/timeline/resource-data-structure.md) - Define resource properties on the JQuery Timeline — set up nested groups, fixed rows, and per-resource drag, resize, and overlap controls.
