Reputation: 1673
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?
Upvotes: 0
Views: 57
Reputation: 63327
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.
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
Upvotes: 1