{"id":16075140,"url":"https://github.com/accessd/yii2-multiple-input","last_synced_at":"2025-07-19T15:03:05.415Z","repository":{"id":147576348,"uuid":"220193147","full_name":"accessd/yii2-multiple-input","owner":"accessd","description":null,"archived":false,"fork":false,"pushed_at":"2019-11-07T09:00:04.000Z","size":324,"stargazers_count":0,"open_issues_count":0,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-01-21T00:05:18.107Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/accessd.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-11-07T08:59:19.000Z","updated_at":"2019-11-07T09:00:06.000Z","dependencies_parsed_at":null,"dependency_job_id":"bae7d8f9-225c-4cc6-a9c7-36f3c06961d2","html_url":"https://github.com/accessd/yii2-multiple-input","commit_stats":{"total_commits":1,"total_committers":1,"mean_commits":1.0,"dds":0.0,"last_synced_commit":"f253d125dc83e167f21e38ab4055a00b0542f15d"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/accessd%2Fyii2-multiple-input","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/accessd%2Fyii2-multiple-input/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/accessd%2Fyii2-multiple-input/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/accessd%2Fyii2-multiple-input/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/accessd","download_url":"https://codeload.github.com/accessd/yii2-multiple-input/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240409553,"owners_count":19796793,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-09T09:01:57.428Z","updated_at":"2025-02-24T02:44:36.456Z","avatar_url":"https://github.com/accessd.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"#Yii2 Multiple input widget.\nYii2 widget for handle multiple inputs for an attribute of model\n\n[![Latest Stable Version](https://poser.pugx.org/unclead/yii2-multiple-input/v/stable)](https://packagist.org/packages/unclead/yii2-multiple-input)\n[![Total Downloads](https://poser.pugx.org/unclead/yii2-multiple-input/downloads)](https://packagist.org/packages/unclead/yii2-multiple-input)\n[![Daily Downloads](https://poser.pugx.org/unclead/yii2-multiple-input/d/daily)](https://packagist.org/packages/unclead/yii2-multiple-input)\n[![Latest Unstable Version](https://poser.pugx.org/unclead/yii2-multiple-input/v/unstable)](https://packagist.org/packages/unclead/yii2-multiple-input) \n[![License](https://poser.pugx.org/unclead/yii2-multiple-input/license)](https://packagist.org/packages/unclead/yii2-multiple-input)\n\n##Latest release\nThe latest version of the extension is v1.2.19. Follow the [instruction](./UPGRADE.md) for upgrading from previous versions\n\nContents:\n\n- [Installation](#installation)\n- [Configuration](#configuration)\n- [Usage](#usage)\n- [Tips and tricks](#tips-and-tricks)\n - [How to customize buttons](#how-to-customize-buttons)\n - [Work with empty list](#work-with-empty-list)\n - [Guess column title](#guess-column-title)\n - [Ajax loading of a widget](#ajax-loading)\n - [Use of a widget's placeholder](#using-placeholder)\n - [Custom index of the row](#custom-index)\n- [Javascript Events](#javascript-events)\n- [Renderers](#renderers)\n\n##Installation\nThe preferred way to install this extension is through [composer](http://getcomposer.org/download/).\n\nEither run\n\n```\nphp composer.phar require  unclead/yii2-multiple-input \"~1.0\"\n```\n\nor add\n\n```\n\"unclead/yii2-multiple-input\": \"~1.0\"\n```\n\nto the require section of your `composer.json` file.\n\n## Configuration\n\nWidget support the following options that are additionally recognized over and above the configuration options in the InputWidget.\n\n### Base options\n\n**limit** *integer*: rows limit. If not set will defaul to unlimited\n\n**min** *integer*: minimum number of rows. Set to `0` if you need the empty list in case you don't have any data\n\n**attributeOptions** *array*: client-side attribute options, e.g. enableAjaxValidation. You may use this property in case when\n  you use widget without a model, since in this case widget is not able to detect client-side options automatically\n\n**addButtonPosition** *integer*: the position of `add` button. This can be MultipleInput::POS_HEADER or MultipleInput::POS_ROW.\n\n**addButtonOptions** *array*: the HTML options for `add` button. Can contains `class` and `label` keys\n\n**removeButtonOptions** *array*: the HTML options for `add` button. Can contains `class` and `label` keys\n\n**data** *array*: array of values in case you use widget without model\n\n**models** *array*: the list of models. Required in case you use `TabularInput` widget\n\n**allowEmptyList** *boolean*: whether to allow the empty list\n\n**columnClass** *string*: the name of column class. You can specify your own class to extend base functionality.\nDefaults to `unclead\\widgets\\MultipleInputColumn` for `MultipleInput` and `unclead\\widgets\\TabularColumn` for `TabularInput`.\n\n**columns** *array*: the row columns configuration where you can set the properties which is described below\n\n**rowOptions** *array|\\Closure*: the HTML attributes for the table body rows. This can be either an array\nspecifying the common HTML attributes for all body rows, or an anonymous function that returns an array of the HTML attributes.\nIt should have the following signature:\n\n```php\nfunction ($model, $index, $context)\n```\n\n- `$model`: the current data model being rendered\n- `$index`: the zero-based index of the data model in the model array\n- `$context`: the widget object\n\n### Column options\n\n**name** *string*: input name. *Required options*\n\n**type** *string*: type of the input. If not set will default to `textInput`. Read more about the types described below\n\n**title** *string*: the column title\n\n**value** *Closure*: you can set it to an anonymous function with the following signature:\n\n```php\nfunction($data) {}\n```\n\n**defaultValue** *string*: default value of input\n\n**items** *array*|*Closure*: the items for input with type dropDownList, listBox, checkboxList, radioList\nor anonymous function which return array of items and has the following signature:\n\n```php\nfunction($data) {}\n```\n\n**options** *array*|*Closure*: the HTML attributes for the input, you can set it as array\nor an anonymous function with the following signature:\n\n```php\nfunction($data) {}\n```\n\n**headerOptions** *array*: the HTML attributes for the header cell\n\n**enableError** *boolean*: whether to render inline error for the input. Default to `false`\n\n**errorOptions** *array*: the HTMl attributes for the error tag\n\n\n### Input types\n\nEach column in a row can has their own type. Widget supports:\n\n- all yii2 html input types:\n  - `textInput`\n  - `dropDownList`\n  - `radioList`\n  - `textarea`\n  - For more detail look at [Html helper class](http://www.yiiframework.com/doc-2.0/yii-helpers-html.html)\n- input widget (widget that extends from `InputWidget` class). For example, `yii\\widgets\\MaskedInput`\n- `static` to output a static HTML content\n\nFor using widget as column input you may use the following code:\n\n```php\n[\n    'name'  =\u003e 'phone',\n    'title' =\u003e 'Phone number',\n    'type' =\u003e \\yii\\widgets\\MaskedInput::className(),\n    'options' =\u003e [\n        'class' =\u003e 'input-phone',\n        'mask' =\u003e '999-999-99-99'\n    ]\n]\n```\n\n##Usage\n\n### Input with one column\n\n![Single column example](./docs/images/single-column.gif?raw=true)\n\nFor example you want to have an ability of entering several emails of user on profile page.\nIn this case you can use yii2-multiple-input widget like in the following code\n\n```php\nuse unclead\\widgets\\MultipleInput;\n\n...\n\n\u003c?php\n    echo $form-\u003efield($model, 'emails')-\u003ewidget(MultipleInput::className(), [\n        'limit'             =\u003e 6,\n        'allowEmptyList'    =\u003e false,\n        'enableGuessTitle'  =\u003e true,\n        'min'               =\u003e 2, // should be at least 2 rows\n        'addButtonPosition' =\u003e MultipleInput::POS_HEADER // show add button in the header\n    ])\n    -\u003elabel(false);\n?\u003e\n```\n\nYou can find more detail about this use case [here](docs/multiple_input_single.md)\n\n### Input with multiple column in each row\n\n![Multiple columns example](./docs/images/multiple-column.gif?raw=true)\n\nFor example you keep some data in json format in attribute of model. Imagine that it is an abstract user schedule with keys: user_id, day, priority\n\nOn the edit page you want to be able to manage this schedule and you can you yii2-multiple-input widget like in the following code\n\n```php\nuse unclead\\widgets\\MultipleInput;\n\n...\n\n\u003c?= $form-\u003efield($model, 'schedule')-\u003ewidget(MultipleInput::className(), [\n    'limit' =\u003e 4,\n    'columns' =\u003e [\n        [\n            'name'  =\u003e 'user_id',\n            'type'  =\u003e 'dropDownList',\n            'title' =\u003e 'User',\n            'defaultValue' =\u003e 1,\n            'items' =\u003e [\n                1 =\u003e 'User 1',\n                2 =\u003e 'User 2'\n            ]\n        ],\n        [\n            'name'  =\u003e 'day',\n            'type'  =\u003e \\kartik\\date\\DatePicker::className(),\n            'title' =\u003e 'Day',\n            'value' =\u003e function($data) {\n                return $data['day'];\n            },\n            'items' =\u003e [\n                '0' =\u003e 'Saturday',\n                '1' =\u003e 'Monday'\n            ],\n            'options' =\u003e [\n                'pluginOptions' =\u003e [\n                    'format' =\u003e 'dd.mm.yyyy',\n                    'todayHighlight' =\u003e true\n                ]\n            ],\n            'headerOptions' =\u003e [\n                'style' =\u003e 'width: 250px;',\n                'class' =\u003e 'day-css-class'\n            ]\n        ],\n        [\n            'name'  =\u003e 'priority',\n            'enableError' =\u003e true,\n            'title' =\u003e 'Priority',\n            'options' =\u003e [\n                'class' =\u003e 'input-priority'\n            ]\n        ],\n        [\n            'name'  =\u003e 'comment',\n            'type'  =\u003e 'static',\n            'value' =\u003e function($data) {\n                return Html::tag('span', 'static content', ['class' =\u003e 'label label-info']);\n            },\n            'headerOptions' =\u003e [\n                'style' =\u003e 'width: 70px;',\n            ]\n        ]\n    ]\n ]);\n?\u003e\n```\n\nYou can find more detail about this use case [here](docs/multiple_input_multiple.md)\n\n### Tabular input\n\nFor example you want to manage some models via tabular input. In this case you can use `TabularInput` widget which is based on `MultipleInput` widget.\nUse the following code for this purpose:\n\n```php\n\u003c?= TabularInput::widget([\n    'models' =\u003e $models,\n    'attributeOptions' =\u003e [\n        'enableAjaxValidation'      =\u003e true,\n        'enableClientValidation'    =\u003e false,\n        'validateOnChange'          =\u003e false,\n        'validateOnSubmit'          =\u003e true,\n        'validateOnBlur'            =\u003e false,\n    ],\n    'columns' =\u003e [\n        [\n            'name'  =\u003e 'title',\n            'title' =\u003e 'Title',\n            'type'  =\u003e TabularInputColumn::TYPE_TEXT_INPUT,\n        ],\n        [\n            'name'  =\u003e 'description',\n            'title' =\u003e 'Description',\n        ],\n        [\n            'name'  =\u003e 'file',\n            'title' =\u003e 'File',\n            'type'  =\u003e \\vova07\\fileapi\\Widget::className(),\n            'options' =\u003e [\n                'settings' =\u003e [\n                    'url' =\u003e ['site/fileapi-upload']\n                ]\n            ]\n        ],\n        [\n            'name'  =\u003e 'date',\n            'type'  =\u003e \\kartik\\date\\DatePicker::className(),\n            'title' =\u003e 'Day',\n            'options' =\u003e [\n                'pluginOptions' =\u003e [\n                    'format' =\u003e 'dd.mm.yyyy',\n                    'todayHighlight' =\u003e true\n                ]\n            ],\n            'headerOptions' =\u003e [\n                'style' =\u003e 'width: 250px;',\n                'class' =\u003e 'day-css-class'\n            ]\n        ],\n    ],\n]) ?\u003e\n```\n\nYou can find more detail about this use case [here](docs/tabular_input.md)\n\n\u003e Also you can find source code of examples [here](./docs/examples/)\n\n\n\n## Tips and tricks\n\n### How to customize buttons\n\nYou can customize `add` and `remove` buttons via `addButtonOptions` and `removeButtonOptions`. Here is the simple example\nhow you can use those options:\n\n```php\n\n    echo $form-\u003efield($model, 'emails')-\u003ewidget(MultipleInput::className(), [\n        'limit' =\u003e 5,\n        'addButtonOptions' =\u003e [\n            'class' =\u003e 'btn btn-success',\n            'label' =\u003e 'add' // also you can use html code\n        ],\n        'removeButtonOptions' =\u003e [\n            'label' =\u003e 'remove'\n        ]\n    ])\n    -\u003elabel(false);\n\n```\n\n### Work with empty list\n\nIn some cases you need to have the ability to delete all rows in the list. For this purpose you can use option `allowEmptyList` like in the example below:\n\n```php\n\n    echo $form-\u003efield($model, 'emails')-\u003ewidget(MultipleInput::className(), [\n        'limit' =\u003e 5,\n        'allowEmptyList' =\u003e true\n    ])\n    -\u003elabel(false);\n\n```\n\nAlso you can set `0` in `min` option if you don't need first blank row when data is empty.\n\n### Guess column title\n\nSometimes you can use the widget without defining columns but you want to have the column header of the table.\nIn this case you can use `enableGuessTitle` option like in the example below:\n\n```php\n\n    echo $form-\u003efield($model, 'emails')-\u003ewidget(MultipleInput::className(), [\n        'limit' =\u003e 5,\n        'allowEmptyList' =\u003e true,\n        'enableGuessTitle' =\u003e true\n    ])\n    -\u003elabel(false);\n\n```\n\n### Ajax loading of a widget \u003ca id=\"ajax-loading\"\u003e\u003c/a\u003e\n\nAssume you want to load a widget via ajax and then show it inside modal window. In this case you MUST:\n\n- Ensure that you specified ID of widget otherwise the widget will get random ID and it can be the same as id of others elements on the page.\n- Ensure that you use the widget inside ActiveForm because it works incorrectly in this case.\n\nYou can fina an example of usage in a discussion of [issue](https://github.com/unclead/yii2-multiple-input/issues/58)\n\n### Use of a widget's placeholder \u003ca id=\"using-placeholder\"\u003e\u003c/a\u003e\n\nYou can use a placeholder `{multiple index}` in a widget configuration, e.g. for implementation of dependent drop down lists.\n\n```php\n    \u003c?= $form-\u003efield($model, 'field')-\u003ewidget(MultipleInput::className(), [\n            'allowEmptyList' =\u003e false,\n            'rowOptions' =\u003e [\n                'id' =\u003e 'row{multiple_index}',\n            ],\n            'columns' =\u003e [\n                [\n                    'name'  =\u003e 'category',\n                    'type'  =\u003e 'dropDownList',\n                    'title' =\u003e 'Category',\n                    'defaultValue' =\u003e '1',\n                    'items' =\u003e [\n                        '1' =\u003e 'Test 1',\n                        '2' =\u003e 'Test 2',\n                        '3' =\u003e 'Test 3',\n                        '4' =\u003e 'Test 4',\n                    ],\n                    'options' =\u003e [\n                        'onchange' =\u003e \u003c\u003c\u003c JS\n$.post(\"list?id=\" + $(this).val(), function(data){\n    console.log(data);\n    $(\"select#subcat-{multiple_index}\").html(data);\n});\nJS\n                    ],\n                ],\n                [\n                    'name'  =\u003e 'subcategory',\n                    'type'  =\u003e 'dropDownList',\n                    'title' =\u003e 'Subcategory',\n                    'items' =\u003e [],\n                    'options'=\u003e [\n                        'id' =\u003e 'subcat-{multiple_index}'\n                    ],\n                ],\n            ]\n    ]);\n    ?\u003e\n```\n\n### Custom index of the row \u003ca id=\"custom-index\"\u003e\u003c/a\u003e\n\nAssume that you want to set specific index for each row. In this case you can pass the `data` attribute as associative array\nas in the example below:\n\n```php\n    \u003c?= $form-\u003efield($model, 'field')-\u003ewidget(MultipleInput::className(), [\n            'allowEmptyList' =\u003e false,\n            'data' =\u003e [\n                3 =\u003e [\n                    'day'       =\u003e '27.02.2015',\n                    'user_id'   =\u003e 31,\n                    'priority'  =\u003e 1,\n                    'enable'    =\u003e 1\n                ],\n\n                'some-key' =\u003e [\n                    'day'       =\u003e '27.02.2015',\n                    'user_id'   =\u003e 33,\n                    'priority'  =\u003e 2,\n                    'enable'    =\u003e 0\n                ],\n            ]\n\n    ...\n\n```\n\n\n## JavaScript events\nThis widget has following events:\n - `afterInit`: triggered after initialization\n - `afterAddRow`: triggered after new row insertion\n - `beforeDeleteRow`: triggered before the row removal\n - `afterDeleteRow`: triggered after the row removal\n\nExample:\n```js\njQuery('#multiple-input').on('afterInit', function(){\n    console.log('calls on after initialization event');\n}).on('beforeAddRow', function(e) {\n    console.log('calls on before add row event');\n}).on('afterAddRow', function(e) {\n    console.log('calls on after add row event');\n}).on('beforeDeleteRow', function(e, row){\n    // row - HTML container of the current row for removal. \n    // For TableRenderer it is tr.multiple-input-list__item\n    console.log('calls on before remove row event.');\n    return confirm('Are you sure you want to delete row?')\n}).on('afterDeleteRow', function(){\n    console.log('calls on after remove row event');\n});\n```\n\n## JavaScript operations\nDynamically operations in widget:\n - `add`: adding new row, **param** *object*: object with values for inputs, can be filled with \u003coption\u003e tags for dynamically added options for select (for ajax select).\n - `remove`: remove row, **param** *integer*: row number for removing, if not specified then removes last row.\n - `clear`: remove all rows\n\nExamples:\n```js\n$('#multiple-input').multipleInput('add', {first: 10, second: '\u003coption value=\"2\" selected=\"selected\"\u003esecond\u003c/option\u003e'});\n$('#multiple-input').multipleInput('remove', 2);\n$('#multiple-input').multipleInput('clear');\n```\n\n##Renderers\n\n\u003e Section is under development\n\nCurrently widget supports only `TableRenderer` which renders content in table format.\n\n##License\n\n**yii2-multiple-input** is released under the BSD 3-Clause License. See the bundled [LICENSE.md](./LICENSE.md) for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faccessd%2Fyii2-multiple-input","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faccessd%2Fyii2-multiple-input","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faccessd%2Fyii2-multiple-input/lists"}