Os atributos do elemento são a base para validadores. Usando atributos, podemos definir imediatamente as seguintes restrições:
obrigatório - o campo é obrigatório, ou seja, requer o preenchimento da etapa
mín. máx. - os valores mínimos e máximos permitidos, bem como a etapa de alteração de minlength e maxlength - limitadores do número de caracteres de entrada permitidos padrão - expressão regular Parece não ser muito, no entanto, o padrão nos dá oportunidades bastante ricas para verificar valores, padrões regulares são facilmente pesquisados permitindo verificar imediatamente números de telefone, endereços de e-mail e URLs e muito mais na demanda.
Dispostos em elementos de formulário, esses atributos não permitirão que o botão seja acionado automaticamente do mesmo formulário executando os valores de envio para o servidor, embora hoje tal caso possa parecer anacrônico para muitos. Mas isso não é um problema, porque com o JavaScript do lado do cliente, podemos usar todos esses validadores da mesma maneira ou de maneira ainda melhor. Portanto, não usaremos input type = email, mas tentaremos fazer nosso próprio campo verificando a entrada para conformidade com as regras de geração de endereços de e-mail. Vamos fazer um formulário simples:
<form name="myform" id="myform">
<input type="text" pattern="^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$" placeholder="email here"/>
<input type="submit">
</form>
O validador funciona imediatamente e, ao tentar pressionar o botão, emite um aviso no idioma da localidade do navegador.
Da mesma forma, inserir mail@example.com resulta no envio do formulário com sucesso.
Para desenvolver seu comportamento, você precisa acessar a instância do formulário, isso pode ser feito através do documento global por nome, índice (id) ou ordinal a partir do zero.
<script type="module">
document.forms.myform.onsubmit = (event) => {
console.log('validate');
return false;
};
</script>
ou por um seletor usando um dos métodos, como document.getElementById () ou document.querySelector (),
para verificar os resultados, execute http-server
npx http-server
após a execução do comando, você pode abrir 127.0.0.1 : 8080 / ou o endereço que ele escreve para você no console do navegador e depurar os resultados.
Vamos substituir o envio por um botão normal e invocar a validação do formulário manualmente, mudando ligeiramente o exemplo.
<form id="myform" action="#">
<input type="text" pattern="^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$" required placeholder="email here" />
<input type="button" name="subm" value="OK" />
</form>
<script type="module">;
myform.subm.onclick = (event) => {
console.log(form.checkValidity());
return false;
};
</script>
Neste exemplo, você pode ver que o mapeamento de objetos de formulário por id e nome funciona para elementos filho em relação ao formulário, que parece muito elegante. Agora nosso código imprime o estado de validade do formulário no console.
A presença de métodos para iniciar a validação manualmente não significa que ela não possa ser executada sem chamá-los.
Os resultados da entrada e outras alterações no formulário são imediatamente refletidos em seu estado, que se manifesta na presença de pseudoclasses de estilos válidos e inválidos . Se você adicionar realce de cor, poderá ver como a validação funciona imediatamente.
<style>
:valid {
border: 1px solid green;
}
:invalid {
border: 1px solid red;
}
</style>
Para evitar que o formulário irrite os olhos com vermelho antes que o usuário tente inserir algo nele, você pode usar um life hack com um placeholder:
<style>
input:valid {
border: 1px solid green;
}
input:not(:placeholder-shown):invalid {
border: 1px solid red;
}
</style>
Manipuladores externos para eventos de validação podem ser suspensos em elementos de formulário.
<script type="module">
myform.email.oninvalid = (event) => {
alert('Wrong email !!11');
};
myform.subm.onclick = (event) => {
console.log(form.checkValidity());
return false;
};
</script>
Neste caso, o mecanismo de gancho é usado pelo nome do evento, se houver algum evento suportado pelo elemento, então atribuindo uma função chamada + <event_name> a ele, podemos ter certeza de que ele será chamado quando for disparado.
E mais um ponto maravilhoso aqui é que eles não serão mais chamados ao inserir dados, mas apenas quando forçar a validação programaticamente, ou seja, chamando o método checkValidity ().
Assim, podemos lidar com este comportamento:
myform.subm.onclick = (event) => {
if (myform.checkValidity()) {
alert('Valid !');
} else {
alert('Invalid !')
}
return false;
};
Na vida real, também podemos precisar chamar event.preventDefault () se a validação falhar em abortar o procedimento de envio do formulário.
Em checkValidity () é um reportValidity () analógico , que retorna o resultado sem causar revalidação.
Como você sabe qual campo está errado?
Cada elemento de entrada do formulário tem a propriedade .validity, bem como a capacidade de chamar métodos de validação nele, a propriedade tem a seguinte estrutura:
ValueState: {
válido - sinal geral de correção do
valorMissing - o valor é obrigatório, mas não definido
typeMismatch - o tipo errado de valor
é inserido patternMismatch - é introduzido valor incompatível
tooLong - valor maior que maxlength
tooShort - valor menor que minlength
rangeUnderflow - valor menor que min
rangeOverflow - valor maior que max
stepMismatch - valor não corresponde à etapa
badInput - a entrada não pode ser convertida em valor
customError - erro arbitrário
}
Basicamente, como podemos ver, propriedades de erro correspondentes aos atributos de validação padrão, enquanto .customError é nosso espaço para extensão. Ao
chamar o método .setCustomValidity () com uma string de erro como argumento, podemos marcar o elemento do formulário como inválido. Você também pode definir ou obter o texto do erro por meio da propriedade .validationMessage...
Para não definir as validações do navegador, você pode usar a propriedade .willValidate , que indica se as validações padrão serão chamadas no campo.
Ao passar uma string vazia como um argumento para .setCustomValidity () , podemos retornar seu estado para válido.
Vamos adicionar suporte para nosso próprio atributo my-pattern , que, para maior clareza, verificará o valor em uma expressão regular da mesma maneira.
Em caso de erro, a mensagem, além da fornecida no navegador, será exibida ao lado do campo A
validação será acionada quando o valor do nosso campo alternativo mudar e quando o botão for pressionado.
<form id="myform" action="#">
<div>
<input type="text" name="email" id="email" value="" pattern="^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$" required placeholder="email here" />
<span class="msg"></span>
</div>
<div>
<input type="text" name="customInput" id="customInput" my-pattern="^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$" required placeholder="text here" />
<span class="msg"></span>
</div>
<button type="submit" name="subm" value="OK">OK</button>
</form>
<style>
input:valid {
border: 1px solid green;
}
input:not(:placeholder-shown):invalid {
border: 1px solid red;
}
</style>
<script type="module">
myform.customInput.oninvalid = (event) => {
let el = event.target;
let msg = el.parentElement.querySelector('.msg');
msg.innerText = el.validationMessage;
console.log('oninvalid, id: ', el.id);
};
myform.customInput.oninput = (event) => {
let el = event.currentTarget;
validateWithMyPattern(el);
markValidity(el);
};
function markValidity(el) {
el.checkValidity();
let msg = el.parentElement.querySelector('.msg');
if (el.validity.valid) {
msg.innerText = '';
} else {
msg.innerText = el.validationMessage;
}
}
function validateWithMyPattern(field) {
if (field.value) {
if (field.hasAttribute('my-pattern') &&
field.value.match(field.getAttribute('my-pattern'))) {
field.setCustomValidity('');
} else {
field.setCustomValidity('My pattern error');
}
}
}
myform.subm.onclick = (event) => {
for (let formEl of myform.querySelectorAll('input')) {
validateWithMyPattern(formEl);
markValidity(formEl);
}
if (myform.reportValidity()) {
alert('Valid !');
} else {
alert('Invalid !')
}
return false;
};
</script>
Agora temos dois campos semelhantes que verificam o valor com um validador padrão e um que nós mesmos escrevemos.
As possibilidades podem não parecer ricas, no entanto, com a ajuda delas você pode implementar quaisquer validações, incl. grupos de campo sem muitas limitações técnicas, como acontece com os frameworks populares.
Das limitações da API de validação, só me lembro da invalidação inicial de campos. Para isso, além do truque com placeholder ou estados especiais a-la intocados, você pode fazer toda a validação programaticamente na entrada e enviar eventos combinando seus próprios validadores com os padrão.
Resolvendo meus problemas, cheguei à necessidade de criar meu próprio componente que executa as tarefas do formulário ao mesmo tempo para suportar meus próprios elementos de entrada, o que permite definir diferentes comportamentos de validação e notificação e travar quaisquer validadores e usar a API de validação padronizada Você pode vê-lo aqui: https://bitbucket.org/techminded/skinny-widgets/src/master/src/form/
e o código de exemplo deste artigo pode ser encontrado aqui:
https://bitbucket.org/techminded/myform /