user3808154
user3808154

Reputation: 13

jQuery-File-Upload rails ajax

I am using Turbolinks in my rails project . When I clicked upload button(ajax call),it fails and the error section is showing Uncaught TypeError: Cannot read property 'length' of undefined. The same problem is showing with regular link(no ajax) which is caused by turbolinks I think because turbolinks uses ajax in the background.

my upload page's javascript:

<html>
..... html code ...

<%= javascript_include_tag 'js/vendor/jquery.ui.widget.js' %>
<%= javascript_include_tag "js/jquery.iframe-transport" %>
<%= javascript_include_tag "js/jquery.fileupload.js" %>

<script>
$(function () {
    'use strict';
    var filestoupload = 0;
    $('#fileupload').fileupload({
        dataType: 'json',
         add: function(e, data) {
                if(data.files[0]['size'] > 20000000) {
                   $('#errors_append').html('maximum size for file allowed is 20 mb');
                } else {
                    data.submit();
                }
        },
        done: function (e, data) {
            $.each(data.result.files, function (index, file) {
                filestoupload++;
                $('').text(file.name + ' ' + 'uploaded successfully').appendTo('#files_append');

                if (filestoupload > 2) {
                  $('#file_button').attr("disabled","disabled");
                }
            });
            $("#btn_text").html('Add more files');
        },
        start: function (e, data) {
            $('#progress .progress-bar').css(
                'width',
                0 + '%'
                );   
        },
        progressall: function (e, data) {
            var progress = parseInt(data.loaded / data.total * 100, 10);
            $('#progress .progress-bar').css(
                'width',
                progress + '%'
                );
        },
        success: function(xhr){
          $('#progress .progress-bar').attr('class', 'progress-bar progress-bar-success');
          $('#errors_append').empty();      
      },
      error: function(xhr){
          var errors = $.parseJSON(xhr.responseText).error
          $('#errors_append').html(errors);
          $('#progress .progress-bar').attr('class', 'progress-bar progress-bar-danger');        
      }
  }).prop('disabled', !$.support.fileInput)
.parent().addClass($.support.fileInput ? undefined : 'disabled');
});
</script>

Upvotes: 1

Views: 1795

Answers (1)

Richard Peck
Richard Peck

Reputation: 76774

We got jquery-file-upload working with ajax here (sign up for account then try updating your profile pic). Model is Veronica Crespo:

enter image description here

--

Turbolinks

The main issue with Turbolinks is that it will prevent your on-page JS from loading the DOM elements it requires.

Because Turbolinks just refreshes the <body> element of your page (not the <head>), JS still thinks that it's in the "old" state, preventing it from picking up any of the newly-loaded elements.

Its fixed by either delegating your JS from a constant element (typically document), or by using the Turbolinks event hooks to fix it:

var load = function() {
   ...
};

$(document).on("page:load ready", load);

--

Fix

In regards to working with Turbolinks, here's the code we used for the Avatar functionality in one of our demo apps:

#app/assets/javascripts/application.js
$('#avatar').fileupload({

    url: '/profile/' + $(this).attr('data_id'),
    dataType: 'json',
    type: 'post',

    add: function (e, data) {
        //$(".items .avatar .avatar").prepend('<div class="loading" id="avatar_loading"><img src="<%= asset_path("profile/avatar_loading.gif") %>"></div>');
        //$('#avatar_loading').fadeIn('100');
        $(this).avatar_loading('avatar_loading');
        data.submit();
    },
    success: function (data, status) {;
        $("#avatar_img").fadeOut('fast', function() {
            $(this).attr("src", data.avatar_url).fadeIn('fast', function(){
                $(this).avatar_loading('avatar_loading');
            });
        });
    }

});

This is in line with the jquery-fileupload gem:

#Gemfile
gem "jquery-fileupload-rails", "~> 0.4.1"

#app/assets/javascripts/application.js
//= require jquery-fileupload/basic

Upvotes: 2

Related Questions