Validando formulários em Javascript

Validação de formulários em Javascript é uma das táticas mais utilizadas atualmente para garantir que os dados requeridos nos campos que o usuário preenche em qualquer website ou blog, sejam realmente fiéis ao que o desenvolvedor deseja. Seja validação após os dados serem enviados ao servidor, com Ajax e PHP, por exemplo, ou a validação em tempo real, ambas envolvem algum tipo de validação em Javascript.

Em nossa última aula, falamos sobre eventos em Javascript, e demonstrei quão importante eles são. Hoje, continuaremos a falar sobre eventos, pois, validação de formulários em Javascript deve ocorrer quando algum evento ocorre, seja focus (quando o usuário entrar em um campo), blur (quando o usuário sair de algum campo), submit (quando o usuário envia o formulário) ou change (quando o usuário muda uma opção do formulário).

Se você entendeu a nossa última aula, com certeza este artigo vai ajudar a aprimorar seus conhecimentos sobre eventos, além de detalhar o que fazer para validar um formulário sem nenhuma biblioteca externa, apenas Javascript e seus conhecimentos.

Capturando formulários em Javascript

Para obter acesso em qualquer formulário em Javascript, existem algumas maneiras diferentes, todas elas chegando ao mesmo ponto, porém, dependendo de fatores diferentes.

A primeira forma é acessando a propriedade forms do elemento document.

Este método retorna todos os formulários presentes em uma página HTML para um array, cada formulário ocupando um índice desse array.

var formulario = document.forms[0];

No trecho acima, tenho acesso ao primeiro formulário da página HTML (índice 0). Se eu quisesse acessar o segundo formulário, utilizaria o índice 1, o terceiro, índice 2, e assim por diante.

A ordem dos índices é simplesmente a ordem em que os formulários são colocados na página, veja um exemplo:

<body>
    <!-- Índice 0 -->
    <form action="" method="post">
        <input type="text" class="teste">
    </form>
    
    <!-- Índice 1 -->
    <form action="" method="post">
        <input type="text" class="teste">
    </form>
    
     <!-- Índice 2 -->
    <form action="" method="post">
        <input type="text" class="teste">
    </form>
</body>

Este método não é interessante, porque se você alterar a ordem dos formulários em sua página, terá que alterar seu código Javascript também.

Uma outra forma para obter acesso aos formulários em Javascript, é criando um identificador (id) para o formulário, e acessando o mesmo através da propriedade  getElementById('id') do objeto document:

<!-- NO HTML -->
<form id="meu_formulario" action="" method="post">
    <input type="text">
</form>
// NO JAVASCRIPT
var formulario = document.getElementById('meu_formulario');

Utilizando o método acima, você pode alterar a página inteira se quiser, e seu formulário e código Javascript de validação ainda estarão funcionando perfeitamente.

Depois de obter o formulário em Javascript, você poderá utilizar qualquer um dos eventos relacionados a ele para fazer o que quiser na validação, por exemplo, não deixar o usuário enviar os dados se algum campo não estiver corretamente preenchido ou vazio (você vai ver isso mais adiante no artigo).

Eventos e formulários em Javascript

Como descrevi anteriormente, você vai precisar de algum evento para manipular os campos do seu formulário, no entanto, antes de continuarmos com os formulários, teremos que estipular como vamos capturar tais eventos.

Em nossa última aula, você viu que existem diferenças em como os navegadores acessam e manipulam os eventos, por exemplo, para obter o evento de submit para um formulário, você pode utilizar addEventListener para os navegadores mais novos, ou attachEvent para as versões 6, 7 e 8 do Internet Explorer.

Por este motivo, temos que verificar se o navegador suporta uma das duas opções toda vez que tentamos capturar um evento para qualquer formulário.

Como sabemos que sempre temos que utilizar um tipo de formulário novo em nossos sites (comentários, contatos, etc…), não seria ideal fazer essa verificação para cada formulário do documento.

Tendo isso em mente, criei uma função que faz essa checagem todas as vezes que precisamos de um evento, assim podemos reutilizar a função para qualquer chamada de evento de qualquer elemento da página. Veja abaixo:

// Função para capturar eventos
function captura_eventos( objeto, evento, funcao ) {
    // Testa se o navegador suporta addEventListener
    if ( objeto.addEventListener ) {
        // Adiciona addEventListener
        objeto.addEventListener( evento, funcao, true );
    } 
    // Testa se o navegador suporta attachEvent
    else if ( objeto.attachEvent ) {
        // Adiciona a palavra on no evento
        var evento = 'on' + evento; // Ex.: on + click = onclick
        // Adicionar attachEvent
        objeto.attachEvent( evento, funcao );
    }
}

Com essa função, você só precisa enviar os dados: O objeto, o evento desejado sem a palavra "on", e a função que vai manipular o evento. Exemplo:

// Carrega a função geral após o carregamento da página
captura_eventos(window,'load',geral); // O mesmo que window.onload=geral;

Nesse caso, estou enviando o objeto window, o evento load e uma função geral para a função "captura_eventos", assim que a página terminar de carregar, a função geral será carregada com o que estiver dentro dela.

Outra função que criei para facilitar nossa vida, foi a função de cancelar um evento, ou melhor, não propagar o evento para outros elementos dentro do seu documento e retornar false caso algum dado do formulário não esteja correto.

// Função para cancelar os eventos
function cancela_evento( evento ) {
    // Testa se o navegador suporta stopPropagation
    if (evento.stopPropagation){
        // Adiciona stopPropagation
        evento.stopPropagation();        
        // Adiciona preventDefault
        evento.preventDefault();
    } else {
        // Configura returnValue como false para o IE
        evento.returnValue = false;        
        // Cancela a propagação para o IE
        evento.cancelBubble = true;
    }
}

Neste caso, você só precisa enviar o evento que deve ser cancelado e a função fará tudo para você. Não vou entrar em muitos detalhes sobre isso aqui, pois, já falamos sobre isso no artigo sobre eventos em Javascript. Mesmo assim, veja um exemplo:

cancela_evento(qualquer_evento);

Para configurar tudo, você deve fazer algo do tipo:

Arquivo HTML

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">

        <title>Olá mundo!</title>

        <script src="meu_arquivo_javascript.js"></script>
    </head>

    <body>
        <form id="meu_formulario" action="" method="post">
            <input type="text"><br>
            <input type="submit">
        </form>
    </body>
</html>

Arquivo Javascript (meu_arquivo_javascript.js):

// Função para capturar eventos
function captura_eventos(objeto, evento, funcao) {
    // Testa se o navegador suporta addEventListener
    if (objeto.addEventListener) {
        // Adiciona addEventListener
        objeto.addEventListener(evento, funcao, true);
    }
    // Testa se o navegador suporta attachEvent
    else if (objeto.attachEvent) {
        // Adiciona a palavra on no evento
        var evento = 'on' + evento;
        // Adicionar attachEvent
        objeto.attachEvent(evento, funcao);
    }
}

// Função para cancelar os eventos
function cancela_evento(evento) {
    // Testa se o navegador suporta stopPropagation
    if (evento.stopPropagation) {
        // Adiciona stopPropagation
        evento.stopPropagation();
        // Adiciona preventDefault
        evento.preventDefault();
    } else {
        // Configura returnValue como false para o IE
        evento.returnValue = false;
        // Cancela a propagação para o IE
        evento.cancelBubble = true;
    }
}

// Função geral para rodar após o load da página
function geral() {
    // Função para capturar o submit do formulário
    captura_eventos(document.getElementById('meu_formulario'), 'submit', envia_formulario);
}

// Carrega a função geral após o carregamento da página
captura_eventos(window, 'load', geral);

// Função para o submit do formulário
function envia_formulario(evento) {
    // Captura o evento para o IE ou outros navegadores
    var o_evento = evento ? evento : window.event;

    alert('Evento de submit enviado!');

    // Cancela o envio do formulário
    cancela_evento(o_evento);
}

Assustador para quem está iniciando, não é? Mas vou detalhar o que acontece no trecho acima:

No primeiro trecho do código, temos a função que já mencionei, ela vai detectar qual modo de captura de eventos o navegador suporta e capturar o evento do objeto escolhido.

Na segunda parte, temos a função para cancelar o evento em si, como também já descrevi.

A função geral, é a função que irá executar assim que o navegador terminar de carregar a página. Dentro dela, chamei a função para capturar o evento de submit do formulário:

captura_eventos(document.getElementById('meu_formulario'), 'submit', envia_formulario);

Utilizei a propriedade getElementById do objeto "document" em "meu_formulario", enviei o evento "submit" e chamei uma função chamada "envia_formulario", que vai manipular o evento de submit do formulário quando este ocorrer.

Você pode adicionar qualquer outra função que deva ser executada após o carregamento da página dentro da função geral

Abaixo dessa função, chamei novamente a função de captura de eventos para capturar o evento load do objeto window. O terceiro parâmetro da função carrega a função geral (que descrevi agora pouco).

captura_eventos(window, 'load', geral);

Por fim, chamei a função envia_formulario, que é a função que vai manipular o evento de submit do formulário.

// Função para o submit do formulário
function envia_formulario(evento) {
    // Captura o evento para o IE ou outros navegadores
    var o_evento = evento ? evento : window.event;

    alert('Evento de submit enviado!');

    // Cancela o envio do formulário
    cancela_evento(o_evento);
}

Na primeira linha, configurei o evento (porque o IE e outros navegadores capturam eventos de maneira diferente – já vimos isso na última aula), em seguida apresentei um alerta falando que o evento de submit foi enviado, e, por fim, cancelei o evento para que o formulário não fosse submetido. Se você não cancelar um evento, o formulário será enviado para o servidor normalmente, e não fará sentido sua validação, pois a página será atualizada e mesmo alertando o usuário que algo está errado, o formulário continuará sendo enviado.

Trabalhando com campos do formulário

Até aqui, presumo que já tenha entendido como capturar um evento de formulário em Javascript, porém, agora vamos entrar em detalhes sobre os campos desse formulário, tais como checkbox, radio, select, text, password, e demais.

O formulário

Antes de entramos no Javascript em si, precisaremos de um formulário em nosso arquivo HTML, portanto, vou criar um formulário genérico com todos os campos necessários para validação, assim não precisamos ficar modificando nosso HTML cada vez que formos falar de um tipo de campo de formulário.

Coloque o formulário abaixo em seu arquivo HTML:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">

        <title>Olá mundo!</title>

        <script src="meu_arquivo_javascript.js"></script>
    </head>

    <body>
        <form id="meu_formulario" action="" method="post">
            Nome: <input id="nome" name="nome" type="text"><br>
            Sobrenome: <input id="sobrenome" name="sobrenome" type="text"><br>
            Senha: <input id="senha" name="senha" type="password"><br>
            Sexo: <input type="radio" name="sexo" value="m" checked=""> Masculino
            <input type="radio" name="sexo" value="f"> Feminino<br>
            Opções: <select name="opcoes" id="opcoes">
                <option></option>
                <option value="Opção 1">Opção 1</option>
                <option value="Opção 2">Opção 2</option>
                <option value="Opção 3">Opção 3</option>
                <option value="Opção 4">Opção 4</option>
            </select><br>
            Mensagem: <textarea name="mensagem"></textarea><br>
            <input type="submit">
        </form>
    </body>
</html>

Ainda que tenhamos que alterar este formulário ligeiramente, ele já contém a maioria dos campos que vamos precisar para que nossos códigos funcionem.

Select

Em nosso formulário existe um campo select com 5 opções, uma opção em branco e outras 4 opções com texto e valores:

Opções: <select name="opcoes" id="opcoes">
<option></option>
<option value="Opção 1">Opção 1</option>
<option value="Opção 2">Opção 2</option>
<option value="Opção 3">Opção 3</option>
<option value="Opção 4">Opção 4</option>
</select><br>

Para obter acesso a este select, precisamos do objeto que o contém (o formulário), seguido do seu atributo name, por exemplo:

var opcoes = document.getElementById('meu_formulario').opcoes;

Porém, como estamos trabalhando dentro de um evento, podemos fazer isso de uma maneira diferente.

Considere nossa função utilizada para envio (evento submit) do formulário:

// Função para o submit do formulário
function envia_formulario(evento) {
    // Captura o evento para o IE ou outros navegadores
    var evento = evento ? evento : window.event;

    alert('Evento de submit enviado!');

    // Cancela o envio do formulário
    cancela_evento(evento);
}

Até então, não estamos verificando campo nenhum, apenas se o envio foi realizado. Porém, podemos criar uma variável para detectar qual objeto estamos manipulando dentro desse evento (nesse caso, o formulário):

// Obtém o elemento que está sendo tratado no evento (o formulário)
var formulario = evento.target ? evento.target : evento.srcElement;

O trecho acima faz com que o elemento que estamos tratando dentro do evento seja passado para uma variável. Como eu sei que estamos manipulando o formulário, criei uma variável com esse nome para melhor entendimento.

Só para lembrar, qualquer navegador recebe o elemento através da propriedade target, porém, os IEs, de 6 a 8, acessam o elemento através da propriedade srcElement.

Agora que já temos o formulário (elemento do evento), podemos acessar qualquer elemento dentro dele através de seu atributo name, portanto, para acessarmos nosso select, utilizamos o trecho abaixo:

var opcoes = formulario.opcoes;

O trecho acima vai gerar um array com todas as opções do nosso select. Dentro de cada uma das opções, podemos acessar várias propriedades, porém, as propriedades que nos interessam para a validação são: selected, value e text.

  • selected – se a opção está selecionada – retorna true para selecionado e false para não selecionado;
  • value – o valor da opção;
  • text – o texto da opção.

Por exemplo, se eu quiser obter o valor e texto da opção selecionada, eu posso utilizar um laço for para passar por todas as opções, verificar se ela está selecionada e apresentar um alerta com seu valor:

for (var i = 0; i < opcoes.length; i++) {
    if (opcoes[i].selected) {
        alert("Opção: " + opcoes[i].text + " - Valor: " + opcoes[i].value);   
    }
}

O laço acima percorre todas as opções do nosso formulário, verifica se ela está selecionada, e, se estiver, apresenta um alerta com o texto e o valor da opção.

Talvez você queira apenas saber se o usuário selecionou uma opção qualquer e se seu valor não é nulo, para isso basta verificar se a opção tem algum valor e cancelar o envio do formulário se essa não tiver.

// Laço para percorrer todas as opções
for (var i = 0; i < opcoes.length; i++) {
    // Verifica se a opção está selecionada
    if (opcoes[i].selected) {
        // Verifica se o valor está em branco
        if(opcoes[i].value == ""){
            // Alerta o usuário
            alert('Selecione ao menos uma opção.');
            // Cancela o evento de envio do formulário
            cancela_evento(evento);
        }   
    }
}

Se você se perdeu no código, veja como ficou nosso Javascript completo:

// Função para capturar eventos
function captura_eventos(objeto, evento, funcao) {
    // Testa se o navegador suporta addEventListener
    if (objeto.addEventListener) {
        // Adiciona addEventListener
        objeto.addEventListener(evento, funcao, true);
    }
    // Testa se o navegador suporta attachEvent
    else if (objeto.attachEvent) {
        // Adiciona a palavra on no evento
        var evento = 'on' + evento;
        // Adicionar attachEvent
        objeto.attachEvent(evento, funcao);
    }
}

// Função para cancelar os eventos
function cancela_evento(evento) {
    // Testa se o navegador suporta stopPropagation
    if (evento.stopPropagation) {
        // Adiciona stopPropagation
        evento.stopPropagation();
        // Adiciona preventDefault
        evento.preventDefault();
    } else {
        // Configura returnValue como false para o IE
        evento.returnValue = false;
        // Cancela a propagação para o IE
        evento.cancelBubble = true;
    }
}

// Função geral para rodar após o load da página
function geral() {
    // Função para capturar o submit do formulário
    captura_eventos(document.getElementById('meu_formulario'), 'submit', envia_formulario);
}

// Carrega a função geral após o carregamento da página
captura_eventos(window, 'load', geral);

// Função para o submit do formulário
function envia_formulario(evento) {
    // Captura o evento para o IE ou outros navegadores
    var evento = evento ? evento : window.event;
    
    // Obtém o elemento que está sendo tratado no evento (o formulário)
    var formulario = evento.target ? evento.target : evento.srcElement;
    
    // Obtém o campo de select através de seu nome
    var opcoes = formulario.opcoes;

    // Laço para percorrer todas as opções
    for (var i = 0; i < opcoes.length; i++) {
        // Verifica se a opção está selecionada
        if (opcoes[i].selected) {
            // Verifica se o valor está em branco
            if (opcoes[i].value == "") {
                // Alerta o usuário
                alert('Selecione ao menos uma opção.');
                // Cancela o evento de envio do formulário
                cancela_evento(evento);
            }
        }
    }
}

Estamos verificando somente o nosso select no formulário inteiro.

Note que, se você quiser verificar apenas uma opção, não precisa do laço, pode verificar diretamente o valor (value) do seu select. Por exemplo:

if ( opcoes.value == '' ) {
    alert('Selecione ao menos uma opção!');
    cancela_evento(evento);
}

Bem mais simples!

Além disso, você também pode obter o valor de uma opção mencionando seu índice no array com a opção selectedIndex. Por exemplo:

alert(opcoes.selectedIndex);

O alerta acima exibe o índice da opção selecionada pelo usuário no envio do formulário.

Adicionando e removendo opções

Você também pode adicionar ou remover opções dinamicamente utilizando Javascript, veja a seguir.

Para adicionar qualquer opção ao seu select, basta criar um novo elemento Option para o último índice do array de opções, por exemplo:

opcoes[opcoes.length] = new Option('Nova opção', 'Seu valor');

Perceba que para adicionar uma nova opção dinamicamente, utilizei o último índice do array mais um, ou seja, como os índices começam de 0, se eu adicionar um novo índice utilizando o número de opções do meu select, o código vai funcionar, pois, para length (número de opções), o zero conta como uma opção. Para resumir, os índices vão de 0 a 4 (0, 1, 2, 3 e 4), por exemplo, este array tem 5 opções (1, 2, 3, 4 e 5).

Para remover uma opção qualquer, basta configurar o índice da opção desejada como null. Exemplo:

opcoes[1] = null;

Para nosso exemplo, estou removendo a segunda opção (Opção 1).

Validação no evento change

Até agora, estamos apenas checando o formulário quando o usuário tenta enviar os dados (submit), porém, podemos fazer a validação sem que o usuário tenha que clicar no botão para enviar o formulário, por exemplo, quando o usuário mudar uma opção do nosso campo de opções, faz a validação.

Para isso, devemos mudar o elemento que estamos verificando e o evento.

Lembra da nossa função que captura os eventos? Estamos checando o envio do formulário, veja:

captura_eventos(document.getElementById('meu_formulario'), 'submit', envia_formulario);

Porém, eu posso querer verificar apenas meu select, para isso devo fazer o seguinte:

captura_eventos(document.getElementById('opcoes'), 'change', muda_selecao);

Perceba que modifiquei o elemento, agora estou enviando nossas opções diretamente para a função de captura de eventos. O evento também mudou para change, e terei que criar uma outra função para verificar apenas a minha seleção, neste caso, muda_selecao.

Veja a função muda_selecao:

function muda_selecao(evento) {
    // Captura o evento para o IE ou outros navegadores
    var evento = evento ? evento : window.event;

    // Obtém o elemento que está sendo tratado no evento (o select)
    var opcoes = evento.target ? evento.target : evento.srcElement;
    
    alert(opcoes.value);
}

Agora, como não preciso mais do formulário, acesso as opções diretamente no elemento que está sendo tratado pelo evento.

Perceba também, que como não estamos mais trabalhando com o nosso formulário, o identificador do nosso select agora não é mais seu atributo "name", mas seu atributo "id".

Utilizando este método, posso fazer tudo o que descrevi anteriormente, porém, sem enviar o formulário, uma simples mudança de opções captura o evento e faz a verificação que eu quiser.

Por exemplo, suponhamos que eu queira remover um índice das opções assim que este índice for selecionado. Para isso, basta fazer o seguinte:

// Função para o select
function muda_selecao(evento) {
    // Captura o evento para o IE ou outros navegadores
    var evento = evento ? evento : window.event;
    
    // Obtém o elemento que está sendo tratado no evento (o select)
    var opcoes = evento.target ? evento.target : evento.srcElement;
    
    // Captura o índice selecionado
    var indice = opcoes.selectedIndex;
    
    // Remove a opção selecionada
    opcoes[indice] = null;
    
    // Alerta o que foi feito
    alert('Índice ' + indice + ' foi removido');
}

Simplesmente criei uma variável que obtém o valor do índice selecionado (selectedIndex), em seguida, atribuí o valor null para o índice dentro das opções. Por fim, alertei o usuário que o índice que ele selecionou foi removido. Pode ser uma boa opção se você estiver utilizando Ajax para excluir algo na base de dados, por exemplo.

Radio e Checkbox

Para verificar inputs do tipo radio ou checkbox, vamos fazer um pouco diferente. Por isso, vamos voltar o nosso evento principal para o submit do formulário:

// Função geral para rodar após o load da página
function geral() {
    // Função para capturar o submit do formulário
    captura_eventos(document.getElementById('meu_formulario'), 'submit', envia_formulario);
}

E nossa função envia_formulário:

// Função para o submit do formulário
function envia_formulario(evento) {
    // Captura o evento para o IE ou outros navegadores
    var evento = evento ? evento : window.event;
    
    // Obtém o elemento que está sendo tratado no evento (o formulário)
    var formulario = evento.target ? evento.target : evento.srcElement;

    // Cancela o envio do formulário
    cancela_evento(evento);
}

Para acessar nossos inputs dentro do formulário, podemos utilizar uma nova função, getElementsByTagName. Essa opção nos retorna todos os elementos de uma determinada tag para um array.

Por exemplo, sabemos que os campos para radio e checkbox, seus tipos (type) devem ser radio ou checkbox.

Sexo: <input type="radio" name="sexo" value="m"> Masculino
<input type="radio" name="sexo" value="f"> Feminino<br>

No exemplo acima temos duas opções sobre o sexo da pessoa, masculino e feminino. Perceba que o atributo type dos inputs é radio, e seu atributo name tem o mesmo valor em ambos os inputs, sexo.

Eu posso verificar algumas coisas no meu código Javascript para saber exatamente qual campo estou manipulando, por exemplo, o tipo do input, seu atributo name e assim por diante.

Perceba como vou verificar todos os campos input do meu formulário:

// Obtém o elemento que está sendo tratado no evento (o formulário)
var formulario = evento.target ? evento.target : evento.srcElement;

// Obtém o campo de select através de seu nome de tag
var radios = formulario.getElementsByTagName('input');

Ou seja, acesso a opção getElementsByTagName('input') do formulário, e agora tenho um array com todos os inputs. Porém, isso inclui outros inputs que não desejo, como nome, senha e outros.

Para especificar que desejo apenas os inputs do tipo radio, devo percorrer este array verificando o tipo de cada input utilizando um laço:

// Variável para verificar se os campos estão marcados
var marcado = false;

// Laço para percorrer os inputs
for(var i = 0; i < radios.length; i++){
    // Verifica se o tipo do input é radio e o nome é sexo
    if (radios[i].type == 'radio' && radios[i].name == 'sexo'){
        // Verifica se o input radio está marcado
        if (radios[i].checked) {
            // Configura a variável marcado como true
            marcado = true;
        }
    }
}

// Verifica se a variável marcado é falsa
if (!marcado){
    alert('Selecione seu sexo!');
    // Cancela o envio do formulário
    cancela_evento(evento);
}

O trecho de código acima está documentado, você pode entender pelos comentários, porém, vou explicar:

Primeiramente, criei uma variável com valor booleano falso; em seguida, criei um laço para percorrer todos os meus inputs. Dentro desse laço, verifico a propriedade type do input para saber se ele é do tipo radio, também verifico a propriedade name para saber se o nome do input é sexo. Por fim, verifico se o input está marcado (checked), se sim, configuro a variável marcado para true.

Depois só preciso verificar se a variável marcado ainda está como false, se sim, significa que o usuário não marcou nenhum input radio com nome sexo. Pronto!

Se você precisar acessar o valor do input marcado, basta utilizar a opção value dentro do laço:

// Laço para percorrer os inputs
for(var i = 0; i < radios.length; i++){
    // Verifica se o tipo do input é radio e o nome é sexo
    if (radios[i].type == 'radio' && radios[i].name == 'sexo'){
        // Verifica se o input radio está marcado
        if (radios[i].checked) {
            alert(radios[i].value);
        }
    }
}

Para checkbox é a mesma coisa, só preciso mudar a verificação de radio para checkbox.

Outro método de seleção do seu grupo de inputs do tipo radio, é pelo seu atributo name. Para isso basta mudar uma linha do nosso código:

// Mude isso
var radios = formulario.getElementsByTagName('input');

// Para isso
var radios = formulario.sexo;

É a mesma coisa, porém, agora você terá apenas os inputs do tipo radio com o atributo name igual a sexo.

Se você estiver perdido no código, segue abaixo o trecho completo:

// Função para capturar eventos
function captura_eventos(objeto, evento, funcao) {
    // Testa se o navegador suporta addEventListener
    if (objeto.addEventListener) {
        // Adiciona addEventListener
        objeto.addEventListener(evento, funcao, true);
    }
    // Testa se o navegador suporta attachEvent
    else if (objeto.attachEvent) {
        // Adiciona a palavra on no evento
        var evento = 'on' + evento;
        // Adicionar attachEvent
        objeto.attachEvent(evento, funcao);
    }
}

// Função para cancelar os eventos
function cancela_evento(evento) {
    // Testa se o navegador suporta stopPropagation
    if (evento.stopPropagation) {
        // Adiciona stopPropagation
        evento.stopPropagation();
        // Adiciona preventDefault
        evento.preventDefault();
    } else {
        // Configura returnValue como false para o IE
        evento.returnValue = false;
        // Cancela a propagação para o IE
        evento.cancelBubble = true;
    }
}

// Função geral para rodar após o load da página
function geral() {
    // Função para capturar o submit do formulário
    captura_eventos(document.getElementById('meu_formulario'), 'submit', envia_formulario);
}

// Carrega a função geral após o carregamento da página
captura_eventos(window, 'load', geral);

// Função para o submit do formulário
function envia_formulario(evento) {
    // Captura o evento para o IE ou outros navegadores
    var evento = evento ? evento : window.event;

    // Obtém o elemento que está sendo tratado no evento (o formulário)
    var formulario = evento.target ? evento.target : evento.srcElement;

    // Obtém os campos de radio através de seu nome
    var radios = formulario.sexo;

    // Laço para percorrer os inputs
    for (var i = 0; i < radios.length; i++) {
        // Verifica se o input radio está marcado
        if (radios[i].checked) {
            alert(radios[i].value);
        }
    }

    // Cancela o envio do formulário
    cancela_evento(evento);
}

Outra coisa que você pode fazer, é criar um novo elemento e incluí-lo no seu formulário. Por exemplo, para incluir um novo checkbox no seu formulário, basta fazer o seguinte:

// Cria um novo input
var novo_checkbox = document.createElement('input');

// Configura o tipo do input como checkbox
novo_checkbox.type = 'checkbox';

// Configura o atributo name
novo_checkbox.name = 'nome_do_campo';

// Marca o novo checkbox
novo_checkbox.checked = true;

// Inclui o novo checkbox ao final do formulário
formulario.appendChild(novo_checkbox);

Simples assim!

Text, Password, Hidden e Textarea

Deixei os campos de texto por último por eles serem mais simples para conseguirmos acesso aos seus valores. Campos de texto têm simplesmente um único valor, e são os que mais devem ser verificados, pois, neles o usuário vai digitar o que quiser.

Para obter acesso a um campo de texto, basta utilizar seu atributo name, por exemplo:

// Obtém o elemento que está sendo tratado no evento (o formulário)
var formulario = evento.target ? evento.target : evento.srcElement;

// Obtém o valor do campo nome e demais campos de texto
var nome = formulario.nome.value;
var sobrenome = formulario.sobrenome.value;
var senha = formulario.senha.value;
var mensagem = formulario.mensagem.value;

alert('Nome: ' + nome);
alert('Sobrenome: ' + sobrenome);
alert('Senha: ' + senha);
alert('Mensagem: ' + mensagem);

Daqui em diante, você pode fazer o que quiser com as variáveis criadas com os valores dos campos de texto (value). Por exemplo, verificar se as variáveis foram preenchidas:

if (nome == '') {
    alert('Preencha seu nome!');
    
    // Para aqui
    return false;
}
if (sobrenome == '') {
    alert('Preencha seu sobrenome!');
    
    // Para aqui
    return false;   
}
if (senha == '') {
    alert('Preencha sua senha!');
    
    // Para aqui
    return false;   
}
if (mensagem == '') {
    alert('Preencha sua mensagem!');
    
    // Para aqui
    return false;  
}

Ou utilizar alguma expressão regular para validar o valor do campo.

Campos de texto também aceitam outros eventos, como focus (quando o usuário entra no campo), ou blur, quando o usuário sai do campo. Veja um exemplo do evento adicionado ao campo nome.

// Função geral para rodar após o load da página
function geral() {
    // Função para capturar o submit do formulário
    captura_eventos(document.getElementById('meu_formulario'), 'submit', envia_formulario);

    // Função para capturar o evento focus do campo name
    captura_eventos(document.getElementById('nome'), 'focus', entrou_no_campo);

    // Função para capturar o evento focus do campo name
    captura_eventos(document.getElementById('nome'), 'blur', saiu_do_campo);
}

function entrou_no_campo(evento){
    // Captura o evento para o IE ou outros navegadores
    var evento = evento ? evento : window.event;

    // Obtém o elemento que está sendo tratado no evento (o formulário)
    var campo_nome = evento.target ? evento.target : evento.srcElement; 
    
    campo_nome.value = 'Entrou no campo.';
}

function saiu_do_campo(evento){
    // Captura o evento para o IE ou outros navegadores
    var evento = evento ? evento : window.event;

    // Obtém o elemento que está sendo tratado no evento (o formulário)
    var campo_nome = evento.target ? evento.target : evento.srcElement; 
    
    alert('Sai do campo, valor: ' + campo_nome.value);
}

É simplesmente uma função boba, ela faz o seguinte: quando o usuário acessa o campo nome (focus), apaga o que estiver no campo e incluir o valor "Entrou no campo.", quando o usuário sai do campo (blur), alerta que ele saiu do campo e o valor que está nele. Era só pra você entender que também da para validar campos na entrada e na saída do mesmo.

Código de validação completo

Agora que falei praticamente tudo o que você poderia querer saber sobre validar formulários em Javascript, veja uma validação simples que fiz em nosso formulário de exemplo:

Arquivo Javascript:

// Função para capturar eventos
function captura_eventos(objeto, evento, funcao) {
    // Testa se o navegador suporta addEventListener
    if (objeto.addEventListener) {
        // Adiciona addEventListener
        objeto.addEventListener(evento, funcao, true);
    }
    // Testa se o navegador suporta attachEvent
    else if (objeto.attachEvent) {
        // Adiciona a palavra on no evento
        var evento = 'on' + evento;
        // Adicionar attachEvent
        objeto.attachEvent(evento, funcao);
    }
}

// Função para cancelar os eventos
function cancela_evento(evento) {
    // Testa se o navegador suporta stopPropagation
    if (evento.stopPropagation) {
        // Adiciona stopPropagation
        evento.stopPropagation();
        // Adiciona preventDefault
        evento.preventDefault();
    } else {
        // Configura returnValue como false para o IE
        evento.returnValue = false;
        // Cancela a propagação para o IE
        evento.cancelBubble = true;
    }
}

// Função geral para rodar após o load da página
function geral() {
    // Função para capturar o submit do formulário
    captura_eventos(document.getElementById('meu_formulario'), 'submit', envia_formulario);

    // Função para capturar o evento focus do campo name
    captura_eventos(document.getElementById('nome'), 'focus', entrou_no_campo);

    // Função para capturar o evento focus do campo name
    captura_eventos(document.getElementById('nome'), 'blur', saiu_do_campo);
}

function entrou_no_campo(evento){
    // Captura o evento para o IE ou outros navegadores
    var evento = evento ? evento : window.event;

    // Obtém o elemento que está sendo tratado no evento (o formulário)
    var campo_nome = evento.target ? evento.target : evento.srcElement; 
    
    campo_nome.value = 'Entrou no campo.';
}

function saiu_do_campo(evento){
    // Captura o evento para o IE ou outros navegadores
    var evento = evento ? evento : window.event;

    // Obtém o elemento que está sendo tratado no evento (o formulário)
    var campo_nome = evento.target ? evento.target : evento.srcElement; 
    
    alert('Sai do campo, valor: ' + campo_nome.value);
}

// Carrega a função geral após o carregamento da página
captura_eventos(window, 'load', geral);

// Função para o submit do formulário
function envia_formulario(evento) {
    // Captura o evento para o IE ou outros navegadores
    var evento = evento ? evento : window.event;

    // Obtém o elemento que está sendo tratado no evento (o formulário)
    var formulario = evento.target ? evento.target : evento.srcElement;

    // Obtém o campo de select através de seu nome
    var nome = formulario.nome.value;
    var sobrenome = formulario.sobrenome.value;
    var senha = formulario.senha.value;
    var radios = formulario.sexo;
    var opcoes = formulario.opcoes;
    var mensagem = formulario.mensagem.value;
    
    // Verifica se os campos de texto foram preenchidos
    if (nome == '' || 
        sobrenome == '' || 
        senha == '' || 
        mensagem == '') {
        alert('Você não preencheu todos os campos de texto!');
        cancela_evento(evento);
        return false;
    }
    
    // Variável para verificar os radios
    var marcados = false;
    // Verifica os radios
    for(var i=0; i < radios.length; i++){
        if(radios[i].checked){
            marcados = true;
        }
    }
    
    if(!marcados) {
        alert('Selecione seu sexo!');
        cancela_evento(evento);
        return false;
    }
    
    if(opcoes.value == ''){
        alert('Escolha ao menos uma das opções');
        cancela_evento(evento);
        return false;
    }
    
    alert('Formulário será enviado e a página atualizada agora!');
}

Arquivo HTML

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">

        <title>Olá mundo!</title>

        <script src="meu_arquivo_javascript.js"></script>
    </head>

    <body>
        <form id="meu_formulario" action="" method="post">
            Nome: <input id="nome" name="nome" type="text"><br>
            Sobrenome: <input id="sobrenome" name="sobrenome" type="text"><br>
            Senha: <input id="senha" name="senha" type="password"><br>
            Sexo: <input type="radio" name="sexo" value="m"> Masculino
            <input type="radio" name="sexo" value="f"> Feminino<br>
            Opções: <select name="opcoes" id="opcoes">
                <option></option>
                <option value="Opção 1">Opção 1</option>
                <option value="Opção 2">Opção 2</option>
                <option value="Opção 3">Opção 3</option>
                <option value="Opção 4">Opção 4</option>
            </select><br>
            Mensagem: <textarea name="mensagem"></textarea><br>
            <input type="submit">
        </form>
    </body>
</html>

Bem simples, mas para que você possa entender e manipular todo o código.

Se tiver dúvidas, basta perguntar nos comentários.

Outras aulas

Caso tenha perdido a aula anterior, segue o link:

Próxima aula:

Caso queira visualizar todas as aulas dessa sessão em ordem cronológica invertida: