> ## Documentation Index
> Fetch the complete documentation index at: https://help.csvbox.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Dynamic Columns

> Add new columns to the sheet at run time through the installation code.

Sometimes you can't use a fixed template to collect data, because the columns in the data model depend on the end user's preferences or other criteria. For these cases, CSVbox lets you add unique **dynamic columns** to each import at run time.

## Basic installation

Configure dynamic columns in the installation code. Here's a basic configuration that adds 2 dynamic columns, `qualification` and `experience`.

<Tabs>
  <Tab title="Javascript">
    Pass the dynamic columns you want to add as an array input parameter to the `setDynamicColumns()` method while initializing the importer.

    ```javascript theme={null}
    importer.setDynamicColumns([
             {
              "column_name" : "qualification"
             },
             {
              "column_name": "experience"
              }
    ])
    ```

    Basic installation steps are available [here](/getting-started/2-install-code).
  </Tab>

  <Tab title="React">
    Pass the dynamic columns as an object to the `dynamicColumns` property of the `CSVBoxButton` component.

    ```javascript theme={null}
      dynamicColumns={[
                   {
                     "column_name" : "qualification"
                   },
                   {
                      "column_name": "experience"
                  }
      ]}
    ```

    Basic installation steps are available [here](/getting-started/2-install-code).
  </Tab>

  <Tab title="Angular">
    Add `[dynamicColumns]="dynamicColumns"` to the existing template.

    ```typescript theme={null}
    @Component({
      selector: 'app-root',
      template: `
        <csvbox-button
          [licenseKey]="licenseKey"
          [user]="user"
          [dynamicColumns]="dynamicColumns"
          [imported]="imported.bind(this)">
          Import
        </csvbox-button>
      `
    })
    ```

    Then pass the dynamic columns as an object to the `dynamicColumns` property of the AppComponent. Example:

    ```javascript theme={null}
      dynamicColumns=[
                   {
                     column_name : "qualification"
                   },
                   {
                      column_name: "experience"
                  }
      ]
    ```

    Basic installation steps are available [here](/getting-started/2-install-code).
  </Tab>

  <Tab title="Vuejs">
    Add `:dynamicColumns="dynamicColumns"` to the existing template.

    ```html theme={null}
    <template>
      <div id="app">
        <CSVBoxButton
          :licenseKey="licenseKey"
          :user="user"
          :dynamicColumns="dynamicColumns"
          :onImport="onImport">
          Upload File
        </CSVBoxButton>
      </div>
    </template>
    ```

    Pass the dynamic columns as an object to the `dynamicColumns` property of the `CSVBoxButton` component. Example:

    ```javascript theme={null}
      dynamicColumns: [
                   {
                     column_name : "qualification"
                   },
                   {
                      column_name: "experience"
                  }
      ]
    ```

    Basic installation steps are available [here](/getting-started/2-install-code).
  </Tab>
</Tabs>

Dynamic columns are visible in the importer along with the other regular columns.

## Advanced configuration

Configure dynamic columns further by passing additional `<key>: <value>` pairs to the array input parameter of the `setDynamicColumns()` method. Here is an example illustrating more configuration options.

<Tabs>
  <Tab title="Javascript">
    ```javascript theme={null}
     importer.setDynamicColumns([
             {
              "column_name" : "qualification",
              "display_label": "Highest Qualification",
              "info_hint": "What is your highest educational degree",
              "matching_keywords": "degree, education",
              "type": "text",
              "validators":
                {
                  "min_length": 2,
                  "max_length": 50
                },
              "default_value": "Masters",
              "position": 2,
              "required": true
            },
            {
              "column_name": "experience",
              "display_label": "Work Experience",
              "info_hint": "Years of work experience",
              "matching_keywords": "",
              "type": "number",
              "validators":
                {
                  "min_value": 0,
                  "max_value": 100
                },
              "position": 4,
              "required": false
            },
            {
              "column_name": "gender",
              "display_label": "Gender",
              "info_hint": "",
              "matching_keywords": "",
              "type": "list",
              "validators":
                {
                  "values": [
                                  {"value": "m", "display_label": "male"},
                                  {"value": "f", "display_label": "female"}
                            ],
                  "case_sensitive": false
                },
              "required": true
            }
    ])
    ```
  </Tab>

  <Tab title="React">
    ```javascript theme={null}
      dynamicColumns={[
             {
              "column_name" : "qualification",
              "display_label": "Highest Qualification",
              "info_hint": "What is your highest educational degree",
              "matching_keywords": "degree, education",
              "type": "text",
              "validators":
              {
                "min_length": 2,
                "max_length": 50
              },
              "default_value": "Masters",
              "position": 2,
              "required": true
        },
     {
              "column_name": "experience",
              "display_label": "Work Experience",
              "info_hint": "Years of work experience",
              "matching_keywords": "",
              "type": "number",
              "validators":
              {
                "min_value": 0,
                "max_value": 100
              },
              "position": 4,
              "required": false
        },
        {
              "column_name": "gender",
              "display_label": "Gender",
              "info_hint": "",
              "matching_keywords": "",
              "type": "list",
              "validators":
              {
                "values": [
                                {"value": "m", "display_label": "male"},
                                {"value": "f", "display_label": "female"}
                          ],
                "case_sensitive": false
              },
              "required": true
        }
    ]}
    ```
  </Tab>

  <Tab title="Angular">
    ```javascript theme={null}
    dynamicColumns=[
        {
         column_name: "qualification",
         display_label: "Highest Qualification",
         info_hint: "What is your highest educational degree",
         matching_keywords: "degree, education",
         type: "text",
         validators:
         {
           min_length: 2,
           max_length: 50
         },
         default_value: "Masters",
         position: 2,
         required: true
      },
      {
         column_name: "experience",
         display_label: "Work Experience",
         info_hint: "Years of work experience",
         matching_keywords: "",
         type: "number",
         validators:
         {
           min_value: 0,
           max_value: 100
         },
         position: 4,
         required: false
      },
      {
         column_name: "gender",
         display_label: "Gender",
         info_hint: "",
         matching_keywords: "",
         type: "list",
         validators:
         {
           values: [
                           {value: "m", display_label: "male"},
                           {value: "f", display_label: "female"}
                     ],
           case_sensitive: false
         },
         required: true
      }
      ];
    ```
  </Tab>

  <Tab title="Vuejs">
    ```javascript theme={null}
     dynamicColumns: [
      {
       column_name: "qualification",
       display_label: "Highest Qualification",
       info_hint: "What is your highest educational degree",
       matching_keywords: "degree, education",
       type: "text",
       validators:
       {
         min_length: 2,
         max_length: 50
       },
       default_value: "Masters",
       position: 2,
       required: true
    },
    {
       column_name: "experience",
       display_label: "Work Experience",
       info_hint: "Years of work experience",
       matching_keywords: "",
       type: "number",
       validators:
       {
         min_value: 0,
         max_value: 100
       },
       position: 4,
       required: false
    },
    {
       column_name: "gender",
       display_label: "Gender",
       info_hint: "",
       matching_keywords: "",
       type: "list",
       validators:
       {
         values: [
                         {value: "m", display_label: "male"},
                         {value: "f", display_label: "female"}
                   ],
         case_sensitive: false
       },
       required: true
    }
    ]
    ```
  </Tab>
</Tabs>

<Note>
  `column_name` is the only mandatory key for adding a dynamic column.
</Note>

### Configuration options

| Key | Description |
| - | - |
| [column\_name](/sheet-settings/columns#column-name) \* | The column name that is pushed to the data destination. |
| [display\_label](/sheet-settings/columns#display-label) | The user-friendly column label that users see in the importer. |
| [info\_hint](/sheet-settings/columns#info-hint) | Help tooltips displayed when users hover the mouse over the Display Label (or click it) in the importer. |
| [matching\_keywords](/sheet-settings/columns#matching-keywords) | Comma-separated set of keywords used as alternative matching options to help users match column names automatically. |
| [type](/sheet-settings/columns#column-type) | The data type of the incoming data. Possible values are: **text**, **number**, **email**, **date**, **boolean**, **regex**, **ip**, **url**, **credit\_card**, **phone\_number**, **currency**, **list**, **dependent\_list**, **dynamic\_list**, **dependent\_dynamic\_list**, **multiselect\_list**, and **multiselect\_dynamic\_list**. |
| [validators](/advanced-installation/dynamic-columns#validator-options) | The validation rules for the data, based on the column type. Validator options are listed below. |
| [default\_value](/sheet-settings/columns#default-value) | A default filler value for the column in case the incoming data is blank. |
| [required](/sheet-settings/columns#required) | Indicates whether a column is mandatory. |
| [position](/advanced-installation/dynamic-columns#column-position) | The display index of the column. Starts from 1. |
| [read\_only](/sheet-settings/columns#read-only) | If set to **true**, users can't edit the data in this column. The default value is **false**. |

### Validator options

<table><thead><tr><th width="150">Column Type</th><th width="329">Validators</th><th>Example</th></tr></thead><tbody><tr><td>text</td><td><ol><li><strong>min\_length</strong></li><li><strong>max\_length</strong></li></ol></td><td><p>"min\_length": 2,</p><p>"max\_length": 50</p></td></tr><tr><td>number</td><td><ol><li><strong>min\_value</strong></li><li><strong>max\_value</strong></li><li><strong>number\_type</strong><br /><strong>-</strong> Valid values: "any", "integer"<br />- Default: "any" </li><li><strong>allow\_commas</strong><br /><strong>-</strong> Valid values: true, false<br />- Default: false</li><li><strong>excel\_value</strong><br />- Valid values: "raw", "formatted"<br />- Default: "formatted" </li></ol></td><td><p>"min\_value": -2,</p><p>"max\_value": 100,<br />"number\_type": "integer",<br />"allow\_commas": true,<br />"excel\_value": "raw"</p></td></tr><tr><td>email</td><td>-</td><td /></tr><tr><td>date</td><td><ol><li><strong>format</strong></li></ol></td><td>"format": \["MM/DD/YYYY", "MM.DD.YYYY", "MM-DD-YYYY"]</td></tr><tr><td>time</td><td><ol><li><strong>format</strong></li></ol></td><td>"format": \["<strong>h:mm:ss</strong>","<strong>hh:mm:ss</strong>"]</td></tr><tr><td>boolean</td><td>-</td><td /></tr><tr><td>regex</td><td><ol><li><strong>expression</strong></li><li><strong>error\_message</strong></li></ol></td><td><p>"expression": "^\[\w-\\.]+@(\[\w-]+\\.)+\[\w-]\{2,4}\$",<br />"error\_message": "Invalid format"</p><p /><p><em>Note: The special characters in the expression need to be escaped. You may use a tool like</em> <a href="https://www.freeformatter.com/javascript-escape.html#ad-output"><em>this</em> </a><em>for escaping.</em></p></td></tr><tr><td>ip</td><td><ol><li><strong>version</strong></li></ol></td><td>"version": “ipv4”</td></tr><tr><td>url</td><td>-</td><td /></tr><tr><td>credit\_card</td><td>-</td><td /></tr><tr><td>phone\_number</td><td><ol><li><strong>country\_code</strong></li></ol></td><td>"country\_code": "de"</td></tr><tr><td>currency</td><td><ol><li><strong>symbol</strong></li><li><strong>require\_symbol</strong></li><li><strong>allow\_space\_after\_symbol</strong></li><li><strong>symbol\_after\_digits</strong></li><li><strong>allow\_negatives</strong></li><li><strong>parens\_for\_negatives</strong></li><li><strong>negative\_sign\_before\_digits</strong></li><li><strong>negative\_sign\_after\_digits</strong></li><li><strong>thousands\_separator</strong></li><li><strong>decimal\_separator</strong></li><li><strong>allow\_decimal</strong></li><li><strong>require\_decimal</strong></li><li><strong>digits\_after\_decimal</strong></li><li><strong>allow\_space\_after\_digits</strong></li></ol><p><strong>Note:</strong> The array <code>digits\_after\_decimal</code> is filled with the exact number of digits allowed, not a range. For example, a range of 1 to 3 will be given as \[1, 2, 3].</p></td><td><p>"symbol": "\$", </p><p>"require\_symbol": false,</p><p>"allow\_space\_after\_symbol": false, "symbol\_after\_digits": false, "allow\_negatives": true, "parens\_for\_negatives": false, "negative\_sign\_before\_digits": false,</p><p>"negative\_sign\_after\_digits": false,</p><p>"thousands\_separator": ",", "decimal\_separator": ".", "allow\_decimal": true, "require\_decimal": false, "digits\_after\_decimal": 2, "allow\_space\_after\_digits": false</p></td></tr><tr><td>list</td><td><ol><li><p><strong>values</strong></p><ul><li><strong>value</strong></li><li><strong>display\_label</strong> (optional)</li><li><p><strong>dependents</strong> (optional)</p><ul><li><strong>value</strong></li><li><strong>display\_label</strong></li></ul></li></ul></li><li><strong>case\_sensitive</strong></li><li><strong>other\_values</strong> (Optional. Default is false)</li><li><strong>accept\_list\_values</strong><br />(Optional. Default is false)</li></ol></td><td><p>"values": \[ </p><p>\{"value": "USA", "display\_label": "USA", "dependents": \[ \{"value": "ny", "display\_label": "New York"}, \{"value": "ch", "display\_label": "Chicago"}, \{"value": "se", "display\_label": "Seattle"}, \{"value": "mi", "display\_label": "Miami"} ]}, \{"value": "Canada", "display\_label": "Canada", "dependents": \[ \{"value": "to", "display\_label": "Toronto"}, \{"value": "va", "display\_label": "Vancouver"}<br />]}</p><p>],</p><p>"case\_sensitive": false,<br />"other\_values": false,<br />"accept\_list\_values": true</p></td></tr><tr><td>dependent\_list</td><td><ol><li><strong>primary\_column</strong></li></ol></td><td>"primary\_column": "countries"</td></tr><tr><td>dynamic\_list</td><td><ol><li><strong>source\_url</strong></li><li><strong>request\_method</strong></li><li><strong>request\_headers</strong></li><li><strong>custom\_user\_attributes</strong> (Optional. Default is true)</li><li><strong>other\_values</strong> (Optional. Default is false)</li></ol></td><td><p>"source\_url": "[https://api.myapp.com/countries](https://api.myapp.com/countries)",<br />"request\_method": "POST",</p><p>"request\_headers": \[</p><p>\{"key": "Content-Type", "value": "application/json"},</p><p>\{"key": "X-Access-Token", "value": "71ab1d73a4d1319b260e9a0sdbdbc1c"}</p><p>],<br />custom\_user\_attributes: true,<br />"other\_values": false</p></td></tr><tr><td>dependent\_dynamic\_list</td><td><ol><li><strong>primary\_column</strong></li></ol></td><td>"primary\_column": "countries"</td></tr><tr><td>multiselect\_list</td><td><ol><li><strong>values</strong></li><li><strong>delimiter</strong> (Optional. Default is comma ",")</li><li><strong>case\_sensitive</strong></li><li><strong>other\_values</strong> (Optional. Default is false)</li></ol></td><td><p>"values": \["Red", "Green", "Blue"],</p><p>"delimiter": ".",<br />"case\_sensitive": false,<br />"other\_values": false</p></td></tr><tr><td>multiselect\_dynamic\_list</td><td><ol><li><strong>source\_url</strong></li><li><strong>request\_method</strong></li><li><strong>request\_headers</strong></li><li><strong>delimiter</strong> (Optional. Default is comma ",")</li><li><strong>other\_values</strong> (Optional. Default is false)</li></ol></td><td><p>"source\_url": "[https://api.myapp.com/colors](https://api.myapp.com/colors)",<br />"request\_method": "POST",</p><p>"request\_headers": \[</p><p>\{"key": "Content-Type", "value": "application/json"},</p><p>\{"key": "X-Access-Token", "value": "71ab1d73a4d1319b260e9a0sdbdbc1c"}</p><p>],<br />"delimiter": ".",<br />"other\_values": false</p></td></tr></tbody></table>

### Column position

By default, dynamic columns are displayed after the regular columns.

The `position` parameter re-orders the dynamic columns so they display before or in between the regular columns.

The `position` value starts from 1, which indicates the first position in the final column list. It is an optional parameter when defining dynamic columns.

## Receiving dynamic data

Data from dynamic columns is available in the data destinations along with the data from the regular columns. Currently, dynamic columns are supported only by the following destinations:

* [None](/destinations#none)
* [API/Webhook](/destinations#api--webhook)
* [Test API](/destinations#test-api)
* [Amazon S3](/destinations#amazon-s3)

### API/Webhook data destination

In the API response JSON object, the dynamic data appears inside the `_dynamic_data` object, as shown below. The `_dynamic_data` object is visible only if dynamic columns are configured for the import. In the example below, check lines 12 and 31.

```json theme={null}
[
  {
    "import_id": 79418895,
    "sheet_id": 55,
    "sheet_name": "Products",
    "row_number": 1,
    "row_data": {
          "Name": "TP-Link TL-WN822N Wireless N300 High Gain USB Adapter",
          "SKU": "AS-100221",
          "Price": "33.00",
          "Quantity": "3",
          "_dynamic_data":{
		"qualification": "MBA",
		"experience": "3"
           }
    },
    "custom_fields": {
      "user_id": "1002"
    }
  },
  {
    "import_id": 79418895,
    "sheet_id": 55,
    "sheet_name": "Products",
    "row_number": 2,
    "row_data":{
          "Name": "EPower Technology EP-600PM Power Supply 600W ATX12V 2.3 Single 120mm Cooling Fan Bare",
          "SKU": "AS-103824",
          "Price": "95.35",
          "Quantity": "8",
           "_dynamic_data":{
		"qualification": "MA",
		"experience": "6"
           }
        },
    "custom_fields": {
      "user_id": "1002"
    }
  },
]
```

### S3 data destination

In the AWS S3 file store, dynamic columns are added as new columns in the uploaded file.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.