Skip to content

Instantly share code, notes, and snippets.

@NaszvadiG
Created September 14, 2013 13:02
Show Gist options
  • Save NaszvadiG/6561864 to your computer and use it in GitHub Desktop.
Save NaszvadiG/6561864 to your computer and use it in GitHub Desktop.
A Pen by terryyounghk.
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>File Uploader</title>
<style>
/* Style for demo, not required */
body { font-size: 62.5%; margin: 50px; }
fieldset { padding: .6em 0;border:0;border-top: 1px dotted #ddd; }
legend { font-size: 1.5em; font-weight: bold; color: #555; padding: .5em 1em .5em 0; background: #fff; }
label { font-size: 1.4em; display: block; margin: .5em 10px .5em 0; }
input#upload { background: #aaa url(http://dl.dropbox.com/u/20165443/jsFiddle/images/jquery.fileinput.bg-btn.png) bottom repeat-x; padding: .4em 1.2em;border: 1px solid #aaa; color: #222; font-size: 1.2em; font-weight: bold; -moz-border-radius: 5px; -webkit-border-radius: 5px; border-radius: 5px; cursor: pointer; margin: 2em 0; }
input#upload:hover { background: #eee; color: #111; border-color:#777; }
</style>
</head>
<body>
<!-- realistic form attributes: <form action="#" method="post" enctype="multipart/form-data"> -->
<form action="#" onsubmit="return false;">
<p>jQuery Custom File Upload Input (Enhancements)</p>
<p>This modification is a derived from the original work by Filament Group: http://filamentgroup.com/lab/jquery_custom_file_input_book_designing_with_progressive_enhancement/ </p>
<p>File Input Examples</p>
<label for="file_A">Default Style</label>
<input type="file" name="file" id="file_A"/>
<label for="file_B">Percentage Width</label>
<input type="file" name="file" id="file_B"/>
<label for="file_C">Custom Text</label>
<input type="file" name="file" id="file_C"/>
<label for="file_D">Test Auto-truncated file name (Try selecting a file with a long name and see what happens)</label>
<input type="file" name="file" id="file_D"/>
<label for="file_E">Button Only (I actually used this once to mashup with another jQuery plugin which enables multiple file uploads using a single button)</label>
<input type="file" name="file" id="file_E"/>
<label for="file_F">onChange event handler (This example writes the function arguments to the JavaScript Console, e.g. Firebug)</label>
<input type="file" name="file" id="file_F"/>
<input type="submit" name="upload" id="upload" value="Upload photo" />
</form>
</body>
</html>
/**
* --------------------------------------------------------------------
* jQuery customfileinput plugin
* Author: Scott Jehl, scott@filamentgroup.com
* Copyright (c) 2009 Filament Group
* licensed under MIT (filamentgroup.com/examples/mit-license.txt)
* --------------------------------------------------------------------
*/
/**
* Modifications: Terry Young (terryyounghk at gmail dot com)
*
* ##1: Added 'option' parameter. Initially for optionally specifying a width. Default is 'inherit' (i.e. not specified)
* ##2: Added options 'buttonText', 'inputText' and 'changeText'
* ##3: Added option 'maxFileSize'. For this technique, @see: http://www.tizag.com/htmlT/htmlupload.php
* ##4: Added auto-truncating the file name if text exceeds the available width (Uses the window.onresize event)
* ##5: Added option 'showInputText'. Default is true
* ##6: Added event handler 'onChange'
*/
$.fn.customFileInput = function(options){
// ##1 ++
var defaults = {
width: 'inherit',
buttonText: 'Browse',
changeText: 'Change',
inputText: 'No file selected',
showInputText: true,
maxFileSize: 0, // ##3 ++
onChange: $.noop
};
// ##1 ++
var opts = $.extend(true, {}, defaults, options);
//apply events and styles for file input element
var fileInput = $(this)
.addClass('customfile-input') //add class for CSS
.mouseover(function(){ upload.addClass('customfile-hover'); })
.mouseout(function(){ upload.removeClass('customfile-hover'); })
.focus(function(){
upload.addClass('customfile-focus');
fileInput.data('val', fileInput.val());
})
.blur(function(){
upload.removeClass('customfile-focus');
$(this).trigger('checkChange');
})
.bind('disable',function(){
fileInput.attr('disabled',true);
upload.addClass('customfile-disabled');
})
.bind('enable',function(){
fileInput.removeAttr('disabled');
upload.removeClass('customfile-disabled');
})
.bind('checkChange', function(){
if(fileInput.val() && fileInput.val() != fileInput.data('val')){
fileInput.trigger('change');
}
})
.bind('change', function() {
// ##5 ++
if (opts.showInputText) {
//get file name
var fileName = $(this).val().split(/\\/).pop();
$(this).data('text', fileName);
//get file extension
var fileExt = 'customfile-ext-' + fileName.split('.').pop().toLowerCase();
//change text of button
// uploadButton.text('Change'); // ##2 --
uploadButton.text(opts.changeText); // ##2 ++
//update the feedback
uploadFeedback
.text(fileName) //set feedback text to filename
.removeClass(uploadFeedback.data('fileExt') || '') //remove any existing file extension class
.addClass(fileExt) //add file extension class
.data('fileExt', fileExt) //store file extension for class removal on next change
.addClass('customfile-feedback-populated'); //add class to show populated state
autoTruncateFileName();
}
if ($.isFunction(opts.onChange)) {
opts.onChange.apply(this, arguments);
}
})
.click(function(){ //for IE and Opera, make sure change fires after choosing a file, using an async callback
fileInput.data('val', fileInput.val());
setTimeout(function(){
fileInput.trigger('checkChange');
},100);
});
//create custom control container
var upload = $('<div class="customfile"></div>');
// ##1 ++
upload.css({
width: opts.width
});
//create custom control button
// ##2
var uploadButton = $('<span class="customfile-button" aria-hidden="true"></span>').html(opts.buttonText).appendTo(upload);
//create custom control feedback
// ##2
var uploadFeedback = $('<span class="customfile-feedback" aria-hidden="true"></span>').html(opts.inputText).appendTo(upload);
// ##3
if (opts.maxFileSize > 0 && $('input[type="hidden"][name="MAX_FILE_SIZE"]').length == 0) {
$('<input type="hidden" name="MAX_FILE_SIZE">').val(opts.maxFileSize).appendTo(upload);
}
// ##4 ++
var autoTruncateFileName = function () {
//get file name
var fileName = fileInput.val() || opts.inputText;
if (fileName.length) {
var limit = 0, // ensuring we're not going into an infinite loop
trimmedFileName = fileName;
uploadFeedback
.text(fileName)
.css({ display: 'inline' });
while (limit < 1024 && trimmedFileName.length > 0 && uploadButton.outerWidth() + uploadFeedback.outerWidth() + 5 >= uploadButton.parent().innerWidth()) {
trimmedFileName = trimmedFileName.substr(0, trimmedFileName.length - 1);
uploadFeedback.text(trimmedFileName + '...');
limit++;
}
uploadFeedback.css({ display: 'block' }); // ##4
}
};
//match disabled state
if(fileInput.is('[disabled]')){
fileInput.trigger('disable');
}
uploadFeedback.data('text', opts.inputText);
// ##5 ++
if (! opts.showInputText ) {
uploadFeedback.hide();
uploadButton
.css({
float: 'inherit',
display: 'block' // take up the full width of the parent container
})
.parent()
.css({
padding: 0
});
} else {
uploadFeedback.css({
display: 'block'
});
$(window).bind('resize', autoTruncateFileName);
}
//on mousemove, keep file input under the cursor to steal click
upload
.mousemove(function(e){
fileInput.css({
'left': e.pageX - upload.offset().left - fileInput.outerWidth() + 20, //position right side 20px right of cursor X)
'top': e.pageY - upload.offset().top - $(window).scrollTop() - 3
});
})
.insertAfter(fileInput); //insert after the input
fileInput.appendTo(upload);
//return jQuery
return $(this);
};
/**
* ----------------------------------------------------------
* EXAMPLE
*/
$(function(){
// default
$('#file_A').customFileInput();
// percentage width
$('#file_B').customFileInput({
width: '50%'
});
// Custom Text
$('#file_C').customFileInput({
width: '30%',
buttonText: 'Select File',
changeText: 'Change File',
inputText: 'Please select a file'
});
// Very short field (to test auto-truncated file name)
$('#file_D').customFileInput({
width: 150,
inputText: ''
});
// button only
$('#file_E').customFileInput({
width: 90,
buttonText: 'Upload File',
changeText: 'Change',
inputText: '',
showInputText: false
});
// Event Handlers
$('#file_F').customFileInput({
width: 250,
onChange: function () {
console.info(arguments);
}
});
});
/**
* ##1: Removed fixed with of .customfile
* ##2: Added white-space: nowrap for text
*/
html, body {
background-color:#222222;
color:white;
}
*, p {
font-family: Consolas;
}
/*custom upload elements*/
.customfile-input {
position: absolute;
height: 100px;
cursor: pointer;
background: transparent;
border: 0;
opacity: 0;
-moz-opacity: 0;
filter: progid:DXImageTransform.Microsoft.Alpha(opacity = 0);
z-index: 999;
}
.customfile {
/*width: 400px;*/ /* ##1 -- */
background: #666;
cursor: pointer;
overflow: hidden;
padding: 2px;
border: 1px solid #444;
-moz-border-radius: 7px;
-webkit-border-radius: 7px;
border-radius: 7px;
position: relative;
/* ##2 ++ */
white-space: nowrap;
}
.customfile-disabled {
opacity: .5;
filter: progid:DXImageTransform.Microsoft.Alpha(opacity = 0);
cursor: default;
}
.customfile-feedback {
/*display: block;*/
margin: 1px 1px 1px 5px;
font-size: 1.2em;
color: #fff;
font-style: italic;
padding: .3em .6em;
}
.customfile-feedback-populated {
color: #fff;
font-style: normal;
font-weight: bold;
padding-left: 20px;
background: url(http://dl.dropbox.com/u/20165443/jsFiddle/images/jquery.fileinput.icon-generic.gif) left 4px no-repeat;
}
.customfile-button {
border: 1px solid #999;
background: #333 url(http://dl.dropbox.com/u/20165443/jsFiddle/images/jquery.fileinput.bg-submit.gif) bottom repeat-x;
color: #fff;
font-weight: bold;
float: right;
/*width: 50px;*/ /* ##1 -- */
padding: .3em .6em;
text-align: center;
text-decoration: none;
font-size: 1.2em;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
border-radius: 5px;
}
.customfile-hover .customfile-button, .customfile-focus .customfile-button {
color: #111;
background: #aaa url(http://dl.dropbox.com/u/20165443/jsFiddle/images/jquery.fileinput.bg-btn.png) bottom repeat-x;
border-color: #aaa;
padding: .3em .6em;
}
.customfile-focus .customfile-button {
outline: 1px dotted #ccc;
}
/*file type icons*/
.customfile-ext-jpg, .customfile-ext-gif, .customfile-ext-png, .customfile-ext-jpeg, .customfile-ext-bmp {
background-image: url(http://dl.dropbox.com/u/20165443/jsFiddle/images/jquery.fileinput.icon-image.gif);
}
.customfile-ext-mp3, .customfile-ext-mp4, .customfile-ext-mov, .customfile-ext-swf, .customfile-ext-wav, .customfile-ext-m4v {
background-image: url(http://dl.dropbox.com/u/20165443/jsFiddle/images/jquery.fileinput.icon-media.gif);
}
.customfile-ext-zip, .customfile-ext-tar, .customfile-ext-sit {
background-image: url(http://dl.dropbox.com/u/20165443/jsFiddle/images/jquery.fileinput.icon-zip.gif);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment