Оформление input type file. Проблема стилизации элементов форм. «Все гениальное - просто!» или стили для способа с применением label
Данный плагин позволяет стилизовать с помощью CSS следующие HTML-элементы:
- флажок ;
- переключатель ;
- поле для выбора файла .
- поле для ввода чисел .
- раскрывающийся список ;
Живые примеры можно посмотреть на отдельной странице . Стоит заметить, что при оформлении элементов форм не использовано ни одного изображения, только CSS.
Достоинства- Общее:
- Простота оформления с помощью CSS.
- При отключенном JavaScript отображаются стандартные элементы форм, т.е. их работоспособность не теряется.
- Псевдоэлементы выводятся внутристрочно, т.е. повторяют свойство стандартных элементов.
- Поддержка работы с динамически добавляемыми/изменяемыми элементами.
- Поддержка атрибутов checked , selected , disabled .
- Атрибуты class , id , data-* , title , указанные у оригинальных элементов форм, передаются в соответствующие псевдоэлементы (id передается с суффиксом, чтобы избежать дублирования).
- Поддержка динамического добавления/изменения атрибутов class , id , data-* , title .
- Поддержка сброса формы при нажатии на .
- Умеет «ловить» нажатие клавиши Tab и позволяет переключать элементы с клавиатуры.
- Кроссбраузерность (все современные браузеры, а также IE8 и выше).
- Поддержка валидации HTML5.
- Поддержка мультиязычности.
- Поддерживает атрибут multiple , т.е. позволяет выбирать несколько пунктов (мультиселект).
- Поддерживает группировку элементов списка в селекте (тег ).
- Позволяет задать максимальную высоту для выпадающего списка (CSS-свойством max-height , либо через опцию selectVisibleOptions).
- Поддерживает «умное позиционирование», т.е. не уходит за видимую часть страницы при открытии списка.
- Поддержка поиска по пунктам одиночного селекта.
- Поддержка замещающего текста (placeholder).
- Автоматически подстраивает ширину, если она не указана.
- Поддерживает прокрутку колесом мыши.
Для селектов:
При использовании некоторых нестандартных шрифтов (например, Open Sans, подключенный с Google Fonts), неправильно определяется ширина псевдоселекта, в связи с чем текст пунктов обрезается. Это связано с тем, что шрифт применяется лишь после стилизации селекта плагином. Как вариант решения этой проблемы, можно сделать отложенный запуск скрипта:
setTimeout(function() { $("input, select").styler(); }, 100)
Еще один вариант решения — использовать , который переинициализирует плагин после окончания загрузки шрифта.
- В Mac OS при переключении селекта с клавиатуры появляется нативный выпадающий список.
Для работы плагина необходимо использовать jQuery не ниже версии 1.7.0.
Подключите jQuery (если он еще не подключен), плагин и стили к нему, добавив следующие строки перед тегом :
Файл jquery.formstyler.css — это обязательные стили, необходимые для корректной работы плагина, а jquery.formstyler.theme.css — визуальное оформление элементов форм.
Для активации плагина примените метод.styler к тегам, которые хотите стилизовать:
(function($) { $(function() { $("input, select").styler(); }); })(jQuery);
Отключение плагина (метод destroy)Если есть необходимость отвязать плагин от стилизованного элемента, то задействуйте метод destroy:
$("select").styler("destroy");
Динамическое изменениеПри динамическом изменении элементов формы необходимо запустить триггер refresh , например:
$("button").click(function(e) { e.preventDefault(); /* делаем чекбокс неактивным */ $("input:checkbox").attr("disabled", true) /* обновляем состояние псевдочекбокса */ .trigger("refresh"); });
При использовании сторонних плагинов, например, jQuery Validation , которые меняют атрибуты элементов формы, событие.trigger("refresh") необходимо запускать, используя setTimeout , иначе состояния псевдоэлементов не изменится. Пример с вышеуказанным плагином:
$("form").validate({ invalidHandler: function() { setTimeout(function() { $("input, select").trigger("refresh"); }, 1) } });
Опции плагинаБольшинство опции плагина можно переопределить для конкретного тега, указав ему соответствующий data-атрибут.
idSuffix | -styler | суффикс к атрибуту id , передаваемому от стилизуемого элемента | |
filePlaceholder | Файл не выбран | текст по умолчанию в поле выбора файла (когда файл не выбран) | data-placeholder |
fileBrowse | Обзор... | текст кнопки у поля для выбора файла | data-browse |
fileNumber | Выбрано файлов: %s | текст после выбора нескольких файлов, вместо %s вставится число | data-number |
selectPlaceholder | Выберите... | замещающий текст (плейсхолдер) в одиночном селекте; отображается, если по умолчанию выбран первый пункт с отсутствующим текстом: | data-placeholder |
selectSearch | false | показывать поисковое поле в одиночном селекте (true — да, false — нет) | data-search |
selectSearchLimit | 10 | минимальное количество пунктов одиночного селекта, при котором показывать поиск | data-search-limit |
selectSearchNotFound | Совпадений не найдено | текст сообщения о том, что нет пунктов, удовлетворяющих поиску | data-search-not-found |
selectSearchPlaceholder | Поиск... | текст по умолчанию в поисковом поле | data-search-placeholder |
selectVisibleOptions | 0 | количество отображаемых пунктов списка в простом селекте без прокрутки | data-visible-options |
selectSmartPositioning | true | умное позиционирование для выпадающего списка селекта: true — работает вверх и вниз false — работает только вниз "-1" — позиционирование отключено | data-smart-positioning |
locale | ru | текущая локаль | |
locales | английская локализация | массив локалей с переводом соответствующих опций, подробнее смотрите |
Пример использования:
$("input, select").styler({ fileBrowse: "Выбрать", singleSelectzIndex: "999", onSelectOpened: function() { // к открытому селекту добавляется красная обводка $(this).css("outline", "3px solid red"); } });
ЛокализацияПлагин поддерживает многоязычность. Для этого используются опции locale и locales .
Пример локализации (английская по умолчанию включена в плагин):
$("input, select").styler({ locale: "en", locales: { "en": { filePlaceholder: "No file selected", fileBrowse: "Browse...", fileNumber: "Selected files: %s", selectPlaceholder: "Select...", selectSearchNotFound: "No matches found", selectSearchPlaceholder: "Search..." } }, });
CSS-селекторы, используемые для оформления.jq-checkbox | чекбокс по умолчанию |
.jq-checkbox__div | дополнительный вложенный тег |
.jq-checkbox.checked | выбранный чекбокс |
.jq-checkbox.disabled | неактивный (недоступный для выбора) чекбокс |
.jq-checkbox.focused | фокус на чекбоксе, когда нажата клавиша Tab |
.jq-checkbox span | дополнительный вложенный тег |
.jq-radio | радиокнопка по умолчанию |
.jq-radio__div | дополнительный вложенный тег |
.jq-radio.checked | выбранная радиокнопка |
.jq-radio.disabled | неактивная (недоступная для выбора) радиокнопка |
.jq-radio.focused | фокус на радиокнопке, когда нажата клавиша Tab |
.jq-radio span | дополнительный вложенный тег |
.jq-file | родительский контейнер |
.jq-file.focused | фокус на поле |
.jq-file.changed | файл выбран |
.jq-file.disabled | неактивное поле |
.jq-file__name | поле с именем файла |
.jq-file__browse | кнопка выбора файла |
.jq-number | родительский контейнер |
.jq-number.focused | фокус на поле |
.jq-number.disabled | неактивное поле |
.jq-number__field | обертка для поля ввода |
.jq-number__spin.minus | кнопка «минус» |
.jq-number__spin.plus | кнопка «плюс» |
.jq-selectbox | родительский контейнер |
.jq-selectbox.opened | выпадающий список селекта раскрыт |
.jq-selectbox.dropup | выпадающий список селекта раскрыт вверх |
.jq-selectbox.dropdown | выпадающий список селекта раскрыт вниз |
.jq-selectbox.changed | выбрано значение, отличное от заданного по умолчанию |
.jq-selectbox__select | селект в свернутом состоянии |
.focused .jq-selectbox__select | фокус на селекте, когда нажата клавиша Tab |
.disabled .jq-selectbox__select | |
.jq-selectbox__select-text | дополнительный вложенный тег для свернутого селекта |
.jq-selectbox .placeholder | замещающий текст |
.jq-selectbox__trigger | правая часть свернутого селекта (условный переключатель) |
.jq-selectbox__trigger-arrow | вложенный тег для переключателя (стрелка) |
.jq-selectbox__dropdown | обертка для выпадающего списка |
.jq-selectbox__search | обертка для поискового поля |
.jq-selectbox__search input | поисковое поле |
.jq-selectbox__not-found | сообщение об отсутствии результатов поиска |
.jq-selectbox ul | выпадающий список |
.jq-selectbox li | пункт (опция) селекта |
.jq-selectbox li.selected | выбранный пункт селекта |
.jq-selectbox li.disabled | |
.jq-selectbox li.optgroup | заголовок для группы пунктов |
.jq-selectbox li.option | пункт списка в группе |
.jq-select-multiple | родительский контейнер |
.jq-select-multiple.disabled | неактивный (недоступный для выбора) селект |
.jq-select-multiple li | пункт (опция) селекта |
.jq-select-multiple li.selected | выбранный пункт селекта |
.jq-select-multiple li.disabled | неактивный (недоступный для выбора) пункт селекта |
.jq-select-multiple li.optgroup | заголовок для группы пунктов |
.jq-select-multiple li.option | пункт списка в группе |
.styler | класс, используемый для стилизации текстовых полей и кнопок (работает независимо от плагина) |
Уже немало копий front-end разработчиков было сломано об проблему стилизации поля ввода input . Суть проблемы заключается в том, что в спецификации HTML нет строгих правил, устанавливающих, как же должен отображаться браузером этот элемент. Более того, для input не предусмотрено атрибутов, которые позволили бы изменить его внешний вид, с помощью стилей CSS можно изменить лишь вид его границы и шрифт, а средствами JavaScript, из соображений безопасности, нельзя сымитировать клик по этому элементу, который вызвал бы системное окно для выбора файла * . Но что же делать, когда заказчик хочет адаптивный сайт с красивыми стилизованными формами, в которых нельзя обойтись без этого поля ввода?
* - на момент написания этой статьи, мне было еще неизвестно, что уже во всех современных браузерах имитация клика по input вызывает системное окно выбора файла. Большое спасибо lutov за ценный комментарий с ссылкой на рабочий пример от Pagefest !
Способы решения проблемы стилизации поля За то время, сколько существует эта проблема (а существует она очень долго), было найдено несколько способов ее решения. Всего их существует пять:Способ №1 (самый распространенный)Убедить заказчика, что можно жить и со стандартным input .Способ №2Написать/использовать готовый загрузчик файлов на Flash/Java-апплете. Используется, например, на habrastorage.org Способ №3 (будет рассмотрен в статье)Средствами CSS «замаскировать» стандартный input , сделать его полностью прозрачным и поместить на месте стилизованного фейкового поля, чтобы клик по последнему вызывал клик по стандартному, и, как следствие, открывал системное окно выбора файла.Способ №4 new! (будет рассмотрен в статье) Поместить прозрачный input внутрь элемента label, вместе с произвольными стилизованными инлайновыми элементами (кроме input, button, select и textarea, разумеется). Клик по label автоматически приведет к клику и по скрытому полю для выбора файла. Спасибо lampa за ценный комментарий !Способ №5 new! (будет рассмотрен в статье)Использовать имитацию клика по скрытому input средствами JavaScript. Да, это уже работает во всех современных браузерах. Еще раз спасибо lutov за ценный комментарий !UPD: Внимание , данный способ неприменим для браузера Internet Explorer! Несмотря на то, что файл выбирается в скрытом input , при отправке формы значение последнего будет «сброшено». Спасибо LeonidFrolov за ценный комментарий !
У всех четырех последних способов, разумеется, есть свои минусы. Существенный недостаток Flash/Java-решения в том, что для его работы нужны соответствующие плагины, которых в браузере пользователя может не оказаться. Большой недостаток «маскировочного» решения же заключается в том, что для его реализации необходимо использовать хаки (про это речь пойдет ниже), а также потому, что оно бессмысленно без использования JavaScript (ведь нужно же как-то различать состояния «файл не выбран» и «файл выбран» для стилизованного фейкового поля, что на одном CSS сделать невозможно). Решение на JavaScript, в целом, было бы очень хорошим, но, как оказалось на практике, оно не поддерживается браузером Internet Explorer, о чем было сказано выше. Минус решения с использованием label - все то же использование JavaScript, однако, оно гораздо лучше «маскировочного» способа и должно, на мой взгляд, использоваться сейчас для решения этой острой проблемы.
Схема велосипеда Ключевой задачей было поставлено создание «резинового» input , который на экранах мобильных устройств представлял бы из себя простую кнопку для выбора файла (имя выбранного файла выводится на ней же), а на широких экранах выглядел бы как привычное для всех текстовое поле + кнопка, которое может тянуться на всю ширину окна:Схематический вид элемента на мобильных устройствах
Схематический вид элемента на десктопных устройствах
В статье будут рассмотрены три последних способа стилизации поля выбора файла. Таким образом, с учетом оговоренной выше схемы, исходная верстка для «маскировочного» способа №3 будет иметь следующий вид (порядок дочерних элементов важен!):
Выбрать Файл не выбран
Возможная верстка для способа с применением элемента label:
Выбрать
Файл не выбран
Возможная верстка для решения на JavaScript (совпадает с версткой для «маскировочного» способа):
Выбрать
Файл не выбран
/* example */
Договорились? Отлично! Начнем стилизовать наше фейковое поле выбора файла с его «обертки» - div.file_upload :
File_upload{
position: relative;
overflow: hidden;
font-size: 1em; /* example */
height: 2em; /* example */
line-height: 2em /* the same as height */
}
- свойство position задается для того, чтобы относительно div.file_upload
можно было абсолютно позиционировать его дочерние элементы, а свойство overflow - для того, чтобы скрывать все то, что по каким-то причинам не влезет в нашу обертку (а такое найдется, но об этом позже). На широких экранах наши красивые поле и кнопка должны отображаться в одну строку - зададим для последней фиксированную ширину и float: right, а для первого - небольшой внутренний отступ:
File_upload > button{
float: right;
width: 8em; /* example */
height: 100%
}
.file_upload > div{
padding-left: 1em /* example */
}
Поскольку мы хотим, чтобы на мобильных устройствах текстовое поле скрывалось, и оставалась одна кнопка выбора файла, необходимо задать media query
:
@media only screen and (max-width: 500px){ /* example */
.file_upload > div{
display: none
}
.file_upload > button{
width: 100%
}
}
Ну а теперь - самое веселое в данном методе! Необходимо сделать стандартный input
полностью прозрачным, и растаращить растянуть его до размеров «обертки» div.file_upload
. Для реализации последнего применим хак в виде абсолютного позиционирования и свойства CSS 3 transform , с помощью которого увеличим элемент, например, в 20 раз (да, это самое обычное «магическое число»):
.file_upload input{
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
transform: scale(20);
letter-spacing: 10em; /* IE 9 fix */
-ms-transform: scale(20); /* IE 9 fix */
opacity: 0;
cursor: pointer
}
Как видно из приведенного выше фрагмента CSS, для IE 9 потребовались дополнительные костыли. Это связано с тем, что данный браузер при клике на текстовое поле не вызывает системное окно выбора файла, а любезно предлагает «стереть» имя уже выбранного, что символизируется мигающим текстовым курсором. Поэтому для него дополнительно задается огромный интервал между буквами, что увеличивает кнопку элемента до размеров div.file_upload
. Отмечу также, что z-index в данном случае не указывается, т.к. элемент идет последним «потомком» в выбранной с самого начала разметке.
На примере десктопного браузера FireFox, сейчас наше кастомизированное поле выбора файла для разных размеров окна выглядит так:
«Все гениальное - просто!» или стили для способа с применением label Основные стили, применяемые к текстовому полю и кнопке, для этого способа похожи на уже рассмотренные выше:File_upload{
display: block;
position: relative;
overflow: hidden;
font-size: 1em; /* example */
height: 2em; /* example */
line-height: 2em /* the same as height */
}
.file_upload .button, .file_upload > mark{
display: block;
cursor: pointer /* example */
}
.file_upload .button{
float: right;
box-sizing: border-box;
-moz-box-sizing: border-box;
width: 8em; /* example */
height: 100%;
text-align: center /* example */
}
.file_upload > mark{
background: transparent; /* example */
padding-left: 1em /* example */
}
Однако, теперь уже нет необходимости использовать хак с «растягиванием» прозрачного input
:
File_upload input{ position: absolute; top: 0; opacity: 0 }
«Как это работает?» или стили для решения на JavaScript Поскольку исходная верстка для данного способа была выбрана такой же, как и в «маскировочном», стили для кнопки и текстового поля для обоих способов также совпадают (за исключением, разве что, свойства cursor: pointer , которое, в данном случае, будет применяться к кнопке и текстовому полю). Стиль же input можно взять тот же, что использовался в методе c применением элемента label, но в нем лучше вместо свойства opacity использовать visibility:File_upload input{ position: absolute; top: 0; visibility: hidden }
Нужно больше стилей! Разумеется, в таком примитивном виде поле выбора файла вряд ли кого-то устроит, поэтому добавим дополнительные стили, которые сделают кнопку выбора файла, скажем, фиолетовой, добавят тени и т.д. Не забудем также добавить свой стиль для кнопки, когда на нее наведен курсор, стиль для нажатой кнопки, а еще добавим стиль для всего элемента, когда на нем находится фокус (будет применяться при помощи JavaScript):/* Making it beautiful */ .file_upload{ border: 1px solid #ccc; border-radius: 3px; box-shadow: 0 0 5px rgba(0,0,0,0.1); transition: box-shadow 0.1s linear } .file_upload.focus{ box-shadow: 0 0 5px rgba(0,30,255,0.4) } .file_upload > button{ background: #7300df; transition: background 0.2s; border: 1px solid rgba(0,0,0,0.1); border-color: rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25); border-radius: 2px; box-shadow: 0 1px 0 rgba(255, 255, 255, 0.2) inset, 0 1px 2px rgba(0, 0, 0, 0.05); color: #fff; text-shadow: #6200bd 0 -1px 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis } .file_upload:hover > button{ background: #6200bd; text-shadow: #5d00b3 0 -1px 0 } .file_upload:active > button{ background: #5d00b3; box-shadow: 0 0 3px rgba(0,0,0,0.3) inset }
Теперь наше поле выбора файла выглядит так:
Нужно больше костылей! Поскольку мы делаем полноценное поле для выбора файла, то нужно позаботиться о том, чтобы его можно было комфортно заполнять и с клавиатуры (для «маскировочного» способа фокус сейчас вначале устанавливается на стилизованную кнопку, а затем - на скрытый input , что никак визуально не проявляется). Для этого, разумеется, используем JavaScript. Чтобы не писать много кода, я позволю себе использовать популярную библиотеку jQuery. Тогда, для «маскировочного» способа:Var wrapper = $(".file_upload"),
inp = wrapper.find("input"),
btn = wrapper.find("button"),
lbl = wrapper.find("div");
btn.focus(function(){
inp.focus()
});
// Crutches for the:focus style:
inp.focus(function(){
wrapper.addClass("focus");
}).blur(function(){
wrapper.removeClass("focus");
});
Для метода с использованием label можно убрать участок кода, отвечающий за принудительный перенос фокуса с кнопки на input
(т.к. там у нас и не кнопка вовсе, а span).
Для метода, суть которого заключается в имитации клика по input , нужно, собственно, добавить эту самую имитацию:
// Yep, it works!
btn.add(lbl).click(function(){
inp.click();
});
а также скорректировать код для установки класса .focus
, предварительно убрав фрагмент, отвечающий за принудительный перенос фокуса:
// Crutches for the:focus style:
btn.focus(function(){
wrapper.addClass("focus");
}).blur(function(){
wrapper.removeClass("focus");
});
Поле ввода до сих пор оставалось «мертвым» - при выборе файла имя последнего нигде не отображалось. Пришло время исправить и это:
Var file_api = (window.File && window.FileReader && window.FileList && window.Blob) ? true: false;
inp.change(function(){
var file_name;
if(file_api && inp[ 0 ].files[ 0 ])
file_name = inp[ 0 ].files[ 0 ].name;
else
file_name = inp.val().replace("C:\\fakepath\\", "");
if(! file_name.length)
return;
if(lbl.is(":visible")){
lbl.text(file_name);
btn.text("Выбрать");
}else
btn.text(file_name);
}).change();
- если браузер поддерживает File API, то имя файла определяется с помощью него, в противном случае оно вырезается из значения скрытого input
. Для мобильных устройств, когда элемент представляет из себя одну кнопку, имя выбранного файла выводится на ней же.
Казалось бы, все, что требуется, уже написано. А вот фигушки! Если выбрать файл, используя «мобильное» поле, а затем увеличить размер окна и перевести элемент в «десктопный», то в текстовом поле так и останется «Файл не выбран» - нужно каждый раз обновлять элемент при изменении размеров окна:
$(window).resize(function(){
$(".file_upload input").triggerHandler("change");
});
- FireFox 22.0 (Linux, Windows)
- Opera 12.16 (Linux, Windows)
- Internet Explorer 9
- Chromium 27.0 (Linux)
- Apple Safari (iOS 6.3.1)
- Android browser (Android 2.3.6)
- Android FireFox
Из плюсов всех рассмотренных в статье подходов можно выделить следующие основные:
- Не используется Flash.
- Элемент можно легко стилизовать средствами CSS, используя современные технологии адаптивного дизайна.
- Поле можно заполнять и с клавиатуры.
Из основных минусов:
- Необходимость использования JavaScript (касается всех способов).
- Использование хаков CSS для «маскировочного» способа.
- Необходимость писать дополнительные костыли для поля с атрибутом multiple (касается всех способов).
- Некроссбраузерность - у всех способов отсутствует поддержка IE 8, а также необходимо использовать «браузерные» свойства CSS для поддержки остальных «старичков».
- Решение на JavaScript не поддерживается всеми версиями Internet Explorer, а также некоторыми старыми версиями других популярных браузеров (хотя ими уже практически никто и не пользуется).
Какой из трех двух элегантных способов создания стилизованного input выбрать для повседневного использования - решать вам. Мой выбор - способ с использованием label (хоть он и имеет несемантичную верстку).
Рабочие примеры всех трех способов можно посмотреть на CodePen.
Я думаю, что многих, как и меня, не совсем устраивает стандартный вид поля загрузки файлов. Помимо того, что оно, грубо говоря, некрасивое, так еще и в разных браузерах выглядит по-разному.
Наша же задача – сделать поле более привлекательным и, разумеется, привести его к единству.
Для решения задачи нам поможет тег label , который связывает текст и прочие элементы с элементами формы (в нашем случае – с кнопкой), jQuery (который поможет нам получить необходимую информацию о выбранных файлах – имена и их расширение) и дополнительное поле input, где мы будем непосредственно хранить нашу информацию о файлах.
1. Первое, что вам потребуется – это само поле с выбором файла. Код его следующий:
Обзор...
И выглядит все это пока так:
Как вы заметили в коде, дополнительное текстовое поле мы заблокировали, чтобы в дальнейшем пользователь не мог на него воздействовать, ведь в нем у нас будет выводиться информация о файле.
2. Теперь мы напишем небольшой скрипт, который как раз и будет выводить нам информацию о файле:
$(document).ready(function() { $(".main_input_file").change(function() { var f_name = ; for (var i = 0; i < $(this).get(0).files.length; ++i) { f_name.push(" " + $(this).get(0).files[i].name); } $("#f_name").val(f_name.join(", ")); }); });
Код желательно вставить перед закрывающим тегом . И смотрим, что у нас получилось:
Отлично! То, что нам нужно. Теперь осталось скрыть стандартное поле выбора файла и причесать нашу созданную форму.
3. Для этого напишем небольшой CSS-стиль:
Main_input_file { display: none; } .upload_form div { width: 100px; height: 32px; background: #3498db; border-radius: 4px; color: #fff; text-align: center; line-height: 32px; font-family: arial; font-size:14px; display: inline-block; vertical-align: top; } .upload_form div:hover { background: #2980b9; cursor: pointer; } #f_name { background: transparent; border: 0; display: inline-block; vertical-align: top; height: 30px; padding: 0 8px; width: 150px; }
Все это сохраняем и любуемся результатом:
По-моему, очень неплохо.
Возможные ошибки в работе этого методаИз так называемых проблем, по которым этот способ может у вас не сработать, – это отсутствие библиотеки jQuery (очень частая проблема статичных сайтов). Решается следующим способом.
Перед закрывающим тегом подключите библиотеку:
Хочу подчеркнуть , что, в отличие от подобных инструкций на других сайтах, моя – более простая и к тому же может работать с множеством фалов в вашем поле (в таком случае все выбранные файлы в поле будут указываться через запятую).
Я думаю, что многих, как и меня, не совсем устраивает стандартный вид поля загрузки файлов. Помимо того, что оно, грубо говоря, некрасивое, так еще и в разных браузерах выглядит по-разному.
Наша же задача – сделать поле более привлекательным и, разумеется, привести его к единству.
Для решения задачи нам поможет тег label , который связывает текст и прочие элементы с элементами формы (в нашем случае – с кнопкой), jQuery (который поможет нам получить необходимую информацию о выбранных файлах – имена и их расширение) и дополнительное поле input, где мы будем непосредственно хранить нашу информацию о файлах.
1. Первое, что вам потребуется – это само поле с выбором файла. Код его следующий:
Обзор...
И выглядит все это пока так:
Как вы заметили в коде, дополнительное текстовое поле мы заблокировали, чтобы в дальнейшем пользователь не мог на него воздействовать, ведь в нем у нас будет выводиться информация о файле.
2. Теперь мы напишем небольшой скрипт, который как раз и будет выводить нам информацию о файле:
$(document).ready(function() { $(".main_input_file").change(function() { var f_name = ; for (var i = 0; i < $(this).get(0).files.length; ++i) { f_name.push(" " + $(this).get(0).files[i].name); } $("#f_name").val(f_name.join(", ")); }); });
Код желательно вставить перед закрывающим тегом . И смотрим, что у нас получилось:
Отлично! То, что нам нужно. Теперь осталось скрыть стандартное поле выбора файла и причесать нашу созданную форму.
3. Для этого напишем небольшой CSS-стиль:
Main_input_file { display: none; } .upload_form div { width: 100px; height: 32px; background: #3498db; border-radius: 4px; color: #fff; text-align: center; line-height: 32px; font-family: arial; font-size:14px; display: inline-block; vertical-align: top; } .upload_form div:hover { background: #2980b9; cursor: pointer; } #f_name { background: transparent; border: 0; display: inline-block; vertical-align: top; height: 30px; padding: 0 8px; width: 150px; }
Все это сохраняем и любуемся результатом:
По-моему, очень неплохо.
Возможные ошибки в работе этого методаИз так называемых проблем, по которым этот способ может у вас не сработать, – это отсутствие библиотеки jQuery (очень частая проблема статичных сайтов). Решается следующим способом.
Перед закрывающим тегом подключите библиотеку:
Хочу подчеркнуть , что, в отличие от подобных инструкций на других сайтах, моя – более простая и к тому же может работать с множеством фалов в вашем поле (в таком случае все выбранные файлы в поле будут указываться через запятую).