Блог

JavaScript: изменение вида input[type=file]

Задание: нужно изменить внешний вид поля input[type=”file”]. Очень частое задание для программистов и верстальщиков. А все почему, а потому что в QA и Клиенты считают, что должно все быть как одно. Согласен, но как же без но. Нужно и понимать, что если кнопки и т.д. не на верстаны то используются браузерный вид кнопок и т.д.

Но если уже есть у вас такая задача, может этот пример поможет Вам в чем-то. Я использую только Javascript с не полным CSS. Писал в целях само обучения.
HTML:

<form method="post" action="index.html" id="frm" enctype="multipart/form-data">
   <input type="file" id="upload" value="" style="display:none;" />
   <br />
   <input type="submit" value="Send form" />
</form>

Данный вариант работает во всех браузерах. Есть одно НО! Как всегда IE отличился от других, придумывают заглужки со своими багами. В общем, возможно вы не увидите результатов из-за установленной безопасности в браузере.

JavaScript

var Upload = function(id) {
	this.isIE = /MSIE/i.test(navigator.userAgent);
	this._file = this._desc = null;

	this._file = document.getElementById(id);
	if (!this._file) {
		return false;
	} else {
		this._file.style.display = '';
	}

	var container = document.createElement('div');

	this.button = document.createElement('input');
	this.button.type = 'button';
	this.button.value = 'Select file...';
	container.appendChild(this.button);

	this._desc = document.createElement('span');
	this._desc.id = this._file.id + '_desc';
	container.appendChild(this._desc);

	var css = {
		_file : 'visibility:hidden; width:0px;',
		_cont : 'padding:0px; margin:0px; height:1.50em; overflow:hidden; ',
		_desc : 'padding-left:5px; color:#A0A0A0'
	};
	if (typeof (container.style.cssText) == 'string') {
		container.style.cssText = css._cont;
		this._file.style.cssText = css._file;
		this._desc.style.cssText = css._desc;
	}
	container.setAttribute('style', css._cont);
	this._file.setAttribute('style', css._file);
	this._desc.setAttribute('style', css._desc);

	this._file.parentElement.insertBefore(container, this._file.nextSibling);

	this.set_event();
}
Upload.prototype.set_event = function() {
	var _upload = this;

	this.button.onclick = (function() {
		var file = _upload._file;
		file.value = '';

		file.click();

		file.onchange = (function(e) {
			return _upload.set_value(this.value);
		});

		if (_upload.isIE && document.createEventObject) {
			var evt = document.createEventObject();
			file.fireEvent('onchange', evt);
		}

	});
}
Upload.prototype.set_value = function(value) {
	if (this.isIE) {
		this._file.blur();
		this._file.onchange = null;
	}
	var name = value.split('\\');
	if (name.length)
		name = name[name.length - 1];

	this._desc.innerHTML = name;

	return true;
}

window.onload = (function() {
	var file = new Upload('upload');
});

В помощь:
http://vremenno.net/design/file-inputs-styling/
http://vremenno.net/examples/file-input-styling/