---
title: "Javascript Event calendar Event Search Popup Example | Mobiscroll"
component: "Event calendar"
framework: "JavaScript"
library_version: "6.1.5"
url: "https://demo.mobiscroll.com/javascript/eventcalendar/searching-events-in-popup"
---

# Event Search Popup - JavaScript Event calendar demo

Search events in real time from the Javascript event calendar header — results appear in an agenda-style popup as you type, grouped by date. Plain JavaScript API.

- [Live demo](https://demo.mobiscroll.com/javascript/eventcalendar/searching-events-in-popup)
- [View code on GitHub](https://github.com/acidb/mobiscroll-demos-javascript/tree/main/src/demos/eventcalendar/calendar-view/searching-events-in-popup)
- This demo in other frameworks: [jQuery](https://demo.mobiscroll.com/jquery/eventcalendar/searching-events-in-popup.md), [Angular](https://demo.mobiscroll.com/angular/eventcalendar/searching-events-in-popup.md), [React](https://demo.mobiscroll.com/react/eventcalendar/searching-events-in-popup.md), [Vue](https://demo.mobiscroll.com/vue/eventcalendar/searching-events-in-popup.md)

## Description

Use the available real estate in the calendar header to add event search. With the [templating capabilities of the header](https://demo.mobiscroll.com/javascript/eventcalendar/customizing-header) you can easily add a search box and use a separate [agenda](https://demo.mobiscroll.com/javascript/agenda) instance to show the search results. This example is relying on a single API endpoint for getting the data onto the primary calendar view and also for getting the filtered data based on the search terms.

[Events can be filtered in real time](https://demo.mobiscroll.com/javascript/eventcalendar/resource-filtering-in-header) so using an agenda view for the search results is an easy choice. It provides all the necessary styling and advanced features that you might need to customize the experience.

Alternatively, search can be implemented in a sidebar next to the event calendar using a similar search box with an [inline agenda](https://demo.mobiscroll.com/javascript/eventcalendar/searching-events-in-sidebar) instead of a dropdown.

## What this demo shows

- A full month event calendar with event labels rendered directly inside the day cells.
- **Event labels** Labels use different visual styles for all-day events, multi-day events, and timed events, with different colors representing different events.
- **Event selection** Hovering over or selecting an event label highlights that event.
- **Day cells** Hovering over a day cell highlights the day number in the top-right corner with a gray background.
- **Date selection** Clicking the empty area of a day cell selects the day and highlights the day number with a blue background.
- **Month navigation** The month view can be changed by clicking and dragging the calendar left or right.
- **Header layout** The header shows the current month and year on the left, a centered search input, and previous, next, and `Today` controls on the right.
- **Search input** The search field includes a search icon and the `Search events` placeholder text.
- **Search results popup** Typing into the search field opens a popup below the input with matching events in an agenda-style list.
- **Agenda results** Search results are grouped by date, and each event row shows a colored marker, the event title, and the event type, such as all-day or timed.
- **Result selection** Clicking an event in the agenda list closes the popup and navigates the month view to the date that contains the selected event.

## Best for

- **Search-heavy calendars** Interfaces where users need to quickly find events by person, keyword, event type, or absence period.
- **Admin and operations tools** Admin dashboards, employee scheduling tools, and internal planning interfaces where users review and search event-heavy calendars.
- **Enterprise planning** Multi-day planning scenarios where users need to move between calendar context and filtered event results without leaving the month view.

## API used in this demo

- [`theme`](https://mobiscroll.com/docs/javascript/eventcalendar/api#opt-theme) - option
- [`themeVariant`](https://mobiscroll.com/docs/javascript/eventcalendar/api#opt-themeVariant) - option
- [`view`](https://mobiscroll.com/docs/javascript/eventcalendar/api#opt-view) - option
- [`showControls`](https://mobiscroll.com/docs/javascript/eventcalendar/api#opt-showControls) - option
- [`onEventClick`](https://mobiscroll.com/docs/javascript/eventcalendar/api#event-onEventClick) - event
- [`navigateToEvent`](https://mobiscroll.com/docs/javascript/eventcalendar/api#method-navigateToEvent) - method
- [`setSelectedEvents`](https://mobiscroll.com/docs/javascript/eventcalendar/api#method-setSelectedEvents) - method
- [`close`](https://mobiscroll.com/docs/javascript/popup/api#method-close) - method
- [`clickToCreate`](https://mobiscroll.com/docs/javascript/eventcalendar/api#opt-clickToCreate) - option
- [`dragToCreate`](https://mobiscroll.com/docs/javascript/eventcalendar/api#opt-dragToCreate) - option
- [`dragToMove`](https://mobiscroll.com/docs/javascript/eventcalendar/api#opt-dragToMove) - option
- [`dragToResize`](https://mobiscroll.com/docs/javascript/eventcalendar/api#opt-dragToResize) - option
- [`selectMultipleEvents`](https://mobiscroll.com/docs/javascript/eventcalendar/api#opt-selectMultipleEvents) - option
- [`labels`](https://mobiscroll.com/docs/javascript/eventcalendar/api#opt-labels) - option
- [`renderHeader`](https://mobiscroll.com/docs/javascript/eventcalendar/api#renderer-renderHeader) - renderer
- [`onPageLoading`](https://mobiscroll.com/docs/javascript/eventcalendar/api#event-onPageLoading) - event
- [`setEvents`](https://mobiscroll.com/docs/javascript/eventcalendar/api#method-setEvents) - method
- [`anchor`](https://mobiscroll.com/docs/javascript/popup/api#opt-anchor) - option
- [`display`](https://mobiscroll.com/docs/javascript/popup/api#opt-display) - option
- [`focusOnClose`](https://mobiscroll.com/docs/javascript/popup/api#opt-focusOnClose) - option
- [`scrollLock`](https://mobiscroll.com/docs/javascript/popup/api#opt-scrollLock) - option
- [`showArrow`](https://mobiscroll.com/docs/javascript/popup/api#opt-showArrow) - option
- [`showOverlay`](https://mobiscroll.com/docs/javascript/popup/api#opt-showOverlay) - option
- [`width`](https://mobiscroll.com/docs/javascript/popup/api#opt-width) - option
- [`open`](https://mobiscroll.com/docs/javascript/popup/api#method-open) - method

## Code

### JS

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

var timer;

var list = mobiscroll.eventcalendar('#demo-search-results', {
  view: {
    agenda: { type: 'year', size: 5 },
  },
  showControls: false,
  onEventClick: function (args) {
    calendar.navigateToEvent(args.event);
    calendar.setSelectedEvents([args.event]);
    popup.close();
  },
});

var calendar = mobiscroll.eventcalendar('#demo-search-events', {
  clickToCreate: false,
  dragToCreate: false,
  dragToMove: false,
  dragToResize: false,
  selectMultipleEvents: true,
  view: {
    calendar: { labels: true },
  },
  renderHeader: function () {
    return (
      '<div mbsc-calendar-nav></div>' +
      '<div class="mds-search-bar mbsc-flex-1-0">' +
      '<label>' +
      '<input id="demo-search-input" mbsc-input autocomplete="off" data-start-icon="material-search" data-input-style="box" placeholder="Search events" />' +
      '</label>' +
      '</div>' +
      '<button mbsc-calendar-prev></button>' +
      '<button mbsc-calendar-today></button>' +
      '<button mbsc-calendar-next></button>'
    );
  },
  onPageLoading: function (args) {
    var start = mobiscroll.formatDate('YYYY-MM-DD', args.viewStart);
    var end = mobiscroll.formatDate('YYYY-MM-DD', args.viewEnd);

    mobiscroll.getJson(
      'https://trial.mobiscroll.com/searchevents/?start=' + start + '&end=' + end,
      function (data) {
        calendar.setEvents(data);
      },
      'jsonp',
    );
  },
});

var searchInput = document.getElementById('demo-search-input');

var popup = mobiscroll.popup('#demo-search-popup', {
  anchor: searchInput,
  contentPadding: false,
  display: 'anchored',
  focusElm: searchInput,
  focusOnClose: false,
  focusOnOpen: false,
  scrollLock: false,
  showArrow: false,
  showOverlay: false,
  width: 400,
});

searchInput.addEventListener('input', function (ev) {
  var searchText = ev.target.value;
  clearTimeout(timer);
  timer = setTimeout(function () {
    if (searchText.length > 0) {
      mobiscroll.getJson(
        'https://trial.mobiscroll.com/searchevents/?text=' + searchText,
        function (data) {
          list.setEvents(data);
          popup.open();
        },
        'jsonp',
      );
    } else {
      popup.close();
    }
  }, 200);
});

searchInput.addEventListener('focus', function (ev) {
  if (ev.target.value.length > 0) {
    popup.open();
  }
});
```

### HTML

```html
<div id="demo-search-events"></div>
<div id="demo-search-popup">
  <div>
    <div id="demo-search-results" class="mds-search-results"></div>
  </div>
</div>
```

### CSS

```css
.mds-search-bar .mbsc-textfield-wrapper {
  max-width: 400px;
  margin: 8px auto;
}

.mds-search-bar .mbsc-textfield.mbsc-ios-dark {
  background: #313131;
}

.mds-search-results .mbsc-calendar-wrapper {
  margin-top: -1px;
}
```

## Implementation notes

- Set `view: { calendar: { labels: true } }` for the main month calendar. Load events via `onPageLoading` using `getJson` with `args.viewStart`/`args.viewEnd` as date range params.
- Use `renderHeader` (Angular: `headerTemplate`, Vue: `#header` slot) to build a custom header: `CalendarNav` on the left, a Mobiscroll `Input` with `startIcon="material-search"` and placeholder "Search events" in the center, and `CalendarPrev`, `CalendarToday`, `CalendarNext` on the right.
- On `Input` `onChange`, debounce by 200ms, then call `getJson` with the search text appended to the API URL. Pass the returned events to a separate search-results `Eventcalendar` and open the `Popup`. Close the popup on empty input.
- Render a `Popup` anchored to the search `Input` element (`anchor`, `focusElm`, `display="anchored"`). Inside the popup, place a second `Eventcalendar` with `showControls: false` and `view: { agenda: { type: 'year', size: 5 } }`.
- On `onEventClick` in the results agenda, call `inst.navigateToEvent(args.event)` on the main calendar instance (Angular: use `@ViewChild`) to navigate to that event's date, set it as `selectedEvents` to highlight it, and close the popup.

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

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 javascript --trial`.

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

## Related demos

- Previous: [Multiple Timezones](https://demo.mobiscroll.com/javascript/eventcalendar/multiple-timezone-support.md) - Show the same events in multiple timezones in a Javascript event calendar — add a header dropdown so users can switch their display timezone on the fly.
- Next: [Search Events in Sidebar](https://demo.mobiscroll.com/javascript/eventcalendar/searching-events-in-sidebar.md) - Add real-time event search to a Javascript event calendar — display filtered results in a sidebar panel, grouped by date, with click-to-navigate.
