1: <?php
2:
3: /**
4: * This file is part of the Nette Framework (https://nette.org)
5: * Copyright (c) 2004 David Grudl (https://davidgrudl.com)
6: */
7:
8: namespace Nette\Forms\Controls;
9:
10: use Nette;
11:
12:
13: /**
14: * Submittable button control.
15: *
16: * @property-read bool $submittedBy
17: */
18: class SubmitButton extends Button implements Nette\Forms\ISubmitterControl
19: {
20: /** @var callable[] function (SubmitButton $sender); Occurs when the button is clicked and form is successfully validated */
21: public $onClick;
22:
23: /** @var callable[] function (SubmitButton $sender); Occurs when the button is clicked and form is not validated */
24: public $onInvalidClick;
25:
26: /** @var array|null */
27: private $validationScope;
28:
29:
30: /**
31: * @param string|object
32: */
33: public function __construct($caption = null)
34: {
35: parent::__construct($caption);
36: $this->control->type = 'submit';
37: $this->setOmitted(true);
38: }
39:
40:
41: /**
42: * Loads HTTP data.
43: * @return void
44: */
45: public function loadHttpData()
46: {
47: parent::loadHttpData();
48: if ($this->isFilled()) {
49: $this->getForm()->setSubmittedBy($this);
50: }
51: }
52:
53:
54: /**
55: * Tells if the form was submitted by this button.
56: * @return bool
57: */
58: public function isSubmittedBy()
59: {
60: return $this->getForm()->isSubmitted() === $this;
61: }
62:
63:
64: /**
65: * Sets the validation scope. Clicking the button validates only the controls within the specified scope.
66: * @return static
67: */
68: public function setValidationScope(/*array*/$scope = null)
69: {
70: if ($scope === null || $scope === true) {
71: $this->validationScope = null;
72: } else {
73: $this->validationScope = [];
74: foreach ($scope ?: [] as $control) {
75: if (!$control instanceof Nette\Forms\Container && !$control instanceof Nette\Forms\IControl) {
76: throw new Nette\InvalidArgumentException('Validation scope accepts only Nette\Forms\Container or Nette\Forms\IControl instances.');
77: }
78: $this->validationScope[] = $control;
79: }
80: }
81: return $this;
82: }
83:
84:
85: /**
86: * Gets the validation scope.
87: * @return array|null
88: */
89: public function getValidationScope()
90: {
91: return $this->validationScope;
92: }
93:
94:
95: /**
96: * Fires click event.
97: * @return void
98: */
99: public function click()
100: {
101: $this->onClick($this);
102: }
103:
104:
105: /**
106: * Generates control's HTML element.
107: * @param string|object
108: * @return Nette\Utils\Html
109: */
110: public function getControl($caption = null)
111: {
112: $scope = [];
113: foreach ((array) $this->validationScope as $control) {
114: $scope[] = $control->lookupPath(Nette\Forms\Form::class);
115: }
116: return parent::getControl($caption)->addAttributes([
117: 'formnovalidate' => $this->validationScope !== null,
118: 'data-nette-validation-scope' => $scope ?: null,
119: ]);
120: }
121: }
122: