---
title: "Angular Timeline Cell Hover Highlight Example | Mobiscroll"
component: "Timeline"
framework: "Angular"
library_version: "6.1.5"
url: "https://demo.mobiscroll.com/angular/timeline/dynamic-resource-column-highlight-on-cell-hover"
---

# Cell Hover Highlight - Angular Timeline demo

Add row and column hover highlighting to a Angular resource timeline — highlight the active resource row and date column on hover.

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

## Description

Highlight the resource row and date column on cell hover to improve usability by clearly showing where the user is interacting.

This is achieved using the `onCellHoverIn` and `onCellHoverOut` lifecycle events. These track the hovered cell and update the resources with a custom `cssClass`, which highlights the resource row. A popup is also shown on hover, displaying relevant information about the cell like the date and resource name.

The column highlight is applied using the `renderCell`, `renderSidebar`, `renderTimelineDay`, and `renderDayFooter` callbacks, where conditional markup is returned to highlight the vertical column.

This makes it easy to implement custom hover interactions that match your design and UX goals.

## What this demo shows

- A desktop monthly timeline with days arranged horizontally and resources listed as rows.
- **Header navigation** The month and year label opens date navigation, the previous and next arrows move between months, and the Today button returns to the current date.
- **Month view** The timeline displays the days of the selected month as horizontal date columns.
- **Footer** The bottom strip repeats the days of the selected month.
- **Resources** Multiple resources are shown as separate timeline rows on the left.
- **Sidebar** Resource names are also rendered in a right-side sidebar.
- **Cell hover** Hovering a timeline cell highlights both the resource row and the date column, making the active cell context clear.
- **Hover popup** A popup appears on cell hover with contextual information, including the resource name and date.
- **Column highlight** The highlighted date column is applied across the timeline body, day header, footer, and sidebar rendering areas.
- **Event cards** Events appear as colored cards with a colored stripe, bold event title, and exact start and end time.
- **Date positioning** Events are positioned by their assigned resource and date 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 dates and resources.

## Best for

- **Resource timelines** Applications that need to show many resources against a shared monthly timeline.
- **Context-heavy scheduling** Scheduling interfaces where users need clear row and column feedback before creating, moving, or resizing events.
- **Operational dashboards** Planning views that benefit from contextual hover details without opening a full editor.
- **Asset management** Interfaces for tracking equipment, rooms, vehicles, or other assignable resources over time.
- **Workforce scheduling** Staff planning views where resource names, dates, and scheduled work need to stay easy to follow.

## API used in this demo

- [`cssClass`](https://mobiscroll.com/docs/angular/eventcalendar/api#opt-cssClass) - option
- [`view`](https://mobiscroll.com/docs/angular/eventcalendar/api#opt-view) - option
- [`data`](https://mobiscroll.com/docs/angular/eventcalendar/api#opt-data) - option
- [`resources`](https://mobiscroll.com/docs/angular/eventcalendar/api#opt-resources) - option
- [`cellTemplate`](https://mobiscroll.com/docs/angular/eventcalendar/api#template-cellTemplate) - template
- [`sidebarTemplate`](https://mobiscroll.com/docs/angular/eventcalendar/api#template-sidebarTemplate) - template
- [`timelineDayTemplate`](https://mobiscroll.com/docs/angular/eventcalendar/api#template-timelineDayTemplate) - template
- [`dayFooterTemplate`](https://mobiscroll.com/docs/angular/eventcalendar/api#template-dayFooterTemplate) - template
- [`onCellHoverIn`](https://mobiscroll.com/docs/angular/eventcalendar/api#event-onCellHoverIn) - event
- [`onCellHoverOut`](https://mobiscroll.com/docs/angular/eventcalendar/api#event-onCellHoverOut) - event
- [`anchor`](https://mobiscroll.com/docs/angular/popup/api#opt-anchor) - option
- [`display`](https://mobiscroll.com/docs/angular/popup/api#opt-display) - option
- [`touchUi`](https://mobiscroll.com/docs/angular/popup/api#opt-touchUi) - option
- [`showOverlay`](https://mobiscroll.com/docs/angular/popup/api#opt-showOverlay) - option

## Code

### Component

```ts
import { CommonModule } from '@angular/common';
import { Component, ViewChild } from '@angular/core';
import {
  formatDate,
  MbscCalendarEvent,
  MbscCellHoverEvent,
  MbscEventcalendarView,
  MbscModule,
  MbscPopup,
  MbscResource,
} from '@mobiscroll/angular';

@Component({
  selector: 'app-root', 
  templateUrl: './app.component.html',
  standalone: true,
  imports: [CommonModule, MbscModule],
})
export class AppComponent {
  @ViewChild('popup', { static: false }) popup!: MbscPopup;

  formatDate = formatDate;
  hoverDate: Date | null = null;
  hoverResource: MbscResource | null = null;
  popupAnchor?: HTMLElement;

  myEvents: MbscCalendarEvent[] = [
    { start: '2026-10-02T00:00', end: '2026-10-05T00:00', title: 'Event 1', resource: 1 },
    { start: '2026-10-10T09:00', end: '2026-10-15T15:00', title: 'Event 2', resource: 3 },
    { start: '2026-10-12T00:00', end: '2026-10-14T00:00', title: 'Event 3', resource: 4 },
    { start: '2026-10-15T07:00', end: '2026-10-20T12:00', title: 'Event 4', resource: 5 },
    { start: '2026-10-03T00:00', end: '2026-10-10T00:00', title: 'Event 5', resource: 6 },
    { start: '2026-10-10T08:00', end: '2026-10-11T20:00', title: 'Event 6', resource: 7 },
    { start: '2026-10-22T00:00', end: '2026-10-28T00:00', title: 'Event 7', resource: 7 },
    { start: '2026-10-08T00:00', end: '2026-10-13T00:00', title: 'Event 8', resource: 15 },
    { start: '2026-10-25T00:00', end: '2026-10-27T00:00', title: 'Event 9', resource: 10 },
    { start: '2026-10-20T00:00', end: '2026-10-23T00:00', title: 'Event 10', resource: 12 },
  ];

  myResources: MbscResource[] = [
    { id: 1, name: 'Resource A', color: '#e20000' },
    { id: 2, name: 'Resource B', color: '#76e083' },
    { id: 3, name: 'Resource C', color: '#4981d6' },
    { id: 4, name: 'Resource D', color: '#e25dd2' },
    { id: 5, name: 'Resource E', color: '#1dab2f' },
    { id: 6, name: 'Resource F', color: '#d6d145' },
    { id: 7, name: 'Resource G', color: '#34c8e0' },
    { id: 8, name: 'Resource H', color: '#9dde46' },
    { id: 9, name: 'Resource I', color: '#166f6f' },
    { id: 10, name: 'Resource J', color: '#f7961e' },
    { id: 11, name: 'Resource K', color: '#34c8e0' },
    { id: 12, name: 'Resource L', color: '#af0000' },
    { id: 13, name: 'Resource M', color: '#446f1c' },
    { id: 14, name: 'Resource N', color: '#073138' },
    { id: 15, name: 'Resource O', color: '#4caf00' },
  ];

  myView: MbscEventcalendarView = {
    timeline: { type: 'month', resolutionHorizontal: 'day' },
  };

  handleCellHoverIn(args: MbscCellHoverEvent) {
    const resId = args.resource.id;
    this.myResources = this.myResources.map((r) => ({
      ...r,
      cssClass: r.id === resId ? 'mds-highlight-row-hover' : '',
    }));

    this.hoverDate = args.date;
    this.hoverResource = this.myResources.find((r) => r.id === resId) || null;
    this.popupAnchor = args.domEvent.target as HTMLElement;
    this.popup.open();
  }

  handleCellHoverOut() {
    this.hoverDate = null;
    this.hoverResource = null;
    this.myResources = this.myResources.map((r) => ({ ...r, cssClass: '' }));
    this.popup.close();
  }
}
```

### Template

```html
<mbsc-eventcalendar
  class="mds-highlight-hover"
  [view]="myView"
  [data]="myEvents"
  [resources]="myResources"
  [cellTemplate]="cellTemplate"
  [sidebarTemplate]="sidebarTemplate"
  [timelineDayTemplate]="dayTemplate"
  [dayFooterTemplate]="dayFooterTemplate"
  (onCellHoverIn)="handleCellHoverIn($event)"
  (onCellHoverOut)="handleCellHoverOut()"
>
  <ng-template #cellTemplate let-cell>
    <div *ngIf="hoverDate?.getTime() === cell.date.getTime()" class="mds-highlight-col-hover"></div>
  </ng-template>

  <ng-template #sidebarTemplate let-resource>
    <div>{{ resource.name }} Sidebar</div>
  </ng-template>

  <ng-template #dayTemplate let-day>
    <div class="mds-highlight-day-content" [class.mds-highlight-col-hover]="hoverDate?.getTime() === day.date.getTime()">
      {{ formatDate('D DDD', day.date) }}
    </div>
  </ng-template>

  <ng-template #dayFooterTemplate let-footer>
    <div class="mds-highlight-day-content" [class.mds-highlight-col-hover]="hoverDate?.getTime() === footer.date.getTime()">
      {{ formatDate('D DDD', footer.date) }}
    </div>
  </ng-template>
</mbsc-eventcalendar>

<mbsc-popup #popup [anchor]="popupAnchor" [closeOnScroll]="true" [display]="'anchored'" [touchUi]="false" [showOverlay]="false">
  <div>
    <div class="mds-highlight-tooltip" *ngIf="hoverResource && hoverDate">
      <div class="mds-highlight-tooltip-name">{{ hoverResource.name }}</div>
      <div class="mds-highlight-tooltip-date">{{ formatDate('MMM DD, YYYY', hoverDate) }}</div>
    </div>
  </div>
</mbsc-popup>
```

### CSS

```css
.mds-highlight-hover .mbsc-timeline-sidebar-col {
  width: 170px;
}

.mds-highlight-hover .mbsc-timeline-sidebar-resource-title {
  font-weight: 500;
}

.mds-highlight-hover .mds-highlight-row-hover,
.mds-highlight-hover .mds-highlight-col-hover {
  background: rgba(220, 220, 220, 0.25);
}

.mds-highlight-col-hover {
  position: absolute;
  inset: 0;
  background: transparent;
  pointer-events: none;
  box-sizing: border-box;
}

.mds-highlight-day-content {
  font-size: 14px;
  height: 30px;
  text-align: center;
  line-height: 30px;
  position: relative;
}

.mds-highlight-tooltip {
  padding: 5px;
  font-size: 14px;
  line-height: 1.4;
}

.mds-highlight-tooltip-name {
  font-weight: bold;
  margin-bottom: 5px;
}

.mds-highlight-tooltip-date {
  color: #888;
}
```

## Implementation notes

- Use `timeline: { type: 'month', resolutionHorizontal: 'day' }` - a monthly view with one column per day.
- Define 15 resources (A-O) with `id`, `name`, and `color`.
- Add 10 events with `dyndatetime` offsets spread across the current month.
- Track the currently hovered cell in a `hoverDateTime` variable (set on hover in, cleared on hover out).
- **Row highlight** via `cssClass` on resource objects:
  - `onCellHoverIn`: iterate the resources array, set `cssClass: 'mds-highlight-row-hover'` on the resource whose `id` matches `args.resource.id`, clear `cssClass` on all others. JS/jQuery: call `calendar.setOptions({ resources: myResources.slice() })` to push the change and trigger a re-render. React/Angular/Vue: instead update the state/binding feeding the `resources` prop directly (e.g. `setResources(myResources.slice())`).
  - `onCellHoverOut`: clear all `cssClass` values. JS/jQuery: wrap `setOptions` in a `setTimeout` (no delay) so the render callbacks reset before the DOM updates. React/Angular/Vue: wrap the equivalent `resources` state/binding update (e.g. `setResources(myResources.slice())`) in the same `setTimeout` (no delay) so the render callbacks reset before the DOM updates.
- **Column highlight** via render callbacks that compare each cell's date to `hoverDateTime`:
  - `renderCell` (Angular: `cellTemplate`, Vue: `#cell`): when `args.date` matches `hoverDateTime`, return a full-cell overlay `<div class="mds-highlight-col-hover">` (positioned absolute, `inset: 0`, `pointer-events: none`); otherwise return an empty string.
  - `renderTimelineDay` (Angular: `timelineDayTemplate`, Vue: `#timelineDay`) and `renderDayFooter` (Angular: `dayFooterTemplate`, Vue: `#dayFooter`): always render a custom day content div showing `formatDate('D DDD', args.date)`. When the date matches `hoverDateTime`, add `mds-highlight-col-hover` to the div's class.
  - `renderSidebar` (Angular: `sidebarTemplate`, Vue: `#sidebar`): renders the resource name with a " Sidebar" suffix.
- **Tooltip popup** (`Popup`, `display: 'anchored'`, `showOverlay: false`, `scrollLock: false`, `focusOnClose: false`, `closeOnScroll: true`):
  - `onCellHoverIn`: set `anchor: args.domEvent.target`, populate the tooltip with `args.resource.name` and `formatDate('MMM DD, YYYY', args.date)`, then open.
  - `onCellHoverOut`: close the popup.
- **CSS**: `.mds-highlight-row-hover` and `.mds-highlight-col-hover` share the same background `rgba(220,220,220,0.25)` - the row class is applied via the resource `cssClass` property (Mobiscroll renders it on the row container), and the column class is applied via the overlay div in `renderCell` and the class added in `renderTimelineDay`/`renderDayFooter`.

## 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-angular.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 angular
   ```

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

   ```
   npm install
   ```

6. Run the project:

   ```
   ng serve
   ```

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

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

## Related demos

- Next: [Custom Time Range Backgrounds](https://demo.mobiscroll.com/angular/timeline/colors-invalids-css-class.md) - Style time range backgrounds and blocked periods on a Angular Timeline using CSS classes — mark recurring hours or special days.
