Upload with Ajax and formData does not send data

6

I have a problem and I can not solve it, I'm trying to upload via ajax and php , I already got some tips here for SO , but I still have problems and I know the big chance of doing something bullshit is great. I'll try to show.

I have a form that is configured like this:

<form enctype="multipart/form-data" class="form-horizontal" id="frmDoc" method="POST">
<!-- CONTEÚDO --> 

The code that should send the information looks like this:

$(document).ready(function(){
    $(function () {
        // Validation
        $("#frmDoc").validate({
            // Do not change code below
            errorPlacement: function (error, element) {
                error.insertAfter(element.parent());
            },
            submitHandler: function (form) {

                var data = new FormData(form[0]);

                // console.log(data);

                $.ajax({

                    type: 'POST',
                    url: 'ajax/pDocsNormativos.php',
                    data: data,
                    dataType: 'json',
                    cache: false,
                    contentType: false,
                    processData: false,

                    beforeSend: function () {
                        $("#msgInsert").html('×AVISO! Enviando...');
                    },
                    success: function (response) {
                        if (response.codigo == "1") {
                            $("#msgInsert").html('×AVISO!' + response.mensagem  + '');
                        } else {
                            $("#msgInsert").html('×ATENÇÃO! ' + response.mensagem + '');
                        }
                    //  $('#frmDoc').each (function(){
                    //      this.reset();
                    //  });
                    },
                    error: function (xhr, ajaxOptions, thrownError) {
                        console.log(xhr, ajaxOptions, thrownError);
                        $("#msgInsert").html('×ATENÇÃO! Ocorreu um erro ao tentar enviar o Documento. Contate o suporte técnico.');
                    }
                });
                return false;
            }
        });
    });
});


And in PHP I have this:

// VARIÁVEL DE CONTROLE
$retorno = array();

// FUNÇÃO PARA CONVERTER DATAS
function parseDate($date, $outputFormat = 'd/m/Y'){
    $formats = array(
        'd/m/Y',
        'd/m/Y H',
        'd/m/Y H:i',
        'd/m/Y H:i:s',
        'Y-m-d',
        'Y-m-d H',
        'Y-m-d H:i',
        'Y-m-d H:i:s',
    );

    foreach($formats as $format){
        $dateObj = DateTime::createFromFormat($format, $date);
        if($dateObj !== false){
            break;
        }
    }

    if($dateObj === false){
        throw new Exception('Data invalida:' . $date);
    }

    return $dateObj->format($outputFormat);
}

// DIRETÓRIO
$diretorio = 'upload/'; 

if ($_SERVER['REQUEST_METHOD'] == 'POST') { 

    // DADOS DO FORMULÁRIO
    $TipoDoc = $_POST['TipoDoc'];
    $Divisao = $_POST['Divisao'];
    $Area = $_POST['AreaBusca'];
    $Pasta = $_POST['Pasta'];
    $Data = $_POST['Data'];
    $Numero = $_POST['Numero'];
    $Revisao = $_POST['Revisao'];
    $Titulo = $_POST['Titulo'];

    $Link = $Pasta;

    $NomePasta = $Pasta;    
    $NomePasta = substr($NomePasta, 13);    
    $NomePasta = rtrim($NomePasta,'/');

    // VALIDAÇÕES DE PREENCHIMENTO
    if ($TipoDoc == 0):
        $retorno = array('codigo' => 0, 'mensagem' => ' Selecione um Tipo de Documento');
        echo json_encode($retorno);
        exit();
    endif;

    if ($Divisao == 0):
        $retorno = array('codigo' => 0, 'mensagem' => ' Selecione uma Divisão');
        echo json_encode($retorno);
        exit();
    endif;

    if ($Area == 0):
        $retorno = array('codigo' => 0, 'mensagem' => ' Selecione uma Área');
        echo json_encode($retorno);
        exit();
    endif;

    if (empty($Data)):
        $retorno = array('codigo' => 0, 'mensagem' => ' Preencha a Data do cadastro');
        echo json_encode($retorno);
        exit();
    endif;

    if (empty($Numero)):
        $retorno = array('codigo' => 0, 'mensagem' => ' Preencha o campo Número');
        echo json_encode($retorno);
        exit();
    endif;

    if (empty($Titulo)):
        $retorno = array('codigo' => 0, 'mensagem' => ' Preencha o campo Título');
        echo json_encode($retorno);
        exit();
    endif;

    if(!isset($_FILES['Arquivo'])):
        $retorno = array('codigo' => 0, 'mensagem' => ' Informe o arquivo para Upload');
        echo json_encode($retorno);
        exit();
    endif;  

    // CONVERTENDO DATAS PARA BD
    $Data = parseDate($Data, "Y-m-d");

    $name     = $_FILES['fileUpload']['name'];
    $tmpName  = $_FILES['fileUpload']['tmp_name'];
    $error    = $_FILES['fileUpload']['error'];
    $size     = $_FILES['fileUpload']['size'];
    $ext      = strtolower(pathinfo($name, PATHINFO_EXTENSION));

    switch ($error) {
        case UPLOAD_ERR_OK:            
            $valid = true;          

            //validate file extensions
            if ( !in_array($ext, array('pdf')) ) {
                $valid = false;
                $retorno = array('codigo' => 1, 'mensagem' => 'Extensao de arquivo invalida ');
                echo json_encode($retorno);
                exit();             
            }
            //validate file size
            if ( $size/1024/1024 > 2 ) {
                $valid = false;
               $retorno = array('codigo' => 1, 'mensagem' => 'Tamanho do arquivo e superior a tamanho maximo permitido');
               echo json_encode($retorno);
               exit();
            }
            //upload file
            if ($valid) {
                $targetPath =  dirname( __FILE__ ) .'/'. $diretorio . '/'. $name;
                move_uploaded_file($tmpName,$targetPath); 

                // INSERE DADOS
                $arrayDados = array('DataEmissao' => $Data,
                                    'IdDivisao' => $Divisao, 
                                    'IdArea' => $Area, 
                                    'Numero' => $Numero,                     
                                    'Titulo' => $Titulo, 
                                    'Link' => $Link, 
                                    'Tipo' => $TipoDoc, 
                                    'Status' => 1, 
                                    'Revisao' => $Revisao, 
                                    'Pasta' => $NomePasta);
                $retorno = $crud->insert($arrayDados);              

                // Se inserido com sucesso código 1, senão retorna mensagem de erro
                if ($retorno):
                    $retorno = array('codigo' => 1, 'mensagem' => ' Documento Normativo inserido com sucesso');
                    echo json_encode($retorno);
                    exit();
                else:
                    $retorno = array('codigo' => '0', 'mensagem' => $TipoDoc);
                    echo json_encode($retorno);
                    exit();
                endif;              
            }
            break;
        case UPLOAD_ERR_INI_SIZE:
            $retorno = array('codigo' => 1, 'mensagem' => 'O arquivo enviado excede a directiva upload_max_filesize em php.ini.');
            echo json_encode($retorno);
            break;
        case UPLOAD_ERR_PARTIAL:
            $retorno = array('codigo' => 1, 'mensagem' => 'O arquivo foi enviado parcialmente.');
            echo json_encode($retorno);
            break;
        case UPLOAD_ERR_NO_FILE:
            $retorno = array('codigo' => 1, 'mensagem' => 'Nenhum arquivo foi tranferido.');
            echo json_encode($retorno);
            break;
        case UPLOAD_ERR_NO_TMP_DIR:
            $retorno = array('codigo' => 1, 'mensagem' => 'Faltando uma pasta temporaria. Introduzida no PHP 4.3.10 e PHP 5.0.3.');
            echo json_encode($retorno);
            break;
        case UPLOAD_ERR_CANT_WRITE:
            $retorno = array('codigo' => 1, 'mensagem' => 'Falha ao gravar arquivo em disco. Introduzido no PHP 5.1.0.');
            echo json_encode($retorno);
            break;
        default:
            $retorno = array('codigo' => 1, 'mensagem' => 'Erro desconhecido');
            echo json_encode($retorno);
            break;
    }
} else {
    //Envia um erro acaso o usuário tente acessar o script por outros métodos
   $retorno = array('codigo' => 1, 'mensagem' => 'Método HTTP não suportado para esta ação');
   echo json_encode($retorno);
   exit();   
}

header('Content-Type: application/json');
echo json_encode($retorno);

I am not able to send the form fields, because my console gives me the following message, I will post an image to not complicate much, see:

Imageofconsole.log

Followingsuggestion,Iamsharinghtmlofform:

<divclass="widget-body">
        <form enctype="multipart/form-data" class="form-horizontal" id="frmDoc" method="POST">
          <fieldset>
            <legend>Adicionar Instrução Normativa</legend>
            <div class="form-group">
              <label class="col-md-2 control-label" for="select-2">Tipo Doc</label>
              <div class="col-md-10">
                <select class="form-control" id="TipoDoc" name="TipoDoc">
                  <option value="0">Tipo Documento</option>
                  <option value="1">Instru&ccedil;&atilde;o Normativa</option>
                  <option value="2">Circular Transit&oacute;ria</option>
                  <option value="3">Manual Operacional</option>
                  <option value="4">Miss&atilde;o</option>
                  <option value="5">Vis&atilde;o</option>
                  <option value="6">Princ&iacute;pios e Valores</option>
                  <option value="7">C&oacute;digo de &Eacute;tica</option>
                  <option value="8">Regulamento Interno</option>
                  <option value="9">Organograma</option>
                  <option value="10">Estatuto Social</option>
                </select>
              </div>
            </div>
            <div class="form-group">
              <label class="col-md-2 control-label" for="select-1">Divisão</label>
              <div class="col-md-10">
                <select class="form-control" name="Divisao" id="Divisao" onchange="buscaDadosArea()">
                  <option value="0">Divisão</option>
                  <?php foreach ($ResDivisao as $Divisao) { ?>
                  <option value="<?php echo $Divisao->IdDivisao ?>"><?php echo $Divisao->Nome ?></option>
                  <?php } ?>
                </select>
              </div>
            </div>
            <!-- RESULTADO DA BUSCA PELA DIVISÃO -->
            <div class="form-group" id="Area"> </div>

            <!-- RESULTADO DA BUSCA PELA ÁREA -->
            <div class="form-group" id="Pasta"> </div>
            <div class="form-group">
              <label class="col-md-2 control-label">Data</label>
              <div class="col-md-10">
                <input type="text" class="form-control datepicker"  data-lang="pt-BR" data-RTL="false" value="" name="Data" id="Data"  data-dateformat="dd/mm/yy">
              </div>
            </div>                
            <div class="form-group">
              <label class="col-md-2 control-label">Numero</label>
              <div class="col-md-10">
                <input name="Numero" type="text" class="form-control" id="Numero" placeholder="Número" />
              </div>
            </div>
            <div class="form-group">
              <label class="col-md-2 control-label">Revisão</label>
              <div class="col-md-10">
                <input name="Revisao" type="text" class="form-control" id="Revisao" placeholder="Revisão" />
              </div>
            </div>
            <div class="form-group">
              <label class="col-md-2 control-label">Título</label>
              <div class="col-md-10">
                <input name="Titulo" type="text" class="form-control" id="Titulo" placeholder="Título" />
              </div>
            </div>
            <legend>Selecione o PDF</legend>
            <div class="form-group">
              <label class="col-md-2 control-label">Arquivo</label>
              <div class="col-md-10">
                <input type="file" class="btn btn-default" id="fileUpload"  name="fileUpload">
                <p class="help-block"> Extensão permitida <strong>PDF</strong>. </p>
              </div>
            </div>
          </fieldset>
          <div class="form-actions">
            <div class="row">
              <div class="col-md-12">
                <button class="btn btn-primary" type="submit"> <i class="fa fa-save"></i> Gravar </button>
              </div>
            </div>
          </div>
        </form>
        <div id="msgInsert" style="padding: 10px;"> 
          <!-- Mensagens --> 
        </div>
      </div>
    
asked by anonymous 01.02.2017 / 13:06

4 answers

4

The line

$TipoDoc = $_POST['TipoDoc'];

You are printing the notice that is in your print, and with this is problem in your return as it fits the 'Json' data type. It will throw the + Json error message there the jQuery interpreter gets lost. Take a look at your Html if you have an input with the name="TipoDoc" or if this field is sent only in some condition, do the following in your php, replace the above line with this (adapted):

$TipoDoc = isset($_POST['TipoDoc']) ? $_POST['TipoDoc'] : 'alguma valor para sua lógica de negócio' ;
    
04.02.2017 / 00:33
3
  

It looks like your data is not in Json format, you can put the   that that

console.log(data);
     

Is it showing?

     

But by the error that appears on your console, it is not in the format   Json, you need to check the data type that PHP is expecting too.

You are saying that the data type is JSON, but from what log that printou is not, it is a multidata.

type: 'POST',
url: 'ajax/pDocsNormativos.php',
data: data,
**dataType: 'json',**
cache: false,
contentType: false,
processData: false,

You must pass the correct date type as a parameter. It may be that just removing the 'dataType: json' resolves, but there may be other errors as well.

    
01.02.2017 / 13:35
2

I've been reading about similar issues and I believe your Data variable is the problem, since it certainly does not have a valid JSON.

Check out this Fiddle that is well applicable to your case.

What you would need to add in your code would be:

(function ($) { // Função que vai tratar os dados do teu form para JSON
$.fn.serializeFormJSON = function () {

    var o = {};
    var a = this.serializeArray();
    $.each(a, function () {
        if (o[this.name]) {
            if (!o[this.name].push) {
                o[this.name] = [o[this.name]];
            }
            o[this.name].push(this.value || '');
        } else {
            o[this.name] = this.value || '';
        }
    });
    return o;
  };
})(jQuery);

And a small change to your code:

submitHandler: function (form) {

e.preventDefault();
var data = $("#frmDoc").serializeFormJSON(); // pode chamar pelo ID do Form ou por THIS

console.log(data); // só pra mostrar o que tem dentro da variável agora

I hope I have helped.

    
06.02.2017 / 12:46
2

Try changing this:

submitHandler: function (form) {

                var data = $(form).serialize();

If you really need to send a JSON to the server, then it does not work ... But try this and see what comes up on the server.

Check the function you are using to validate the form - FormData() .

It seems that no value is being sent to the server (the item keys has length: 0)

Since your $.ajax expects a response in the format JSON , because of dataType: 'json' , any response from the server that is not in that format will generate an error. Since no value is being passed to the server, the generated response is probably not in the JSON pattern

RECEIVED data must be in JSON format.

  

dataType (default: Intelligent Guess (xml, json, script, or html))   Type: String    The type of data you are expecting back from the server.

    
04.02.2017 / 02:05