Seat Plan Widget

The Seat Plan widget is the simplest way to deliver a fully interactive seat plan to your customers, allowing them to visualise the layout of a venue, where their seats would be and select the seats, which they'd like to purchase.

🚧

Note: you can add only one reservation per basket. In case you are trying to add more items to the existing basket, you will see a warning popup.

Benefits

Visualised Seat Plans

All seat plans have been meticulously constructed for the vast majority of theatre and attraction venues which Encore support - allowing customers to see before they buy!

Fully Interactive

Pan, zoom in, zoom out, choose your sections, choose your seats - all seat plans offer super intuitive controls for your customers to choose their seats as easily as possible

Optimized across Devices

The Seat Plan widget has been optimized across all channels - desktop, mobile, tablet - with full responsiveness and device-specific actions, like "pinch to zoom"

Built-in Availability

All seat plans come built-in with your assigned performance-level availability - no need to make extra calls for availability and manipulate this data for display

Embedding the widget

To embed the Seat Plan widget:

  1. Ensure you've got a valid channel Id. This should be provided to you as part of your account setup.
  2. Create a new HTML page and add the following markup:
<!doctype html>
<html lang="en">
  <head>
    <title>Seat Plan example</title>
    <!-- CSS file is optional and needed only if you want to use default styling -->
    <link rel="stylesheet" href="https://venue-service.tixuk.io/v4/css/main.css" />
  </head>
  <body>
    <div
      data-app="venue-app"
      data-view-name="seat-plan"
      data-channel-id="{your-channel-id}"
      data-product-id="{product-id}"
      data-product-type="{show|attraction}"
      data-performance-type="{A|M|E}"
      data-performance-date="{date of performance e.g. 2019-01-10}"
      data-performance-time="{time of performance e.g. 19:30}"
      data-quantity="{number of tickets e.g. 2}"
      data-api-path="{url where the booking will be made e.g. http://your-website-url}"
    ></div>

    <script type="text/javascript" src="https://venue-service.tixuk.io/v4/js/venue-app.js"></script> 
  </body>
</html>
  1. This will display the Seat Plan widget, allowing users to select some seats. Doing so will display details of the selected seat and provide a button to add these to their basket, like so:
🚧

In case the seat chart is not available or cannot be rendered, widget will render Seat List view

Supported data attributes

In addition to the standard data attributes used by all widgets, the following data attributes are used to customise the behaviour of the Seat Plan widget.

Name

Mandatory

Type

Sourced from Query String

Description

data-app

Yes

String

n/a

Indicates the host app to communicate with. It should be "venue-app"

data-api-path

Yes

String

n/a

The host for the data service to use. This should be the fully qualified domain for the relevant capability service. Example: https://venue-service.tixuk.io/

data-channel-id

Yes

String

n/a

The id of the affiliate for which the embedding context (i.e. website) belongs.

data-performance-date

Yes*

Date

date

Date of the performance in the format YYYY-MM-DD e.g. 2019-01-10.

*Data-attr can be omitted in favor of property being supplied via query string. Query string values override data-attrs.

data-performance-time

Yes*

Time

slot

Start time of the performance in 24-hour format HH:MM e.g. 19:30.

*Data-attr can be omitted in favor of property being supplied via query string. Query string values override data-attrs.

data-product-id

Yes*

Number

product_id

Identifier of the product Id using for requests.

  • *Data-attr can be omitted in favour of property being supplied via query string. Query string values override data-attrs_.

data-view-name

No

String

n/a

Identifies the view for the app to load.

Default value - "seat-plan"

data-performance-type

No*

String

performance_type

Indicates the type of performance, based on the part of day. Valid values are:

A - indicates "all" M - indicates "matinee" E - indicates "evening"

*Data-attr can be omitted in favour of property being supplied via query string. Query string values override data-attrs.

data-product-id-for-content

No*

Number

content_product_id

Identifier of the product for content-service api calls. Default value: data-product-id

*Data-attr can be omitted in favor of property being supplied via query string. Query string values override data-attrs.

data-product-type

No*

String

product_type

Valid values are: show (default) attraction

*Data-attr can be omitted in favor of property being supplied via query string. Query string values override data-attrs.

data-quantity

No*

Number

qt

Number of tickets to be selected e.g. "2".

*Data-attr can be omitted in favor of property being supplied via query string. Query string values override data-attrs.

data-suppress-addtobasket

No

Boolean

n/a

Suppresses the redirection on add to basket CTA to allow custom handling of users selected ticket data.

Default value: False

Event: venue-app_selected-seats-summary-on-addtobasket

data-without-seat-summary

No

Boolean

n/a

Prevent displaying seat summary on seat selection.

data-user-locale

No

String

n/a

Identifies user locale for labels from data-labels-config. Used to format prices for custom currencies ('en-GB' used by default).

data-labels-config

No

String (JSON Object)

n/a

Identifies user labels.

data-hide-spinner

No

Boolean

n/a

Hides loading spinner.

data-use-external-availability

No

Boolean

n/a

Uses external availability.

data-hide-price-decimals

No

Boolean

n/a

Hide decimal part from prices.

data-defer-rendering

No

Boolean

n/a

Defer rendering until user call venue-app_render event.

Example: window.dispatchEvent(new CustomEvent('venue-app_render'))

data-disable-seat-plan-height-calculation

No

Boolean

n/a

Disable automatic Seat Plan height calculation

data-inventory-api-url

No

String

n/a

Set custom API URL for inventory service. Example: https://inventory-service.tixuk.io/api/vLatest

data-venue-api-url

No

String

n/a

Set custom API URL for content service. Example: https://content-service.tixuk.io/api/vLatest

data-basket-api-url

No

String

n/a

Set custom API URL for basket service. Example: https://basket-service.tixuk.io/api/vLatest

General Admission Tickets

❗️

Important Note

A single show can have both PYOS (Pick your own seats) and General Admission seats available. The event details will reflect the type of seat selected.

The widget now supports the selection of General Admission (GA) tickets. GA areas are identified by a mode: 'freesell' attribute, in contrast to seated areas which have mode: 'allocated'. When selecting tickets in a GA area, the seat information might display "General Admission" instead of a specific row number.

Price Overrides

The widget allows for dynamic price overrides. This is achieved by intercepting the pricing data before it's displayed and applying custom modifications.

How it works:

  1. Fetch Area Data: A custom function (e.g., priceValueOverride as seen in the example) makes an API call to retrieve the area and grouping information for a specific product, performance date, and time.
    • Example API call: GET /products/{productId}/areas?quantity={quantity}&date={performanceDate}&time={formattedPerformanceTime}
  2. Iterate and Modify Groupings: The function then iterates through the areas and their groupings. For each group, it extracts the original salePrice.
  3. Apply Price Modifier: A priceModifier function can be applied to the original price. This function takes the original price as an argument and returns the new, modified price.
    • Example priceModifier: (price) => price * 1.1 (increase the price by 10%).
  4. Construct Override Object: An overrideObject is created for each modified group. This object includes:
    • groupIdentifier: Unique identifier for the group.
    • pricing: An object containing the modified salePrice, faceValue, and optionally promotionLabel, noBookingFee, percentageDiscount, and includesBookingFee.
  5. Apply Overrides to Widget: The priceOverridesList (an array of overrideObjects) is then passed to the widget using window.encoreSeatWidget.onGetOverridePriceGroups(data). This method instructs the widget to use the provided overridden prices for the specified groups.

Listening to custom events

The following events are raised by the SeatPlan widget:

EventDescription
venue-app_data-attributes-validation-failedRaised when there is a validation error with the data attributes.
venue-app_selected-seats-summary-on-addtobasketRaised on add to basket submission.
venue-app_on-seats-selection-changeRaised when the user changes the seat selection.
venue-app_on-seats-deselectionRaised when the user deselects all seats.
venue-app_exceptionRaised when an exception occurs in the application.

How to Use These Events

All custom events dispatched by the widget will have type (the event name) and timeStamp (the time the event was created) properties available directly on the event object (e), in addition to the detail object. These events can be used to track user interactions, update the UI dynamically, or trigger other application logic. Below is a detailed explanation of each event, its purpose, and the data it provides.

  1. venue-app_data-attributes-validation-failed

    • Purpose: This event is triggered when there is an error validating the data attributes passed to the widget.
    • Data: The detail object contains information about the validation error:
      • {
        "type": "error",
        "errorTitle": "Data-attribute configured incorrectly",
        "errorMessage": "data-quantity or qt url parameter should be in the range 1 - 10",
        "errorId": "Data-attribute configured incorrectly: data-quantity or qt url parameter should be in the range 1 - 10"
        }
    • Usage Example:
      window.addEventListener("venue-app_data-attributes-validation-failed", function(e) {
        console.log("Data attributes validation failed:", e.detail);
      });
  2. venue-app_selected-seats-summary-on-addtobasket

    • Purpose: This event is triggered when the user clicks the "Add to Basket" button in the seat summary.

    • Data: The detail object contains the selected seats (selectedElement) and performance parameters (performanceParams). The structure of selectedElement will differ depending on whether the selection is for PYOS or General Admission seats.

    • detail object properties:

      • selectedElement: An array of objects, where each object represents a single selected seat.

        Note: The structure of the seat objects within selectedElement is identical to the structure of objects in the selectedSeats array of the venue-app_on-seats-selection-change event.

        • id: Unique identifier for the seat. For PYOS seats, this is per-seat (e.g., 'BLOCK E-C-13'). For General Admission, this is the same for all seats in the area (e.g., 'DANCE FLOOR-General Admission').
        • groupName: The group name of the seat (e.g., 'BLOCK E' or 'DANCE FLOOR').
        • row: The row of the seat (e.g., 'C' for PYOS, 'General Admission' for General Admission).
        • number: The seat number. For PYOS seats, this is the actual seat number (e.g., 13). For General Admission, it is a sequential number from 1 up to the quantity of tickets requested (e.g., 1, 2, 3, ...).
        • lump: An object defining the start and end seat numbers of the lump.
        • listOfAvailableLumps: An array of available lump options.
        • faceValue: The original face value of the ticket.
        • salePrice: The selling price of the ticket.
        • percentageDiscount: The percentage discount applied.
        • faceCurrency: The currency of the face value.
        • currency: The currency of the sale price.
        • faceDecimalPlaces: Number of decimal places for face currency.
        • decimalPlaces: Number of decimal places for currency.
        • hideFaceValue: Boolean indicating if face value is hidden.
        • hideDiscount: Boolean indicating if discount is hidden.
        • promotionLabel: Label for any promotion.
        • restrictedView: Boolean indicating if the seat has a restricted view.
        • includesBookingFee: Boolean indicating if booking fee is included.
        • seatKey: A unique key for the seat (e.g., "eyJ0eXAiOiJKV1Qi...").
        • category: An object containing value and price.
        • attributes: An array of seat attributes.
        • seatIdentifier: A unique identifier for the seat (e.g., BLOCK_E-C13 or "eyJ0eXAiOiJKV1Qi...-1").
        • aggregateReference: A reference for the aggregated seats (e.g., "eyJ0eXAiOiJKV1Qi...").
        • displayCurrency: The currency for display.
        • orderFee: An object with value, currency, and decimalPlaces.
      • performanceParams: An object containing parameters related to the performance:

        • channelId: The channel identifier (e.g., 'viatorwhitelabel').
        • productId: The product ID (e.g., '25118').
        • productType: The product type (e.g., 'A').
        • venueId: The venue ID (e.g., '846').
        • performanceType: The performance type (e.g., 'A').
        • performanceDate: The date of the performance (e.g., '2026-01-23').
        • performanceTime: The time of the performance (e.g., '19:45').
        • quantity: The quantity of seats (e.g., '2').
        • productIdForContent: Product ID for content (e.g., '25118').
        • viewName: The view name (e.g., 'seat-plan').

    Key Differences: General Admission vs. PYOS (Pick your own seats)

    • Selection Granularity:

      • General Admission: While each ticket is an object in the selectedElement array, they share a common id and row, representing a selection within a general area rather than a specific, unique seat.
      • PYOS: Each object in the selectedElement array represents a unique, specific seat with its own id, row, and number.
    • Identification:

      • General Admission: Seats are identified by their groupName and number within the General Admission row.
      • PYOS: Each seat is individually identified by its unique id (e.g., 'BLOCK E-C-13'), row, and number.
    • Usage Example:

      window.addEventListener("venue-app_selected-seats-summary-on-addtobasket", function(e) {
        console.log("Seats added to basket:", e.detail);
      
        // Example of logging each seat's details to a hypothetical logging system
        e.detail.selectedElement.forEach(seat => {
          console.log(`Seat added to basket: ID: ${seat.id}, Row: ${seat.row}, Number: ${seat.number}, Price: ${seat.salePrice} ${seat.currency}`);
          // PYOS: Seat added to basket: ID: BLOCK E-C-14, Row: C, Number: 14, Price: 110 EUR
          // General Admission: Seat added to basket: ID: DANCE FLOOR-General Admission, Row: General Admission, Number: 2, Price: 86.9 EUR
        });
      
        const params = e.detail.performanceParams;
        console.log(`Performance: ${params.productId}, Date: ${params.performanceDate}, Time: ${params.performanceTime}`);
        // Performance: 25118, Date: 2026-01-23, Time: 19:45
      });
  3. venue-app_on-seats-selection-change

    • Purpose: This event is triggered whenever the user's seat selection changes. This can happen when they select a seat, change their selection, or deselect all seats.

    • Data: The detail object contains a selectedSeats array and a selectedCategory object. The structure of these is consistent, but the values within will differ depending on whether the selection is for PYOS or General Admission seats.

    • detail object properties:

      • selectedCategory: An object containing details about the price category of the selection.

        • category: The category ID.
        • price: The price of the category.
        • salePrice: The sale price of the category.
        • faceValue: The face value of the category.
        • faceCurrency: The currency of the face value (e.g., 'EUR').
        • currency: The currency of the sale price (e.g., 'EUR').
        • faceDecimalPlaces: Number of decimal places for face currency.
        • decimalPlaces: Number of decimal places for currency.
        • percentageDiscount: The percentage discount applied.
        • includesBookingFee: Boolean indicating if booking fee is included.
        • restrictedView: Boolean indicating if the category has restricted view seats.
        • color: The color associated with the category.
        • borderColor: The border color associated with the category.
        • hideFaceValue: Boolean indicating if face value is hidden.
        • hideDiscount: Boolean indicating if discount is hidden.
        • orderFee: An object with value, currency, and decimalPlaces.
        • promotionLabel: Label for any promotion (e.g., 'Christmas Promo').
      • selectedSeats: An array of objects, where each object represents a single selected seat.

        Note: The structure of the seat objects within selectedSeats is identical to the structure of objects in the selectedElement array of the venue-app_selected-seats-summary-on-addtobasket event.

        • id: Unique identifier for the seat. For PYOS seats, this is per-seat (e.g., 'BLOCK E-C-13'). For General Admission, this is the same for all seats in the area (e.g., 'DANCE FLOOR-General Admission').
        • groupName: The group name of the seat (e.g., 'BLOCK E' or 'DANCE FLOOR').
        • row: The row of the seat (e.g., 'C' for PYOS, 'General Admission' for General Admission).
        • number: The seat number. For PYOS seats, this is the actual seat number (e.g., 13). For General Admission, it is a sequential number from 1 up to the quantity of tickets requested (e.g., 1, 2, 3, ...).
        • lump: An object defining the start and end seat numbers of the lump.
        • listOfAvailableLumps: An array of available lump options.
        • faceValue: The original face value of the ticket.
        • salePrice: The selling price of the ticket.
        • percentageDiscount: The percentage discount applied.
        • faceCurrency: The currency of the face value.
        • currency: The currency of the sale price.
        • faceDecimalPlaces: Number of decimal places for face currency.
        • decimalPlaces: Number of decimal places for currency.
        • hideFaceValue: Boolean indicating if face value is hidden.
        • hideDiscount: Boolean indicating if discount is hidden.
        • promotionLabel: Label for any promotion.
        • restrictedView: Boolean indicating if the seat has a restricted view.
        • includesBookingFee: Boolean indicating if booking fee is included.
        • seatKey: A unique key for the seat (e.g., "eyJ0eXAiOiJKV1Qi...").
        • category: An object containing value and price.
        • attributes: An array of seat attributes.
        • seatIdentifier: A unique identifier for the seat (e.g., BLOCK_E-C13 or "eyJ0eXAiOiJKV1Qi...-1").
        • aggregateReference: A reference for the aggregated seats (e.g., "eyJ0eXAiOiJKV1Qi...").
        • displayCurrency: The currency for display.
        • orderFee: An object with value, currency, and decimalPlaces.

    Key Differences: General Admission vs. PYOS (Pick your own seats)

    • Selection Granularity:

      • General Admission: While each ticket is an object in the selectedSeats array, they share a common id and row, representing a selection within a general area rather than a specific, unique seat.
      • PYOS: Each object in the selectedSeats array represents a unique, specific seat with its own id, row, and number.
    • Identification:

      • General Admission: Seats are identified by their groupName and number within the General Admission row.
      • PYOS: Each seat is individually identified by its unique id (e.g., 'BLOCK E-C-13'), row, and number.

    Usage Example:

    window.addEventListener("venue-app_on-seats-selection-change", function(e) {
      e.detail.selectedSeats.forEach(seat => {
        console.log(`Seat selection changed: ID: ${seat.id}, Row: ${seat.row}, Number: ${seat.number}, Price: ${seat.salePrice} ${seat.currency}`);
        // PYOS: Seat selection changed: ID: BLOCK E-C-14, Row: C, Number: 14, Price: 110 EUR
        // General Admission: Seat selection changed: ID: DANCE FLOOR-General Admission, Row: General Admission, Number: 2, Price: 86.9 EUR
      });
    });
  4. venue-app_on-seats-deselection

    • Purpose: This event is triggered when a user clicks "Make a different selection" button. It is not triggered when selection is changed otherwise.
    • Data: The detail object is empty ({}).
    • Usage Example:
      window.addEventListener("venue-app_on-seats-deselection", function(e) {
        console.log("All seats deselected");
      });
  5. venue-app_exception

    • Purpose: This event is triggered when an exception occurs in the application.
    • Data: The detail object contains information about the exception, including:
    • type: The type of the error (e.g., 'warning').
    • errorTitle: A title for the error (e.g., 'Unable to get basket').
    • errorMessage: A detailed message about the error (e.g., 'The basket with reference [TTG11111111] was expired.').
    • errorId: A unique identifier for the error (e.g., 'Get basket: The basket with reference [TTG11111111] was expired.').
    • Usage Example:
      window.addEventListener("venue-app_exception", function(e) {
        console.log("Exception occurred:", e.detail);
      });

Configuring labels

The Seat Plan widget comes with some default text labels, but these can be customized to your liking. To do so, use the "data-labels-config" attribute, like so:


<div 
  data-app="venue-app"
  data-view-name="seat-plan"
  data-channel-id="encoretickets"
  data-product-id="1587"
  data-product-type="show"
  data-performance-type="A"
  data-performance-date="2020-03-21"
  data-performance-time="19:30"
  data-quantity="2"
  data-api-path="http://encoretickets.co.uk"
  data-redirect-url=""
  data-user-locale="en-GB"
  data-labels-config='{ 
   "seatList":{ 
      "findingAvailability":{ 
         "en-GB":"Finding Availability",
         "it-IT":"Trovare disponibilità"
      },
      "reservingSelection":{
         "en-GB": "Reserving Selection",
         "it-IT": "Selezione della prenotazione"
      }
   },
   "seatSummary":{ 
      "seats":{ 
         "en-GB":"Seats",
         "it-IT":"Sedili"
      },
      "restrictedView":{ 
         "en-GB":"Restricted view",
         "it-IT":"Visione limitata"
      },
      "sideView":{ 
         "en-GB":"Side view",
         "it-IT":"Vista laterale"
      },
      "seatPrice":{ 
         "en-GB":"Seat price",
         "it-IT":"Prezzo del posto"
      },
      "noBookingFee":{ 
         "en-GB":"No booking fee",
         "it-IT":"Nessuna commissione di prenotazione"
      },
      "addToBasket":{ 
         "en-GB":"Add to basket",
         "it-IT":"Aggiungi al carrello"
      }
   },
   "legend":{ 
      "restrictedView":{ 
         "en-GB":"Restricted view",
         "it-IT":"Visione limitata"
      },
      "offer":{ 
         "en-GB":"Offer",
         "it-IT":"Offrire"
      },
      "restrictedViewOffer":{ 
         "en-GB":"Restricted view & offer",
         "it-IT":"Offerta e vista riservata"
      },
      "noFees":{ 
         "en-GB":"No fees",
         "it-IT":"Senza tasse"
      }
   },
   "seatPlan":{ 
      "notAvailable":{ 
         "en-GB":"notAvailable",
         "it-IT":"Non disponibile"
      },
      "sectionAvailability.none":{ 
         "en-GB":"sectionAvailability.none",
         "it-IT":"Nessun posto disponibile"
      },
      "clickToSelect":{ 
         "en-GB":"clickToSelect",
         "it-IT":"Clic per selezionare"
      },
      "clickToDeselect":{ 
         "en-GB":"clickToDeselect",
         "it-IT":"Clic per deselezionare"
      },
      "row":{ 
         "en-GB":"row",
         "it-IT":"riga"
      },
      "seat":{ 
         "en-GB":"seat",
         "it-IT":"sedia"
      },
      "table":{ 
         "en-GB":"table",
         "it-IT":"Tavola"
      },
      "section":{ 
         "en-GB":"section",
         "it-IT":"Section"
      },
      "restrictedView":{ 
         "en-GB":"restrictedView",
         "it-IT":"Visione limitata"
      },
      "couch":{ 
         "en-GB":"Couch",
         "it-IT":"Divano"
      },
      "bar":{ 
         "en-GB":"Bar",
         "it-IT":"Bar"
      }
    }
  }' />

seatList -> findingAvailability

Spinner message showing during availability data loading

seatList -> reservingSelection

Spinner message showing during basket reservation process

seatSummary -> seats

Seats label

seatSummary -> restrictedView

Restricted view label

seatSummary -> sideView

Side view restriction

seatSummary -> seatPrice

Seat Price label

seatSummary -> noBookingFee

No Booking Fee label

seatSummary -> addToBasket

Add to Basket button text

legend -> restrictedView

Restricted View label in legend

legend -> offer

Offer label in legend

legend -> restrictedViewOffer

Offer & Restricted View label in legend

legend -> noFees

No fees label in legend

seatPlan -> notAvailable

Not Available label in seat plan tooltip

seatPlan -> sectionAvailability.none

No seats available label in section popup when no seats for section available

seatPlan -> clickToSelect

Click to Select label in seat plan tooltip

seatPlan -> clickToDeselect

Click to Deselect label in seat plan tooltip

seatPlan -> row

Row label in seat plan tooltip

seatPlan -> seat

Seat label in seat plan tooltip

seatPlan -> table

Table label in seat plan tooltip

seatPlan -> section

Section label in seat plan tooltip

seatPlan -> restrictedView

Restricted View label in seat plan tooltip

seatPlan -> couch

Couch label in seat plan tooltip

seatPlan -> bar

Bar label in seat plan tooltip