Skip to content

Instantly share code, notes, and snippets.

@dairiki
Created October 6, 2013 16:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dairiki/6855814 to your computer and use it in GitHub Desktop.
Save dairiki/6855814 to your computer and use it in GitHub Desktop.
.btn-file {
background-color: #f2f2f2;
}
.btn-file:hover {
background-color: #ededed;
}
.upload-filename[readonly] {
background-color: #fdfdfd;
}
<!DOCTYPE html>
<html>
<head>
<meta name="description" content="file upload for bootstrap" />
<script src="http://code.jquery.com/jquery.min.js"></script>
<link href="http://getbootstrap.com/dist/css/bootstrap.css" rel="stylesheet" type="text/css" />
<script src="http://getbootstrap.com/dist/js/bootstrap.js"></script>
<meta charset=utf-8 />
<title>JS Bin</title>
</head>
<body>
<div class="container">
<h1>Styled file inputs for bootstrap 3</h1>
<p>Nicer looking file inputs for bootstrap 3.
Ideas ripped off from
<a href="http://www.abeautifulsite.net/blog/2013/08/whipping-file-inputs-into-shape-with-bootstrap-3/">here</a>.
</p>
<div class="row">
<div class="col-md-6">
<div class="panel panel-default">
<div class="panel-heading">Basic</div>
<div class="panel-body">
<form class="form-horizontal">
<div class="form-group">
<label for="upload1" class="col-sm-3 control-label">
Upload
</label>
<div class="col-sm-9">
<input type="file" name="upload" id="upload1">
</div>
</div>
</form>
</div>
</div>
</div>
<div class="col-md-6">
<p>Basic file input in a “horizontal” form.</p>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="panel panel-default">
<div class="panel-heading">With existing filename</div>
<div class="panel-body">
<form class="form-horizontal">
<div class="form-group">
<label for="upload2" class="col-sm-3 control-label">
Upload
</label>
<div class="col-sm-9">
<input type="file" name="upload" id="upload2"
data-filename="existing.txt">
</div>
</div>
</form>
</div>
</div>
</div>
<div class="col-md-6">
<pre>
&lt;input type="file" data-filename="existing.txt"&gt;
</pre>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="panel panel-default">
<div class="panel-heading">With explicit style</div>
<div class="panel-body">
<form class="form-horizontal">
<div class="form-group">
<label for="upload3" class="col-sm-3 control-label">
Upload
</label>
<div class="col-sm-9">
<input type="file" name="upload" id="upload3"
style="width:75%;">
</div>
</div>
</form>
</div>
</div>
</div>
<div class="col-md-6">
<p>Explicit style attribute on the file input gets applied to the wrapper.</p>
<pre>
&lt;input type="file" style="width:75%;"&gt;
</pre>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="panel panel-default">
<div class="panel-heading">Programatic Initialization</div>
<div class="panel-body">
<form class="form-horizontal">
<div class="form-group">
<label for="upload4" class="col-sm-3 control-label">
Upload
</label>
<div class="col-sm-9">
<input type="file" name="upload" id="upload4">
</div>
</div>
</form>
</div>
</div>
</div>
<div class="col-md-6">
<p>Explicit initialization/destruction.</p>
<p>
<button type="button" onclick="$('#upload4').upload('destroy');">Destroy</button>
<button type="button" onclick="$('#upload4').upload();">Create</button>
</p>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="panel panel-default">
<div class="panel-heading">Custom button text</div>
<div class="panel-body">
<form class="form-horizontal">
<div class="form-group">
<label for="upload5" class="col-sm-3 control-label">
Upload
</label>
<div class="col-sm-9">
<input type="file" name="upload" id="upload5"
data-selectfile="Pick!"
data-changefile="Change!">
</div>
</div>
</form>
</div>
</div>
</div>
<div class="col-md-6">
<pre>
&lt;input type="file" data-selectfile="Pick!" data-changefile="Change!"&gt;
</pre>
</div>
</div>
</div>
<script>
$(document).ready(function () {
$(':file').upload();
});
</script>
</body>
</html>
/**
* Nicer looking file inputs for bootstrap 3
* By Jeff Dairiki <dairiki@dairiki.org> based on ideas from
* http://www.abeautifulsite.net/blog/2013/08/whipping-file-inputs-into-shape-with-bootstrap-3/
*/
(function ($) {
var Upload = function (element, options) {
this.$element = $(element);
this.options = $.extend({}, Upload.DEFAULTS, this.$element.data(), options);
this.$input_group = $(this.options.template)
.replaceAll(this.$element)
.attr('style', this.$element.attr('style'));
this.$input_group.find('.input-group-btn')
.append(this.$element);
this.$element
.css(this.options.element_style)
.on('change.dairiki.upload', $.proxy(this.change, this));
this.update_filename(this.options.filename);
};
Upload.DEFAULTS = {
filename: null,
selectfile: 'Select file…',
changefile: 'Change file…',
template: ('<div class="input-group">'
+ '<span class="input-group-btn" style="position: relative; overflow: hidden;">'
+ '<span class="btn btn-default btn-file">Select file…</span>'
+ '</span>'
+ '<input type="text" readonly="" class="form-control upload-filename"/>'
+ '</div>'),
element_style: {
position: 'absolute',
top: '0',
right: '0',
minWidth: '100%',
minHeight: '100%',
fontSize: '999px',
textAlign: 'right',
filter: 'alpha(opacity=0)',
opacity: '0',
background: 'red',
cursor: 'inherit',
display: 'block'
}
};
Upload.prototype.change = function () {
var filename = this.$element.val().replace(/\\/g, '/').replace(/.*\//, '');
this.update_filename(filename || this.options.filename);
this.$element.trigger('changed.dairiki.upload', filename);
};
Upload.prototype.update_filename = function (filename) {
this.$input_group.find(':text')
.val(filename);
this.$input_group.find('.btn-file')
.text(filename ? this.options.changefile : this.options.selectfile);
};
Upload.prototype.destroy = function () {
this.$element
.off('.dairiki.upload')
.attr('style', this.$input_group.attr('style') || null)
.replaceAll(this.$input_group)
.removeData('dairiki.upload');
};
var old = $.fn.upload;
$.fn.upload = function (option) {
var args = [].slice.call(arguments, 1);
return this.each(function () {
var $this = $(this);
var data = $this.data('dairiki.upload');
var options = typeof option == 'object' && option;
if (!data) $this.data('dairiki.upload', (data = new Upload(this, options)));
if (typeof option == 'string') data[option].apply(data, args);
});
};
$.fn.upload.Constructor = Upload;
$.fn.upload.noConflict = function () {
$.fn.upload = old;
return this;
};
})(window.jQuery);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment