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