---
title: "Vue Select Multiline select Example | Mobiscroll"
component: "Select"
framework: "Vue"
library_version: "6.1.5"
url: "https://demo.mobiscroll.com/vue/select/multiple-lines"
---

# Multiline select - Vue Select demo

Vue Select scroller style demo supporting long text rendered in multiple rows. With smooth scrolling and native look & feel. For Vue and Nuxt.

- [Live demo](https://demo.mobiscroll.com/vue/select/multiple-lines)
- [View SFC JS code on GitHub](https://github.com/acidb/mobiscroll-demos-vue/tree/main/src/demos/pickers/select/multiple-lines)
- [View SFC TS code on GitHub](https://github.com/acidb/mobiscroll-demos-vue-ts/tree/main/src/demos/pickers/select/multiple-lines)
- This demo in other frameworks: [JavaScript](https://demo.mobiscroll.com/javascript/select/multiple-lines.md), [jQuery](https://demo.mobiscroll.com/jquery/select/multiple-lines.md), [Angular](https://demo.mobiscroll.com/angular/select/multiple-lines.md), [React](https://demo.mobiscroll.com/react/select/multiple-lines.md)

## Description

Sometimes, the items of the select can get very long and they won't fit a single line. For those cases you can use the [custom item templating](https://demo.mobiscroll.com/vue/select/item-templating) and [`itemHeight`](https://mobiscroll.com/docs/vue/select/api#opt-itemHeight) to solve the rendering problems.

## What this demo shows

- Shows a single-value select with custom item templates that display options across multiple lines.
- **Opening and closing** Focusing or clicking the input opens the picker below it. Clicking outside the picker closes it.
- **Picker content** A predefined list of options appears in a dropdown-style popup, with each option formatted using a custom multiline template.
- **Hover state** Hovering over an option highlights it in the picker.
- **Selection** Selecting an option marks it with a checkmark to identify the current value.
- **Scrolling** The picker supports scrolling through the full list of options.
- **Input value** Selecting an option updates the input with the chosen value.

## Best for

- **Descriptive choices** Options that combine a primary label with supporting details or explanatory text.
- **People and account selection** Names that need secondary information, such as a role, team, email address, or account identifier.
- **Product and service selection** Items that include a name together with a variant, specification, or short description.
- **Location selection** Long place names or addresses that are easier to scan when displayed across multiple lines.

## Tutorial

```vue
<script setup>
const myData = [
  { value: 1, text: 'Percentage of assets covered by systematic risk assessments (>99)' },
  { value: 2, text: 'Number of personal vacancies in the security roles required for ISMS (Nil)' },
  { value: 3, text: 'Time taken to grant, change and remove access privileges (Max. 2 hours)' },
  { value: 4, text: 'Percentage of agents covered by an effective security awareness program (100%)' },
  { value: 5, text: 'Number of security access violations (<2)' },
  { value: 6, text: 'Number of emergency changes (<5)' },
  { value: 7, text: 'Number of security incidents involving malicious code (Max. 2)' },
  { value: 8, text: 'Number of systems where security requirements are not met (Max. 2)' },
  { value: 9, text: 'Average turnaround time of incidents (Max. 2 hours)' },
  { value: 10, text: 'Number of pending actions to meet response and recovery requirements (Max. 5)' },
  { value: 11, text: 'Number of scheduled internal audits not done (Max. 1)' },
  { value: 12, text: 'Number of scheduled penetration tests not done (Max. 1)' },
  { value: 13, text: 'Number of overdue actions arising out of audit reports (Max. 5)' },
  { value: 14, text: 'Number of changes not carried out as per change control procedure (Max. 1)' }
]
</script>
<template>
  <MbscSelect
    :data="myData"
    :itemHeight="60"
    :maxWidth="400"
    :touchUi="false"
  >
    <template #item="item">
      <div class="my-multi-lines-item"><span class="my-multi-lines-text">{{ item.display }}</span></div>
    </template>
  </MbscSelect>
</template>
<style>
.my-multi-lines-item {
  font-size: 14px;
  white-space: initial;
  display: flex;
  height: 60px;
  line-height: normal;
}

.my-multi-lines-text {
  margin-top: auto;
  margin-bottom: auto;
}
</style>
```

## API used in this demo

- [`theme`](https://mobiscroll.com/docs/vue/select/api#opt-theme) - option
- [`themeVariant`](https://mobiscroll.com/docs/vue/select/api#opt-themeVariant) - option
- [`label`](https://mobiscroll.com/docs/vue/select/api#opt-label) - option
- [`display`](https://mobiscroll.com/docs/vue/select/api#opt-display) - option
- [`labelStyle`](https://mobiscroll.com/docs/vue/select/api#opt-labelStyle) - option
- [`inputStyle`](https://mobiscroll.com/docs/vue/select/api#opt-inputStyle) - option
- [`data`](https://mobiscroll.com/docs/vue/select/api#opt-data) - option
- [`itemHeight`](https://mobiscroll.com/docs/vue/select/api#opt-itemHeight) - option

## Code

### SFC JS

```vue
<script setup>
import { MbscPage, MbscSelect, setOptions } from '@mobiscroll/vue'

setOptions({
  theme: 'ios',
  themeVariant: 'light'
})

const myData = [
  {
    text: 'Percentage of assets covered by systematic risk assessments (>99)',
    value: 1
  },
  {
    text: 'Number of personal vacancies in the security roles required for ISMS (Nil)',
    value: 2
  },
  {
    text: 'Time taken to grant, change and remove access privileges (Max. 2 hours)',
    value: 3
  },
  {
    text: 'Percentage of agents covered by an effective security awareness program (100%)',
    value: 4
  },
  {
    text: 'Number of security access violations (<2)',
    value: 5
  },
  {
    text: 'Number of emergency changes (<5)',
    value: 6
  },
  {
    text: 'Number of security incidents involving malicious code (Max. 2)',
    value: 7
  },
  {
    text: 'Number of systems where security requirements are not met (Max. 2)',
    value: 8
  },
  {
    text: 'Average turnaround time of incidents (Max. 2 hours)',
    value: 9
  },
  {
    text: 'Number of pending actions to meet response and recovery requirements (Max. 5)',
    value: 10
  },
  {
    text: 'Number of scheduled internal audits not done (Max. 1)',
    value: 11
  },
  {
    text: 'Number of scheduled penetration tests not done (Max. 1)',
    value: 12
  },
  {
    text: 'Number of overdue actions arising out of audit reports (Max. 5)',
    value: 13
  },
  {
    text: 'Number of changes not carried out as per change control procedure (Max. 1)',
    value: 14
  }
]
</script>

<template>
  <MbscPage>
    <MbscSelect
      label="Multiline"
      display="anchored"
      labelStyle="stacked"
      inputStyle="box"
      placeholder="Please select..."
      :data="myData"
      :itemHeight="60"
    >
      <template #item="item">
        <div class="md-multiple-lines-item">
          <span class="md-multiple-lines-text">{{ item.display }}</span>
        </div>
      </template>
    </MbscSelect>
  </MbscPage>
</template>

<style>
.md-multiple-lines-item {
  font-size: 14px;
  white-space: initial;
  display: flex;
  height: 60px;
  line-height: normal;
}

.md-multiple-lines-text {
  margin-top: auto;
  margin-bottom: auto;
}
</style>
```

### SFC TS

```vue
<script setup lang="ts">
import { MbscPage, MbscSelect, setOptions } from '@mobiscroll/vue'

setOptions({
  theme: 'ios',
  themeVariant: 'light'
})

const myData = [
  {
    text: 'Percentage of assets covered by systematic risk assessments (>99)',
    value: 1
  },
  {
    text: 'Number of personal vacancies in the security roles required for ISMS (Nil)',
    value: 2
  },
  {
    text: 'Time taken to grant, change and remove access privileges (Max. 2 hours)',
    value: 3
  },
  {
    text: 'Percentage of agents covered by an effective security awareness program (100%)',
    value: 4
  },
  {
    text: 'Number of security access violations (<2)',
    value: 5
  },
  {
    text: 'Number of emergency changes (<5)',
    value: 6
  },
  {
    text: 'Number of security incidents involving malicious code (Max. 2)',
    value: 7
  },
  {
    text: 'Number of systems where security requirements are not met (Max. 2)',
    value: 8
  },
  {
    text: 'Average turnaround time of incidents (Max. 2 hours)',
    value: 9
  },
  {
    text: 'Number of pending actions to meet response and recovery requirements (Max. 5)',
    value: 10
  },
  {
    text: 'Number of scheduled internal audits not done (Max. 1)',
    value: 11
  },
  {
    text: 'Number of scheduled penetration tests not done (Max. 1)',
    value: 12
  },
  {
    text: 'Number of overdue actions arising out of audit reports (Max. 5)',
    value: 13
  },
  {
    text: 'Number of changes not carried out as per change control procedure (Max. 1)',
    value: 14
  }
]
</script>

<template>
  <MbscPage>
    <MbscSelect
      label="Multiline"
      display="anchored"
      labelStyle="stacked"
      inputStyle="box"
      placeholder="Please select..."
      :data="myData"
      :itemHeight="60"
    >
      <template #item="item">
        <div class="md-multiple-lines-item">
          <span class="md-multiple-lines-text">{{ item.display }}</span>
        </div>
      </template>
    </MbscSelect>
  </MbscPage>
</template>

<style>
.md-multiple-lines-item {
  font-size: 14px;
  white-space: initial;
  display: flex;
  height: 60px;
  line-height: normal;
}

.md-multiple-lines-text {
  margin-top: auto;
  margin-bottom: auto;
}
</style>
```

## Implementation notes

- `data` is an array of `{ value, text }` objects; long `text` strings are what forces the wrapped, multi-line rendering shown in this demo.
- `itemHeight` (number, px) sets a fixed row height for every option in the popup list - it must be increased from the default single-line height (e.g. to `60`) so a multi-line custom item template has room to render without clipping or overlapping neighboring rows.
- `maxWidth` (number, px) caps the popup's width (e.g. `400`) so long option text wraps within a readable column instead of stretching the picker edge to edge.
- Custom item markup is supplied per framework: JS/jQuery pass a `renderItem(item)` function option that returns an HTML string, using `item.display` for the option's resolved label; React passes a `renderItem` prop function that returns JSX, also reading `item.display`; Vue uses the `#item` scoped slot on `<MbscSelect>`, receiving the item as the slot prop and reading `item.display`; Angular passes `[itemTemplate]` pointing to an `<ng-template #itemTemp let-item>` and reads `item.display` via interpolation (`{{item.display}}`).
- `item.display` is the resolved/formatted label Mobiscroll computes for the option (distinct from the raw `item.text` on the data object) - templating code should read `.display`, not `.text`, to get the same value the default renderer would have shown.
- The custom item wrapper needs its own CSS to actually use the extra `itemHeight` (e.g. a flex container with `white-space: initial` and a height matching `itemHeight` so wrapped text is vertically centered) - this is regular page CSS, not a Select option.

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

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

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

## Related demos

- Previous: [Image & text](https://demo.mobiscroll.com/vue/select/image-text.md) - Vue select with custom item templates rendering in image & text. Build custom UI, not just plain text/value picker.
