Permalink
Browse files

form controls are auto-optional

- setRequired(false) is unnecessary
- BaseControl::enableAutoOptionalMode() deprecated
  • Loading branch information...
dg committed Jun 29, 2016
1 parent 2210656 commit 5a6ec496d20b1c92f44053ba259da9f0cb1ec6fe
@@ -93,7 +93,6 @@
->addRule($form::EQUAL, 'Passwords do not match', $form['password']);
$form->addUpload('avatar', 'Picture:')
->setRequired(false)
->addRule($form::IMAGE, 'Uploaded file is not image');
$form->addHidden('userid');
@@ -29,8 +29,7 @@ class DateInput extends Nette\Forms\Controls\BaseControl
public function __construct($label = null)
{
parent::__construct($label);
$this->setRequired(false)
->addRule([__CLASS__, 'validateDate'], 'Date is invalid.');
$this->addRule([__CLASS__, 'validateDate'], 'Date is invalid.');
}
@@ -263,7 +263,6 @@ public function addTextArea(string $name, $label = null, int $cols = null, int $
public function addEmail(string $name, $label = null): Controls\TextInput
{
return $this[$name] = (new Controls\TextInput($label))
->setRequired(false)
->addRule(Form::EMAIL);
}
@@ -276,7 +275,6 @@ public function addInteger(string $name, $label = null): Controls\TextInput
{
return $this[$name] = (new Controls\TextInput($label))
->setNullable()
->setRequired(false)
->addRule(Form::INTEGER);
}
@@ -74,9 +74,6 @@
/** @var array user options */
private $options = [];
/** @var bool */
private static $autoOptional = false;
/**
* @param string|object $caption
@@ -87,9 +84,6 @@ public function __construct($caption = null)
$this->label = Html::el('label');
$this->caption = $caption;
$this->rules = new Rules($this);
if (self::$autoOptional) {
$this->setRequired(false);
}
$this->setValue(null);
$this->monitor(Form::class, function (Form $form): void {
if (!$this->isDisabled() && $form->isAnchored() && $form->isSubmitted()) {
@@ -528,12 +522,11 @@ public function cleanErrors(): void
/**
* Globally enables new required/optional behavior.
* This method will be deprecated in next version.
* @deprecated
*/
public static function enableAutoOptionalMode(): void
{
self::$autoOptional = true;
trigger_error(__METHOD__ . '() is deprecated.', E_USER_DEPRECATED);
}
@@ -32,8 +32,7 @@ public function __construct($label = null, bool $multiple = false)
$this->control->type = 'file';
$this->control->multiple = $multiple;
$this->setOption('type', 'file');
$this->addCondition(Forms\Form::FILLED)
->addRule([$this, 'isOk'], Forms\Validator::$messages[self::VALID]);
$this->addRule([$this, 'isOk'], Forms\Validator::$messages[self::VALID]);
$this->monitor(Forms\Form::class, function (Forms\Form $form): void {
if (!$form->isMethod('post')) {
@@ -591,9 +591,6 @@ protected function beforeRender()
public function fireRenderEvents(): void
{
if (!$this->beforeRenderCalled) {
foreach ($this->getComponents(true, Controls\BaseControl::class) as $control) {
$control->getRules()->check();
}
$this->beforeRenderCalled = true;
$this->beforeRender();
$this->onRender($this);
@@ -128,9 +128,6 @@ public static function exportRules(Rules $rules): array
$payload[] = $item;
}
if ($payload && $rules->isOptional()) {
array_unshift($payload, ['op' => 'optional']);
}
return $payload;
}
@@ -19,7 +19,7 @@ class Rules implements \IteratorAggregate
{
use Nette\SmartObject;
/** @var Rule|false|null */
/** @var Rule|null */
private $required;
/** @var Rule[] */
@@ -51,7 +51,7 @@ public function setRequired($value = true)
if ($value) {
$this->addRule(Form::REQUIRED, $value === true ? null : $value);
} else {
$this->required = false;
$this->required = null;
}
return $this;
}
@@ -66,15 +66,6 @@ public function isRequired(): bool
}
/**
* @internal
*/
public function isOptional(): bool
{
return $this->required === false;
}
/**
* Adds a validation rule for the current control.
* @param callable|string $validator
@@ -217,7 +208,7 @@ public function getToggleStates(array $toggles = [], bool $success = true): arra
*/
public function validate(bool $emptyOptional = false): bool
{
$emptyOptional = $emptyOptional || $this->isOptional() && !$this->control->isFilled();
$emptyOptional = $emptyOptional || !$this->isRequired() && !$this->control->isFilled();
foreach ($this as $rule) {
if (!$rule->branch && $emptyOptional && $rule->validator !== Form::FILLED) {
continue;
@@ -236,30 +227,6 @@ public function validate(bool $emptyOptional = false): bool
}
/**
* @internal
*/
public function check(): bool
{
if ($this->required !== null) {
return false;
}
foreach ($this->rules as $rule) {
if ($rule->control === $this->control && ($rule->validator === Form::FILLED || $rule->validator === Form::BLANK)) {
// ignore
} elseif ($rule->branch) {
if ($rule->branch->check() === true) {
return true;
}
} else {
trigger_error("Missing setRequired(true | false) on field '{$rule->control->getName()}' in form '{$rule->control->getForm()->getName()}'.", E_USER_WARNING);
return true;
}
}
return false;
}
/**
* Clear all validation rules.
*/
@@ -149,6 +149,7 @@
elem = elem.tagName ? elem : elem[0]; // RadioNodeList
rules = rules || JSON.parse(elem.getAttribute('data-nette-rules') || '[]');
value = value === undefined ? {value: Nette.getEffectiveValue(elem)} : value;
emptyOptional = emptyOptional || !Nette.validateRule(elem, ':filled', null, value);
for (var id = 0, len = rules.length; id < len; id++) {
var rule = rules[id],
@@ -161,9 +162,6 @@
if (!curElem) {
continue;
} else if (rule.op === 'optional') {
emptyOptional = !Nette.validateRule(elem, ':filled', null, value);
continue;
} else if (emptyOptional && !rule.condition && rule.op !== ':filled') {
continue;
}
@@ -221,5 +221,5 @@ test(function () { // addInteger
Assert::null($input->getValue());
Assert::same('<input type="number" name="text" id="frm-text" data-nette-rules=\'[{"op":"optional"},{"op":":integer","msg":"Please enter a valid integer."}]\'>', (string) $input->getControl());
Assert::same('<input type="number" name="text" id="frm-text" data-nette-rules=\'[{"op":":integer","msg":"Please enter a valid integer."}]\'>', (string) $input->getControl());
});
@@ -65,14 +65,14 @@ test(function () { // validation rules
test(function () { // accepted files
$form = new Form;
$input = $form->addUpload('file1')->setRequired(false)->addRule(Form::MIME_TYPE, null, 'image/*');
Assert::same('<input type="file" name="file1" accept="image/*" id="frm-file1" data-nette-rules=\'[{"op":"optional"},{"op":":mimeType","msg":"The uploaded file is not in the expected format.","arg":"image/*"}]\'>', (string) $input->getControl());
$input = $form->addUpload('file1')->addRule(Form::MIME_TYPE, null, 'image/*');
Assert::same('<input type="file" name="file1" accept="image/*" id="frm-file1" data-nette-rules=\'[{"op":":mimeType","msg":"The uploaded file is not in the expected format.","arg":"image/*"}]\'>', (string) $input->getControl());
$input = $form->addUpload('file2')->setRequired(false)->addRule(Form::MIME_TYPE, null, ['image/*', 'text/html']);
Assert::same('<input type="file" name="file2" accept="image/*, text/html" id="frm-file2" data-nette-rules=\'[{"op":"optional"},{"op":":mimeType","msg":"The uploaded file is not in the expected format.","arg":["image/*","text/html"]}]\'>', (string) $input->getControl());
$input = $form->addUpload('file2')->addRule(Form::MIME_TYPE, null, ['image/*', 'text/html']);
Assert::same('<input type="file" name="file2" accept="image/*, text/html" id="frm-file2" data-nette-rules=\'[{"op":":mimeType","msg":"The uploaded file is not in the expected format.","arg":["image/*","text/html"]}]\'>', (string) $input->getControl());
$input = $form->addUpload('file3')->setRequired(false)->addRule(Form::IMAGE);
Assert::same('<input type="file" name="file3" accept="image/gif, image/png, image/jpeg, image/webp" id="frm-file3" data-nette-rules=\'[{"op":"optional"},{"op":":image","msg":"The uploaded file must be image in format JPEG, GIF, PNG or WebP."}]\'>', (string) $input->getControl());
$input = $form->addUpload('file3')->addRule(Form::IMAGE);
Assert::same('<input type="file" name="file3" accept="image/gif, image/png, image/jpeg, image/webp" id="frm-file3" data-nette-rules=\'[{"op":":image","msg":"The uploaded file must be image in format JPEG, GIF, PNG or WebP."}]\'>', (string) $input->getControl());
});
@@ -31,7 +31,7 @@
<tr>
<th><label for="frm-email">Email:</label></th>
<td><input type="email" name="email" id="frm-email" data-nette-rules='[{"op":"optional"},{"op":":email","msg":"Please enter a valid email address."}]' data-nette-empty-value="&#64;" value="&#64;" class="text"></td>
<td><input type="email" name="email" id="frm-email" data-nette-rules='[{"op":":email","msg":"Please enter a valid email address."}]' data-nette-empty-value="&#64;" value="&#64;" class="text"></td>
</tr>
</table>
</fieldset>
@@ -56,7 +56,6 @@ test(function () {
$input->setRequired(false);
$input->addRule(Form::EMAIL);
Assert::same([
['op' => 'optional'],
['op' => ':email', 'msg' => 'Please enter a valid email address.'],
], Helpers::exportRules($input->getRules()));
});
@@ -75,7 +74,6 @@ test(function () {
->addRule($form::EMAIL);
Assert::same([
['op' => 'optional'],
[
'op' => ':email',
'rules' => [
@@ -87,7 +85,6 @@ test(function () {
[
'op' => ':integer',
'rules' => [
['op' => 'optional'],
['op' => ':email', 'msg' => 'Please enter a valid email address.'],
],
'control' => 'text1',

0 comments on commit 5a6ec49

Please sign in to comment.