Form widgets

  1. Atributos
  2. Elementos input
  3. Validação
  4. Botões
  5. Textarea
  6. Labels
  7. Elementos de seleção

Nesse tutorial, vou falar sobre form widgets, que são os elementos que fazem parte de um formulário (campos de texto, checkboxes, selects, botões, dentre outros).

Atributos

Há muitos atributos que são comuns a vários form widgets. Antes de começar a falar sobre os form widgets, vou falar sobre os atributos, explicando para que eles servem e onde eles podem ser usados.

disabled
Serve para desabilitar campos. Pode ser usado em campos de texto, checkboxes, elementos de seleção, dentre outros.
placeholder
É usado em campos de texto (exceto senhas). É um texto, geralmente renderizado com uma cor mais clara do que o valor real do campo. Quando o campo tem um valor, o placeholder não é exibido. O placeholder é usado muitas vezes como um substituto para a label, que é basicamente o nome de uma widget.
readonly
Serve para marcar campos não-editáveis. Vale lembrar que o campo é enviado quando o formulário é submetido.
autocomplete
Define se um campo pode ser completado automaticamente pelo browser.
autofocus
Indica que um campo deve receber foco quando a página é carregada.
step
Pode ser usado em vários campos, tais como number, range, date, datetime-local, time e campos similares. Define o valor de cada incremento.
form
Indica o formulário ao qual o campo pertence (use o ID do formulário). Desnecessário quando o campo está dentro do formulário ao qual ele pertence.

Elementos input

São elementos que são colocados dentro de formulários e recebem algum tipo de input (entrada de dados) do usuário. Esse input nem sempre é pelo teclado. Pode ser pelo mouse também, como acontece com checkboxes e selects. O elemento input pode ser praticamente qualquer coisa. Simplesmente definindo seu atributo type, ele pode mudar radicalmente. A maioria dos widgets são elementos <input>.

Todos os campos de texto (não apenas campos do tipo text, mas também outros campos, como email e password) compartilham alguns comportamentos: podem ser somente leitura, podem ser desabilitados, podem ter um placeholder e podem ser restringidos em tamanho físico e em comprimento (número de caracteres).

Veja os principais tipos de <input>:

Input text

Esse é o tipo de input mais comum. É um input que recebe texto de linha única. É o tipo padrão quando o atributo type não é definido ou quando o browser não suporta o tipo de input definido. Você pode definir o tamanho do campo usando o atributo size:

<input type="text" name="bairro" size="50">

Esse atributo define a largura baseado na fonte que está sendo usada e na largura que os caracteres ocupam.

Checkable items

Checkable items são itens que podem ser marcados/desmarcados: eles são checkboxes e radio buttons. Ambos usam o atributo checked. Diferentemente dos outros widgets, checkable items só são enviados na submissão do formulário se forem marcados. Caso contrário, eles não são enviados. É um comportamento semelhante à atributos booleanos.

No caso da checkbox, que só tem dois estados (marcado/desmarcado), esses estados podem ser representados pela presença ou ausência do campo nos parâmetros da request. No caso do radio button, é melhor definir valores, porque radio buttons fazem parte de grupos que podem ter vários radio buttons. Por isso, cada um deve ter um valor.

Radiobuttons só fazem sentido em grupos. O grupo ao qual eles pertence é definido pelo atributo name, que deve ser o mesmo para os radio buttons do grupo. A seleção do radio button é mutuamente exclusiva. Por isso, ao marcar um radio button de um grupo, os demais são desmarcados. Exemplo de um grupo de radiobuttons:

<fieldset>
  <legend>Sexo</legend>
  <label>
    <input type="radio" name="sexo" value="Masculino">
    Masculino
  </label>
  <label>
    <input type="radio" name="sexo" value="Feminino">
    Feminino
  </label>
</fieldset>

Já checkboxes são independentes. Por isso, elas devem ter nomes diferentes:

<label>
  <input type="checkbox" name="estrangeiro">
  Estrangeiro
</label>
<label>
  <input type="checkbox" name="estudante">
  Estudante
</label>

Note como tanto os radio buttons como a checkbox foram envolvidas em labels. Esses labels são essenciais nesses widgets. É a melhor forma de colocar um texto ao lado das checkboxes, até porque o texto se torna clicável e seu clique afeta o estado da checkbox ou do radiobutton relacionado.

Use o atributo checked para marcar uma checkbox ou um radio button. Esse é um atributo booleano. É a presença dele que indica se a checkbox ou o radio button serão marcados.

Input color

O Input do tipo color permite especificar uma cor. O padrão é preto. A cor é especificada em formato hexadecimal. Exemplo:

<input type="color" name="cor_camisa" value="#aa78b4">

Input password

O input password é usado para colocar senhas. Ele é o mais recomendado para esse propósito, porque oculta o texto digitado pelo usuário. Porém, isso não significa que a senha é enviada de forma criptografada ou segura. Ela pode ser enviada em texto plano, caso você não use HTTPS nem outro meio para criptografar os dados antes do envio. A ocultação do texto é para se proteger das pessoas que estão ao seu redor. Uma pessoa mal-intencionada poderia ver o que você está digitando sem essa proteção.

<input type="password" name="password">

Input file

O input file é usado para o upload de arquivos. Você pode usar o atributo multiple para enviar múltiplos arquivos:

<input type="file" name="capa-cd">
<input type="file" name="fotos" multiple>

Input hidden

O input hidden é invisível para o usuário, mas é enviado para o servidor quando os dados do formulário são enviados:

<input type="hidden" name="inputName" value="inputValue">

Input tel

O input tel serve para inserir um telefone. Devido a ampla variedade de formatos de números telefônicos que existem, esse tipo de campo não limita o que o usuário pode inserir. Em alguns dispositivos (especialmente dispositivos móveis), um teclado virtual diferente mais apropriado para digitar números telefônicos é usado nesse campo. Exemplo:

<input type="tel" value="+551199999999">

Input email

É usado para inserção de um ou mais endereços de email. Para permitir múltiplos endereços de e-mail, use o atributo multiple. Os emails devem ser separados por vírgulas. Exemplos:

<label>
  Email do professor
  <input type="email" name="email_professor">
</label>
<label>
  Emails dos alunos
  <input type="email" name="emails_alunos" placeholder="email, email2, email3" multiple>
</label>

Inputs numéricos

O input number é usado para inserir números. Porém, ele apenas limita os caracteres que podem ser inseridos a caracteres que podem ser usados em qualquer número real. Ele não verifica se o número tem o formato correto. Assim, o usuário pode colocar um número inválido, como e1e-,0. Exemplo:

<label>
  Produtos vendidos
  <input type="number" value="0" name="produtos_vendidos">
</label>

O input range é um slider. Os atributos min e max definem os limites do valor definido. Já o atributo step define em quanto cada valor pode ser incrementado por vez. Um problema dos sliders é que eles não oferecem qualquer tipo de feedback visual sobre qual é o valor atual. Você precisa adicionar isso você mesmo com Javascript, mas isso é fácil de fazer. Exemplo de slider:

<label>
  Número de quartos
  <input type="range" min="1" max="6">
</label>

Input image

O input image define uma imagem como um botão de submissão. Esse elemento suporta exatamente o mesmo conjunto de atributos que o elemento <img>, além de todos os atributos suportados por outros botões de formulários. Veja um exemplo de uso desse input:

<input type="image" src="restaurante.png">

Esse widget envia as coordenadas X e Y do clique na imagem (as coordenadas são relativas à imagem, o que quer dizer que o canto superior esquerdo da imagem representa as coordenadas 0, 0). O valor da coordenada X é o valor do atributo name seguido pela string .x. O valor da coordenada Y também segue essa regra, só que usa a string .y no final. Esse tipo de elemento é usado para criar mapas de calor.

O input search é ótimo para formulários de busca. Ele exibe uma lupa dentro do campo na maioria dos browsers:

<input type="search" name="busca">

Input URL

O Input URL recebe uma URL:

<input type="url" name="url_site">

Inputs de data e horário

O input datetime-local permite que o usuário escolha uma data e um horário. Há também o input datetime, que é global (inclui fuso horário):

<input type="datetime-local">
<input type="datetime">

Os inputs date, time e month permitem escolher data, horário e mês, respectivamente:

<input type="date">
<input type="time">
<input type="month">

Validação

Validar os campos é verificar se eles cumprem determinadas condições. Há dois tipos de validação: a que ocorre no lado do cliente (client-side) e a que ocorre no lado do servidor (server-side). Como estamos falando de HTML, a validação que nos interessa é a client-side, pois o HTML está no lado do cliente. É importante que você saiba que as duas validações são importantes, mas a server-side é imprescindível.

Enquanto a validação client-side pode ser facilmente evitada ou manipulada, a server-side é inacessível ao usuário (a não ser que o usuário tenha acesso ao seu servidor, é claro). Porém, a validação client-side é uma boa prática de UX, visto que fornece um feedback instantâneo sobre a validade dos widgets, coisa que geralmente não ocorre com a validação server-side.

Alguns tipos de input, como email, url, tel, date e outros, são validados automaticamente pelo browser e não precisam de atributos de validação. Inputs desabilitadas ou somente leitura não vão ativar a validação.

Veja alguns atributos usados em validações:

  • required: define que o valor do campo precisa ser fornecido
  • minlength / maxlength: especificam o comprimento mínimo e máximo em caracteres do campo, respectivamente
  • min / max: especificam o valor numérico mínimo e máximo do campo, respectivamente
  • pattern: especifica uma expressão regular que deve ser cumprida para que a validação seja sucedida

Para campos de input do tipo file, é possível aceitar apenas certos tipos de arquivos. É possível restringir o MIME type que você quer aceitar (podendo restringir o tipo e o subtipo ou apenas o tipo) e também as extensões que você quer aceitar. Exemplo:

<input type="file" accept="video/*,image/png,.pdf">

Use o atributo formnovalidate em um botão de envio do formulário para que o formulário não seja validado se for submetido:

<input type="submit" value="Enviar" formnovalidate>

Botões

Botões em formulários podem ser criados tanto com o elemento <input>, como com o elemento <button>. O elemento <button>, além de ser mais semântico, pode conter outros elementos dentro dele, já que não é um elemento vazio, ao contrário do <input>. Veja um exemplo com os dois:

<input type="button" value="Botão" onclick="funcao();">
<button type="button" onclick="funcao();">Botão</button>

Note a presença do atributo onclick. Ele é muito usado em botões do tipo button, que são botões que não tem comportamento padrão, e por isso são usados para ações personalizadas. Há outros tipos de botões. Eles podem ser usados tanto no elemento <input>, como no elemento <button>. Veja quais são os outros tipos a seguir:

  • submit: envia os dados do formulário para o servidor. É o valor padrão.
  • reset: reseta o formulário

Você também pode usar o atributo formaction para especificar para onde os dados do formulário devem ser enviados. É uma forma de sobrescrever o atributo action do <form>, que vale apenas para o botão onde o formaction é usado.

Textarea

Enquanto o input text é usado para campos de texto de apenas uma linha, o elemento <textarea> é usado para campos de texto de múltiplas linhas. Você pode usar o atributo rows para determinar o número de linhas visíveis da <textarea>, e o atributo cols para determinar o número de colunas visíveis. Também há o atributo maxlength, que especifica o comprimento máximo da <textarea> (em número de caracteres).

A <textarea> não tem seu conteúdo determinado pelo atributo value. Como ela não é um elemento vazio como o input text, seu conteúdo é determinado pelo conteúdo do próprio elemento. Veja um exemplo de uso da <textarea>:

<textarea name="mensagem">
  Conteúdo inicial
<textarea>

Labels

Labels são usados para dar nome a um elemento de um formulário. São essenciais no caso de checkboxes e radio buttons, mas devem ser usados em outros elementos também. Há duas formas de usar um label: como um wrapper ou como referência a um elemento especificado no atributo for (deve ser colocado o ID do elemento nesse atributo). Veja a seguir como usar essas duas formas.

Wrapper

<label>
  <input type="checkbox" name="campo">
  Estrangeiro
<label>

Referência a um elemento

<input id="estrangeiro" type="checkbox" name="campo">
<label for="estrangeiro">Estrangeiro</label>

Envolvendo um label e seu widget

É uma prática comum envolver um label e seu widget em um elemento <div> ou <p>, quando necessário. Exemplo:

<div>
  <label>
    <input type="checkbox" name="campo">
    Estrangeiro
  </label>
</div>

Elementos de seleção

Elemento select

O elemento <select> permite que o usuário selecione uma opção de uma lista de opções, ou permite que ele selecione múltiplas opções, se o atributo multiple for usado. É útil para permitir que o usuário selecione uma Unidade Federativa ou suas comidas favoritas, por exemplo. As opções são marcadas com o elemento <option>. O valor que o campo terá na submissão do formulário é o valor do atributo value da opção selecionada. O conteúdo do elemento <option> é o texto da opção que fica visível para os usuários. Exemplo de uso:

<select name="ufs">
  <option value="ac">AC</option>
  <option value="al">AL</option>
  <option value="am">AM</option>
  <!-- ... -->
</div>

Você pode usar o atributo size para definir o tamanho da <select>. Se o valor dele for 0 ou 1, a select será exibida no estilo dropdown. Se o valor for maior do que 1, a select será exibida no estilo de uma caixa com múltiplas linhas, com uma opção por linha e uma barra de rolagem para navegar pelas opções:

<select name="ufs" size="4"></select>
  <option value="ac">AC</option>
  <option value="al">AL</option>
  <option value="am">AM</option>
  <option value="ba">BA</option>
  <option value="ce">CE</option>
  <!-- ... -->
</div>

Caso você use o atributo multiple, a select sempre será exibida no formato de caixa.

Uma outra forma de especificar o texto da opção é pelo atributo label. O conteúdo do elemento é usado no lugar dos atributos label e value, quando um deles não é especificado. Quando ambos são especificados, ele se torna irrelevante e dispensável:

<option label="Texto da opção" value="Valor da opção"></option>

Porém, o mais comum é especificar apenas o atributo value e usar o conteúdo do elemento ao invés de definir um valor para o atributo label.

O atributo selected é usado para deixar uma opção selecionada. Ele é um atributo booleano, assim como o checked. Por isso, o que define se a opção é selecionada ou não é a presença ou a ausência do atributo. Exemplo:

<option value="Valor" selected="selected">Texto</option>

Note que você pode dividir suas opções em grupos usando o elemento <optgroup>. Isso torna as opções mais organizadas. O atributo label serve para nomear o grupo. Exemplo:

<select name="ufs">
  <optgroup label="Centro-Oeste">
    <option value="df">DF</option>
    <option value="go">GO</option>
    <option value="ms">MS</option>
    <option value="mt">MT</option>
  </optgroup>
  <optgroup label="Nordeste">
    <option value="al">AL</option>
    <option value="ba">BA</option>
    <option value="ce">CE</option>
    <option value="ma">MA</option>
    <option value="pb">PB</option>
    <option value="pe">PE</option>
    <option value="pi">PI</option>
    <option value="rn">RN</option>
    <option value="se">SE</option>
  </optgroup>
  <optgroup label="Norte">
    <option value="ac">AC</option>
    <option value="ap">AP</option>
    <option value="am">AM</option>
    <option value="pa">PA</option>
    <option value="ro">RO</option>
    <option value="rr">RR</option>
    <option value="to">TO</option>
  </optgroup>
  <optgroup label="Sudeste">
    <option value="es">ES</option>
    <option value="mg">MG</option>
    <option value="rj">RJ</option>
    <option value="sp">SP</option>
  </optgroup>
  <optgroup label="Sul">
    <option value="pr">PR</option>
    <option value="rs">RS</option>
    <option value="sc">SC</option>
  </optgroup>
</select>

Elemento datalist

O elemento <datalist> marca uma lista de opções, que são fornecidas para um campo de input de texto. Essa lista de opções aparece como sugestões para o usuário. Para exibir as opções da <datalist>, o input deve usar o atributo list, definindo seu valor igual ao id da <datalist>. Exemplo:

<label>
  Massa favorita
  <input list="massa-favorita">
</label>
<datalist id="massa-favorita">
  <option value="Macarrão">
  <option value="Pão">
  <option value="Pizza">
</datalist>