Как стать автором
Поиск
Написать публикацию
Обновить

Меняем input[type=file]

Я думаю что все кто занимается версткой так или иначе сталкивались с проблемой кастомизации input[type=file]. Задача сама по себе не тривиальная, так как на прямую возможность задать стиль для данного поля нельзя. Вот и на моей профессиональной улице случился праздник, когда для одного проекта понадобилось изменить стиль отображения для стандартных полей выбора файлов. О том как я это делал я и собираюсь рассказать.



Конечно же первым делом я обратился к великому и могучему гуглу и менее великому, но в некоторых моментах не менее могучему яндексу. И что же я увидел? Конечно же огромное количество репостов двух трех статей (вот кстати ссылки на них — здесь взята основная идея и html составляющая, очень хорошая статья по теме), но все найденные решения не подходили под то что надо сделать. В общем то кастомизировать файл-инпут с сохранением функциональности и максимальной похожестью на оригинал. Начнем с HTML составляющей.


<div class="input_file">
 <input type="file" name="" >
 <div class="fake_file"><input type="text" class="fake_file_input">
  <input type="button" value="Выбрать"></div>
</div>


* This source code was highlighted with Source Code Highlighter.

Создаем блок, в который помещаем наш файл-инпут, и еще один блок, в который помещаем замену для него, в виде текст-инпута и кнопки.



.input_file {
 position: relative;
 margin: 0 0 10px 0;
}
.input_file input[type=file] {
 opacity: 0;
 filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);
 position: relative;
 z-index: 2;
 cursor: pointer;
 height: 34px;
 width: 300px;
}


* This source code was highlighted with Source Code Highlighter.

Я думаю что со стилями для оберточного блока все понятно. Самое интересное в стилях для файл-инпута.


Во первых мы сделаем его полностью прозрачным, так как он нам не нужен, а спрятать его через visibility:hidden или display:none не получиться, потому что тогда мы потеряем возможность клика по этому полю. Так же тут же добавил фильтр для всеми любимого IE. Во вторых поднимем файл-инпут над другими элементами, что бы опять же иметь возможность кликнуть по нему. В третьих мы задаем высоту, так как нам нужно что бы поля которые выполняют роль заместителей перекрывались невидимым инпутом полностью (что бы пользователь не промазал случайно).



В стилях для «заменителя» стоит отметить абсолютное позиционирование, и то что данный блок располагается за файл-инпутом. В остальном же это просто стилизация (каждому по вкусам и по потребностям).


В общем то на данный момент мы имеем полностью рабочую версию, за исключением того что мы не видим имени файлов, которые мы выбрали. Вот тут к нам на помощь приходит JavaScript (я использую jQuery).



$('.input_file input[type=file]').change(function(){
 var t = $(this).val();
 if(t.indexOf('C:\\fakepath\\')+1)
  t = t.substr(12);
 var e = $(this).next().find('
.fake_file_input');
 e.val(t);
});


* This source code was highlighted with Source Code Highlighter.

Небольшая функция которая вызывается при изменении значения файл-инпута, в задачу которой входит вставить название файла в текст-инпут. Так как в большинстве браузеров, в целях обеспечения безопасности напрямую это сделать невозможно, точнее возможно, но подставляется C:\fakepath\, то соответственно этот fakepath обрезается, оставляя только само значение файла.



$('.clear_input').click(function(){
 var a = $(this).parent();
 var e = a.find('.fake_file_input');
 var t = a.find('input[type=file]');
 t.replaceWith('<input type="file" name="" >');
 e.val('');
});


* This source code was highlighted with Source Code Highlighter.

Вторая функция предназначена для очищения значения введенного в поле, так как напрямую мы этого сделать не можем. Поступает оно просто, создает новый файл-инпут, в замен старого (опять же, в целях безопасности мы не можем менять значение файл-инпута напрямую) и очищая значения текст-инпута. Ну и для того что бы эта функция сработала, добавим ссылку



<div class="input_file">
 ...
 <a href="#" class="clear_input">Очистить</a>
</div>


* This source code was highlighted with Source Code Highlighter.

Вот в общем то и все.
Итоговый результат
Теги:
Хабы:
Данная статья не подлежит комментированию, поскольку её автор ещё не является полноправным участником сообщества. Вы сможете связаться с автором только после того, как он получит приглашение от кого-либо из участников сообщества. До этого момента его username будет скрыт псевдонимом.