66
77use App \Components \CategoryEntry ;
88use App \Components \TeamForm ;
9- use App \Helpers \Iter ;
109use App \Model \Configuration \Entries ;
10+ use Contributte \FormMultiplier \Multiplier ;
1111use Contributte \Translation \Wrappers \Message ;
12- use Kdyby \Replicator \Container as ReplicatorContainer ;
1312use Nette ;
1413use Nette \Forms \Container ;
15- use Nette \Forms \Controls \ SubmitButton ;
14+ use Nette \Forms \Form ;
1615use Nette \Localization \Translator ;
1716use Nextras \FormComponents \Controls \DateControl ;
1817use Nextras \FormsRendering \Renderers \Bs5FormRenderer ;
@@ -54,6 +53,13 @@ public function create(
5453 // Handled in TeamPresenter::renderCreate.
5554 $ initialMembers = $ this ->entries ->minMembers ;
5655
56+ // Group for top submit button, since DefaultFormRenderer renders group before all ungrouped Controls.
57+ $ group = $ form ->addGroup ();
58+ $ group ->setOption ('container ' , 'div aria-hidden="true" class="visually-hidden" ' );
59+ // Browsers consider the first submit button a default submit button for use when submitting the form using Enter key.
60+ // Let’s add the save button to the top, to prevent the remove button of the first container from being picked.
61+ $ form ->addSubmit ('save_default_submit ' , 'messages.team.action.register ' )->getControlPrototype ()->setHtmlAttribute ('aria-hidden ' , 'true ' )->setHtmlAttribute ('tabindex ' , '-1 ' );
62+
5763 $ form ->addProtection ();
5864 $ form ->addGroup ('messages.team.info.label ' );
5965 $ form ->addText ('name ' , 'messages.team.name.label ' )->setRequired ();
@@ -77,20 +83,20 @@ public function create(
7783 $ rule ->addRule (function (CategoryEntry $ entry ) use ($ defaultMaxMembers ): bool {
7884 $ category = $ entry ->getValue ();
7985 $ maxMembers = $ this ->entries ->categories ->allCategories [$ category ]->maxMembers ?? $ defaultMaxMembers ;
80- /** @var ReplicatorContainer */
81- $ replicator = $ entry ->form ['persons ' ];
86+ /** @var Multiplier */ // For PHPStan.
87+ $ multiplier = $ entry ->form ['persons ' ];
8288
83- return iterator_count ( $ replicator -> getContainers () ) <= $ maxMembers ;
89+ return $ multiplier -> getCopyNumber ( ) <= $ maxMembers ;
8490 }, 'messages.team.error.too_many_members_simple ' ); // TODO: add params like in add/remove buttons
8591
8692 $ rule = $ category ->addCondition (true ); // not to block the export of rules to JS
8793 $ rule ->addRule (function (CategoryEntry $ entry ) use ($ defaultMinMembers ): bool {
8894 $ category = $ entry ->getValue ();
8995 $ minMembers = $ this ->entries ->categories ->allCategories [$ category ]->minMembers ?? $ defaultMinMembers ;
90- /** @var ReplicatorContainer */
91- $ replicator = $ entry ->form ['persons ' ];
96+ /** @var Multiplier */ // For PHPStan.
97+ $ multiplier = $ entry ->form ['persons ' ];
9298
93- return iterator_count ( $ replicator -> getContainers () ) >= $ minMembers ;
99+ return $ multiplier -> getCopyNumber ( ) >= $ minMembers ;
94100 }, 'messages.team.error.too_few_members_simple ' );
95101
96102 $ fields = $ this ->entries ->teamFields ;
@@ -99,36 +105,11 @@ public function create(
99105 $ form ->addTextArea ('message ' , 'messages.team.message.label ' );
100106
101107 $ form ->setCurrentGroup ();
102- $ form ->addSubmit ('save ' , $ isEditing ? 'messages.team.action.edit ' : 'messages.team.action.register ' );
103- $ form ->addSubmit ('add ' , 'messages.team.action.add ' )->setValidationScope ([])->onClick [] = function (SubmitButton $ button ) use ($ defaultMaxMembers ): void {
104- $ category = $ button ->form ->getUnsafeValues (null )['category ' ];
105- $ maxMembers = $ this ->entries ->categories ->allCategories [$ category ]->maxMembers ?? $ defaultMaxMembers ;
106- /** @var ReplicatorContainer */
107- $ replicator = $ button ->form ['persons ' ];
108- if (iterator_count ($ replicator ->getContainers ()) < $ maxMembers ) {
109- $ replicator ->createOne ();
110- } else {
111- $ button ->form ->addError ($ this ->translator ->translate ('messages.team.error.too_many_members ' , $ maxMembers , ['category ' => $ category ]), false );
112- }
113- };
114- $ form ->addSubmit ('remove ' , 'messages.team.action.remove ' )->setValidationScope ([])->onClick [] = function (SubmitButton $ button ) use ($ defaultMinMembers ): void {
115- $ category = $ button ->form ->getUnsafeValues (null )['category ' ];
116- $ minMembers = $ this ->entries ->categories ->allCategories [$ category ]->minMembers ?? $ defaultMinMembers ;
117- /** @var ReplicatorContainer */ // For PHPStan.
118- $ replicator = $ button ->form ['persons ' ];
119- if (iterator_count ($ replicator ->getContainers ()) > $ minMembers ) {
120- $ lastPerson = Iter::last ($ replicator ->getContainers ());
121- if ($ lastPerson !== null ) {
122- $ replicator ->remove ($ lastPerson , true );
123- }
124- } else {
125- $ button ->form ->addError ($ this ->translator ->translate ('messages.team.error.too_few_members ' , $ minMembers , ['category ' => $ category ]), false );
126- }
127- };
108+ $ renderer ->primaryButton = $ form ->addSubmit ('save ' , $ isEditing ? 'messages.team.action.edit ' : 'messages.team.action.register ' );
128109
129110 $ fields = $ this ->entries ->personFields ;
130111 $ i = 0 ;
131- $ form ->addDynamic ('persons ' , function (Container $ container ) use (&$ i , $ fields, $ form ): void {
112+ $ multiplier = $ form ->addMultiplier ('persons ' , function (Container $ container, TeamForm $ form ) use (&$ i , $ fields ): void {
132113 ++$ i ;
133114 $ group = $ form ->addGroup ();
134115 $ group ->setOption ('label ' , new Message ('messages.team.person.label ' , $ i ));
@@ -151,7 +132,22 @@ public function create(
151132 $ email ->setRequired ();
152133 $ group ->setOption ('description ' , 'messages.team.person.isContact ' );
153134 }
154- }, $ initialMembers , true );
135+ }, $ initialMembers , $ defaultMaxMembers );
136+ $ multiplier ->onCreateComponents [] = function (Multiplier $ multiplier ) use ($ form , $ defaultMaxMembers ): void {
137+ if (!$ form ->isSubmitted ()) {
138+ return ;
139+ }
140+
141+ $ category = $ form ->getUnsafeValues (null )['category ' ];
142+ $ maxMembers = $ this ->entries ->categories ->allCategories [$ category ]->maxMembers ?? $ defaultMaxMembers ;
143+ $ count = iterator_count ($ multiplier ->getContainers ());
144+ if ($ count >= $ maxMembers ) {
145+ $ form ->addError ($ this ->translator ->translate ('messages.team.error.too_many_members ' , $ maxMembers , ['category ' => $ category ]), false );
146+ }
147+ };
148+ $ multiplier ->setMinCopies ($ defaultMinMembers );
149+ $ multiplier ->addCreateButton ('messages.team.action.add ' )->setNoValidate ();
150+ $ multiplier ->addRemoveButton ('messages.team.action.remove ' );
155151
156152 return $ form ;
157153 }
0 commit comments