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: * @author David Grudl
17: *
18: * @property-read bool $submittedBy
19: */
20: class SubmitButton extends Button implements Nette\Forms\ISubmitterControl
21: {
22: /** @var callable[] function (SubmitButton $sender); Occurs when the button is clicked and form is successfully validated */
23: public $onClick;
24:
25: /** @var callable[] function (SubmitButton $sender); Occurs when the button is clicked and form is not validated */
26: public $onInvalidClick;
27:
28: /** @var array */
29: private $validationScope;
30:
31:
32: /**
33: * @param string caption
34: */
35: public function __construct($caption = NULL)
36: {
37: parent::__construct($caption);
38: $this->control->type = 'submit';
39: $this->setOmitted(TRUE);
40: }
41:
42:
43: /**
44: * Loads HTTP data.
45: * @return void
46: */
47: public function loadHttpData()
48: {
49: parent::loadHttpData();
50: if ($this->isFilled()) {
51: $this->getForm()->setSubmittedBy($this);
52: }
53: }
54:
55:
56: /**
57: * Tells if the form was submitted by this button.
58: * @return bool
59: */
60: public function isSubmittedBy()
61: {
62: return $this->getForm()->isSubmitted() === $this;
63: }
64:
65:
66: /**
67: * Sets the validation scope. Clicking the button validates only the controls within the specified scope.
68: * @return self
69: */
70: public function setValidationScope(/*array*/$scope = NULL)
71: {
72: if ($scope === NULL || $scope === TRUE) {
73: $this->validationScope = NULL;
74: } else {
75: $this->validationScope = array();
76: foreach ($scope ?: array() as $control) {
77: if (!$control instanceof Nette\Forms\Container && !$control instanceof Nette\Forms\IControl) {
78: throw new Nette\InvalidArgumentException('Validation scope accepts only Nette\Forms\Container or Nette\Forms\IControl instances.');
79: }
80: $this->validationScope[] = $control;
81: }
82: }
83: return $this;
84: }
85:
86:
87: /**
88: * Gets the validation scope.
89: * @return array|NULL
90: */
91: public function getValidationScope()
92: {
93: return $this->validationScope;
94: }
95:
96:
97: /**
98: * Fires click event.
99: * @return void
100: */
101: public function click()
102: {
103: $this->onClick($this);
104: }
105:
106:
107: /**
108: * Generates control's HTML element.
109: * @param string
110: * @return Nette\Utils\Html
111: */
112: public function getControl($caption = NULL)
113: {
114: $scope = array();
115: foreach ((array) $this->validationScope as $control) {
116: $scope[] = $control->lookupPath('Nette\Forms\Form');
117: }
118: return parent::getControl($caption)->addAttributes(array(
119: 'formnovalidate' => $this->validationScope !== NULL,
120: 'data-nette-validation-scope' => $scope ?: NULL,
121: ));
122: }
123:
124:
125: /**
126: * Submitted validator: has been button pressed?
127: * @return bool
128: * @internal
129: */
130: public static function validateSubmitted(SubmitButton $control)
131: {
132: return $control->isSubmittedBy();
133: }
134:
135: }
136: