¿Como usar serialize en un formulario con input de tipo File?

publicado por: Anonymous

Tengo un formulario en html para registrar un producto para ello uso ajax, cuando hago un serialize al formulario logro obtener todos los campos del mismo a excepción del campo de tipo file se que con FormData(), puedo obtener este campo pero me gustaría saber hay un manera con serialize para obtenerlo.

function ajaxRequest(url, method, data, datatype, successCallback, errorCallback) {
  $.ajax({
    url: url,
    data: data,
    dataType: datatype,
    type: method,
    // cache: false,
    // contentType: false,
    processData: false,
    success: function (response) {
      eval(successCallback + '(' + JSON.stringify(response) + ')');
    },
    error: function(error){
      eval(successCallback + '(' + JSON.stringify(error) + ')');
    }
  });
}

$('#crear-producto').click(function(){
    let data = $('#nuevo-producto').serialize();
    // let file = new FormData();
    // data = {
    //   'datos': $('#nuevo-producto').serialize(),
    //   'file': file.append('imagen', $('#imagen-producto')[0])
    // };
    ajaxRequest(constants.URL.PRODUCTOS.CREAR, 'POST', data, 'json', 'successRequest', 'errorRequest');
  });

<form enctype="multipart/form-data" id="nuevo-producto">
          <div class="row">
            <div class="col-md-6">
              <label for="producto" class="control-label">Producto:</label>
              <input type="text" name="producto" id="producto" class="form-control border-green" value="{% if p is defined %}{{ p.nombre }} {% endif %}"/>
            </div>
            <div class="col-md-6">
              <label for="marca" class="control-label">Marca:</label>
              <select class="form-control get-dependency border-green" name="marca" id="marca" data-element="referencia" >
                <option selected disabled>--Seleccionar--</option>
                {% for marca in marcas %}
                    <option value="{{ marca.id }}">{{ marca.nombre }}</option>
                {% endfor %}
              </select>
            </div>
            <div class="col-md-6">
              <label for="referencia" class="control-label">Referencia:</label>
              <select class="form-control border-green" name="referencia" id="referencia">
                <option selected disabled>--Seleccionar--</option>
              </select>
            </div>
            <div class="col-md-6">
              <label for="precio" class="control-label">Valor Unidad</label>
              <input type="number" name="precio" id="precio" class="form-control border-green" />
            </div>
            <div class="col-md-6">
              <label for="unidades" class="control-label">Unidades:</label>
              <input type="number" name="unidades" id="unidades" class="form-control border-green" />
            </div>
            <div class="col-md-12"></div>
            <div class="col-md-6">
              <label for="genero" class="control-label">Genero:</label>
              <select class="form-control border-blue" name="genero" id="genero" >
                <option selected disabled>--Seleccionar--</option>
                {% for genero in generos %}
                    <option value="{{ genero.id }}">{{ genero.nombre }}</option>
                {% endfor %}
              </select>
            </div>
            <div class="col-md-6">
              <label for="estado" class="control-label">Estado:</label>
              <select class="form-control border-blue" name="estado" id="estado" >
                <option selected disabled>--Seleccionar--</option>
                {% for estado in estados %}
                    <option value="{{ estado.id }}">{{ estado.nombre }}</option>
                {% endfor %}
              </select>
            </div>
            <div class="col-md-6">
              <label for="lanzamiento" class="control-label">Lanzamiento:</label>
              <input type="date" name="lanzamiento" id="lanzamiento" class="form-control border-blue" />
            </div>
            <div class="col-md-6">
              <label for="" class="control-label" style="margin-bottom: 0 !important;">Calificación:</label><br>
              <span class="clasificacion">
                <input class="estrella" id="radio1" name="estrellas" value="5" type="radio">
                <label for="radio1" class="label-estrella">★</label>
                <input class="estrella" id="radio2" name="estrellas" value="4" type="radio">
                <label for="radio2" class="label-estrella">★</label>
                <input class="estrella" id="radio3" name="estrellas" value="3" type="radio">
                <label for="radio3" class="label-estrella">★</label>
                <input class="estrella" id="radio4" name="estrellas" value="2" type="radio">
                <label for="radio4" class="label-estrella">★</label>
                <input class="estrella" id="radio5" name="estrellas" value="1" type="radio">
                <label for="radio5" class="label-estrella">★</label>
              </span>
            </div>
            <div class="col-md-12">
              <label for="imagen-producto" class="control-label">Imagen del producto</label>
              <input type="file" name="imagen-producto" id="imagen-producto" class="form-control" />
            </div>
            <div class="col-md-12">
              <input type="button" value="Crear Producto" class="btn btn-success pull-right enviar" id="crear-producto"/>
            </div>
          </div>
        </form>

solución

Al parecer no hay forma de hacerlo con serialize(), para tu caso se puede hacer con FormData de la siguiente manera:

$('#crear-producto').click(function(){
    let data = new FormData($('#nuevo-producto')[0]);
    ajaxRequest(constants.URL.PRODUCTOS.CREAR, 'POST', data, 'json', 'successRequest', 'errorRequest');
});

La información del form la podrás obtener de $_POST y la de los archivos de $_FILES.
Es importante también asignarle a los parámetros el valor de contentType: false porque si no jQuery lo enviará como application/x-www-form-urlencoded; charset=UTF-8 que es su valor por defecto.

Tu función ajaxRequest quedaría así:

function ajaxRequest(url, method, data, datatype, successCallback, errorCallback) {
  $.ajax({
    url: url,
    data: data,
    dataType: datatype,
    type: method,
    // Ambos importantes para que jQuery no transforme la información
    contentType: false,
    processData: false,
    success: function (response) {
      eval(successCallback + '(' + JSON.stringify(response) + ')');
    },
    error: function(error){
      eval(successCallback + '(' + JSON.stringify(error) + ')');
    }
  });
}
Respondido por: user22721

Leave a Reply

Your email address will not be published. Required fields are marked *