# Widgets

Use widgets in any Customer Service Center customizable area. Commonly used widgets include `attribute_layout`, `attribute_form`, `attribute_listing`, `text`, `link`, and `tabs`.

Widgets are always named directly and configured by registering them with a type.

| Name     | Type   | Description                                            |
| -------- | ------ | ------------------------------------------------------ |
| `config` | object | an object that contains widget-specific configurations |
| `type`   | string | the required widget type                               |

Example of widget registration:

```json
"widgets": {
  "description": {
    "type": "attribute_listing",
    "config": {
      "attributes": [
        "system_attribute",
        "c_customAttribute"
      ],
      "columns": 2
    }
  },
  "my_layout" : {
    "type" : "attribute_layout"
  },
  "option-selector": {
    "type": "product_option"
  },
  "quantity-selector": {
    "type": "product_quantity"
  }
}
```

Details on customizing each widget are included in the remaining sections of this guide.

## Attribute_form Widget

The `attribute_form` widget provides a form element for attributes depending on metadata. The metadata are either derived from attributes or through metadata overwrite in layout.

The attribute_form widget is only configured through layout and its subelements.

```json
{
  "layout": [
    {
      "condition":"data",
      "layout": [
        {
          "id":"address",
          "layout": [
            {
              "attribute":"first_name",
              "meta": {
                "maxLength":50
              },
              "width":6
            },
            {
              "attribute":"last_name",
              "meta": {
                "maxLength":50,
                "required":true
              },
              "width":6
            }
          }
        ]
    }
  ],
  "widgets": {
    "address": {
      "type":"attribute_form"
    }
  }
}
```

With the customization, it's also possible to override the metadata of attributes to:

- Provide or restrict options of values, for example, the state codes for certain countries
- Change the type, format or constraints of attributes, for example, the format of the credit card expiration month or the maximum input length
- Mark an attribute as required

This table lists the options of overriding meta data.

<table><tbody><tr><td><p>label</p></td><td><p>Metadata can be adjusted to show different localized text as coming from the Salesforce B2C Commerce platform metadata</p></td></tr><tr><td><p>required</p></td><td>

If an attribute is required in a form, it can be marked accordingly for mark in the UI and verify it.

```json
{
  "attribute": "payment_card.holder",
  "meta": {
    "required": true
  }
}
```

</td></tr><tr><td><p>disabled</p></td><td>

A form element can be disabled for read-only purposes with `disabled`.

```json
{
  "attribute": "customer_no",
  "meta": {
    "disabled": true
  }
}
```

</td></tr><tr><td><p>type & format</p></td><td>

The `format` attribute lets you override the default display, for example, to show a string in a textbox only. ("format": "text")

The format requires an explicit type declaration.

```json
{
  "attribute": "note",
  "meta": {
    "type" : "string",
    "format": "text",
    ...
  }
}
```

Currently supported are:

- string: text, password, email, html, null, date, date-time, and time

- number: int32, int64, float, double, byte, and null

- integer: int32, int64, byte, and null

</td></tr><tr><td><p>maxLength</p></td><td>

The maximum length of an attribute can be restricted with `maxLength`.

```json
{
  "attribute": "postal_code",
  "meta": {
    "maxLength": 5
  }
}
```

</td></tr><tr><td><p>enum</p></td><td>

The configuration of an `attribute_form` widget allows the override of enumeration values to either limit enum values in a certain dropdown based on conditions or localize values differently.

The current example would lead to a dropdown with three items (Price Match, Appeasement, Other) regardless the number of items declared in the meta data. The condition makes sure that this enum is active for product level only.

Each enum element has a separate label attribute including localization.

```json
{
  "attribute": "reason_code",
  "condition": "data.level === 'product'",
  "meta": {
    "enum": [
      {
        "code": "PRICE_MATCH",
        "label": {
          "default": "Price match",
          "de": "Preisänderung"
        }
      },
      {
        "code": "Appeasement",
        "label": {
          "default": "Appeasement"
        }
      },
      {
        "code": "Other"
      }
    ],
    "required": true
  },
  "width": 6
}
```

</td></tr><tr><td><p>regex</p></td><td>

The attribute form widget recognized regex configured in the meta data. The values can be overwritten if they are more specific to CSC.

```json
{
  "attribute": "postal_code",
  "meta": {
    "required": true,
    "maxLength": 5,
    "pattern": "^[0-9]{5}$"
  }
}
```

</td></tr><tr><td><p>dynamic_enum</p></td><td>

The `dynamic_enum` option refers to a particular property that contains the allowed values for a certain attribute. Those values could be determined during the request processing.

```json
{
  "attribute": "c_shipping_schedule",
  "meta": {
    "type": "string",
    "format": "date",
    "dynamic_enum": {
      "code_property": "c_shipping_schedule_selection_codes",
      "label_property": "c_shipping_schedule_selection_labels"
    }
  }
}
```

</td></tr></tbody></table>

For example, To avoid errors when entering the state code, the state code values are provided as a selection for the US. For Canada and France, a simple input field is shown:

```json
{
  "layout" : [
    {
      "layout": [
        {
          "id": "address",
          "layout": [
            {
            ... more attributes ...
            },
            {
              "attribute": "state_code",
              "condition": "data.country_code === 'FR' || data.country_code === 'CA'",
              "width": 6
            },
            {
              "attribute": "state_code",
              "condition": "data.country_code === 'US'",
              "meta": {
                 "required": true,
                 "enum": [
                   {"code":"AL", "label":{"default":"AL-Alabama"}},
                   {"code":"AK", "label":{"default":"AK-Alaska"}},
                   ... more states ...
                 ]
              },
              "width": 6
            }
          ]
        }
      ]
    }
  ],
  "widgets" : {
    "address" : {
      "type" : "attribute_form"
    }
  }
}
```

## Attribute_layout Widget

The `attribute_layout` widget prints the content of a certain attribute.

This widget is only configured through layout and its subelements and needs only a simple widget registration. The following example shows how the attributes `first_name`, `last_name`, `postal_code`, and `city` can be arranged in a layout using the default width, which results in a line break after each attribute.

```json
{
  "layout": [
    {
      "id": "address",
      "layout": [
        {
          "layout": [
            {
              "attribute": "first_name"
            },
            {
              "attribute": "last_name"
            }
          ]
        },
        {
          "layout": [
            {
              "attribute": "postal_code"
            },
            {
              "attribute": "city"
            }
          ]
        }
      ]
    }
  ],
  "widgets": {
    "address": {
      "type": "attribute_layout"
    }
  }
}
```

This example result in the following view of the billing address at an order, in which the grid distributes the cells automatically.

![Example billing address rendered with the attribute_layout widget using automatic grid distribution](https://a.sfdcstatic.com/developer-website/sfdocs/commerce-cloud/media/b2c-commerce/b2c_customer_service_center_billing_address_without_anything.png)

## Attribute_listing Widget

The `attribute_listing` widget can show system and custom attributes in either one, two or three columns in the order of the configuration.

| Name         | Type             | Description                                                           |
| ------------ | ---------------- | --------------------------------------------------------------------- |
| `columns`    | integer          | the number of columns (1, 2, or 3) to use                             |
| `attributes` | array of strings | the attributes to display                                             |
| `show_empty` | Boolean          | whether an attribute appears when no value's defined default is false |

```json
{
  "columns": 2,
  "attributes": ["attribute1", "attribute2"]
}
```

## Link Widget

A link widget shows a link with an href and text information.

```json
"product_link": {
  "link": {
   "type": "link",
     "data": {
        "href": {
           "template": "/s/{0}/dw/shop/v16_9/products/{1}",
           "attributes": ["SITE_ID", "id"]
        },
        "text": {
           "template": {"default":"Product {0}"},
           "attributes": ["id"]
        }
     }
  }
}
```

## Tabs Widget

Use the tabs widget to place tabs somewhere in the layout. Each tab can be of type widget_tab or form_tab.

Tabs can contain available widgets and forms.

<table><thead><tr><th>Name</td><th>Type</td><th>Description</td></tr></thead><tbody><tr><td><p>type</p></td><td><p>string</p></td><td><p>Declares the type of tab:</p><ul><li><p><code>widget_tab</code> - to reference a widget directly</p></li><li><p><code>form_tab</code> - to reference a particular configured area</p></li></ul></td></tr><tr><td><p>caption</p></td><td> </td><td><p>a template to define localized meta data</p>

```json
"caption": {
  "template": {
    "de": "Kunde (de)",
    "default": "Customer Data",
    "de-DE": "Kundendaten (de-DE)"
  }
}
```

</td></tr><tr><td><p>config</p></td><td> </td><td><p>A configuration for <code>form_tab</code> tabs:</p><ul><li><p><code>area_id</code> (string): Specifies the area id to appear in this tab.</p></li><li><p><code>default_data_provider</code> (string): A data provider to access the data in the form</p></li><li><p><code>query_params</code> (Boolean): query params for the particular data provider</p></li></ul></td></tr></tbody></table>

```json
"tabs": {
  "type": "tabs",
  "config": {
    "tabs": [
      {
        "type": "widget_tab",
        "caption": {
          "template": {
            "default": "Coupons"
          }
        },
        "widget_id": "basket_coupons"
      },
      {
        "type": "form_tab",
        "caption": {
          "template": {
            "default": "Customer Data"
          }
        },
        "config": {
          "area_id": "customer_view",
          "default_data_provider": "Customer",
          "query_params": {
            "customer_id": {
              "attribute": "customer_info.customer_id"
            }
          }
        }
      }
    ]
  }
}
```

The main layout section needs a reference to the tabs widget only to show the configured tabs with their content.

```json
"layout": [
  {
    "layout": [
      {
        "id": "tabs",
        "width": 8
      }
    ]
  }
]
```

## Text Widget

The text widget shows localized and parametrized text.

```json
"text_id": {
  "type": "text",
  "data": {
    "template": {
      "default": "Hello World - {0} - {1}:"
    },
    "attributes": [
      "order_no",
      "site_id"
    ]
  }
}
```

![Example rendering of a Customer Service Center text widget showing localized and parametrized text output](https://a.sfdcstatic.com/developer-website/sfdocs/commerce-cloud/media/b2c-commerce/b2c_customer_service_center_text_widget.png)
