Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Zinhani

Enviando formulário sem refresh na página.

Recommended Posts

Olá pessoal,

 

Preciso de ajuda para adaptar esse script http://faael.net/envio-de-formulario-sem-refresh-com-jquery-php/ ao meu sistema.

Sei que não é lugar para tal fazer esse tipo de proposta, mas ofereço até uns 100 conto pra quem resolver esse problema (infelizmente não dá pra pagar mais).

Entretanto, se alguem na boa vontade puder esclarecer alguns pontos dos meus problemas vou agradecer.

 

O código do fael esta funcionando perfeitamente no meu servidor.

O problema foi quando tentei adaptar ele ao meu sistema ja pronto.

 

O sistema está composto de uma index unica onde pega as páginas via get e inclui na index, além de estar com url amigavel.

Ex: www.meusite.com.br/contato

 

Vamos aos problemas:

 

1- a primeira questão é apenas uma dúvida. No código do fael vejo que tudo é feito por jquery, mas comparando com alguns outros scripts percebi que eles usam XMLHttpRequest e o fael não usa. Oq isso tem de diferente?

 

2- na minha index eu tenho uma validação <noscript>. E quando coloquei o script no meu form e cliquei em submit para testar, ele simplesmente redirecionou para o link do noscript como se a aplicação não fosse reconhecida pelo navegado. Não entendi porque isso aconteceu. E quando eu retirei o noscript ele funcionou.

 

3- Como dito, ele funcionou, mas a index tratou a resposta html do enviar.php como um include e causou uma duplicidade de conteudo. ou seja, a resposta do enviar.php ficou na forma de uma index (repetindo o cabeçalho, corpo e rodapé da index) dentro da div #status. É como se eu desse um include da minha propria index dentro dela mesmo. coisa de loco... Tbm não faço a menor ideia porque isso ocorreu. O que teria haver o ($.post('envia.php', ...) em relação ao get q a index faz para incluir as paginas?

 

4- No geral, ao clicar no submit ele valida corretamente, gera o loader, e carrega a resposta. Porém, com os problemas acima.

 

 

Vou tentar upar os arquivos para vcs olharem, mas acredito que não fará muita diferença.

 

De qualquer forma, se puderem até indicar novos scripts par eu estudar tbm ficarei grato.

 

Lembrando, que não necessáriamente o form precisa ser de um Contato.

A questão é: enviar um post, validar, criar um load, inserir os dados no sql e retornar uma respota.

Tudo de forma sem que ele de refresh na página.

 

Abraços.

Compartilhar este post


Link para o post
Compartilhar em outros sites

1- a primeira questão é apenas uma dúvida. No código do fael vejo que tudo é feito por jquery, mas comparando com alguns outros scripts percebi que eles usam XMLHttpRequest e o fael não usa. Oq isso tem de diferente?

 

jQuery também utiliza XMLHttpRequest, mas disponibiliza métodos fáceis para que não se tenha que configurar muita coisa, apenas instanciar e utilizar.

// Create the request object
// (This is still attached to ajaxSettings for backward compatibility)
jQuery.ajaxSettings.xhr = window.ActiveXObject ?
/* Microsoft failed to properly
 * implement the XMLHttpRequest in IE7 (can't request local files),
 * so we use the ActiveXObject when it is available
 * Additionally XMLHttpRequest can be disabled in IE7/IE8 so
 * we need a fallback.
 */
function() {
	if ( window.location.protocol !== "file:" ) {
		try {
			return new window.XMLHttpRequest();
		} catch( xhrError ) {}
	}

	try {
		return new window.ActiveXObject("Microsoft.XMLHTTP");
	} catch( activeError ) {}
} :
// For all other browsers, use the standard XMLHttpRequest object
function() {
	return new window.XMLHttpRequest();
};

http://code.jquery.com/jquery-1.5.js

 

2- na minha index eu tenho uma validação <noscript>. E quando coloquei o script no meu form e cliquei em submit para testar, ele simplesmente redirecionou para o link do noscript como se a aplicação não fosse reconhecida pelo navegado. Não entendi porque isso aconteceu. E quando eu retirei o noscript ele funcionou.

 

Há uma série de divergências quanto ao uso de <noscript> e o comportamento dos navegadores. Algumas versões do Chrome por exemplo, simplesmente ignoram o bloco noscript, ainda que o javascript esteja desabilitado. Procure desenvolver seguindo as práticas de progressive enhancement. Desenvolva primeiro para quem não tem Javascript. Depois, aplicar JS pra quem tem fica fácil.

 

3- Como dito, ele funcionou, mas a index tratou a resposta html do enviar.php como um include e causou uma duplicidade de conteudo. ou seja, a resposta do enviar.php ficou na forma de uma index (repetindo o cabeçalho, corpo e rodapé da index) dentro da div #status. É como se eu desse um include da minha propria index dentro dela mesmo. coisa de loco... Tbm não faço a menor ideia porque isso ocorreu. O que teria haver o ($.post('envia.php', ...) em relação ao get q a index faz para incluir as paginas?

Não tem nada a ver. Na verdade existe uma necessidade de se tratar a resposta enviada pela 'enviar.php'. Provavelmente ao se acessar diretamente pelo navegador, a mesma está programada para incorporar o leiaute padrão do site. O que pode ser feito é enviar um cabeçalho ao servidor indicando que a requisição foi feita via AJAX.

Quando feito com jQuery, o cabeçalho é enviado automaticamente. Se feito pelo objeto padrão, execute o método:

(nome do seu XMLHttpRequest).setRequestHeader('HTTP_X_REQUESTED_WITH', 'XMLHttpRequest');

 

Então, o seu script de resposta PHP fica responsável por verificar se este cabeçalho existe ou não, e enviar a resposta otimizada para cada caso:

<?php $resposta = 'resposta';
if(!empty($_SERVER['HTTP_X_REQUESTED_WITH'])) die($resposta); // Envia apenas a resposta e para por aqui.

include 'topo.html';
echo '<p>' . $reposta . '</p>';
include 'rodape.html';

Compartilhar este post


Link para o post
Compartilhar em outros sites

Muito Obrigado por responder de boa vontade,

Mas eu ainda preciso de sua ajuda para alguns detalhes.

 

1- a primeira questão é apenas uma dúvida. No código do fael vejo que tudo é feito por jquery, mas comparando com alguns outros scripts percebi que eles usam XMLHttpRequest e o fael não usa. Oq isso tem de diferente?

 

jQuery também utiliza XMLHttpRequest, mas disponibiliza métodos fáceis para que não se tenha que configurar muita coisa, apenas instanciar e utilizar.

// Create the request object
// (This is still attached to ajaxSettings for backward compatibility)
jQuery.ajaxSettings.xhr = window.ActiveXObject ?
/* Microsoft failed to properly
 * implement the XMLHttpRequest in IE7 (can't request local files),
 * so we use the ActiveXObject when it is available
 * Additionally XMLHttpRequest can be disabled in IE7/IE8 so
 * we need a fallback.
 */
function() {
	if ( window.location.protocol !== "file:" ) {
		try {
			return new window.XMLHttpRequest();
		} catch( xhrError ) {}
	}

	try {
		return new window.ActiveXObject("Microsoft.XMLHTTP");
	} catch( activeError ) {}
} :
// For all other browsers, use the standard XMLHttpRequest object
function() {
	return new window.XMLHttpRequest();
};

http://code.jquery.com/jquery-1.5.js

 

Eu uso essa versão: http://code.jquery.com/jquery-1.3.2.js

E não entendi uma coisa. Usando o script do fael eu preciso ou não instanciar o XMLHttpRequest? Ou do modo que o script esta ele ja faz isso sozinho?

Se eu preciso instanciar como eu colocaria isso no scrip dele?

 

 

 

2- na minha index eu tenho uma validação <noscript>. E quando coloquei o script no meu form e cliquei em submit para testar, ele simplesmente redirecionou para o link do noscript como se a aplicação não fosse reconhecida pelo navegado. Não entendi porque isso aconteceu. E quando eu retirei o noscript ele funcionou.

 

Há uma série de divergências quanto ao uso de <noscript> e o comportamento dos navegadores. Algumas versões do Chrome por exemplo, simplesmente ignoram o bloco noscript, ainda que o javascript esteja desabilitado. Procure desenvolver seguindo as práticas de progressive enhancement. Desenvolva primeiro para quem não tem Javascript. Depois, aplicar JS pra quem tem fica fácil.

 

Então, eu preciso usar o js e por isso coloquei o <noscript>. Acontece que eu nunca tive problema com ele até tentar adptar esse script no meu form.

Testando ele separadamente (modo demo) ele funciona mesmo com o <noscript>. Mas justamente no meu site pronto deu o problema, to achando q o problema esta em resolver a pergunta 3. vamos ver...

 

 

3- Como dito, ele funcionou, mas a index tratou a resposta html do enviar.php como um include e causou uma duplicidade de conteudo. ou seja, a resposta do enviar.php ficou na forma de uma index (repetindo o cabeçalho, corpo e rodapé da index) dentro da div #status. É como se eu desse um include da minha propria index dentro dela mesmo. coisa de loco... Tbm não faço a menor ideia porque isso ocorreu. O que teria haver o ($.post('envia.php', ...) em relação ao get q a index faz para incluir as paginas?

 

Não tem nada a ver. Na verdade existe uma necessidade de se tratar a resposta enviada pela 'enviar.php'. Provavelmente ao se acessar diretamente pelo navegador, a mesma está programada para incorporar o leiaute padrão do site. O que pode ser feito é enviar um cabeçalho ao servidor indicando que a requisição foi feita via AJAX.

Quando feito com jQuery, o cabeçalho é enviado automaticamente. Se feito pelo objeto padrão, execute o método:

(nome do seu XMLHttpRequest).setRequestHeader('HTTP_X_REQUESTED_WITH', 'XMLHttpRequest');

 

Acho q entendi, porem não sei como aplicar.

Então vamos por parte, Estou usando esse script que é o mesmo do fael:

<script type="text/javascript" language="javascript">
$(function($) {
// Quando o formulário for enviado, essa função é chamada
$("#formulario").submit(function() {
	// Colocamos os valores de cada campo em uma váriavel para facilitar a manipulação
	var nome = $("#xcontato_nome").val();
	var email = $("#xcontato_email").val();
	var mensagem = $("#xcontato_mensagem").val();
	// Exibe mensagem de carregamento
	$("#status").html("Enviando");
	// Fazemos a requisão ajax com o arquivo envia.php e enviamos os valores de cada campo através do método POST
	$.post('envia.php', {nome: nome, email: email, mensagem: mensagem }, function(resposta) {
			// Quando terminada a requisição
			// Exibe a div status
			$("#status").slideDown();
			//$("#boxprincipal").fadeIn(200).hide();
			//$('.error').fadeOut(200).show();
			// Se a resposta é um erro
			if (resposta != false) {
				// Exibe o erro na div
				$("#status").html(resposta);
			} 
			// Se resposta for false, ou seja, não ocorreu nenhum erro
			else {
				// Exibe mensagem de sucesso
				$("#status").html("Mensagem enviada com sucesso!");
				// Coloca a mensagem no div de mensagens
				$("#mensagens").prepend("<strong>"+ nome +"</strong> disse: <em>" + mensagem + "</em><br />");
				// Limpando todos os campos
				$("#xcontato_nome").val("");
				$("#xcontato_email").val("");
				$("#xcontato_mensagem").val("");
			}
	});
});
});
</script>

 

A pergunta é onde insiro isto? E qual o nome do meu XMLHttpRequest? rs...

(nome do seu XMLHttpRequest).setRequestHeader('HTTP_X_REQUESTED_WITH', 'XMLHttpRequest');

 

 

O php que trata as informações e retorna as mensagens (envia.php) esta assim:

// Recuperamos os valores dos campos através do método POST
$nome = $_POST["nome"];
$email = $_POST["email"];
$mensagem = $_POST["mensagem"];
// Verifica se o nome foi preenchido
if (empty($nome)) {
echo "Escreva seu nome";
} 
// Verifica se o email é válido
elseif (!eregi("^[a-z0-9_\.\-]+@[a-z0-9_\.\-]*[a-z0-9_\-]+\.[a-z]{2,4}$", $email)) {
echo "Digite um email válido";
} 
// Verifica se a mensagem foi digitada
elseif (empty($mensagem)) {
echo "Escreva uma mensagem";
} 
// Verifica se a mensagem nao ultrapassa o limite de caracteres
elseif (strlen($mensagem) > 140) {
echo "A mensagem deve ter no máximo 140 caracteres";
} 
// Se não houver nenhum erro
else {
// Inserimos no banco de dados
$query = mysql_query("INSERT INTO _mensagens VALUES ('', '".$nome."', '".$email."', '".$mensagem."')");
// Se inserido com sucesso
if ($query) {
	echo false;
} 
// Se houver algum erro ao inserir
else {
	echo "Não foi possível inserir a mensagem no momento.";
}
}

 

E conforme o exemplo do script do fael, coloquei uma div pra receber a mensagem:

<div id="status" style="display:none"></div>

 

Então, o seu script de resposta PHP fica responsável por verificar se este cabeçalho existe ou não, e enviar a resposta otimizada para cada caso:

<?php $resposta = 'resposta';
if(!empty($_SERVER['HTTP_X_REQUESTED_WITH'])) die($resposta); // Envia apenas a resposta e para por aqui.

 

Isso eu coloco no envia.php ou na div status?

 

include 'topo.html';
echo '<p>' . $reposta . '</p>';
include 'rodape.html';

 

Não é o jquery que vai colocar a resposta do envia.php na div status? pq eu teria que criar essa variavel?

 

 

mais uma vez, obrigado!!!

Compartilhar este post


Link para o post
Compartilhar em outros sites

1. Seu arquivo envia.php só retorna texto. Não dá pra entender o porque do conteúdo duplicado. Esqueça a verificação de cabeçalho. Ao que tudo indica, seu arquivo envia.php está correto.

 

2. Utilizando jQuery, esqueça o método setRequestHeader(), não será necessário.

 

3. Poste o conteúdo de <noscript>

 

4.

if (resposta != false) {

 

Este tipo de verificação às vezes falha. Como se por exemplo receber uma mensagem vazia ou o número 0. Dê preferência para checagem do Status do XMLHttp, que deve receber (em caso de sucesso) ou o status 200 (OK) ou o status 304 (Não modificado).

 

O método .load() chama um callback enviando 3 parâmetros:

'resposta' -> o conteúdo de XMLHttpRequest.response[Text/XML]

'statusText' -> o valor inteligível do status

'XHR' -> o objeto utilizado na requisição

 

Para verificar se algum erro ocorreu, receba o objeto XHR e verifique seu status:

.post('pagina', {dados: ''}, function(resposta, status, xhr){
   if(xhr.status !== 200 && xhr.status !== 304) return alert('O seguinte erro ocorreu: ' + status);
   // restante do código
});

Compartilhar este post


Link para o post
Compartilhar em outros sites

Este é o noscript:

<noscript><meta http-equiv="refresh" content="0;url=http://www.meusite.com.br/javascript"/></noscript>

 

Uma notícia boa, fiz alguns teste e ele parou a duplicidade de conteudo e inseriu corretamente a resposta na div status. Porem, tbm continua alguns problemas. Vamos lá:

 

Substitui isso:

$.post('fx-contato', {nome: nome, email: email, mensagem: mensagem }, function(resposta) {

Por isso:

$.post('fx-contato', {nome: nome, email: email, mensagem: mensagem }, function(resposta, status, xhr){

 

Ao fazer isso ele já parou de duplicar a index dentro da div.

 

 

Substitui isso:

if (resposta != false) {
    // Exibe o erro na div
    //$("#status").html(status);
} 

Por isso:

if (xhr.status !== 200 && xhr.status !== 304) {
   //return alert('O seguinte erro ocorreu: ' + status);
   // Exibe o erro na div
   //$("#status").html(status);
}

 

Como dito, ele inseriu o que seria a mensagem de loading (Enviando...) corretamente na div status.

Mas mesmo com seu "return alert('O seguinte erro ocorreu: ' + status);" ou com o meu "$("#status").html(status);"

Eu não recebo a resposta do enviar.php. Ele fica parado no loading exibindo a mensagem Enviando...

 

Talvez é por isso q a index nao foi duplicada na div. Como eu nao estou recebendo resposta nao tem o que incluir.

 

 

Se você tiver msn ou gtalk, eu gostaria de enviar o endereço do site para você olhar oq esta acontecendo.

Estou enviando meu email por PM.

 

Obrigado!!!

Compartilhar este post


Link para o post
Compartilhar em outros sites

Eduardo, a primeira coisa a se fazer é corrigir o 'action' do formulário. Ele chama a função func(), que quando não encontrada gera uma Exceção. Em linguagens orientadas a objetos (Javascript é uma), qualquer exceção arremessada (throw) que não for pega (catch) gera um erro fatal de 'uncaught exception'. Primeiro motivo para uma eventual paralisia no script.

 

Pelas normas de progressive enhancement, como já postei anteriormente, o valor de 'action' deveria ser um script que processasse os dados e retornasse uma página completa. Caso isto não seja possível, faça do action do formulário um callback para a função, muito parecido com o que você está tentando fazer com o jQuery.

 

var minhafuncao = function(){
   // códigos aqui
}

 

<elemento onmouseover="javascript:minhafuncao()">

 

Ou, melhor ainda, alterar o evento com javascript, impedindo o formulário de ser enviado:

document.forms[0].onsubmit = function(){
   this.preventDefault();
}

 

Também notei que você não aponta para nenhum envia.php e sim para fx-contato. Tanto o envia quanto o FX retornam uma página de 'não encontrado'. Certifique-se de estar informando o caminho corretamente.

 

Acho que o resultado final se aproximaria de algo assim:

$(function(){
   $('#formulario').submit(function(e){
       var nome = $("#xcontato_nome").val();
       var email = $("#xcontato_email").val();
       var mensagem = $("#xcontato_mensagem").val();
       $.post('envia.php', {nome: nome, email: email, mensagem: mensagem }, function(resp, status, xhr) {
           $('#status').html(
               xhr.status !== 200 && xhr.status !== 304 ? status : resp;
           );

       e.preventDefault();
   });
});

Compartilhar este post


Link para o post
Compartilhar em outros sites

EDITADO:

 

percebi que esta funcionando, ele valida, ele salva na db ou ele retorna erro.

Porem, o problema esta na resposta enviado pelo arquivo php.

Ou seja, mesmo sendo

if (resposta != false) {

ou

xhr.status !== 200 && xhr.status !== 304 ? status : resp;

sempre vai dar erro pq ele não esta interpretando o html do php.

dei um echo na xhr e ele esta retornando como undefined.

 

O pior de tudo ainda é o include da index dentro da div status.

Isso realmente é uma coisa preocupante. Você chegou a ver isso?

 

Eu troquei o envia.php como mostra no tutorial pra fx-contato.

Ele não tem a extensão .php pq o apache esta configurado pra entender qualquer arquivo como .php

e se colocar a extensão no navegador ele redireciona pro erro404.

 

Mas pelo menos já sei oq é.

Estou colocando todos os arquivos, com exceção da index, css e js atrás do public_html

desta maneira quando eu chamo o fx-contato ele insere como se fosse um get e não como um arquivo

Minha pergunta é:

É possível chamar este arquivo via js atras do public_html?

 

Vou fazer umas perguntas idiotas mas eu realmente nao consigo entender esse js

 

Entendi pq tem que colocar nome na função, seu exemplo ficou muito claro, até uso isso em algumas outras coisa.

mas como colocar nome nessa função? nem seu ultimo exemplo esta com nome. fiquei confuso.

 

$(function(){
   $('#formulario').submit(function(e){

 

E se ela fica assim mesmo como fica o action então?

Compartilhar este post


Link para o post
Compartilhar em outros sites

para fazer o DEBUG da resposta, chame o script que irá interpretar os dados passando os valores como parâmetros.

 

Por exemplo, caso seja o envia.php, execute em seu navegador http://blablabla/envia.php?nome=teste&email=teste@teste.com&mensagem=teste E veja no navegador a resposta que está vindo. NÃO DEVERÁ VIR uma página inteira, somente o texto puro. Corrija o envia.php ou equivalente até que a resposta seja apenas texto. Depois deste passo, teste novamente e poste os resultados.

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.