entre Desarrolladores

Recibe ayuda de expertos

Registrate y pregunta

Es gratis y fácil

Recibe respuestas

Respuestas, votos y comentarios

Vota y selecciona respuestas

Recibe puntos, vota y da la solución

Pregunta

2votos

Hayageek JQuery Upload File Plugin no funciona dentro de un formulario

Hola amigos de entre desarrolladores :)

Estoy usando el plugin JQuery Upload File de hayageek, obtenido desde: http://hayageek.com/docs/jquery-upload-file.php.

He intentado usar el <div> que carga los archivos dentro de un <form> para poder enviar otra información junto con los archivos, tengo la opción autoSubmit: false, y cuando doy click para enviar el formulario llamo la función startUpload();

Mi problema es que al momento de dar click para enviar el formulario sólo se envían los <input> del formulario, y los archivos cargados no son enviados, al lado del servidor tengo el siguiente código para saber si llegan los archivos y los campos del formulario:

print_r($_POST); pring_r($_FILES);

Si cambio la opción autoSubmit: true, si se envían los archivos junto con los campos del formulario.

Nota: la alerta dentro de onSubmit no es ejecutada.

De ante mano muchas gracias por su tiempo y colaboración :)

A continuación les presento mi código:

<--------------------------------------------- HTML ------------------------------------------->

<form class="form-horizontal" id="form-editar-slider-ajax" method="post">
<input type="hidden" name="idImagen" id="idImagen" readonly="readonly">
<div class="form-group">
    <label for="inputName" class="control-label col-xs-2">Titulo:</label>
    <div class="col-xs-10">
        <input type="name" id="tituloImagen" name="tituloImagen" class="form-control" placeholder="Titulo">
    </div>
</div>
<div class="form-group">
    <label class="control-label col-xs-2">Imagen:</label>
    <div class="col-xs-10" id="cargador">
        <div id="fileuploader">Cargar imagen</div>
    </div>
</div>    
<div class="form-group">
    <div class="col-xs-offset-2 col-xs-8">
        <button type="submit" id="btn-editar-slider-ajax" class="btn btn-success">Guardar Cambios</button> 
    </div>
 </div>

</form>

<--------------------------------- JAVASCRIPT - PLUGIN ------------------------------------>

<script type="text/javascript">
var uploadObj = $("#fileuploader").uploadFile({
    url: "../controller/editarSliderAjax", //url donde se enviará la petición
    multiple: false, //defino que no se puedan arrastrar y soltar mas de 1 archivo
    allowedTypes: "png,jpg,jpeg", // extensiones permitidas
    fileName: "myfile", //nombre del archivo a enviar por $_Files
    showDelete: false, //mostrar botón eliminar
    showDone: false, //ocultar botón de Hecho
    showProgress: true, //mostrar barra de progreso
    showPreview: true, //mostrar previsualización de las imagenes a cargar
    autoSubmit: false, //deshabilitar el envio del archivo automaticamente, para poder ser enviado se utiliza la función startUpload()
    showStatusAfterSuccess: true, //mostrar estado despues de haber cargado correctamente las imagenes
    maxFileCount: 1, //número máximo de archivos a subir
    maxFileSize: 3145728, //tamaño máximo permitido de los archivos en bytes, en MB: 3MB
    maxFileCountErrorStr: "Acción no permitida, el número máximo de archivos a subir es: ", //string que aparece al momento de tener un error del número máximo de archivos
    dragDropStr: "<span><b> Arrastra & Suelta los Archivos</b></span>", //string que aparece al momento de tener un error de arrastrar y soltar varios archivos cuando la opción multiple está en false
    sizeErrorStr: "Acción no permitida, el tamaño máximo del archivo es: ", //string que aparece cuando los archivos superan el tamaño máximo permitido
    extErrorStr: "Acción no permitida, las extensiones válidas son: ", //string que aparece cuando existe un error en las extensiones de los archivos a cargar
    cancelStr: "Cancelar", //string del botón cancelar
    uploadButtonClass:"btn btn-info", //clase del botón de carga, se definió una clase de bootstrap
    dragdropWidth: "100%", //defino el ancho del area donde se arrastra y sueltan los archivos
    statusBarWidth: "100%", //defino el acho de la barra de estado.
    //Datos del formulario dinámico, estos son los datos que se envian además de las imagenes, se recuperan con
    // $_POST['ID_ESPECIFICADO']
    dynamicFormData:function()
    {
        var id = $("#idImagen").val(); //capturo el id de la imagen cargado en el input oculto
        var titulo =  $("#tituloImagen").val(); //capturo el titulo cargado en el input.
        // los datos que se van a enviar
        var data = {
          idImagen: id, //id de la imagen
          tituloImagen: titulo //titulo de la imagen
        };
        alert(data['idImagen']);
        alert(data['tituloImagen']);
        return data; //debo retornar data para poder que se envien junto con las imagenes.
    },
    onSuccess:function(files,data,xhr,pd) //función que se llama despues de haber subido los archivos.
    {
        $("#mensaje").html(data); // Mostrar la respuestas del script PHP.
    },
    onSubmit:function()
    {
        alert("Envié Archivos");
    }
});

// al dar clic en guardar cambios al momento de editar una imagen del slider
// ejecuto el plugin uploadFile.
$('btn-editar-slider-ajax').click(function(){      
    uploadObj.startUpload();
});</script>

2 Respuestas

2votos

white Puntos75880

$('btn-editar-slider-ajax') deberia ser: $('#btn-editar-slider-ajax')

intenta reemplazando:

<button type="submit" id="btn-editar-slider-ajax" class="btn btn-success">Guardar Cambios</button> 

por:

<input type="button" id="btn-editar-slider-ajax" class="btn btn-success" value="Guardar Cambios">

asi no se enviaria el formulario y startUpload() correria normalmente, el plugin crea etiquetas <form> dinamicamente, creo que el formulario .form-horizontal esta demás, ya que estas agregando programaticamente los valores en el metodo dynamicFormData

por cierto tu tag <script> esta antes de </body>?

0voto

admont28 comentado

Muchas gracias white por responder, mi tag <script> está antes del </head>.

Tienes un ojo de halcón, no estaba referenciando correctamente el id del botón $('#btn-editar-slider-ajax'); por el momento me ha funcionado enviando los archivos y los campos de texto, pero al parecer realiza 2 llamados a editarSliderAjax, porque obtengo 2 respuestas.

Nota: se supone que la variable $mensaje sólo puede ser get_error_edit_image_slider() o get_success_edit_image_slider(), y efectivamente muestra que fue exitoso, pero dicho mensaje me sale 2 veces seguidas, como si obtuviera 2 respuestas.

Este es el archivo al que es enviado el formulario:

<------------------------------ PHP- editarSliderAjax ------------------------------->

<?php 
    session_start();
    if(!isset($_SESSION['idUsuario'],$_SESSION['nombreUsuario'], $_SESSION['apellidoUsuario'], $_SESSION['superAdminUsuario'])){
            header('location: error');
    }
    require_once ("notificaciones.php");
    require_once ("sliderModel.php");
    $mensaje = get_error_edit_image_slider();
    print_r($_POST);
    print_r($_FILES);
    if(sizeof($_POST) == 1 && isset($_POST['idImagen'])){
        $idImagen = $_POST['idImagen'];
        $sliderModel = new SliderModel();
        $consulta = $sliderModel->view_db_image($idImagen);
        if($consulta != null){
            $tituloImagen = $consulta['tituloImagen'];

            $mensaje = "<script> 
                            document.getElementById('tituloImagen').value='".$tituloImagen."';
                            document.getElementById('idImagen').value='".$idImagen."';
                        </script>";
        }
    }
    else if(sizeof($_POST) == 2 && isset($_POST['idImagen'], $_POST['tituloImagen'])){
        $idImagen = $_POST['idImagen'];
        $sliderModel = new SliderModel();
        $consulta = $sliderModel->view_db_image($idImagen);
        if($consulta != null){
            if (isset($_FILES["myfile"])) {
                $directorioDeGuardado = "../../images/slide/";
                $ret = array();

            //  This is for custom errors;  
            /*  $custom_error= array();
                $custom_error['jquery-upload-file-error']="File already exists";
                echo json_encode($custom_error);
                die();
            */
                $error =$_FILES["myfile"]["error"];
                //You need to handle  both cases
                //If Any browser does not support serializing of multiple files using FormData() 
                if(!is_array($_FILES["myfile"]["name"])) //verifico si es un solo archivo.
                {
                    $rutaImagenConsulta = $consulta['rutaImagen'];
                    if (file_exists($rutaImagenConsulta)){ //verifico que exista la imagen anterior
                        unlink($rutaImagenConsulta); // elimino la imagen anterior
                        $nombreArchivo = $_FILES["myfile"]["name"]; //capturo el nombre del archivo cargado
                        $fullPath = $directorioDeGuardado.$nombreArchivo; // construyo la ruta completa donde se guardará el archivo.
                        $resultado = $sliderModel->update_db_dir_image_slider($idImagen, $fullPath); //actualizo la ruta en la bd
                        if($resultado){ // si es exitosa la actualización, muevo el archivo cargado a la ruta completa
                            /*if (!is_dir($uploaddir)) {
                                mkdir($uploaddir);
                            }*/
                            move_uploaded_file($_FILES["myfile"]["tmp_name"], $fullPath); //muevo el archivo cargado
                            $ret[]= $nombreArchivo;
                        }
                    }
                }
            }

            $tituloImagen = $_POST['tituloImagen']; //titulo de la imagen cargada
            $tituloImagen = htmlspecialchars($tituloImagen, ENT_NOQUOTES); //evito ataques XSS
            $resultado = $sliderModel->update_db_title_image_slider($idImagen, $tituloImagen); //actualizo el titulo de la imagen
            if($resultado){
                $mensaje = get_success_edit_image_slider(); // obtengo el mensaje de que todo ha salido bien.
            }
        }
    }

echo $mensaje; //envio respuestas de exito o de fracaso.
?>

0voto

admont28 comentado

Creo que la doble respuesta se debe a los dos formularios (no estoy seguro), el formulario que está a nivel mas alto y el formulario que el plugin crea dinámicamente.

¿como podría evitar esto?

0voto

white comentado

Estas enviando 2 imagenes? recuerda que al llamar al metodo startUpload() se enviaran las imagenes en peticiones separadas. reviza tu consola con firebug o con la consola por defecto del navegador y reviza cuantas peticiones se estan enviando. podria resolverse haciendo uso de los eventos del plugin y modificando el dom. si este fuese el caso, o cambiando de plugin.

0voto

admont28 comentado

Buen consejo white.

Sólo estoy enviando 1 imagen más 2 campo de texto en el formulario, así que realiza 2 envíos, primero realiza el envío de los campos de texto y luego realiza el envío de los campos de texto más la imagen.
Esta es la respuesta que obtengo en el primer envío:

< ----------------- PRIMER RESPUESTA ------------------------>

Array
(
    [idImagen] => 2
    [tituloImagen] => Edificio Torreyana, entrada
)
Array
(
)
<script type='text/javascript'>
                        $(function(){
                            new PNotify({
                                title: 'Acción Exitosa',
                                text: 'La imagen se ha editado con éxito.<br>La página será recargada en 7 segundos.',
                                type: 'success',
                                delay: 6500,
                                animation: 'show',
                            });
                        });

                    setTimeout(function(){
                        location.reload();
                    }, 7000);
                </script>

Donde el primer Array() corresponder a los campos de texto, el segundo Array() corresponde a los datos de la imagen, y el <scrip> es la respuesta con el mensaje de que se ha editado con éxito.

Luego de eso me aparece de nuevo otro envío hacia editarSliderAjax, y está es la respuesta:

< ----------------- SEGUNDA RESPUESTA ------------------------>

Array
(
    [idImagen] => 2
    [tituloImagen] => Edificio Torreyana, entrada
)
Array
(
    [myfile] => Array
        (
            [name] => 2.jpg
            [type] => image/jpeg
            [tmp_name] => /Applications/XAMPP/xamppfiles/temp/phpoeOKlN
            [error] => 0
            [size] => 174931
        )

)
<script type='text/javascript'>
                        $(function(){
                            new PNotify({
                                title: 'Acción Exitosa',
                                text: 'La imagen se ha editado con éxito.<br>La página será recargada en 7 segundos.',
                                type: 'success',
                                delay: 6500,
                                animation: 'show',
                            });
                        });

                    //setTimeout(function(){
                      //  location.reload();
                    //}, 7000);
                </script>

Donde en el segundo Array() si aparecen los datos de la imagen.

Aun no consigo que sólo sea un envío, es decir que se omita el primer envío donde no están los datos de la imagen.

0voto

white comentado

las 2 respuestas son vía ajax? lo que comentas podria ser a causa de:

  • estas llamando a startUpload() 2 veces ( improbable que envie nada con el plugin, asi que dudo que sea esto.)

  • estas haciendo un submit, asegurate de haber removido <form class="form-horizontal" id="form-editar-slider-ajax" method="post"> y haber reemplazado el tag <button>

0voto

admont28 comentado

No puede ser que se efectúe 2 veces startUpload().

El problema ha de ser por el formulario general.

Si elimino <form class="form-horizontal" id="form-editar-slider-ajax" method="post"> como podría mantener la funcionalidad de acceder a los datos de los <input> mediante var id = $("#idImagen").val(); y a la vez mantener el estilo del formulario?

0voto

white comentado

para acceder a los elementos input no necesitas que esten en un formulario, simplemente los obtienes por su identificador o por un selector css con Jquery ( $('input.clase') || $('input#identificador') , etc ) como ya lo hiciste en dynamicFormData

si deseas mantener el estilo del formulario a cambio de <form class="form-horizontal" usa un <div class="form-horizontal" asegurandose de editar los estilos css si tuvieran este formato form.form-horizontal{}.

De todos modos si deseas mantener tu formulario, cosa que es absurda,
agrega este codigo:

$('#form-editar-slider-ajax').on('submit', function(e){
    e.preventDefault();
    return false;
});

PD: si esto no soluciona tu problema, te sugiero abrir una nueva pregunta asi no se alarga este tema.

saludos!

0voto

admont28 comentado

White, quiero agradecerte de nuevo por colaborarme.

Mi problema se ha resuelto, ahora poseo un nuevo problema, así que seguiré tu consejo de crear una nueva pregunta :)

Saludos.

1voto

Leonardo-Tadei Puntos227320

Probá con definir la codificación del formulario como

<form enctype="multipart/form-data" ... >

0voto

admont28 comentado

Hola Leonardo-Tadei.

Primero que todo, muchas gracias por responder mi pregunta.
He intentado con el código que me mostraste y aún así no me ha funcionado, aún no llegan los archivos.

Gracias...

0voto

Leonardo-Tadei comentado

Se está haciendo la llamada a ../controller/editarSliderAjax ?
El código que está está procesando las imágenes?

1voto

admont28 comentado

si, se está efectuando la llamada correctamente.

cuando me responde (print_r($_POST); print_r($_FILES);) el archivo editarSliderAjax, me muestra lo siguiente:

Array ( [idImagen] => 2 [tituloImagen] => Texto escrito en el input ) 
Array ( )

El primer Array() corresponder a $_POST y el segundo Array() corresponde a $_FILES.

CÓDIGO EN: editarSliderAjax

<------------------------------ PHP- editarSliderAjax ------------------------------->

<?php 
    session_start();
    if(!isset($_SESSION['idUsuario'],$_SESSION['nombreUsuario'], $_SESSION['apellidoUsuario'], $_SESSION['superAdminUsuario'])){
            header('location: error');
    }
    require_once ("notificaciones.php");
    require_once ("sliderModel.php");
    $mensaje = get_error_edit_image_slider();
    print_r($_POST);
    print_r($_FILES);
    if(sizeof($_POST) == 1 && isset($_POST['idImagen'])){
        $idImagen = $_POST['idImagen'];
        $sliderModel = new SliderModel();
        $consulta = $sliderModel->view_db_image($idImagen);
        if($consulta != null){
            $tituloImagen = $consulta['tituloImagen'];

            $mensaje = "<script> 
                            document.getElementById('tituloImagen').value='".$tituloImagen."';
                            document.getElementById('idImagen').value='".$idImagen."';
                        </script>";
        }
    }
    else if(sizeof($_POST) == 2 && isset($_POST['idImagen'], $_POST['tituloImagen'])){
        $idImagen = $_POST['idImagen'];
        $sliderModel = new SliderModel();
        $consulta = $sliderModel->view_db_image($idImagen);
        if($consulta != null){
            if (isset($_FILES["myfile"])) {
                $directorioDeGuardado = "../../images/slide/";
                $ret = array();

            //  This is for custom errors;  
            /*  $custom_error= array();
                $custom_error['jquery-upload-file-error']="File already exists";
                echo json_encode($custom_error);
                die();
            */
                $error =$_FILES["myfile"]["error"];
                //You need to handle  both cases
                //If Any browser does not support serializing of multiple files using FormData() 
                if(!is_array($_FILES["myfile"]["name"])) //verifico si es un solo archivo.
                {
                    $rutaImagenConsulta = $consulta['rutaImagen'];
                    if (file_exists($rutaImagenConsulta)){ //verifico que exista la imagen anterior
                        unlink($rutaImagenConsulta); // elimino la imagen anterior
                        $nombreArchivo = $_FILES["myfile"]["name"]; //capturo el nombre del archivo cargado
                        $fullPath = $directorioDeGuardado.$nombreArchivo; // construyo la ruta completa donde se guardará el archivo.
                        $resultado = $sliderModel->update_db_dir_image_slider($idImagen, $fullPath); //actualizo la ruta en la bd
                        if($resultado){ // si es exitosa la actualización, muevo el archivo cargado a la ruta completa
                            /*if (!is_dir($uploaddir)) {
                                mkdir($uploaddir);
                            }*/
                            move_uploaded_file($_FILES["myfile"]["tmp_name"], $fullPath); //muevo el archivo cargado
                            $ret[]= $nombreArchivo;
                        }
                    }
                }
            }

            $tituloImagen = $_POST['tituloImagen']; //titulo de la imagen cargada
            $tituloImagen = htmlspecialchars($tituloImagen, ENT_NOQUOTES); //evito ataques XSS
            $resultado = $sliderModel->update_db_title_image_slider($idImagen, $tituloImagen); //actualizo el titulo de la imagen
            if($resultado){
                $mensaje = get_success_edit_image_slider(); // obtengo el mensaje de que todo ha salido bien.
            }
        }
    }

echo $mensaje; //envio respuestas de exito o de fracaso.
?> 

Por favor, accede o regístrate para responder a esta pregunta.

Otras Preguntas y Respuestas


...

Bienvenido a entre Desarrolladores, donde puedes realizar preguntas y recibir respuestas de otros miembros de la comunidad.

Conecta