{"id":15040456,"url":"https://github.com/wavevision/dependent-selectbox","last_synced_at":"2025-10-04T05:30:57.981Z","repository":{"id":37549152,"uuid":"213659368","full_name":"wavevision/dependent-selectbox","owner":"wavevision","description":"🔗 Dependent select box component for @nette forms","archived":true,"fork":false,"pushed_at":"2023-01-07T10:29:36.000Z","size":4095,"stargazers_count":3,"open_issues_count":18,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-01-14T15:10:54.344Z","etag":null,"topics":["dependent-selects","forms","naja","nette","nette-forms","selectbox"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/wavevision.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-10-08T14:05:37.000Z","updated_at":"2024-07-28T14:26:58.000Z","dependencies_parsed_at":"2023-02-06T22:20:18.855Z","dependency_job_id":null,"html_url":"https://github.com/wavevision/dependent-selectbox","commit_stats":null,"previous_names":[],"tags_count":42,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wavevision%2Fdependent-selectbox","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wavevision%2Fdependent-selectbox/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wavevision%2Fdependent-selectbox/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wavevision%2Fdependent-selectbox/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/wavevision","download_url":"https://codeload.github.com/wavevision/dependent-selectbox/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":235222539,"owners_count":18955327,"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":["dependent-selects","forms","naja","nette","nette-forms","selectbox"],"created_at":"2024-09-24T20:44:38.036Z","updated_at":"2025-10-04T05:30:52.622Z","avatar_url":"https://github.com/wavevision.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\u003ca href=\"https://github.com/wavevision\"\u003e\u003cimg alt=\"Wavevision s.r.o.\" src=\"https://wavevision.com/images/wavevision-logo.png\" width=\"120\" /\u003e\u003c/a\u003e\u003c/p\u003e\n\u003ch1 align=\"center\"\u003eDependent SelectBox\u003c/h1\u003e\n\n[![CI](https://github.com/wavevision/dependent-selectbox/workflows/CI/badge.svg)](https://github.com/wavevision/dependent-selectbox/actions/workflows/ci.yml)\n[![Coverage Status](https://coveralls.io/repos/github/wavevision/dependent-selectbox/badge.svg?branch=master\u0026service=github)](https://coveralls.io/github/wavevision/dependent-selectbox?branch=master)\n[![PHPStan](https://img.shields.io/badge/style-level%20max-brightgreen.svg?label=phpstan)](https://github.com/phpstan/phpstan)\n[![Nette Forms](https://img.shields.io/badge/nette/forms-3.1-blue)](https://github.com/nette/forms)\n[![Naja](https://img.shields.io/badge/naja-2.1-blue)](https://github.com/jiripudil/Naja)\n\nDependent select box component for [nette/forms](https://github.com/nette/forms) with [naja](https://github.com/jiripudil/Naja) extension on client side.\n\n## Features:\n\n- strict typed\n- works on any form without customizing its renderer (no need for snippets)\n- supports form containers (unlimited depth, both for select box itself and its parents)\n- TypeScript and Naja powered client side with events emitted so you can attach listeners to them\n- conditional parents (make a form control become a select box's parent when some other control has a certain value)\n\n## Installation\n\nUse [Composer](http://getcomposer.org) to get the Nette forms component\n\n```bash\ncomposer require wavevision/dependent-selectbox\n```\n\nInstall the client side via [Yarn](https://yarnpkg.com)\n\n```bash\nyarn add @wavevision/dependent-selectbox\n```\n\nor [npm](https://npmjs.com)\n\n```bash\nnpm install --save @wavevision/dependent-selectbox\n```\n\n## Usage\n\n### Server side\n\nCreate a form that will be an instance of `Wavevision\\DependentSelectBox\\Form\\Form`.\n\nIf you don't want to / cannot inherit from our base form, just make sure the form you create uses\n`Wavevision\\DependentSelectBox\\Form\\DependentForm` trait.\n\nYour form should also use `Wavevision\\DependentSelectBox\\Form\\DependentContainer` to have its containers extended with\nthe dependent select box too, however, if you already have your own implementation of `Nette\\Forms\\Container`,\njust make sure the container uses `Wavevision\\DependentSelectBox\\Form\\DependentControl` trait.\n\nAfter this, your form and its containers will be extended with `addDependentSelectBox` method. This method accepts following arguments:\n\n| **Argument**  | **Type**                             | **Description**                                                                                |\n| ------------- | ------------------------------------ | ---------------------------------------------------------------------------------------------- |\n| `$name`       | `string`                             | name of the control                                                                            |\n| `$label`      | `string`                             | label for the control                                                                          |\n| `...$parents` | `Nette\\Forms\\Controls\\BaseControl[]` | list of form controls whom's values will be treated as parent values to get the dependent data |\n\nThe method returns an instance of [`Wavevision\\DependentSelectBox\\DependentSelectBox`](./src/DependentSelectBox/DependentSelectBox.php).\n\n#### The recommended way of using the form is in a `Control` component.\n\n```php\nuse Nette\\Application\\UI\\Control;\nuse Nette\\Application\\UI\\Presenter;\nuse Wavevision\\DependentSelectBox\\DependentComponent;\nuse Wavevision\\DependentSelectBox\\DependentData;\nuse Wavevision\\DependentSelectBox\\DependentValues;\nuse Wavevision\\DependentSelectBox\\Form\\Form;\n\nclass FormComponent extends Control\n{\n\n    // add 'loadDependenData' signal and a few utilities\n    use DependentComponent;\n\n    public function __construct()\n    {\n        $this-\u003emonitor(Presenter::class, function (): void {\n            // setup form in component - optionally pass form name (default 'form')\n            $this-\u003edependentComponentSetup();\n            if ($this-\u003ehasReceivedDependentSignal()) {\n                // if 'loadDependenData' signal received, do anything extra we need\n            }\n        });\n    }\n\n    protected function createComponentForm(): Form\n    {\n        // create your form as you are used to\n        $form-\u003eaddDependentSelectBox('name', 'Label', $form['someParentControl'])\n            -\u003esetDependentCallback(function (DependentValues $values): DependentData {\n                // get ArrayHash values, if you perfer array, use getRawValues\n                $formattedValues = $values-\u003egetValues();\n                $data = new DependentData();\n                if ($formattedValues-\u003esomeParentControl === 'someDependentValue') {\n                    $data-\u003esetItems(['firstItem' =\u003e 'firstValue']);\n                }\n                return $data;\n            })\n            // make the select box disabled when no values have been loaded\n            -\u003esetDisabledWhenEmpty()\n            // if loaded values contain only one item, select it so the user does not have to\n            -\u003esetAutoSelectSingleValue()\n            // if 'someOtherControl' has 'someValue', treat 'someControl' as parent\n            -\u003eaddConditionalParent($form['someControl'], $form['someOtherControl'], 'someValue');\n        // add form handlers etc.\n        return $form;\n    }\n}\n```\n\n\u003e **NOTE**: You can use the form in a `Presenter` too, the only limitation is that you can only have one dependent form per page like this.\n\u003e If you wrap your form in a component (each using `DependentComponent` trait), you can then use as many forms on one page as you wish.\n\n### Client side\n\nThere are a few ways of integrating the client side into your project.\n\n#### 1. Register dependent select box as Naja extension\n\n```typescript\nimport naja from 'naja';\nimport DependentSelectBox from '@wavevision/dependent-selectbox';\n\nnaja.registerExtension(new DependentSelectBox());\n// add other extensions, initialize etc.\n```\n\nAs mentioned in features, the extension emits events you can attach listeners to.\n\n| Event                       | Description                                                                    |\n| --------------------------- | ------------------------------------------------------------------------------ |\n| `dependentSelectBoxLoading` | fires right after a parent changes and a request to server is being dispatched |\n| `dependentSelectBoxLoaded`  | fires when the data loading is finished                                        |\n\nListeners for both events will receive a `CustomEvent` object containing `detail` with these properties:\n\n| Property               | Type                  | Description                                        |\n| ---------------------- | --------------------- | -------------------------------------------------- |\n| `form`                 | `HTMLFormElement`     | the form in which the event has been triggered     |\n| `dependentSelectBoxes` | `HTMLSelectElement[]` | an array of all dependent select boxes in the form |\n\nThe first event also contains `request` property, which is an object containing:\n\n| Property  | Type                                                                   | Description                                                                                                         |\n| --------- | ---------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |\n| `trigger` | `string`                                                               | HTML `id` of a parent that triggered the request                                                                    |\n| `values`  | \u003ccode\u003e[ParentsValues](./src/assets/DependentSelectBox/types.ts)\u003c/code\u003e | object with current values of parents and filled select boxes (HTML `name` properties of elements are used as keys) |\n\nThe latter one contains `response` object, in which keys are HTML `id` attributes of updated select boxes\nand values are objects with:\n\n| Property   | Type      | Description                  |\n| ---------- | --------- | ---------------------------- |\n| `disabled` | `boolean` | select box state             |\n| `items`    | `string`  | inner HTML of the select box |\n\nPlease, refer to [Naja docs](https://naja.js.org) to find out more about its extensions.\n\n#### 2. Import bundled version with Naja included\n\nIf you don't use Naja elsewhere in your project an you don't want to set it up, this is your way to go.\n\n⚠️ **WARNING:** This might collide with other Nette AJAX libraries, if used!\n\n```typescript\nimport '@wavevision/dependent-selectbox/dist/dependentSelectBox.all';\n```\n\n#### 3. Use it directly in a `script` tag\n\nFor old-school people only 😎.\n\n```html\n\u003cscript src=\"/path/to/assets/dependentSelectBox.all.js\"\u003e\u003c/script\u003e\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwavevision%2Fdependent-selectbox","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwavevision%2Fdependent-selectbox","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwavevision%2Fdependent-selectbox/lists"}