If you have your own Symfony constraint, implement the matching constraint on the JavaScript side too. The JavaScript constructor name should match the full PHP class name with namespace separators removed.
For example, a PHP constraint:
<?php
// src/Validator/Constraints/ContainsAlphanumeric.php
namespace App\Validator\Constraints;
use Symfony\Component\Validator\Constraint;
class ContainsAlphanumeric extends Constraint
{
public string $message = 'The string "%string%" contains an illegal character: it can only contain letters or numbers.';
}<?php
// src/Validator/Constraints/ContainsAlphanumericValidator.php
namespace App\Validator\Constraints;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
class ContainsAlphanumericValidator extends ConstraintValidator
{
public function validate(mixed $value, Constraint $constraint): void
{
if (!is_string($value) || '' === $value) {
return;
}
if (!preg_match('/^[a-zA-Z0-9]+$/', $value)) {
$this->context->buildViolation($constraint->message)
->setParameter('%string%', $value)
->addViolation()
;
}
}
}requires this JavaScript constraint:
<script type="text/javascript">
function AppValidatorConstraintsContainsAlphanumeric() {
/**
* This value will be filled with the real message received from the PHP constraint.
*/
this.message = '';
/**
* This method is required.
* It should return an error message or an array of messages.
*/
this.validate = function(value) {
if (value.length && !/^[a-zA-Z0-9]+$/.test(value)) {
return this.message.replace('%string%', value);
}
return [];
};
/**
* Optional method.
*/
this.onCreate = function() {
// Put setup logic here if the constraint needs it.
};
}
</script>