Elgg-friendly approach for AJAX file uploads?

I've noticed that both elgg.action() and Ajax.action() do not like options.data to be a FormData object.   In the case of elgg.action() it results in a TypeError because elgg.security.addToken() only wants options.data to be a string or plain object.  In the case of Ajax.action(), Ajax.fetch() requires options.data to be a string or plain object, and throws an Error if it's FormData.

So it appears that Elgg does not support FormData for actions.  I've been able to work around this by submitting the form in an iFrame, but this seems a little hacky.  Is there a better way to do this in Elgg?

  • Maybe helpful:

    define(function(require) {
        var $ = require('jquery');
        var elgg = require('elgg');
        var Ajax = require('elgg/Ajax');
        var spinner = require('elgg/spinner');
    
        // manage Spinner manually
        var ajax = new Ajax(false);
    
        $(document).on('submit', '.elgg-form-path-to-form-formname', function(e) {
            var $form = $(this);
    
            spinner.start();
            ajax.action($form.prop('action'), {
                data: ajax.objectify($form)
            }).done(function(json, status, jqXHR) {
                if (jqXHR.AjaxData.status == -1) {
                    spinner.stop();
    
                    // ERROR
    
                    return;
                }
    
                if (json) {
                    spinner.stop();
    
                    // SUCCESS
                }
            });
    
            e.preventDefault();
        });
    });
    
    
  • Yes, it's a bit trickt in 2.x. I haveanaged to get around it in one of the projects using hooks and overriding some views, but it wasn't a very elegant solution.
    jQuery form plugin is bundled with Elgg, and you can require it as jquery.form. I belive I have examples of usage in my plugins, perhaps hypeWall. But, if you already have an iframe solution, it does the same thing.

  • @iionly -- thanks for the idea!  I was hoping this would work, but unfortunately $_FILES is empty when using this approach.  It seems FormData is the secret sauce to get AJAX file uploads, but it is not supported in Elgg.

    @Ismayil -- maybe I'll take a look at hypeWall for inspiration.  My approach isn't particularly elegant either, so it wouldn't hurt to see how someone else accomplished something similar.

    It will be interesting to see if FormData is supported properly in 3.0.

  • FormData is fully supported in 3.0, I made sure of that :)

  • In theory elgg/Ajax is just a wrapper around jQuery Ajax API. You can copy it into another AMD module and hack it to support FormData

  • @Ismayil -- that's great news about 3.0.  Thanks for confirming it supports FormData, and for your work on it!

    I think I can live with my hacky iFrame approach in 2.3.x for now, knowing it can go away in the not-too-distant future.

  • Im having the exact same issue using Elgg 3.3.

    Both elgg.action and ajax.action are not happy with data being a FormData object.

    Can anyone confirm FormData it is fully supported in Elgg 3?