javascriptjquerycoffeescriptjquery-file-uploadjquery-fileupload-rails

using $(this) with coffee script


I am using query file upload. I have several forms on the page, each identical except for a hidden field called 'project'. Here is the coffee script that handles the upload:

jQuery ->
  $(document).ajaxComplete ->
    $('.project_file').fileupload
      dataType: "script"
      url: ($(this).prev('form').attr("action"))
      paramName: 'file_yo'
      formData: (form) -> 
        [{ name: 'authenticity_token',  value: $('meta[name="csrf-token"]').attr('content')}, { name: 'project',value: $(this).prev().val()}]
      alert($(this).prev().val())
      done: (e, data) ->
        $('#finish-text').html "Upload finished"

Here is the html for one of the forms. The only thing that changes from from to form is the value of the hidden field called 'project'.

<form accept-charset="UTF-8" action="/projects/6/project_files" class="edit_project" data-remote="true" id="project_file_form" method="post"><div style="margin:0;padding:0;display:inline">        <input name="utf8" type="hidden" value="✓"><input name="_method" type="hidden" value="patch"><input name="authenticity_token" type="hidden" value="iIQXYRJfXRFAaSsvSpb4H+HEUMeAI3pubXDRyd+2Ehk="></div>
    <input id="project" name="project" type="hidden" value="6">
    <input authenticity_token="true" class="field file-field project_file" id="" name="file_yo" title="" type="file" value="">  
</form>

The problem is that $(this) is undefined. When the alert shows up, it says undefined. How do I get $(this) to return the specific element with class 'project_file' as it should?

UPDATE:

Here is what the coffee script compiles to:

(function() {
  jQuery(function() {
    $(document).ajaxComplete(function() {
      return $('.project_file').fileupload({
        dataType: "script",
        url: $(this).prev('form').attr("action"),
        paramName: 'file_yo',
        formData: function(form) {
          return [
            {
              name: 'authenticity_token',
              value: $('meta[name="csrf-token"]').attr('content')
            }, {
              name: 'project',
              value: $(this).prev().val()
            }
          ];
        }
      }, alert($(this).prev().val()));
    });
    return {
      done: function(e, data) {
        return $('#finish-text').html("Upload finished");
      }
    };
  });

}).call(this);

Solution

  • Keep in mind that the options are evaluated when you call $('.project_file').fileupload() so even if $(this) was what you expect it to, you'd be setting exactly the same url on each uploader. I don't think ajaxComplete sets any particular context so this inside that callback isn't terribly useful on its own.

    If you want different options for each instance then you'll have to say so:

    $('.project_file').each ->
      $(@).fileupload
        #... $(@) should be what you want in here
    

    I don't know why you have this bound to ajaxComplete but that seems odd at first glance, I'd expect this to be handled directly by $(document).ready(...).