---
title: User-Defined Choice Options
product: Form Library
description: Allow users to manually add their own choices in Dropdown and Tag Box questions if the option they're looking for isn't available. View the interactive JavaScript form builder demo to learn more.
framework: Vue 3
source: https://surveyjs.io/form-library/examples/dropdown-custom-choice-options/vue3js
index: https://surveyjs.io/form-library/examples/overview.md
---

# User-Defined Choice Options (Vue 3)

Respondents can add their own choice options to a Dropdown or Tag Box if the desired option isn't available. Click into the dropdown below and start typing a car brand. If the brand isn't found, a "Create 'X' item" command will appear. You can click it to save the entered text as a new choice. In this demo, custom choices are saved in the `localStorage` and restore on page reload. Click the "Clear saved choices" button to delete the choices from the `localStorage`.

To let users add custom choice options, set the [`allowCustomChoices`](https://surveyjs.io/form-library/documentation/api-reference/dropdown-menu-model#allowCustomChoices) property to `true` for an individual Dropdown or Tag Box question. By default, custom choices are only stored temporarily and will be lost once the browser page is closed. If you'd like to keep these custom choices longer, handle the [`onCreateCustomChoiceItem`](https://surveyjs.io/form-library/documentation/api-reference/survey-data-model#onCreateCustomChoiceItem) event to save them to your own data storage. Within the event handler, you'll have access to both the new item being added and the list of [previously added custom choices](https://surveyjs.io/form-library/documentation/api-reference/dropdown-menu-model#customChoices). You can store the new item, the existing ones, or both. Refer to the Code tab for a code example.

## Files

### `public/index.html`

```html
<div id="app" style="position: absolute; top: 0; left: 0; right: 0; bottom: 0; height:100%"></div>
```

### `src/App.vue`

```html
<template>
    <SurveyComponent :model="survey" />
</template>
<script setup lang="ts">
    import { Model } from "survey-core";
    import { SurveyComponent } from "survey-vue3-ui";
    import "survey-core/survey-core.min.css";
    import "./index.css";
    import { json } from "./json";

    const survey = new Model(json);
    survey.onComplete.add((sender, options) => {
        console.log(JSON.stringify(sender.data, null, 3));
    });
    survey.onCreateCustomChoiceItem.add((_, { question, item }) => {
        localStorage.setItem(question.name, JSON.stringify(question.customChoices.concat(item)));
    });
    
    survey.addNavigationItem({
        id: "clear-custom-choices",
        title: "Clear saved choices",
        action: () => clearCustomChoices(survey)
    });
    
    restoreCustomChoices(survey);
    
    function getQuestionsWithCustomChoices(survey) {
        const allQuestions = survey.getAllQuestions();
        return allQuestions.filter(q => q.allowCustomChoices);
    }
    
    function restoreCustomChoices(survey) {
        const questionsWithCustomChoices = getQuestionsWithCustomChoices(survey);
        questionsWithCustomChoices.forEach(q => {
            const customChoices = JSON.parse(localStorage.getItem(q.name));
            if (customChoices)
                q.customChoices = customChoices;
        });
    }
    
    function clearCustomChoices(survey) {
        const questionsWithCustomChoices = getQuestionsWithCustomChoices(survey);
        let notificationType = "info";
        questionsWithCustomChoices.forEach(q => {
            if (q.customChoices.length > 0) {
                q.customChoices = [];
                localStorage.removeItem(q.name);
                notificationType = "success";
            }
        });
        const notificationMessage = notificationType === "info" ? "No custom choices found" : "Custom choices are deleted successfully";
        survey.notify(notificationMessage, notificationType);
    }
</script>
```

### `src/index.css`

```css
/* You can add your custom CSS here. */
```

### `src/json.ts`

```ts
export const json = {
  "elements": [
    {
      "type": "dropdown",
      "name": "current-car",
      "title": "Which is the brand of your current car?",
      "showNoneItem": true,
      "choices": [ "Ford", "Vauxhall", "Volkswagen", "Nissan", "Audi", "Mercedes-Benz", "BMW", "Peugeot", "Toyota", "Citroen" ],
      "allowCustomChoices": true
    },
    {
      "type": "tagbox",
      "name": "previous-cars",
      "title": "Which car brands have you owned before?",
      "showNoneItem": true,
      "choices": [ "Ford", "Vauxhall", "Volkswagen", "Nissan", "Audi", "Mercedes-Benz", "BMW", "Peugeot", "Toyota", "Citroen" ],
      "allowCustomChoices": true
    }
  ]
};
```

### `src/main.ts`

```ts
import { createApp } from "vue";
import App from "./App.vue";

const app = createApp(App);
app.mount("#app");
```

### `src/shims-vue.d.ts`

```ts
/* eslint-disable */
declare module "*.vue" {
    import type { DefineComponent } from "vue"
    const component: DefineComponent<{}, {}, any>
    export default component
}
```

### `src/theme.ts`

```ts
export const themeJson = {};
```

### `.eslintrc.js`

```js
module.exports = {
    root: true,
    env: {
        node: true
    },
    extends: [
        "plugin:vue/vue3-essential",
        "eslint:recommended",
        "@vue/typescript/recommended",
        "@vue/prettier",
        "@vue/prettier/@typescript-eslint"
    ],
    parserOptions: {
        ecmaVersion: 2020
    },
    rules: {
        "no-console": process.env.NODE_ENV === "production" ? "warn" : "off",
        "no-debugger": process.env.NODE_ENV === "production" ? "warn" : "off"
    },
    overrides: [
        {
            files: [
                "**/__tests__/*.{j,t}s?(x)",
                "**/tests/unit/**/*.spec.{j,t}s?(x)"
            ],
            env: {
                jest: true
            }
        }
    ]
};
```

### `babel.config.js`

```js
module.exports = {
  presets: ["@vue/cli-plugin-babel/preset"]
};
```

### `package.json`

```json
{
  "name": "surveyjs-library-vue3",
  "version": "0.1.0",
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint"
  },
  "dependencies": {
    "core-js": "^3.6.5",
    "tslib": "2.6.1",
    "vue": "^3.4.1",
    "survey-core": "latest",
    "survey-vue3-ui": "latest",
    "vue-router": "^4.0.0-0",
    "vuex": "^4.0.0-0"
  },
  "devDependencies": {
    "@typescript-eslint/eslint-plugin": "^2.33.0",
    "@typescript-eslint/parser": "^2.33.0",
    "@vue/cli-plugin-babel": "~4.5.0",
    "@vue/cli-plugin-eslint": "~4.5.0",
    "@vue/cli-plugin-pwa": "~4.5.0",
    "@vue/cli-plugin-router": "~4.5.0",
    "@vue/cli-plugin-typescript": "~4.5.0",
    "@vue/cli-plugin-vuex": "~4.5.0",
    "@vue/cli-service": "~4.5.0",
    "@vue/compiler-sfc": "^3.0.0",
    "@vue/eslint-config-prettier": "^6.0.0",
    "@vue/eslint-config-typescript": "^5.0.2",
    "@vue/test-utils": "^2.0.0-0",
    "eslint": "^6.7.2",
    "eslint-plugin-prettier": "^3.1.3",
    "eslint-plugin-vue": "^7.0.0-0",
    "node-sass": "^4.12.0",
    "prettier": "^1.19.1",
    "sass-loader": "^8.0.2",
    "typescript": "~3.9.3"
  }
}
```

### `tsconfig.json`

```json
{
  "compilerOptions": {
    "target": "esnext",
    "module": "esnext",
    "strict": true,
    "jsx": "preserve",
    "importHelpers": true,
    "moduleResolution": "node",
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "sourceMap": true,
    "baseUrl": ".",
    "types": [
      "webpack-env",
      "jest"
    ],
    "paths": {
      "@/*": [
        "src/*"
      ]
    },
    "lib": [
      "esnext",
      "dom",
      "dom.iterable",
      "scripthost"
    ]
  },
  "include": [
    "src/**/*.ts",
    "src/**/*.tsx",
    "src/**/*.vue",
    "tests/**/*.ts",
    "tests/**/*.tsx"
  ],
  "exclude": [
    "node_modules"
  ]
}
```

## Other Frameworks

- [Angular](https://surveyjs.io/form-library/examples/dropdown-custom-choice-options/angular.md)
- [React](https://surveyjs.io/form-library/examples/dropdown-custom-choice-options/reactjs.md)
- [jQuery](https://surveyjs.io/form-library/examples/dropdown-custom-choice-options/jquery.md)
- [Vanilla JS](https://surveyjs.io/form-library/examples/dropdown-custom-choice-options/vanillajs.md)
