> ## Documentation Index
> Fetch the complete documentation index at: https://docs-dev-docs-event-stream-action-templates.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# カスタムフィールドコンポーネント

> カスタムコンポーネントを使用して、特定のロジックやUIに必要なフィールドをJavaScriptやHTMLとCSSを用いて作成する方法について説明します。

<Frame>
  <img src="https://mintcdn.com/docs-dev-docs-event-stream-action-templates/itywf6vBRFUC2Nea/docs/images/ja-jp/cdy7uua7fh8z/3bZUItvx7VQG1AUuTah1V0/6ba3b7e9909d189f418cdc85a5ed53b9/custom-field.png?fit=max&auto=format&n=itywf6vBRFUC2Nea&q=85&s=b7c10a7cf3e1f27abde5a328530435b0" alt="Dashboard > Actions > Forms > Custom field" data-og-width="1408" width="1408" data-og-height="850" height="850" data-path="docs/images/ja-jp/cdy7uua7fh8z/3bZUItvx7VQG1AUuTah1V0/6ba3b7e9909d189f418cdc85a5ed53b9/custom-field.png" data-optimize="true" data-opv="3" srcset="https://mintcdn.com/docs-dev-docs-event-stream-action-templates/itywf6vBRFUC2Nea/docs/images/ja-jp/cdy7uua7fh8z/3bZUItvx7VQG1AUuTah1V0/6ba3b7e9909d189f418cdc85a5ed53b9/custom-field.png?w=280&fit=max&auto=format&n=itywf6vBRFUC2Nea&q=85&s=bda65bae6f2318e29222f4e7c9e87b70 280w, https://mintcdn.com/docs-dev-docs-event-stream-action-templates/itywf6vBRFUC2Nea/docs/images/ja-jp/cdy7uua7fh8z/3bZUItvx7VQG1AUuTah1V0/6ba3b7e9909d189f418cdc85a5ed53b9/custom-field.png?w=560&fit=max&auto=format&n=itywf6vBRFUC2Nea&q=85&s=f7460eecbdbd3d7a136315c2c7bf5a0e 560w, https://mintcdn.com/docs-dev-docs-event-stream-action-templates/itywf6vBRFUC2Nea/docs/images/ja-jp/cdy7uua7fh8z/3bZUItvx7VQG1AUuTah1V0/6ba3b7e9909d189f418cdc85a5ed53b9/custom-field.png?w=840&fit=max&auto=format&n=itywf6vBRFUC2Nea&q=85&s=f598001fa33ea81da397fbbc832fcdb5 840w, https://mintcdn.com/docs-dev-docs-event-stream-action-templates/itywf6vBRFUC2Nea/docs/images/ja-jp/cdy7uua7fh8z/3bZUItvx7VQG1AUuTah1V0/6ba3b7e9909d189f418cdc85a5ed53b9/custom-field.png?w=1100&fit=max&auto=format&n=itywf6vBRFUC2Nea&q=85&s=17090fc1020ddcbacd25793ab124074e 1100w, https://mintcdn.com/docs-dev-docs-event-stream-action-templates/itywf6vBRFUC2Nea/docs/images/ja-jp/cdy7uua7fh8z/3bZUItvx7VQG1AUuTah1V0/6ba3b7e9909d189f418cdc85a5ed53b9/custom-field.png?w=1650&fit=max&auto=format&n=itywf6vBRFUC2Nea&q=85&s=45a3161ad0f3e1b7defe749896b01875 1650w, https://mintcdn.com/docs-dev-docs-event-stream-action-templates/itywf6vBRFUC2Nea/docs/images/ja-jp/cdy7uua7fh8z/3bZUItvx7VQG1AUuTah1V0/6ba3b7e9909d189f418cdc85a5ed53b9/custom-field.png?w=2500&fit=max&auto=format&n=itywf6vBRFUC2Nea&q=85&s=1205b73c824a3958fc271b9ac537c10b 2500w" />
</Frame>

カスタムコンポーネントを使用すると、フォームの外観や操作性を拡張したり、JavaScriptやHTML、CSSを用いて強力なロジックを追加したりできます。

カスタムフィールドには、フロントエンドやバックエンドの変数を追加し、フォーカスやぼかしなどをの共通イベントを処理するなど、フォームにデータを渡すための内部メソッドがあります。

カスタムフィールドは以下の作成に使用できます。

* カスタムデータ構造のあるフィールド

  * **例** ：オブジェクト、文字列配列
* サードパーティーのウィジェットを使用するフィールド

  * **例** ：Google Addressのオートコンプリート
* 他のフィールドを表示または非表示するロジックのあるフィールド
* 値の取得に外部のAPIが必要なフィールド

<Warning>
  カスタムフィールドを使用するには、[カスタムドメイン](/docs/ja-jp/customize/custom-domains)を有効化する必要があります。カスタムフィールドのあるフォームをカスタムドメインの外部でレンダリングすると、エラーが表示されます。
</Warning>

## カスタムフィールドの設定

カスタムフィールドには以下の設定があります。

### Params

カスタムフィールドのソースコードで参照するキーと値のペアを追加します。キーと値のペアはフィールド[変数](/docs/ja-jp/customize/forms/variables)から含めることができます。

<Frame>
  <img src="https://mintcdn.com/docs-dev-docs-event-stream-action-templates/ZqABYvyPOuGZRvBz/docs/images/ja-jp/cdy7uua7fh8z/6VEtliKd20ZF4MJKhvB5Z0/e1b3b5df4860d013d1e3eb79d1174b35/params.png?fit=max&auto=format&n=ZqABYvyPOuGZRvBz&q=85&s=cc471c4f50fade7e37b0da5cb55a4bbb" alt="" width="821" height="320" data-path="docs/images/ja-jp/cdy7uua7fh8z/6VEtliKd20ZF4MJKhvB5Z0/e1b3b5df4860d013d1e3eb79d1174b35/params.png" />
</Frame>

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  パラメーター値は、フォームが`init()`メソッドを呼び出した後でのみ使用できます。
</Callout>

下の例では、キーと値のペアである`symbol={{fields.symbol}}`と`separator=,`を使用して、カスタムフィールドの設定が入力されています。

```javascript lines expandable theme={null}
function CustomComponent(context) {
  const input = document.createElement('input');
  let mask = null;

  function mountComponent() {
    /** getParams() method returns the params you've configured in your input */
    const config = context.custom.getParams();
    const { symbol, separator } = config;

    mask = IMask(input,
    {
      mask: `${symbol}num`,
      blocks: {
        num: {
          mask: Number,
          thousandsSeparator: separator,
        }
      }
    });
  }

  return {
    /** Invoked once when the field is created */
    init() {
      mountComponent();
      return input;
    },
    ...
  };
}
```

### ソースコード

カスタムフィールドにJavaScriptコードを追加します。

<Frame>
  <img src="https://mintcdn.com/docs-dev-docs-event-stream-action-templates/9Vac8_IYDB9MGlmx/docs/images/ja-jp/cdy7uua7fh8z/TMuY21ILSxBiBWv792cTB/97e9855145d7b52fc33ed60249e86642/source-code.png?fit=max&auto=format&n=9Vac8_IYDB9MGlmx&q=85&s=25ef7368e5685bbf9025bdf319d6dc39" alt="" width="958" height="405" data-path="docs/images/ja-jp/cdy7uua7fh8z/TMuY21ILSxBiBWv792cTB/97e9855145d7b52fc33ed60249e86642/source-code.png" />
</Frame>

```javascript lines theme={null}
function customInput() {
  const input = document.createElement('input');
  input.type = 'text';

  return {
    init() {
      return input;
    },

    block() {
      input.disabled = true;
    },

    unblock() {
      input.disabled = false;
    },

    getValue() {
      return input.value;
    }
  };
}
```

### JSONスキーマ

カスタムフィールドはデフォルトで任意の値形式を受け付けます。ただし、[JSONスキーマ](https://json-schema.org/)を使用すると、サーバー側で値を検証することができます。

<Frame>
  <img src="https://mintcdn.com/docs-dev-docs-event-stream-action-templates/V-g8sIA_dMysRiDH/docs/images/ja-jp/cdy7uua7fh8z/5iQfwWq8Scx11s1fcSONvK/d7af907f575095d66558ee2631c73113/json-schema.png?fit=max&auto=format&n=V-g8sIA_dMysRiDH&q=85&s=dec23c9996844bc60f66a8be9e942763" alt="" width="672" height="351" data-path="docs/images/ja-jp/cdy7uua7fh8z/5iQfwWq8Scx11s1fcSONvK/d7af907f575095d66558ee2631c73113/json-schema.png" />
</Frame>

```json lines theme={null}
{
  "type": "array",
  "items": {
    "type": "string"
  },
  "minItems": 2
}
```

複雑な検証要件に対応させるには、[フロー](/docs/ja-jp/customize/forms/flows)を使用することができます。

### CSS

カスタムフィールドにCSSコードを追加します。

<Frame>
  <img src="https://mintcdn.com/docs-dev-docs-event-stream-action-templates/9Vac8_IYDB9MGlmx/docs/images/ja-jp/cdy7uua7fh8z/lC4w1THpVDD32Ke6IsXrl/e1371beeed09d5f12b6656d397c3b692/css.png?fit=max&auto=format&n=9Vac8_IYDB9MGlmx&q=85&s=78e00fa7dcc0a3c07d6879017a6e9b61" alt="" width="812" height="343" data-path="docs/images/ja-jp/cdy7uua7fh8z/lC4w1THpVDD32Ke6IsXrl/e1371beeed09d5f12b6656d397c3b692/css.png" />
</Frame>

## カスタムフィールドハンドラー

以下のハンドラーを使用すると、フィールドにカスタムの動作を追加することができます。

### init(params?)

フィールドの作成時に一度だけ呼び出され、Params設定で構成済みのprams値を渡します。

HTML要素、文字列または空の値を返します。

| パラメーター   | 説明                                    |
| -------- | ------------------------------------- |
| `params` | *任意のオブジェクト*です。カスタムフィールド設定からのパラメーターです。 |

```javascript lines theme={null}
const input = document.createElement('input');
input.type = 'text';

init() {
  return input;
}
```

### update(params?)

ユーザーがフォームにある同じ手順を再表示したときに呼び出されます。

このオプションは、UIロジックの再レンダリングや、変更されたかもしれないparams値の更新が必要な場合に便利です。

| パラメーター   | 説明                                    |
| -------- | ------------------------------------- |
| `params` | *任意のオブジェクト*です。カスタムフィールド設定からのパラメーターです。 |

### onFocus()

フォーカスがカスタムフィールドのHTML要素に移動すると呼び出されます。

### onBlur()

フォーカスがカスタムフィールドのHTML要素から外れると呼び出されます。

### getValue()

フォームがカスタムフィールド値の取得を1回以上必要とする場合に呼び出されます。これは通常、ユーザーがフォームの手順を送信したときに実行されます。クライアント側の検証が必要な場合には、エラーをスローして、ユーザーにカスタムエラーメッセージを表示することができます。

**例：**

```javascript lines theme={null}
function customTextInput() {
  const input = document.createElement('input');
  input.type = 'text';

  return {
    init() {
      return input;
    },

    getValue() {
      if (input.value !== 'Auth0') {
        throw new Error('The value must be Auth0')
      }

      return input.value;
    }
  };
}
```

### block()

カスタムフィールドをブロックしなければならない場合に呼び出されます。これは通常、ユーザーがフォームの手順を送信し、データが当方のバックエンドで処理されたときに実行されます。

### unblock()

カスタムフィールドをブロック解除しなければならない場合に呼び出されます。これは通常、ユーザーがフォームの手順を送信した後か、検証エラーにより当方のバックエンドでデータの処理が停止したときに実行されます。

### getScripts()

`init()`メソッドが呼び出される前に読み込みが終了することをフォームが保証するURLのリストを返します。

```js lines theme={null}
getScripts() {
  return ['https://example.com/script_a.js', 'https://example.com/script_b.js'];
}
```

## コンテキストオブジェクト

コンテキストオブジェクトを渡す際には、以下のメソッドを使用して、フォームやコンポーネントのロジックを扱うことができます。

### カスタムメソッド

#### context.custom.getValue()

現在のカスタムフィールドの値を受け取ります。

#### context.custom.setValue()

現在のカスタムフィールドに値を設定します。

```javascript lines theme={null}
function customInput(context) {
  const input = document.createElement('input');
  input.type = 'text';

  input.addEventListener('change', () => {
    context.custom.setValue(input.value);
  });

  return {
    init() {
      return input;
    },
  };
}
```

#### context.custom.createUid()

現在のカスタムフィールドの一意の識別子を返します。

```javascript lines theme={null}
function customInput(context) {
  const input = document.createElement('input');
  input.type = 'text';
  input.id = context.custom.createUid();

  return {
    init() {
      return input;
    },

    getValue() {
      return input.value;
    }
  };
}
```

#### context.custom.getParams()

現在のカスタムフィールドの設定からパラメーターを受け取ります。

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  パラメーター値は、フォームが`init()`メソッドを呼び出した後でのみ使用できます。
</Callout>

```javascript lines theme={null}
function customInput(context) {
  // Accessing parameters on the root of the function does NOT work
  // const { defaultValue } = context.custom.getParams();
  // console.log(defaultValue); // undefined

  function buildInput() {
    const { defaultValue } = context.custom.getParams();
    const input = document.createElement('input');
    input.type = 'text';
    input.value = defaultValue;

    return input;
  }

  return {
    init() {
      return buildInput();
    },

    getValue() {
      return input.value;
    }
  };
}
```

### フォームメソッド

フォームとやり取りして他のフィールドから値を集めたり、他のフォームの手順に移動したりしなければならない場合には、以下のフォームメソッドを使用することができます。

#### context.form.getId()

現在のフォームの一意の識別子を返します。

#### context.form.getRoot()

現在のフォームのルートHTML要素を返します。

#### context.form.goForward()

1つ次のフォームの手順に移動します。

#### context.form.goPrevious()

1つ前のフォームの手順に移動します。

#### context.form.isValid()

フォームがクライアント側の検証にすべて合格した場合にブール値を返します。

#### context.form.validate()

続行する前にクライアント側の検証を用いて既存のフィールド値を評価します。フィールドが検証に合格しない場合には、エラーメッセージを表示します。

#### context.form.getAllHiddenFields()

すべての隠しフィールド値を含むオブジェクトを返します。

#### context.form.setHiddenField(id, value)

非表示フィールドの値を設定します。

| パラメーター  | 説明                   |
| ------- | -------------------- |
| `id`    | *文字列*。非表示フィールドのIDです。 |
| `value` | *文字列*。非表示フィールドの値です。  |

#### context.form.getValues()

すべてのフィールドおよび隠しフィールド値を含むオブジェクトを返します。

#### context.form.getField(id)

指定したフィールドのインスタンスを返します。

* `getNode() | true` フィールドのルートHTML要素を返します。
* `getValue()` フィールド値を返します。
* `setRequired(boolean)` フィールドを必須または任意に設定します。

| パラメーター | 説明                |
| ------ | ----------------- |
| `id`   | *文字列*。IDフィールド値です。 |

```javascript lines theme={null}
const fullName = context.form.getField('full_name');
const fullNameValue = fullName.getValue();
console.log(fullNameValue); // John Doe
```

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  `setRequired()`は、クライアント側でのみ必須フィールドを設定または設定解除します。たとえば、あるフィールドの必須設定を解除しても、フィールド設定で必須としてマークされていた場合、フィールドに値がないとフォームはエラーを返します。
</Callout>

## カスタムフィールドの例

このセクションでは、フォームに追加できるカスタムフィールドの例を説明します。

### 範囲入力カスタムフィールド

あらかじめ設定された範囲からの値を返すカスタムフィールドです。

<Frame>
  <img src="https://mintcdn.com/docs-dev-docs-event-stream-action-templates/oCq_HmOgBHEv-wbr/docs/images/ja-jp/cdy7uua7fh8z/4afLZWM9MAXXti4F3Cuc3D/c6c6d33c650b7b9fde3de011feb82192/range-input-custom-field.png?fit=max&auto=format&n=oCq_HmOgBHEv-wbr&q=85&s=5e2c3a5443c039fd21711edeb9c25382" alt="" width="380" height="242" data-path="docs/images/ja-jp/cdy7uua7fh8z/4afLZWM9MAXXti4F3Cuc3D/c6c6d33c650b7b9fde3de011feb82192/range-input-custom-field.png" />
</Frame>

**ソースコード** :：

```javascript lines theme={null}
function rangeInput() {
  const input = document.createElement('input');
  input.type = 'range';
  input.min= '0';
  input.max= '100';
  input.value = '0';

  return {
    init() {
      return input;
    },

    getValue() {
      return input.value;
    }
  };
}
```

### 色入力カスタムフィールド

色の16進数値を返すカスタムフィールドです。

<Frame>
  <img src="https://mintcdn.com/docs-dev-docs-event-stream-action-templates/oCq_HmOgBHEv-wbr/docs/images/ja-jp/cdy7uua7fh8z/5HAWLZJmCRlyl3dIrgzgWv/c602ccc1662d40d03898dcaa94d213dc/color-input-custom-field.png?fit=max&auto=format&n=oCq_HmOgBHEv-wbr&q=85&s=6ebee5304a385aa315d048972e03ff03" alt="" width="376" height="262" data-path="docs/images/ja-jp/cdy7uua7fh8z/5HAWLZJmCRlyl3dIrgzgWv/c602ccc1662d40d03898dcaa94d213dc/color-input-custom-field.png" />
</Frame>

**ソースコード** :：

```javascript lines theme={null}
function colorInput() {
  const input = document.createElement('input');
  input.type = 'color';
  input.value = '#20c5a0';

  return {
    init() {
      return input;
    },

    getValue() {
      return input.value;
    },
  };
}
```

### APIからの値を用いたオートコンプリート入力カスタムフィールド

サードパーティーのAPIを使用したオートコンプリート値を返すカスタムフィールドです。

<Frame>
  <img src="https://mintcdn.com/docs-dev-docs-event-stream-action-templates/9Vac8_IYDB9MGlmx/docs/images/ja-jp/cdy7uua7fh8z/l0lvyJgPLrHrLT8rpR6IF/800868d966ef5b64effbb6a3b0cabf94/autocomplete-api.png?fit=max&auto=format&n=9Vac8_IYDB9MGlmx&q=85&s=69bef85959cdf31cd05d4903fccf2d3f" alt="" width="380" height="294" data-path="docs/images/ja-jp/cdy7uua7fh8z/l0lvyJgPLrHrLT8rpR6IF/800868d966ef5b64effbb6a3b0cabf94/autocomplete-api.png" />
</Frame>

**ソースコード** :：

```javascript lines expandable theme={null}
function textInputWithAutocomplete(context) {
  const input = document.createElement('input');
  input.type = 'text';

  function populateInputValue(json) {
    const { city } = json;

    input.value = city;
  }

  function fetchIpInfo() {
    const url = 'https://ipinfo.io/json';
    fetch(url)
      .then((res) => res.json())
      .then((json) => populateInputValue(json));
  }

  return {
    init() {
      fetchIpInfo();
      return input;
    },

    getValue() {
      return input.value;
    },
  };
}
```

### APIからの値を用いた動的ドロップダウンカスタムフィールド

サードパーティーのAPIを使用した動的ドロップダウンリストからの値を返すカスタムフィールドです。

<Frame>
  <img src="https://mintcdn.com/docs-dev-docs-event-stream-action-templates/ZqABYvyPOuGZRvBz/docs/images/ja-jp/cdy7uua7fh8z/6gwOMuZaYi3dh0bkrxnKy9/33172d00e3933c74954a8ac3befaff7f/dropdowncustomfield.png?fit=max&auto=format&n=ZqABYvyPOuGZRvBz&q=85&s=84b99d86c674fad25e022adac20f6dc4" alt="" width="379" height="254" data-path="docs/images/ja-jp/cdy7uua7fh8z/6gwOMuZaYi3dh0bkrxnKy9/33172d00e3933c74954a8ac3befaff7f/dropdowncustomfield.png" />
</Frame>

**ソースコード** :：

```javascript lines expandable theme={null}
function dynamicDropdown() {
  const select = document.createElement('select');
  select.classList.add('af-stringField-input');

  function buildOption(data) {
    const { name: { first } } = data;
    const option = document.createElement('option');
    option.value = first;
    option.innerText = first;

    return option;
  }

  function populateNames(json) {
    const { results } = json;

    results.forEach((o) => {
      const option = buildOption(o);

      select.appendChild(option);
    });
  }

  function fetchNames() {
    const url = 'https://randomuser.me/api/?results=10&inc=name';
    fetch(url)
      .then((res) => res.json())
      .then((json) => populateNames(json));
  }

  return {
    init() {
      fetchNames();
      return select;
    },

    getValue() {
      return select.value;
    },
  };
}
```

### ＋ボタンでフィールドを追加できる動的入力カスタムフィールド

ユーザーがフィールドを追加できるカスタムフィールドです。

<Frame>
  <img src="https://mintcdn.com/docs-dev-docs-event-stream-action-templates/9Vac8_IYDB9MGlmx/docs/images/ja-jp/cdy7uua7fh8z/7xM41qqb1zYjLAPG16wxGc/a33a3dd624222643e3f967ff35acbbac/Screenshot_2024-09-12_at_09.32.35.png?fit=max&auto=format&n=9Vac8_IYDB9MGlmx&q=85&s=46cad7eb6b0805f9a4139021cf9ce951" alt="" width="381" height="330" data-path="docs/images/ja-jp/cdy7uua7fh8z/7xM41qqb1zYjLAPG16wxGc/a33a3dd624222643e3f967ff35acbbac/Screenshot_2024-09-12_at_09.32.35.png" />
</Frame>

**ソースコード** :：

```javascript lines expandable theme={null}
function DynamicInputs(context) {
  const DEFAULT_INITIAL_INPUTS = 2;
  const DEFAULT_PLACEHOLDER = 'jane.doe@example.com';
  const DEFAULT_ADD_BUTTON_TEXT = 'Add new item';
  const DEFAULT_INPUT_TYPE = 'email';
  const STATE_VALUE = {};
  const FIELD_ID = context.custom.createUid();
  let UUID_COUNTER = 0;
  let INPUTS_COUNTER = 0;

  const container = document.createElement('div');

  const inputsContainer = document.createElement('div');
  container.appendChild(inputsContainer);

  function buildAddNewItem() {
    const config = context.custom.getParams();
    const { add_button_text } = config;

    const ADD_BUTTON_TEXT = add_button_text || DEFAULT_ADD_BUTTON_TEXT;

    const addInputButton = document.createElement('button');
    addInputButton.type = 'button';
    addInputButton.classList.add('af-dynamic-input-add-button');
    addInputButton.id = `${FIELD_ID}_add-input-button`;
    addInputButton.onclick = buildInputContainer.bind(this);

    const addInputButtonIcon = document.createElement('span');
    addInputButtonIcon.classList.add('af-button', 'af-dynamic-input-add-button-icon');
    addInputButtonIcon.innerText = '+';

    const addInputButtonText = document.createElement('span');
    addInputButtonText.classList.add('af-dynamic-input-add-button-text');
    addInputButtonText.innerText = ADD_BUTTON_TEXT;

    addInputButton.appendChild(addInputButtonIcon);
    addInputButton.appendChild(addInputButtonText);
    container.appendChild(addInputButton);
  }

  function removeInput(container, input) {
    delete STATE_VALUE[input.name];
    container.remove();
  }

  function buildRemoveInputButton(container, input) {
    const button = document.createElement('button');
    button.type = 'button';
    button.classList.add('af-button', 'af-dynamic-input-remove-button');
    button.innerText = '-';
    button.onclick = removeInput.bind(this, container, input);

    INPUTS_COUNTER--;

    return button;
  }

  function buildInput() {
    const config = context.custom.getParams();
    const { placeholder, input_type } = config;

    const PLACEHOLDER = placeholder || DEFAULT_PLACEHOLDER;
    const INPUT_TYPE = input_type || DEFAULT_INPUT_TYPE;

    const input = document.createElement('input');
    input.type = INPUT_TYPE;
    input.placeholder = PLACEHOLDER;
    input.classList.add('af-stringField-input');
    input.name = `${FIELD_ID}_${UUID_COUNTER}`;
    input.id = input.name;
    input.addEventListener('change', () => {
      STATE_VALUE[input.name] = input.value;
    });

    UUID_COUNTER++;

    return input;
  }

  function buildInputContainer() {
    const container = document.createElement('div');
    container.classList.add('af-dynamic-input-container');

    const input = buildInput();
    container.appendChild(input);

    const removeButton = buildRemoveInputButton(container, input);
    container.appendChild(removeButton);

    inputsContainer.appendChild(container);

    INPUTS_COUNTER++;
  }

  function initComponent() {
    const config = context.custom.getParams();
    const { initial_inputs } = config;

    const INITIAL_INPUTS = initial_inputs || DEFAULT_INITIAL_INPUTS;
    INPUTS_COUNTER = INITIAL_INPUTS

    for (let i = 0; i < INITIAL_INPUTS; i++) {
      buildInputContainer();
    }
  }

  function blockFields(value) {
    const inputKeys = Object.keys(STATE_VALUE);

    inputKeys.forEach((o) => {
      const selector = document.getElementById(o);
      selector.disabled = value;
    });
  }

  return {
    init() {
      buildAddNewItem();
      initComponent();
      return container;
    },

    block() {
      blockFields(true);
    },

    unblock() {
      blockFields(false);
    },

    getValue() {
      return Object.values(STATE_VALUE);
    },
  };
}
```

**CSSコード** ：

```css lines expandable theme={null}
.af-button.af-dynamic-input-remove-button {
  width: 48px;
  color: var(--button-font-color);
  background: var(--button-background-color);
}

.af-dynamic-input-container {
  display: flex;
  margin-bottom: var(--spacing-1);
}

.af-dynamic-input-container input {
  margin-right: var(--spacing-1);
}

button.af-dynamic-input-add-button {
  background: none;
  border: none;
  padding: 0;
  margin: 0;
  margin-top: var(--spacing-1);
  display: inline-flex;
  cursor: pointer;
  align-items: center;
}

.af-button.af-dynamic-input-add-button-icon {
  background: var(--primary-color);
  width: 24px;
  padding: 0;
  height: 24px;
  border-radius: .3em;
  display: flex;
  justify-content: center;
  align-items: center;
  color: #fff;
  margin-right: var(--spacing-1);
}

.af-dynamic-input-add-button-text {
  color: var(--label-font-color);
  font-size: var(--label-font-size);
}

.af-dynamic-input-add-button:focus {
  outline: none;
}

.af-dynamic-input-add-button:hover .af-button {
  transition: filter var(--transition-normal), box-shadow var(--transition-normal);
  filter: brightness(1.1);
  box-shadow: 0 0 0 var(--outline-width) var(--outline-color), 0px 4px 8px -4px var(--shadow-color), 0px 16px 24px var(--shadow-color);
}

.af-dynamic-input-add-button:focus .af-button {
  box-shadow: 0 0 0 var(--outline-width) var(--outline-color), 0px 4px 8px -4px var(--shadow-color), 0px 16px 24px var(--shadow-color);
}
```
