Melhorar progressivamente um formulário a um formulário Modal

Com algo tão importante como uma forma de contato, você quer trabalhar corretamente para todos os visitantes e até mesmo o JavaScript desafiado. Como você lida com isso se você quiser usar um modal (pop-up forma)? A resposta é reforço progressivo; começar com a funcionalidade de base, utilizáveis, em seguida, aumentar a experiência do usuário para aqueles que têm browsers para apoiá-lo.


Etapa 1: Decidir sobre o Projeto Gols

Antes de iniciar qualquer viagem, ajuda (na maioria das vezes) para ter um destino. O objetivo deste projeto é fazer um link para uma página padrão que contém um formulário de contato e permitir que formam a pop-up na página atual em uma caixa de diálogo modal.

Há várias razões para essa abordagem:

  • Se o usuário tem JavaScript desativado, elas são enviadas para a página de formulário de contato, como de costume.
  • Somente uma versão do formulário deve ser mantido.
  • O conteúdo adicional (a forma) podem ser carregados de forma assíncrona.
Um formulário Modal

Passo 2: Lista das ferramentas

Para escrever este a partir do zero em JavaScript-primas seria um monte de código. Felizmente para nós, existem ferramentas existentes que podemos aproveitar para fazer a tarefa mais fácil. Este tutorial baseia-se em:

Para fazer esse código como reutilizáveis possível, nós vamos escrever um plug-in. Se você não estiver familiarizado com o autor de um plug-in, você pode começar uma introdução de Jeffrey's Way artigo aqui no NETTUTS + . A funcionalidade modal virá de diálogo $. JQuery-UI.

Plug-In Theory

Passo 3: Criar a interface plug-in

Nós vamos seguir o padrão normal para uma jQuery plug-in: chamar o plug-in em um seletor e configurar as opções via matriz. Quais as opções que são necessários? Haverá opções tanto para a janela modal e para o próprio plug-in. Vamos esperar o plug-in para ser chamado de âncora, e impor que, no código.


$ ('A.form_link) popUpForm. ((
container:''
modais: true,
resizeable: false,
width: 440,
Formulário de título: 'Website',
beforeOpen: função container () ()
onSuccess: função container () ()
onError: função container () ()
));

Examinar as opções

Container: Isto é como o plug-in usuário especificar a identificação do formulário na página remoto. O link se especifica a página, mas a opção recipiente permitirá buscar a parte em questão. Esta será a única opção quando necessário chamar o plug-in.

Modal, Resizeable, largura Título: Essas opções estão todos indo para ser repassada ao consumidor jQuery. US $ diálogo UI. Os valores acima são padrões eo plug-in vai funcionar muito bem sem qualquer um destes que está sendo ajustado quando popUpForm $. É chamado.

beforeOpen, onSuccess onError: Estes são todos os retornos, e esperam uma função. A função será passado o objeto para o link que foi clicado como 'presente' e do recipiente para que esse link é direcionado. Callbacks são projetados para permitir a funcionalidade personalizada para os usuários de um plug-in. O padrão para esses callbacks será uma função vazia.

O código mínimo necessário para usar o plug-in, então, algo como isto:


$ ('A.form_link) popUpForm. ((Recipiente:' # form_id '));

Isso parece simples, não é? Quando você chamar um plug-in como este, o plug-in do código é chamado com uma coleção jQuery de todos os elementos DOM correspondente ao selector, que estará disponível na variável especial "isto".


Etapa 4: O Plug-do esqueleto em

A maioria jQuery plug-ins seguem um padrão muito semelhante. Eles iterar sobre o grupo de seletores e fazer tudo o que eles fazem. Eu tenho uma base plug-in "esboço" Costumo trabalhar e vai se encaixar muito bem aqui. Este seria o início de seu plug-in do arquivo, popUpForm.jquery.js.


(Function ($) (
função $. fn.popUpForm = (options) (

/ / Defaults e opções
defaults = (var
container:''
modais: true,
resizeable: false,
width: 440,
Formulário de título: 'Website',
beforeOpen: função container () ()
onSuccess: função container () ()
onError: função container () ()
);
opta var = $. estender ((), padrões, opções);

self.each (function () (

/ / O REAL trabalho acontece aqui.
/ / No âmbito desta função "isto" se refere a um único
/ DOM elemento dentro da coleção jQuery (e não um obj jQuery)
));
)
)) (JQuery);

O código é envolto em uma função de auto-execução, e acrescenta-se a jQuery usando o namespace $ fn.. O seguinte identificador $. Fn é o nome do método que você usará para invocá-lo.

Nós também estamos seguindo boas práticas de codificação, passando a variável jQuery explicitamente. Isso vai nos impedir de ficar em apuros se o plug-in é usado em uma página com outros frameworks JavaScript, algumas das quais utilizam $ como uma variável.

Em seguida, uma matriz de valores padrão é criado, e esses padrões serão usadas se não forem definidos quando o plug-in é chamado. A linha imediatamente a seguir os padrões de matriz mescla o passado com as opções padrão e armazena-los todos na matriz opta.

Finalmente, um loop é criado para iteração sobre a coleção jQuery identificados pelo selector quando o plug-in é chamado .. Embora as chances são na maioria das situações, será um único item (âncora), ainda vai lidar com vários links com uma única chamada - supondo-se que toda a carga da mesma forma.

Uma coisa importante a entender é que o valor da variável especial 'this' muda quando entramos no loop self.each, é um método jQuery especial destinada a fazer coleções DOM looping mais fácil. A função de callback usa o contexto do elemento DOM atual, então a variável "isto" refere-se a esse elemento dentro do loop.

Você pode ver em um exemplo muito simples como "isto" se refere a uma coleção de objetos jQuery jQuery no plug-in âmbito da função, mas dentro do ciclo cada um, "isto" se refere a um único elemento DOM não jQuery.

O escopo do presente

Passo cinco: Iniciando o Guts

O código para próximas seções são todos contidos dentro do bloco self.each do nosso esqueleto. O que fazemos agora? Para cada elemento jQuery passado, não vão ser vários passos a tomar:

  • Certifique-se que é um link, e que vai em algum lugar
  • Buscar a parte da página remoto especificado
  • Anexar o formulário de controle remoto para a página e criar um diálogo oculto para ele
  • Roube o link para que ele cria o nosso pop-up
  • submissões de forma Handle estilo AJAX

Antes de fazer qualquer um dos que, no entanto, vamos adicionar uma linha de código dentro do callback, logo no início


var $ this = $ (this);

Isso é mais do que apenas a conveniência, a variável "isto" vai sair do âmbito de eventuais encerramentos dentro do ciclo cada um, e vamos precisar de acesso ao objeto atual posteriormente. Desde que nós quase sempre quer como um objeto jQuery, nós estamos armazenando-o como um.


Passo 6: Certifique-se o elemento é válido

$. PopUpForm só vai funcionar com marcas de âncora, ea âncora deve ter um valor href para que saibam onde buscar a forma de. Se qualquer dessas condições não for cumprida, vamos deixar o elemento sozinho. A segunda linha do nosso 'coragem' será:


if (! $ this.is ('a') | | $ this.attr ('href') =='') (return;)

Algumas pessoas odeiam retorno pontos múltiplos em uma função, mas eu sempre achei ter um no início pode fazer uma função mais legível, em vez de usar um if (condição) para envolver o resto da função. Em termos de desempenho, eles são idênticos.


Passo 7: Obter o de De Page Remote

Os US $. Carga método tem uma funcionalidade interessante que permite uma chamada para especificar e ID, a fim de anexar apenas parte de um documento obtido. O script não irá anexar o HTML retornado diretamente para o DOM, porque carga de $. Só substitui, não acrescentar.


var SRC = $ this.attr ('href') opts.container + '' +;
formDOM var = $ (/> <div "). carga (SRC, function () (

O opts.container variável tem a identificação do elemento de formulário na página remoto. As cargas de segunda linha esta página remoto, e atribui a forma e seu conteúdo para um div, a totalidade do que é armazenado no formDOM variável. Observe que $. Carga inclui um callback (função) - usaremos formDOM dentro desse retorno.


Passo 8: Coloque o código HTML e criar o diálogo

Dentro da carga de retorno $., o código vai anexar o formulário, substituir o evento clique do âncora, e substituir o caso de submeter o formulário.

O formulário HTML é armazenado na variável formDOM neste momento, e anexá-lo à página existente é fácil.


$ ('# PopUpHide). Append (formDOM);

O popUpHide # id se refere a um div escondido que acompanha a página, o plug-in. A fim de garantir que div, a seguinte linha será adicionada no topo do plug-in. Se já existe, não recriá-lo.


$ ("# PopUpHide"). | Comprimento | $ ('<div id="popUpHide" />) appendTo. ("Corpo"). CSS (' display ',' none ');

Agora que o formulário está oculto distância segura em nossa página, é hora de usar uma chamada para o $. Diálogo método para criar o formulário. A maior parte do set-up params são tomadas a partir de nosso plug-in. A opção 'AutoOpen é codificado pois queremos que o diálogo seja aberta quando o link for clicado, e não quando o diálogo é criado.


/ / Criar e armazenar o diálogo
$ (Opts.container). Diálogo ((
AutoOpen: false,
width: opts.width,
modal: opts.modal,
resizable: opts.resizeable,
Título: opts.title
));

Passo 9: Evento substituir o tratamento padrão

Se paramos aqui, o plug-in não estaria fazendo muito. O link ainda levar-nos para a próxima página. O comportamento que desejamos é que o link para abrir o diálogo.


this.bind $ ('click', function (e) (
e.preventDefault ();
opts.beforeOpen.call ($ this [0], opts.container);
$ (Opts.container). Dialog ('open');
));

A primeira linha do manipulador de clique é muito importante. Ela pára o link de carregar a nova página quando é clicada.

A segunda linha é a nossa "callback beforeOpen. O opts.beforeOpen variável contém uma referência de função - isso é óbvio. A. Chamada de método é usado para chamar a função de uma maneira que podemos fornecer o contexto - o 'this' variável para essa função. O primeiro argumento passado torna-se 'presente' para a função chamada.

Quando uma função tem acesso à variável "isto" há alguns contratos JavaScript tem com o programador que devemos manter.

  • O "isto" variável deve ser o objeto atua sobre a função
  • O "isto" variável é um objeto DOM único

Para manter esse contrato, nós passamos $ this [0] ao invés de $ this. $ This 0] [representa um único, não jQuery objeto DOM.

Para ajudar a compreender isto um pouco melhor, imagine a seguinte função de callback:


função opts.beforeOpen = (recipiente) (

/ / Dá o valor do link que você acabou de clicar
alert ('The página remoto é o this.href +);

/ / Dá o recipiente id atribuído a este link
alert ('E o recipiente é' container +);
)

O clique no link não é o comportamento padrão apenas para substituir. Queremos também que o formulário para enviar via AJAX, por isso o evento onsumbit forma normal deve ser evitada e um novo comportamento codificado.


$ (Opts.container). Bind ('enviar', function (e) (
e.preventDefault ();
ajaxSubmit ();
));

Novamente, usamos preventDefault () para interromper o evento, e neste caso, adicionar uma nova função para lidar com a submissão do formulário. O ajaxSubmit () código pode ir diretamente no retorno, mas foi transferido para uma nova função para facilitar a leitura.


Passo 10: Manipular envios de formulários, de estilo AJAX

Essa função será adicionada imediatamente após o final do loop self.each (não se preocupe, você vai ver todo o plug-shot no código em um só um pouco). Ele toma a forma, submete-lo para um script remoto e aciona o callbacks adequado.

O primeiro passo é obter a forma como um objeto jQuery, e determinar o método do formulário, os métodos GET ou POST.


ajaxSubmit função () (
forma var = $ opts.container ();
método var = form.attr ('method') | | 'GET';

Se você lembrar, nós ID armazenada sob a forma em opts.container. As verificações próxima linha a forma de um método, e atribui 'GET', se nenhum método é presente. Isto é consistente com HTML que usa GET por padrão nos formulários que nenhum método é especificado.

Use o $. Ajax método para enviar o formulário:


$. Ajax ((
Tipo: Método,
url: form.attr ('action'),
dados: form.serialize ()
sucesso: function () (
$ (Opts.container). Dialog ('fechar');
opts.onSuccess.call ($ this [0], opts.container);
)
erro: function () (
$ (Opts.container). Dialog ('fechar');
opts.onError.call ($ this [0], opts.container);
)
));

A opção é determinada URL do atributo action da tag form. Os dados são produzidos usando o método serialize no jQuery objeto que contém o formulário.

O sucesso e as opções de erro é de US $. Ajax callbacks, que por sua vez, está usando para chamar nossa callbacks, da mesma forma que o retorno beforeOpen foi invocado.

Estamos também a fechar a janela de tanto sucesso e manipuladores de erro.


Passo 11: todo o Plug-In

Como uma revisão, vamos olhar para o código que tenho escrito até agora como um todo, incluindo alguns comentários de código úteis:


(Function ($) (
ALOG var = window.console? console.log: alerta;

função $. fn.popUpForm = (options) (
/ / Requer um recipiente
if (! options.container) (alert ('Container opção desejada'); return;)

/ Dá-nos um lugar para anexar formas
$ ("# PopUpHide"). | Comprimento | $ ('<div id="popUpHide" />) appendTo. ("Corpo"). CSS (' display ',' none ');

/ / Defaults e opções
defaults = (var
container:''
modais: true,
resizeable: false,
width: 440,
Formulário de título: 'Website',
beforeOpen: função container () ()
onSuccess: função container () ()
onError: função container () ()
);
opta var = $. estender ((), padrões, opções);

/ / O "this" dentro do ciclo cada um se refere ao item único DOM
/ / Da coleção jQuery atualmente estamos operando em
this.each (function () (
/ * Nós queremos manter o valor "isto" disponível para o $. Carga
* Callback /
var $ this = $ (this);

/ * Só querer processar um item se ele é um link e
* Tem um valor de href
* /

if (! $ this.is ('a') | | $ this.attr ('href') =='') (return;)

/ * Para a $. Load () função, o parâmetro é a url seguido
* O seletor de ID para a seção da página para pegar
* /
var SRC = $ this.attr ('href') opts.container + '' +;

/ * Caso de ligação é feito em chamar de volta, caso o
* Forma não carregar, ou o usuário clica no link antes
* O modal está pronto
* /
formDOM var = $ (/> <div "). carga (SRC, function () (
/ / Adiciona a página
$ ('# PopUpHide). Append (formDOM);

/ / Criar e armazenar o diálogo
$ (Opts.container). Diálogo ((
AutoOpen: false,
width: opts.width,
modal: opts.modal,
resizable: opts.resizeable,
Título: opts.title
));

/ * Interrompe o envio do formulário normal, tinha que vir depois
* Criar a janela de outro modo a forma não existe
* Ainda colocar um manipulador de eventos para
* /
$ (Opts.container). Bind ("submit", function (e) (
e.preventDefault ();
ajaxSubmit ($ this [0]);
));

/ / Cria uma ligação para a ligação passados para o plug-in
this.bind $ ("click", function (e) (
e.preventDefault ();
opts.beforeOpen.call ($ this [0], opts.container);
$ (Opts.container). Dialog ('open');
));
));

));

ajaxSubmit função (anchorObj) (
console.log (anchorObj);
forma var = $ opts.container ();
método var = form.attr ('method') | | 'GET';

$. Ajax ((
Tipo: Método,
url: form.attr ('action'),
dados: form.serialize ()
sucesso: function () (
$ (Opts.container). Dialog ('fechar');
opts.onSuccess.call (anchorObj, opts.container);
)
erro: function () (
opts.onError.call (anchorObj, opts.container);
)
));
)
)
)) (JQuery);

Este código deve ser todos salvos em um arquivo chamado popUpForm.jquery.js


Passo 12: Configurar o Plug-In

O primeiro passo no plug-in de uso seria para incluir todas as dependências necessárias em sua página HTML. Pessoalmente eu prefiro usar o Google CDN. Os arquivos de estar em um domínio separado pode ajudar a velocidade de carregamento da página, e os servidores são rápidos. Além disso, ela aumenta as chances de um visitante que já terá esses arquivos em cache.

No HEAD do documento HTML, adicione o seguinte:


rel="stylesheet" <link href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/black-tie/jquery-ui.css" type="text/css" />
rel="stylesheet" <link href="css/main.css" type="text/css" />

<Src='http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js'> <script / script>
<Src='http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.2/jquery-ui.min.js'> <script / script>

O arquivo main.css é para o nosso site estilos específicos, tudo o resto é de CDN Google. Observe que você pode até usar temas jQuery UI-do CDN desta forma.


Passo 13: Invocando o Plug-In

Lembre-se, nós só queremos chamar o plug-in em links que levam a uma página de formulário. Na demo online, as formas estão contidas na form.html, e apenas dois links vá para essa página.


<script>
$ (Document). Ready (function () (
$ ('Contato. A') popUpForm. ((
modalform recipiente: '#',
onSuccess: function () (alert ('Obrigado pelo seu interesse!');)
onError: function () (alert ('Desculpe, ocorreu um erro ao enviar o seu formulário.');)
));

$ ('Inquérito. A') popUpForm. (('Container': 'othercontainer #'));
));
</ Script>

Os convites são embalados em um bloco document.ready assim podemos ter a certeza da âncora elementos existem antes de tentar actuar sobre elas. A segunda chamada, $ ('inquérito. A') é um exemplo do valor mínimo necessário para usar o novo plug-in. O primeiro exemplo define um retorno tanto para onSuccess e onError.


Passo 14: Styling o Modal

Se você chegou agora, e você criou formas e exemplos de uma página para chamá-los de, você pode notar a forma como o modal é, provavelmente, bem feio. O modal em si não é ruim, porque nós estamos usando um tema-jQuery UI. Mas a forma dentro do modal é mais sem estilo, por isso, devemos fazer alguns esforços para bem acima.

O formulário sem estilo

Há algumas coisas para manter em mente ao criar estilos para uso em jQuery UI-modal:

  • O modal em si é apenas uma criança do elemento body da página
  • O conteúdo do modal são todos filhos de uma div da classe 'ui de diálogo'

Usando esses pequenos pedaços de informação que nós podemos começar a aplicar estilos para o formulário no modal. Primeiramente nós damos a cor de um modal de fundo estamos felizes com, e também modificar a fonte para a barra de título.


. Ui de diálogo (
background: rgb (237237237);
font: 11px verdana, arial, sans-serif;
)
. Ui diálogo. Ui-subtítulo de diálogo (
font: small-caps bold 24px Georgia, Times, serif;
)

Em seguida, queremos separar cada item, sob a forma de linhas. Desde que a estrutura de forma suplentes H3s com divs que contenham elementos de formulário, nós adicionamos as seguintes regras:


. H3 ui de diálogo,
. Div (ui de diálogo
border-top: 1px sólida rgb (247247247);
border-bottom: 1px sólida rgb (212212212);
padding: 8px 0 12px 10px;
)

E nós só queremos as linhas entre as partes, e não no topo ou muito baixo.


. Ui diálogo. PuForm div: last-child (
border-bottom: none;
)
. Ui diálogo. PuForm h3: first-child (
border-top: none;
)

Não esqueçamos que o estilo H3s, e os elementos do formulário. Os botões de rádio precisam mostrar inline que eles estão todos em uma linha.


. H3 (ui de diálogo
font: 18px Georgia, Times, serif;
margin: 0;
)
. Seleccionar ui de diálogo,
. Textarea ui de diálogo,
. Input (ui de diálogo
width: 76%;
display: block;
)
. Rating ui entrada de diálogo #
. Rótulo de classificação de diálogo ui # (
display: inline;
width: auto;
)

Lembre-se, esses estilos são específicas para este projeto, você terá ao seu estilo de formulários próprios, dependendo de qual a estrutura que você usa. Para direcionar os elementos de formulário específico, pode-alvo descendentes. Ui diálogo, ou o estilo de cada formulário individualmente, incluir estilos decrescente a partir do formulário de identificação que você incluiu.

O formulário de estilo:

O formulário Styled

Passo 15: Conclusão

Então o que temos feito realmente? Temos tido uma ligação normal levando a um formulário de contacto (ou formas) e fez com que forma a carga em uma caixa de diálogo modal, e enviar via ajax. Para os usuários sem javascript, nada acontece e as ligações se comportar normalmente, então não pararam de alguém de preencher os formulários.

Se você clicar no link pesquisa no demo, não se esqueça de apresentar algo. Vou postar os resultados nos comentários para se divertir depois de uma semana mais ou menos!

Nenhum comentário: