Validace formulářů – možnost validace pouze některých containerů/prvků
Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
- Foowie
- Člen | 269
Tuhle fíčuru už jsem několikrát potřeboval, zatím je stav
public function setValidationScope($scope)
{
// TODO: implement groups
$this->validationScope = (bool) $scope;
return $this;
}
Jedná se o změnu celkem 3 metod, takže pokud by byl čas, tak by nebylo
špatné to dodělat.
Lehký nástřel jak by fix mohl vypadat (pro Nette 1.0-dev) je níže:
public function setValidationScope($scope)
{
$this->validationScope = $scope;
$this->control->data("nette-scope", is_array($scope) ? implode(" ", $scope) : $scope);
return $this;
}
public function validate()
{
$this->onValidate($this);
$name = ($this instanceof Form) ? "" : $this->lookupPath("Form");
$submit = $this->getForm()->isSubmitted();
if($submit === false)
$scope = true; // is not submitted -> validate all items
else {
$scope = $submit->getValidationScope();
if($scope === false)
return $this->valid = true;
}
if($scope === true)
$scope = array("");
else if(is_string($scope))
$scope = array($scope);
$validate = !(is_array($scope) && !in_array($name, $scope, true));
$this->valid = TRUE;
if($validate) { // validate all components
foreach ($this->getControls() as $control) {
if (!$control->getRules()->validate()) {
$this->valid = FALSE;
}
}
} else { // validate only containers
foreach($this->getComponents(false, "FormContainer") as $container)
if(!$container->isValid())
$this->valid = false;
}
}
A nakonec ještě změna v netteForms.js
<script>
nette.validateForm = function(sender) {
var form = sender.form || sender;
if (form['nette-submittedBy'] && form.elements[form['nette-submittedBy']].getAttribute('data-nette-scope')) {
var scopes = form.elements[form['nette-submittedBy']].getAttribute('data-nette-scope').split(" ");
for (var i = 0; i < scopes.length; i++) {
var splited = scopes[i].split("-");
var first = splited.shift();
scopes[i] = first + ((splited.length > 0) ? "[" + splited.join("][") + "]" : "");
}
for (i = 0; i < form.elements.length; i++) {
var doValidate = false;
for(var j = 0; j < scopes.length; j++) {
var elementName = form.elements[i].name;
var scopeName = scopes[j];
if(scopeName == "1" || elementName.indexOf(scopeName) === 0 && (elementName.length == scopeName.length || elementName.length > scopeName.length && elementName[scopeName.length] == "[")) {
doValidate = true;
break;
}
}
if (doValidate && !nette.validateControl(form.elements[i]))
return false;
}
}
return true;
}
</script>
A použití:
$submitButton->setValidationScope(true); // celý form
$submitButton->setValidationScope(false); // nic
$submitButton->setValidationScope("container"); // pouze container "container"
$submitButton->setValidationScope("container-subcontainer"); // pouze container "subcontainer" v containeru "container"
$submitButton->setValidationScope(array("container1", "container2")); // pouze "container1" a "container2"
Btw je to jenom nástřel…