Subida de archivos AJAX - TypeError: ajaxSubmit() no es una función

25 sept 2014, 19:36:56
Vistas: 15.2K
Votos: 0

Tengo un plugin que funciona como POST estándar pero no como solicitud POST AJAX.

Estoy recibiendo un error de "no es una función" en Firebug con esta función:

TypeError: jQuery(...).ajaxSubmit is not a function

jQuery(this).ajaxSubmit(options);

Esta solución mágica vino al rescate: http://codeimpossible.com/2010/01/13/solving-document-ready-is-not-a-function-and-other-problems/

( function($) {

} ) ( jQuery );

Este es el archivo js que se está encolando con mi plugin - sí se carga en el encabezado:

jQuery(document).ready(function(){

        var options = { 
            target:         '#output',   // elemento(s) objetivo a actualizar con la respuesta del servidor
            beforeSubmit:   beforeSubmit,  // callback pre-envío
            success:        afterSuccess,  // callback post-envío
            uploadProgress: OnProgress, //callback de progreso de carga
            resetForm:      true        // reiniciar el formulario después de un envío exitoso    
        }

    jQuery('#nanny_app_upload').on('submit', function(e) {
                e.preventDefault();

                alert('jQuery submit llamado');            
                jQuery(this).ajaxSubmit(options);
                alert('jQuery post submit'); 
                // siempre retornar false para prevenir el envío estándar del navegador y navegación de página
                alert('Recibí esto del servidor: ' + response);
                return false;
    });


//función después de una subida de archivo exitosa (cuando el servidor responde)
function afterSuccess(){

    alert('jQuery afterSuccess');
    jQuery('#submit-btn').show(); //mostrar botón de enviar
    jQuery('#loading-img').hide(); //ocultar botón de carga
    jQuery('#progressbox').delay( 1000 ).fadeOut(); //ocultar barra de progreso
}

//función para verificar el tamaño del archivo antes de subirlo
function beforeSubmit(){

    alert('jQuery beforeSubmit');
    jQuery('#submit-btn').hide(); //ocultar botón de enviar
    jQuery('#loading-img').show(); //mostrar botón de carga
    jQuery("#output").html("");
}

//función de barra de progreso
function OnProgress(event, position, total, percentComplete)
{
    //Barra de progreso
    alert('jQuery OnProgress');
    jQuery('#progressbox').show();
    jQuery('#statustxt').show();
    jQuery('#progressbar').width(percentComplete + '%') //actualizar porcentaje completado de la barra
    jQuery('#statustxt').html(percentComplete + '%'); //actualizar texto de estado
    if(percentComplete>50)
        {
            jQuery('#statustxt').css('color','#000'); //cambiar color del texto después del 50%
        }
}

});  

Aquí está el Formulario generado desde un tema hijo:

//Formulario de subida para Nannies
add_action("action_nannie_upload_form", "do_action_nannie_upload_form");

function do_action_nannie_upload_form()
{   
    $url = plugins_url();
    $plugins_url = $url . "/nannie-app/";
    ?><br>
    ¡Un FORMULARIO de Subida!<br>
    <form action="<?php echo admin_url('admin-ajax.php'); ?>" 
    method="post" enctype="multipart/form-data" id="nannie_app_upload">
    <br>
        <?php wp_nonce_field('nannie_app_upload','nannie_upload_ajax_nonce'); ?>  
        <!-- Añadir nuevo Archivo -->  
        <span class="btn btn-file">Seleccionar archivo: 
        <input name="FileInput" id="FileInput" type="file" /></span>                
        <button type="submit" class="btn" id="submit-btn">Subir</button>                         
    </form>

    <img src="<?php echo $plugins_url; ?>images/ajax-loader.gif" id="loading-img"
    style="display:none;" alt="Por favor espere"/>
    <div id="progressbox" style="display:none;"><div id="progressbar"></div >
    <div id="statustxt">0%</div></div>
    <div id="output"></div>
    <br>
    <br>                    
    <hr/>
<script src="<?php echo get_stylesheet_directory_uri(); ?>/plugins/form/jquery.form.js"></script>
<script src="<?php echo get_stylesheet_directory_uri(); ?>/plugins/uload/ajaxFileUpload.js"></script> 

<?php 
}

Y aquí está la acción llamada por el envío del formulario. Si elimino la verificación de cabeceras AJAX, sube el archivo pero me redirige a una página en blanco.

add_action("wp_ajax_nopriv_nannie_app_upload", "nannie_app_upload");

function nannie_app_upload(){
    global $wpdb;   

    if(isset($_FILES["FileInput"])){
        log_me("nannie_app_upload: FileInput encontrado");

    if (!isset( $_POST['nannie_upload_ajax_nonce']) || 
       !wp_verify_nonce($_POST['nannie_upload_ajax_nonce'], 'nannie_app_upload')){
       print 'Lo siento, tu nonce no se verificó.';
       log_me("nannie_app_upload: nonce no se verificó");
       exit;
    }

    if (!isset($_SERVER['HTTP_X_REQUESTED_WITH'])){
        if(isset($_SESSION["naap_app_uid"])){
             $app_uid = $_SESSION["naap_app_uid"];
        }
        log_me('nannie_app_upload: AJAX No Llamado #' . $app_uid);
        die();
    }

    //Verificar si el tamaño del archivo es menor al permitido.
    if ($_FILES["FileInput"]["size"] > 5242880) {
        log_me('nannie_app_upload: ¡El tamaño del archivo es muy grande! #' . $app_uid);
        die("¡El tamaño del archivo es muy grande!");
    }       

    $_SESSION["naap_app_uid"] = $app_uid;    
    $UploadDirectory = WP_PLUGIN_DIR."/nannie-app/tmp/" . $app_uid . "/";

        ////////////////////////////////////////////////////
        //http://www.saaraan.com/2012/06/ajax-file-upload-with-php-and-jquery

        if (!@file_exists($UploadDirectory)) {
                //la carpeta de destino no existe
            if(!is_dir($UploadDirectory)) {
                mkdir($UploadDirectory);
                if (!@file_exists($UploadDirectory)) {

                    log_me('nannie_app_upload: Directorio de subida faltante para AJAX #' . $app_uid);
                    die("¡Asegúrate que el directorio de subida exista!");

                }
            }
        }

        //verificación de tipo de archivo permitido en el servidor
        switch(strtolower($_FILES['FileInput']['type']))
        {
                //tipos de archivo permitidos
                case 'image/png': //archivo png
                case 'image/gif': //archivo gif
                case 'image/jpeg': //archivo jpeg
                case 'application/pdf': //archivo PDF
                case 'application/msword': //archivo word
                case 'application/vnd.ms-excel': //archivo excel
                case 'application/x-zip-compressed': //archivo zip
                case 'text/plain': //archivo txt
                case 'text/html': //archivo html

                        //El Título del Archivo se usará como nuevo nombre
                        $FileName       = strtolower($_FILES['FileInput']['name']); //nombre del archivo subido
                        $ImageExt       = substr($FileName, strrpos($FileName, '.')); //extensión del archivo              
                        $NewFileName    = substr($FileName, 0, strrpos($FileName, '.')); //nombre del archivo antes del random 

                        $FileType       = $_FILES['FileInput']['type']; //tipo de archivo
                        $FileSize       = $_FILES['FileInput']["size"]; //tamaño del archivo

                        $RandNumber     = rand(0, 9999999999); //Número aleatorio para hacer cada nombre único.
                        $uploaded_date  = date("Y-m-d H:i:s");

                        $NewFileName = preg_replace(array('/\s/', '/\.[\.]+/', '/[^\w_\.\-]/'), array('_', '.', ''), strtolower($NewFileName));
                        $NewFileName = $NewFileName.'_'.$RandNumber.$ImageExt;

                        //Renombrar y guardar archivo subido en la carpeta destino.
                        if(move_uploaded_file($_FILES['FileInput']["tmp_name"], $UploadDirectory . $NewFileName )){
                                    //futuro INSERT SQL para registrar los archivos subidos - nueva tabla napp_applications_files
                                    log_me('nannie_app_upload: ¡Subida Exitosa! #' . $app_uid);
                                    die('¡Éxito! Archivo Subido.');
                                    break;

                        }else{
                                    log_me('nannie_app_upload: ¡Subida Fallida! #' . $app_uid);
                                    die('¡Error subiendo archivo!');
                                    break;
                        }            

                        break;
                default:
                        log_me('nannie_app_upload: ¡Archivo no soportado! #' . $app_uid);
                        die('¡Archivo no soportado!'); //error al forzar tipos de archivo
                        break;
        }

    }else{
        log_me('nannie_app_upload: ¡Algo salió mal con la subida! ¿Está configurado correctamente "upload_max_filesize"? #' . $app_uid);
        die('¡Algo salió mal con la subida! ¿Está configurado correctamente "upload_max_filesize"?');
    }
}
0
Todas las respuestas a la pregunta 2
2

ajaxSubmit no es una función central de jQuery.

Parece que tienes que incluir un plugin de jQuery (como este), o reescribir tu función para usar una sintaxis como esta, utilizando jQuery post()

$.post(ajaxurl, data, function(response) {
    // función de respuesta
}

o con jQuery ajax()

$.ajax({
    url: ajaxurl,
    context: data
});

Asegúrate de tener ajaxurl definido en el frontend - WordPress lo define automáticamente en el Backend.

Por cierto, usar post() sí es usar AJAX, ya que envías tu solicitud de forma asíncrona desde el navegador al servidor y manejas el resultado después. Esto es de lo que trata AJAX, incluso si tu función no tiene un nombre como AJAX :)

26 sept 2014 10:18:39
Comentarios

Lo has clavado - ajaxSubmit es de jQuery form. Intenté añadir el plugin js a la página única - solo para probar pero sigo recibiendo que no es una función. He actualizado el js anterior para reflejar los cambios hasta ahora.

jharrell jharrell
28 sept 2014 04:43:05

Parece que otra copia de jQuery me estaba jugando una mala pasada... Encontré el tema conflictivo y lo eliminé. Envolví mi código en un escudo: ( function($) {

} ) ( jQuery );

No más errores :-)

jharrell jharrell
28 sept 2014 05:05:46
1

Debes agregar jquery.form.min.js para que funcione, a mí me sirvió.

Espero que también te funcione.

20 may 2015 13:50:36
Comentarios

Sí, jQuery.form es necesario - asegúrate de estar atento a otras instancias de jQuery que puedan sobrescribir tu atajo $.

( function($) {

} ) ( jQuery );

jharrell jharrell
20 may 2015 17:02:07