Usamos cookies para medir audiência e melhorar sua experiência. Você pode aceitar ou recusar a qualquer momento. Veja sobre o iMasters.
Com o código abaixo eu consigo recuperar todos os campos tipo text, textarea,..., porém, o campo do tipo file ele não retorna, já tentei vários métodos mas não consegui.
$('form#agenda').live('submit',function(e){
e.preventDefault();
var action = $(this);
//Apenas para mostrar no console os retornos do envio
console.log(action.serialize());
$.ajax({
url: action.attr("action"),
type: 'post',
data: action.serialize(),//serializeArray() é melhor para ser debugado, mas tem o mesmo resultado
success: function( response ){
var data = $( '<div>'+response+'</div>' ).find('#conteudo').html();
conteudo.html(data);
}
});
});
O formulário é esse:
<form method="post" id="agenda" action="?pag=agenda.php&fazer=adicionar" enctype="multipart/form-data">
<input type="hidden" name="acao" id="acao" value="Adicionar">
Título:
<input type="text" name="titulo" id="titulo" size="60" value="Titulo">
Data:
<input type="text" name="data" id="data" size="11" maxlength="10" value="<?php echo $data;?>"><br>
URL: <input type="text" name="url" id="url" size="60" value="http://localhost/admin/agenda/"><br>
Foto: <br><input name="foto" id="foto" type="file" value="" /> <br><!---->
Descrição: <br>
<textarea name="descricao" cols="74" rows="10">Minha Descrição aqui</textarea><br>
<input type="submit" value="Adicionar" />
</form>
A página php que pega esses valores tá normal, pois se o form não for enviado via $.ajax() ele captura todos os campos sem problema.
Como eu disse é só o campo (<input name="foto" id="foto" type="file" value="" />) que o $.ajax() não está serializando corretamente com o serialize(), com o console.log(action.serialize()) se pode verificar.
Alguma idéia de como retornar esse campo do tipo file pelo $.ajax()?
Obrigado pela atenção.
>
não dá.
ajax não envia arquivos.
Mas, felizmente, isto logo logo irá mudar. http://dev.w3.org/2006/webapi/FileAPI/
Cara esse meu ajax só manda as os campos por POST(serializado) para uma página PHP fazer o upload, página essa que também é responsável por pegar esses valores e gravar no DB, a bronca é que o campo do tipo file não vai nessa serialização
Eu imaginei algo do tipo: o campo file gerar um caminho para um campo hidden com outro nome e esse campo hidden passar por POST para o meu script PHP para que ele por referencia possa fazer o upload, mas não sei se isso vai dar certo.
Qualquer ajuda é bem vinda.
Obrigado pela atenção.
>
não dá.
ajax não envia arquivos.
Eu imaginei algo do tipo: o campo file gerar um caminho para um campo hidden com outro nome e esse campo hidden passar por POST para o meu script PHP para que ele por referencia possa fazer o upload, mas não sei se isso vai dar certo.
Não tem como, o PHP não pode acessar o computador do cliente para 'puxar' o arquivo para download, mesmo que você coloque o endereço.
O upload de arquivos tem que ser 'empurrado' do cliente para o servidor.
A única coisa que tenho certeza é que a função serialize() não está retornando o campo do tipo file, os outros estão todos corretos e gravando no DB pelo código php que faz essa insersão(isso sem refresh).
1 - O código que eu postei no inicio funciona com todos os campos, menos o <input name="foto" id="foto" type="file" value="" />
2 - O código PHP também está funcionando pois se eu enviar normalmente sem o uso do método $.ajax, $.post, ..., o PHP faz a inserção no DB e o upload sem bronca.
Acredito que a bronca esteja na função serialize() do jQuery, pois, quem testar o código que eu postei perceberá(no console) que o campo do tipo file é o único que não é serializado e não dá retorno, e se não há a variável $_FILES['foto'] retornada pelo form enviado o PHP não faz o upload.
Obrigado pela atenção.
vou falar denovo:
não dá. Ok ?
o serialize(), nunca vai te enviar o campo type="file", pq ajax, não envia arquivos.
O "problema", não é o .serialize(), mas sim a linguagem, que não suporta isso.
Por motivos de segurança, a linguagem javascript, não tem permissão para manipular arquivos. Entendeu agora ?
Se você quiser fazer um upload assincrono, só existem 2 opções:
-> usar flash, ou
-> usar um iframe escondido.
Com javascript não é possível.
Espero que agora você compreenda.
Ou tem uma 3ª opção que é um plugin(http://jquery.malsup.com/form/) que esse sim envia todos os campos(incluindo os do tipo file) por post no meu caso ficou assim:
$(':submit').live('click',function(e){
e.preventDefault();
var action = $(this).parent();//recupera o valor do pai(meu form #agenda) do botão submit
$.ajax({
success: function( response ){
action.ajaxSubmit();
}
});
});
Na maioria das vezes eu sou do tipo: Se funcionou não deixa!
Mas nesse caso é intrigante saber que esse plugin retorna todos os campos por post e o serialize() não.
Há não esqueça de por o plugin no head: <script type="text/javascript" src="js/jquery.form.js"></script>
ok, agora você quer entender oque o plugin fez?
linha 203 dele:
$io = $('<iframe name="' + id + '" src="'+ s.iframeSrc +'" />');
ou seja, a minha segunda opção disfarçada.
ou seja, o plugin não fez milagre, apenas enviou pelo iframe, e te "enganou".
Não tem mistério e nem nada intrigante qndo você sabe como funciona.
Sim, parece que é isso mesmo.
Não sou lá essas coisas em javascript, por isso não vou entrar nessa pq é de competência de quem sabe mais do que eu(o que é bem fácil, rsrsrs), mas comparando os dois envios no console do FF dá pra perceber que pelo 1º script o form é enviado como application/x-www-form-urlencoded mas para enviar um arquivo tem que ser multipart/form-data, isso já tem como parametro no form original só que o serialize() não recupera o valor de enctype do form, e parece que a bronca toda está aí.
Já o pluguin não envia esse parametro, mas sim um Content-Disposition: form-data; name="NOME_DO_CAMPO" para cada campo e parece que ele converte a imagem para um código utf8 ou algo assim(sei lá), e isso vai comprometer o desempenho de códigos maiores que esse meu.
Acredito que se houver como passar o form como multipart/form-data para ser serializado não vai dar bronca no script.
então cara.. mas olha a aba REDE do Firebug.
você vai ver q o form de upload, não faz XHR, mas sim um POST normal.(pelo iframe, ou seja, o js não envia nada)
Since it is not possible to upload files using the browser's XMLHttpRequest object, the Form Plugin uses a hidden iframe element to help with the task.
Bom eu me virei a tarde toda e consegui adicionar um script para pegar todos os campos do form:
var params = {};
jQuery.each(action.find('input'), function(index,value) {
params[value.name] = value.value;
});
e bastou que eu trocar data:action.serialize() por data: param para pegar realmente todos os campos do form, depois eu adicionei a linha contentType: 'multipart/form-data', e arequisição ajax deu um sinal de que iria funcionar, porem o sinal foi falso, eu li a docomentação da jQuery, mas meu ingles é, ou melhor não é, e a tradução do google não ajuda muito, o que deu pra entender é que além de tocar o cabeçalho da requisição vai ser preciso fazer uma série de rotinas para encodar em base64, passar por um iframe, ..., e isso tudo o plugin já faz, por isso é melhor deixar esse plugin trabalhar ou ser muito fera em javascript para escrever uma rotina só pra isso, rsrsrs.
Agora com tudo de pesquisa que fiz, e mais os testes realizados, eu achei que o código
var params = {};
jQuery.each(jQuery('form').find('input'), function(index,value) {
params[value.name] = value.value;
});
é mais rápido(uns 3ms em média) que o serialize() e serializeArray(), e me pareceu mais seguro também já que não dá erros e nem deixa campo algum sem retorno.
O código original está nos comentários da documentação da api, porém eu revirei tanto que não sei exatamente onde é que está.
Insistência é uma coisa boa e sempre traz bons frutos para o trabalho.
Teimosia é ruin e atrasa a o desenvolvimento pessoal e proficional.
Agradeço a atenção de todos.
<script type="text/javascript">
$("#form_oferta").submit(function(event) {
var dados = $( form ).serialize();
$.ajax({
type: "POST",
contentType:attr( "enctype", "multipart/form-data" ),
url: "<?php echo site_url(); ?>adm/oferta_insert",
data: dados,
success: function( data )
{
alert( data );
}
});
return false;
}
</script>
Acresentando contentType:attr( "enctype", "multipart/form-data" ) ao script você conseguei enviar arquivos por ajax jquery.
>
<script type="text/javascript">
$("#form_oferta").submit(function(event) {
var dados = $( form ).serialize();
$.ajax({
type: "POST",
contentType:attr( "enctype", "multipart/form-data" ),
url: "<?php echo site_url(); ?>adm/oferta_insert",
data: dados,
success: function( data )
{
alert( data );
}
});
return false;
}
</script>Acresentando contentType:attr( "enctype", "multipart/form-data" ) ao script você conseguei enviar arquivos por ajax jquery.
tentei assim e tenho o erro "attr is not defined"
não dá.
ajax não envia arquivos.