From 7664cbe176a776c8fc2720dd69f853ef4a593025 Mon Sep 17 00:00:00 2001 From: barton Date: Fri, 26 Oct 2018 18:08:03 +0200 Subject: [PATCH] README & composer.json --- README.md | 227 +++++++++++++++++++++++++++++++++++++++++------ composer.json | 55 +++--------- docs/en/index.md | 222 --------------------------------------------- 3 files changed, 215 insertions(+), 289 deletions(-) mode change 100755 => 100644 README.md delete mode 100644 docs/en/index.md diff --git a/README.md b/README.md old mode 100755 new mode 100644 index fc2ba0b..fae29a6 --- a/README.md +++ b/README.md @@ -1,47 +1,222 @@ -Kdyby/FormsReplicator -====== +Quickstart +========== -[![Build Status](https://travis-ci.org/Kdyby/FormsReplicator.svg?branch=master)](https://travis-ci.org/Kdyby/FormsReplicator) -[![Downloads this Month](https://img.shields.io/packagist/dm/kdyby/forms-replicator.svg)](https://packagist.org/packages/kdyby/forms-replicator) -[![Latest stable](https://img.shields.io/packagist/v/kdyby/forms-replicator.svg)](https://packagist.org/packages/kdyby/forms-replicator) -[![Coverage Status](https://coveralls.io/repos/github/Kdyby/FormsReplicator/badge.svg?branch=master)](https://coveralls.io/github/Kdyby/FormsReplicator?branch=master) -[![Join the chat at https://gitter.im/Kdyby/Help](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/Kdyby/Help) +Nette forms container replicator aka `addDynamic`. -Save me please! ---------------- -The maintainer of this project has no more time to maintain it. It may even contain unfixed bugs :( +Installation +------------ -If you need something like this and you're willing to join in, you're welcome to take over this project. +The best way to install webwings/form-replicator is using [Composer](http://getcomposer.org/): -![help](https://cdn.kdyby.org/keyboard-help.png) +```php +$ composer require webwings/forms-replicator +``` +Now you have to enable the extension using your neon config -Requirements ------------- +```yml +extensions: + replicator: Webwings\Replicator\DI\ReplicatorExtension +``` -Kdyby/FormsReplicator requires PHP 5.5 or higher. +Or place the Replicator class to folder, where it is autoloaded and add following line to `boostrap.php` or to `BasePresenter::startup()`. -- [Nette Framework](https://github.com/nette/nette) +```php +Webwings\Replicator\Container::register(); +``` -Installation ------------- +Attaching to form +----------------- -The best way to install Kdyby/FormsReplicator is using [Composer](http://getcomposer.org/): +It can be used for simple things, for example list of dates -```sh -$ composer require kdyby/forms-replicator:~1.1 +```php +use Nette\Forms\Container; + +$form->addDynamic('dates', function (Container $container) { + $container->addDate('date'); +}); +``` + +Or complex combinations, for example users and their addresses + +```php +$form->addDynamic('users', function (Container $user) { + $user->addText('name', 'Name'); + $user->addText('surname', 'surbame'); + $user->addDynamic('addresses', function (Container $address) { + $address->addText('street', 'Street'); + $address->addText('city', 'City'); + $address->addText('zip', 'Zip'); + // ... + }, 1); + // ... +}, 2); ``` +There has been little misunderstanding, that when form is submitted, and new container is created, that replicator automatically adds default containers. I was not sure if this is the correct behaviour so I've added new options `$forceDefault` in [a934a07](https://github.com/Kdyby/Replicator/blob/master/src/Kdyby/Replicator/Container.php#L62) that won't let you have less than default count of containers in replicator. -Documentation ------------- -Learn more in the [documentation](https://github.com/Kdyby/FormsReplicator/blob/master/docs/en/index.md). +Handling +-------- + +Handling is trivial, you just walk the values from user in cycle. + +```php +use Nette\Application\UI\Form; + +public function FormSubmitted(Form $form) +{ + foreach ($form['users']->values as $user) { // values from replicator + dump($user['name'] . ' ' . $user['surname']); + + foreach ($user['addresses'] as $address) { // working with values from container + dump($address['city']); + } + } +} +``` + +[WARNING] +Replicator is not suitable for handling file uploads. If you do not have detailed knowledge, how the forms work, and don't need Replicator's functionality specifically, consider using a [Multiple File Upload](http://addons.nette.org/jkuchar/multiplefileupload) component instead. + + +Editation of items +------------------ + +You can use names of nested containers as identifiers. From the nature of form containers, you can work with them like this: + +```php +public function actionEditUsers() +{ + $form = $this['myForm']; + if (!$form->isSubmitted()) { // if form was not submitted + // expects instance of model class in presenter + $users = $this->model->findAll(); + foreach ($users as $user) { + $form['users'][$user->id]->setDefaults($user); + // fill the container with default values + } + } +} +``` + +And modify the handling + +```php +public function FormSubmitted(Form $form) +{ + foreach ($form['users']->values as $userId => $user) { + // now we have asscesible ID of the user and associated values from the container + } +} +``` + + +Adding and removing of containers +--------------------------------- + +There is an example in sandbox, where every container has button to be deleted and at the end is button for adding new one + +```php +protected function createComponentMyForm() +{ + $form = new Nette\Application\UI\Form; + $removeEvent = callback($this, 'MyFormRemoveElementClicked'); ------ + // name, factory, default count + $users = $form->addDynamic('users', function (Container $user) use ($removeEvent) { + // ... + $user->addSubmit('remove', 'Remove') + ->setValidationScope(FALSE) # disables validation + ->onClick[] = $removeEvent; + }, 1); -Homepage [http://www.kdyby.org](http://www.kdyby.org) and repository [http://github.com/kdyby/FormsReplicator](http://github.com/kdyby/FormsReplicator). + $users->addSubmit('add', 'Add next person') + ->setValidationScope(FALSE) + ->onClick[] = callback($this, 'MyFormAddElementClicked'); + + // ... +} +``` + +Handling of add button is easy. Next example is useful, when you expect that your users like to prepare more containers before they fill and submit them. + +```php +use Nette\Forms\Controls\SubmitButton; + +public function MyFormAddElementClicked(SubmitButton $button) +{ + $button->parent->createOne(); +} +``` + +When you want to allow adding only one container each time, so there will be no more than one unfilled at time, you would have to check for values manualy, or with helper function. + +```php +public function MyFormAddElementClicked(SubmitButton $button) +{ + $users = $button->parent; + + // count how many containers were filled + if ($users->isAllFilled()) { + // add one container to replicator + $button->parent->createOne(); + } +} +``` + +Method `Replicator::isAllFilled()` checks, if the form controls are not empty. It's argument says which ones not to check. + +When the user clicks to delete, the following event will be invoked + +```php +public function MyFormRemoveElementClicked(SubmitButton $button) +{ + // first parent is container + // second parent is it's replicator + $users = $button->parent->parent; + $users->remove($button->parent, TRUE); +} +``` + +If I'd want to for example delete user also from database and I have container names as identifiers, then I can read the value like this: + +```php +public function MyFormRemoveElementClicked(SubmitButton $button) +{ + $id = $button->parent->name; +} +``` + + +Manual rendering +---------------- + +When you add a submit button to replicator, you certainly don't want to try it render as container, so for skipping them, there is a method `getContainers()`, that will return only existing [containers](doc:/en/forms#toc-addcontainer). + +```html +{form myForm} +{foreach $form['users']->getContainers() as $user} + + {$user['name']->control} {$user['name']->label} + +{/foreach} +{/form} +``` + +Or with form macros + +```html +{form myForm} +{foreach $form['users']->getContainers() as $id => $user} + + {input users-$id-name} {label users-$id-name /} + +{/foreach} +{/form} +``` diff --git a/composer.json b/composer.json index 819bbea..f4bac59 100644 --- a/composer.json +++ b/composer.json @@ -1,58 +1,31 @@ { "name": "kdyby/forms-replicator", "type": "library", - "description": "Nette forms container replicator aka addDynamic", + "description": "Nette forms container replicator aka addDynamic, based on kdyby/form-replicator", "keywords": ["nette", "kdyby", "forms", "replicator", "addDynamic"], - "homepage": "http://kdyby.org", + "homepage": "https://webwings.cz", "license": ["BSD-3-Clause", "GPL-2.0", "GPL-3.0"], "authors": [ { "name": "Filip Procházka", "homepage": "http://filip-prochazka.com", "email": "filip@prochazka.su" + }, + { + "name": "Webwings", + "homepage": "https://webwings.cz", + "email": "info@webwings.eu" } ], - "support": { - "email": "filip@prochazka.su", - "issues": "https://github.com/kdyby/replicator/issues" - }, "require": { - "nette/forms": "~2.4@dev" - }, - "require-dev": { - "php": ">=5.6", - "nette/application": "~2.4@dev", - "nette/bootstrap": "~2.4@dev", - "nette/caching": "~2.4@dev", - "nette/component-model": "~2.2@dev", - "nette/database": "~2.4@dev", - "nette/deprecated": "~2.4@dev", - "nette/di": "~2.4@dev", - "nette/finder": "~2.4@dev", - "nette/forms": "~2.4@dev", - "nette/http": "~2.4@dev", - "nette/mail": "~2.4@dev", - "nette/neon": "~2.4@dev", - "nette/php-generator": "~2.4@dev", - "nette/reflection": "~2.4@dev", - "nette/robot-loader": "~2.4@dev", - "nette/safe-stream": "~2.3@dev", - "nette/security": "~2.4@dev", - "nette/tokenizer": "~2.2@dev", - "nette/utils": "~2.4@dev", - "latte/latte": "~2.4@dev", - "tracy/tracy": "~2.4@dev", - - "nette/tester": "~1.7" + "php": ">= 7.1", + "nette/forms": "^2.4", + "nette/utils": "^2.4" }, + "suggest": { + "nette/di": "^2.4" + }, "autoload": { - "psr-0": { - "Kdyby\\Replicator\\": "src/" - } - }, - "extra": { - "branch-alias": { - "dev-master": "1.2-dev" - } + "classmap": ["/src"] } } diff --git a/docs/en/index.md b/docs/en/index.md deleted file mode 100644 index ba202dc..0000000 --- a/docs/en/index.md +++ /dev/null @@ -1,222 +0,0 @@ -Quickstart -========== - -Nette forms container replicator aka `addDynamic`. - - - -Installation ------------- - -The best way to install Kdyby/Replicator is using [Composer](http://getcomposer.org/): - -```php -$ composer require kdyby/forms-replicator:@dev -``` - -Now you have to enable the extension using your neon config - -```yml -extensions: - replicator: Kdyby\Replicator\DI\ReplicatorExtension -``` - -Or place the Replicator class to folder, where RobotLoader can find it and add following line to `app/boostrap.php` or to `BasePresenter::startup()`. - -```php -Kdyby\Replicator\Container::register(); -``` - - -Attaching to form ------------------ - -It can be used for simple things, for example list of dates - -```php -use Nette\Forms\Container; - -$form->addDynamic('dates', function (Container $container) { - $container->addDate('date'); -}); -``` - -Or complex combinations, for example users and their addresses - -```php -$form->addDynamic('users', function (Container $user) { - $user->addText('name', 'Name'); - $user->addText('surname', 'surbame'); - $user->addDynamic('addresses', function (Container $address) { - $address->addText('street', 'Street'); - $address->addText('city', 'City'); - $address->addText('zip', 'Zip'); - // ... - }, 1); - // ... -}, 2); -``` - -There has been little misunderstanding, that when form is submitted, and new container is created, that replicator automatically adds default containers. I was not sure if this is the correct behaviour so I've added new options `$forceDefault` in [a934a07](https://github.com/Kdyby/Replicator/blob/master/src/Kdyby/Replicator/Container.php#L62) that won't let you have less than default count of containers in replicator. - - -Handling --------- - -Handling is trivial, you just walk the values from user in cycle. - -```php -use Nette\Application\UI\Form; - -public function FormSubmitted(Form $form) -{ - foreach ($form['users']->values as $user) { // values from replicator - dump($user['name'] . ' ' . $user['surname']); - - foreach ($user['addresses'] as $address) { // working with values from container - dump($address['city']); - } - } -} -``` - -[WARNING] -Replicator is not suitable for handling file uploads. If you do not have detailed knowledge, how the forms work, and don't need Replicator's functionality specifically, consider using a [Multiple File Upload](http://addons.nette.org/jkuchar/multiplefileupload) component instead. - - -Editation of items ------------------- - -You can use names of nested containers as identifiers. From the nature of form containers, you can work with them like this: - -```php -public function actionEditUsers() -{ - $form = $this['myForm']; - if (!$form->isSubmitted()) { // if form was not submitted - // expects instance of model class in presenter - $users = $this->model->findAll(); - foreach ($users as $user) { - $form['users'][$user->id]->setDefaults($user); - // fill the container with default values - } - } -} -``` - -And modify the handling - -```php -public function FormSubmitted(Form $form) -{ - foreach ($form['users']->values as $userId => $user) { - // now we have asscesible ID of the user and associated values from the container - } -} -``` - - -Adding and removing of containers ---------------------------------- - -There is an example in sandbox, where every container has button to be deleted and at the end is button for adding new one - -```php -protected function createComponentMyForm() -{ - $form = new Nette\Application\UI\Form; - - $removeEvent = callback($this, 'MyFormRemoveElementClicked'); - - // name, factory, default count - $users = $form->addDynamic('users', function (Container $user) use ($removeEvent) { - // ... - $user->addSubmit('remove', 'Remove') - ->setValidationScope(FALSE) # disables validation - ->onClick[] = $removeEvent; - }, 1); - - $users->addSubmit('add', 'Add next person') - ->setValidationScope(FALSE) - ->onClick[] = callback($this, 'MyFormAddElementClicked'); - - // ... -} -``` - -Handling of add button is easy. Next example is useful, when you expect that your users like to prepare more containers before they fill and submit them. - -```php -use Nette\Forms\Controls\SubmitButton; - -public function MyFormAddElementClicked(SubmitButton $button) -{ - $button->parent->createOne(); -} -``` - -When you want to allow adding only one container each time, so there will be no more than one unfilled at time, you would have to check for values manualy, or with helper function. - -```php -public function MyFormAddElementClicked(SubmitButton $button) -{ - $users = $button->parent; - - // count how many containers were filled - if ($users->isAllFilled()) { - // add one container to replicator - $button->parent->createOne(); - } -} -``` - -Method `Replicator::isAllFilled()` checks, if the form controls are not empty. It's argument says which ones not to check. - -When the user clicks to delete, the following event will be invoked - -```php -public function MyFormRemoveElementClicked(SubmitButton $button) -{ - // first parent is container - // second parent is it's replicator - $users = $button->parent->parent; - $users->remove($button->parent, TRUE); -} -``` - -If I'd want to for example delete user also from database and I have container names as identifiers, then I can read the value like this: - -```php -public function MyFormRemoveElementClicked(SubmitButton $button) -{ - $id = $button->parent->name; -} -``` - - -Manual rendering ----------------- - -When you add a submit button to replicator, you certainly don't want to try it render as container, so for skipping them, there is a method `getContainers()`, that will return only existing [containers](doc:/en/forms#toc-addcontainer). - -```html -{form myForm} -{foreach $form['users']->getContainers() as $user} - - {$user['name']->control} {$user['name']->label} - -{/foreach} -{/form} -``` - -Or with form macros - -```html -{form myForm} -{foreach $form['users']->getContainers() as $id => $user} - - {input users-$id-name} {label users-$id-name /} - -{/foreach} -{/form} -```