# Dynamic Columns

Consider a scenario where you cannot have a fixed template for collecting data. The columns in the data model depend on the end user's preferences and/or some other criteria.&#x20;

For such cases, csvbox provides the flexibility to add unique **dynamic columns** for each import at run-time.

### Basic Installation

You can configure **dynamic columns** via the installation code.

Here's a basic configuration that adds 2 dynamic columns **qualification** and **experience**.&#x20;

{% tabs %}
{% tab title="Javascript" %}
Pass the dynamic columns that you want to add as an array input parameter to th&#x65;**`setDynamicColumns()`**&#x6D;ethod while initializing the importer.

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

Basic installation steps are available [here](https://help.csvbox.io/advanced-installation/pages/-MOGv6-aW2aB2fgDl2Eo#2.-install-code).
{% endtab %}

{% tab title="React" %}
Pass the dynamic columns as an object to the **`dynamicColumns`**&#x70;roperty of the **`CSVBoxButton`** component.&#x20;

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

Basic installation steps are available [here](https://help.csvbox.io/advanced-installation/pages/-MOGv6-aW2aB2fgDl2Eo#2.-install-code).
{% endtab %}

{% tab title="Angular" %}
Add `[dynamicColumns]="dynamicColumns"` to the existing template.&#x20;

```
@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 th&#x65;**`dynamicColumns`**&#x70;roperty of the AppComponent. Example:

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

Basic installation steps are available [here](https://help.csvbox.io/advanced-installation/pages/-MOGv6-aW2aB2fgDl2Eo#2.-install-code).
{% endtab %}

{% tab title="Vuejs" %}
Add `:dynamicColumns="dynamicColumns"` to the existing template.&#x20;

```
<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 th&#x65;**`dynamicColumns`**&#x70;roperty of th&#x65;**`CSVBoxButton`** component. Example:

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

Basic installation steps are available [here](https://help.csvbox.io/advanced-installation/pages/-MOGv6-aW2aB2fgDl2Eo#2.-install-code).
{% endtab %}
{% endtabs %}

Dynamic columns will be visible in the importer along with the other regular columns.

<img src="/files/yZrGgxa4FQAIitYODbb2" alt="Dynamic Columns" data-size="original">

### **Advanced Configuration**

Dynamic columns can be configured by passing additiona&#x6C;**`<key>: <value>`**&#x70;airs to the array input parameter of th&#x65;**`setDynamicColumns()`**&#x6D;ethod.

Here is an example illustrating more configuration options.

{% tabs %}
{% tab title="Javascript" %}

```javascript
 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
        }
])
```

{% endtab %}

{% tab title="React" %}

```javascript
  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
    }
]}
```

{% endtab %}

{% tab title="Angular" %}

```javascript
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
  }
  ];
```

{% endtab %}

{% tab title="Vuejs" %}

```javascript
 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
}
]
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**column\_name** is the only key that is mandatory for adding a dynamic column.
{% endhint %}

#### Configuration Options

<table><thead><tr><th width="321.0208971718002">Key</th><th>Description</th></tr></thead><tbody><tr><td><a href="/pages/-MfXTzcp1nRANdG4Hwlq#column-name">column_name</a> <mark style="color:red;">*</mark></td><td>It is the column name that will be pushed to the data destination.</td></tr><tr><td><a href="/pages/-MfXTzcp1nRANdG4Hwlq#display-label">display_label</a></td><td>The user-friendly column label that the users will see in the importer.</td></tr><tr><td><a href="/pages/-MfXTzcp1nRANdG4Hwlq#info-hint">info_hint</a></td><td>Info Hints are help tooltips that will get displayed when the users hover the mouse over the Display Label (or click it) in the importer.</td></tr><tr><td><a href="/pages/-MfXTzcp1nRANdG4Hwlq#matching-keywords">matching_keywords</a></td><td>Comma-separated set of keywords as alternative matching options to help users match column names automatically. </td></tr><tr><td><a href="/pages/-MfXTzcp1nRANdG4Hwlq#column-type">type</a></td><td>It specifies the data type of the incoming data. Possible values are: <strong>text</strong>, <strong>number</strong>, <strong>email</strong>, <strong>date</strong>, <strong>boolean</strong>, <strong>regex</strong>, <strong>ip</strong>, <strong>url</strong>, <strong>credit_card</strong>, <strong>phone_number, currency, list, dependent_list, dynamic_list, dependent_dynamic_list, multiselect_list,</strong> and <strong>multiselect_dynamic_list.</strong></td></tr><tr><td><a href="#validator-options">validators</a></td><td>The validation rules for the data based on the column type. Validator options are mentioned below.</td></tr><tr><td><a href="/pages/-MfXTzcp1nRANdG4Hwlq#default-value">default_value</a></td><td>A default filler value for the column in case the incoming data is blank.</td></tr><tr><td><a href="/pages/-MfXTzcp1nRANdG4Hwlq#required">required</a></td><td>It indicates whether a column is mandatory.</td></tr><tr><td><a href="#column-position">position</a></td><td>It defines the display index of the column. Starts from 1.</td></tr><tr><td><a href="/pages/-MfXTzcp1nRANdG4Hwlq#read-only">read_only</a></td><td>If configured to <strong>true</strong> then the users will not be able to edit the data of this column. The default value is <strong>false</strong>.</td></tr></tbody></table>

#### Validator options

<table><thead><tr><th width="150">Column Type</th><th width="329.4">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></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></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><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></td></tr><tr><td>credit_card</td><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_separato</strong></li><li><strong>decimal_separator</strong></li><li><strong>allow_decimal</strong></li><li><strong>require_decimal</strong></li><li><strong>digits_after_decima</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 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": "Seatle"}, {"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",<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",<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**

In general, the dynamic columns are displayed only after the regular columns.

The `position`parameter helps to re-order the position of the dynamic columns and get them displayed before or in between the regular columns.&#x20;

The `position` value starts from 1 indicating the first position in the final column list. It is an optional parameter while defining the dynamic columns.

### **Receiving Dynamic Data**

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

1. [None](/destinations.md#none)
2. [API/Webhook](/destinations.md#webhook)
3. [Test API](/destinations.md#test-api)
4. [Amazon S3](/destinations.md#amazon-s3)

#### API/Webhook Data Destination

In the API response JSON object, the dynamic data will be displayed inside the **\_dynamic\_data** object as shown below. The **\_dynamic\_data** object will be visible only if the dynamic columns are configured for the import. In the example below check lines 12 and 31.

```json
[
  {
    "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, the dynamic columns will be added as new columns in the uploaded file.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://help.csvbox.io/advanced-installation/dynamic-columns.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
