0

I trying to customize HTML file input and wrote simplest jquery API function:

(function($)
{    
  $.fn.selectFileInputGUI = function()
  { 
    var outerWrapper = $('<div>').css({'display':'inline-block'});
    var innerWrapper = $('<div>').css({'width':'0', 'height':'0', 'overflow':'hidden'});
    var fileInput    = $('<input>').attr({type:'file'});
    var fileNameHTML = $('<div>').css({'display':'inline-block', 'margin-left':'3px'});

    var selectBtnGUI = $('<button>').addClass('btn btn-success btn-sm').text('Select file').click(function()
       {
          $.fn.selectFileInputGUI.resetInput();
          fileInput.trigger('click');
       });

       fileInput.on('change', function()
       {   
          $.fn.selectFileInputGUI.displayFileName();
       });

    $(this)
    .append(outerWrapper.append(innerWrapper.append(fileInput)).append(selectBtnGUI))
    .append(fileNameHTML);

   $.fn.selectFileInputGUI.displayFileName = function()
   {
      var fileName = fileInput.val();
      if(fileName.length > 0)
      {
          var pos = fileName.lastIndexOf("\\");
          if(pos != -1) fileName = fileName.substr(pos + 1);
          if(fileName.length > 14) fileName = fileName.substr(0, 14) + '...';
       } else
       {
          fileName = 'File not selected';
       }
       fileNameHTML.text(fileName);
};


   $.fn.selectFileInputGUI.resetInput = function()
   {           
     fileInput.wrap('<form>').parent('form').trigger('reset');
     fileInput.unwrap();
   };   
}
})(jQuery);

When I trying to apply selectFileInputGUI api function to the several selectors, only last selector handles well - http://jsfiddle.net/URKM5/5/

How to implement it correctly?

0

1 Answer 1

1

Looks like your problem is in how you reuse the variable fileInput and fileNameHTML, after user selecting the file, and you call this $.fn.selectFileInputGUI.displayFileName(); the fileInput and fileNameHTML always refer to the fileInput and fileNameHTML of the second fileDialog (because the second fileDialog is initialized after the first and all these variables are overridden). So to solve this problem, you have to pass these variables via the so-called event data, it's much helpful in this case:

//Note the second argument, it's passed in as event data
//You can access the event data via e.data
fileInput.on('change', fileNameHTML, function(e) {              
    $.fn.selectFileInputGUI.displayFileName($(this), e.data);
});

Your displayFileName need to accept 2 arguments, the first refers to the fileInput (which can be passed in as $(this) in the onchange event handler of the fileInput), the second refers to the fileNameHTML (which is passed in as e.data).

//note about the change of the arguments
$.fn.selectFileInputGUI.displayFileName = function(fileInput, fileNameHTML) {
   //the code is unchanged here ...
}

Now selecting the files between the 2 dialogs is independent.

Demo.

After some deeper looking into the problem, looks like you don't need to use event data here. Just pass the fileNameHTML right as the second argument into displayFileName(...) function. Updated Demo

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.