Twitter Bootstrap Input File — Стилизация файл-инпутов

twitter-bootstrap

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

Я надеюсь на, то что вы знакомы с Twitter Bootstrap и знаете, что это за зверь и с чем его едят, поэтому приступлю сразу к делу.

Создание HTML разметки

На данном шаге все просто, для этого давайте создадим файл index.html с следующим содержимым:

<!DOCTYPE html>
<html>
    <head>
        <title>Twitter Bootstrap Input File</title>
        <link href="/bootstrap/css/bootstrap.min.css" rel="stylesheet" type="text/css" />
        <link href="/css/styles.css" rel="stylesheet" type="text/css">
    </head>

    <body>
        <div class="container">
            <div class="row-fluid">
                <div class="control-group">
                    <label class="control-label">Picture:</label>
                    <div class="controls clearfix">
                        <span class="btn btn-success btn-file">
                            <i class="icon-plus"></i> <span>Choose picture...</span>
                            <input type="file" name="image" id="image" />
                        </span>
                    </div>
                </div>
            </div>
        </div>

        <script type="text/javascript" src="http://yandex.st/jquery/1.9.0/jquery.min.js"></script>
        <script type="text/javascript" src="/bootstrap/js/bootstrap.min.js"></script>
    </body>
</html>

Я хотел бы в вкратце пояснить, что и зачем я тут делаю. Особого внимание в данном коде заслуживает следующий код:

<span class="btn btn-success btn-file">
    <i class="icon-plus"> </i><span>Choose picture...</span>
    <input type="file" name="image" id="image" />
</span>

Специально для тех кто мало знаком с Twitter Bootstrap хотел бы выделить этот код, т.к. он является не стандартным и для Twitter Bootstrap и выступает в качестве обвязки над файл-инпутом с помощью которой мы далее будем производить его последующую стилизацию при помощи css.

Создание файла стилей

Давайте не будем тянуть кота за хвост и сразу посмотрим на код:

/** Layout **/
body{ padding-top: 50px; }

/** Styling input[type=file] **/
.btn-file { position: relative; overflow: hidden; margin-right: 4px; }
.btn-file input { position: absolute; top: 0; right: 0; margin: 0; opacity: 0; filter: alpha(opacity=0);
    transform: translate(-300px, 0) scale(4); font-size: 23px; direction: ltr; cursor: pointer; }
/* Fix for IE 7: */
* + html .btn-file { padding: 2px 15px; margin: 1px 0 0 0; }

Как вы видите кода не так уж и много получилось, а так же то, что тут все достаточно просто и понятно. Не знаю как вы, а я бы на вашем месте уже нравное сгорал бы от любопытства увидеть то, что у нас получилось,  поэтому давайте уже наверное просто взглянем на результат.

Ну собственно говоря цель достигнута, файл-инпут выглядит в стиле Twitter Bootstrap, но только не знаю как вам, а мне кажется, что данный вариант имеет один весьма серьезный недостаток! Мы не видим выбрали мы файл или нет, а так же то, что мы выбрали! К моему большому сожалению с помощью css мы исправить этот не достаток не сможем, но с помощью javascript это вполне возможно!

Улучшение с помощью javascript

Давайте вставим после подключения скриптов Twitter Bootstrap в файле HTML разметки следующий код:

<script type="text/javascript">
    (function ($){
        $(function (){
            $('.btn-file').each(function (){
                var self = this;
                $('input[type=file]', this).change(function (){
                    // remove existing file info
                    $(self).next().remove();
                    // get value
                    var value = $(this).val();
                    // get file name
                    var fileName = value.substring(value.lastIndexOf('/')+1);
                    // get file extension
                    var fileExt = fileName.split('.').pop().toLowerCase();
                    // append file info
                    $('<span><i class="icon-file icon-' + fileExt + '"></i> ' + fileName + '</span>').insertAfter(self);
                });
            });
        });
    })(jQuery);
</script>

Код содержит подробные комментарии поэтому объяснять, что тут и как не имеет смыла, давайте просто еще раз взглянем на результат.

Ну вот собственно и все, теперь стилизованный файл-инпут в полной мере своим функционалом соответствует оригинальному и формлен в стиле Twitter Bootstrap.

Демо | Скачать исходные коды урока

13 комментариев

  1. Xrystalll:

    Как убрать путь чтобы осталось только название?

    • Radik:

      Судя по всему вы используете Windows, поэтому в качестве разделителя путей у вас используется \ вместо /, поэтому нужно изменить способ получения имени файла в данный момент в статье используется:
      var fileName = value.substring(value.lastIndexOf(‘/’)+1);

      Как вариант можно сделать так:

      var fileName = value.substring(value.lastIndexOf(‘\\’)+1);

      Для windows, ну и поставить небольшой if для того, что бы определить как нужно разбивать строку, к примеру так:

      var fileName = value.substring(value.lastIndexOf(value.indexOf(‘/’) == -1 ? ‘\\’ : ‘/’) + 1);

      Как то так.

  2. Владислав:

    К сожалению, не работает в IE (11).

    • Radik:

      Возможно, ведь когда тестировался и выкладывался данный метод IE 11 еще не было.

  3. Мария:

    Огромное спасибо!

  4. Savva:

    Искал решение для стилизации у Вас нашел! Спасибо!

    Вы не подскажете как реализовать программную часть? Те как оформить скрипт для отправки данных и файла на почту?

    • Radik:

      Здравствуйте, готового скрипта у меня нет, но могу подсказать смотрите в сторону использования библиотеки SwiftMailer с ее помощью накидать скрипт отправки файла на почту пяти минутное дело.

  5. GarrySeldon:

    Лучше использовать регулярные выражения, а то в некоторых браузерах, например в IE9 добавляет путь «C:fakepath».
    var reWin = /.*\(.*)/;
    var reUnix = /.*/(.*)/;
    var fileTitle = file.replace(reWin, «$1»);
    fileTitle = fileTitle.replace(reUnix, «$1»);
    rod.html(fileTitle);

  6. CyberKatze:

    var value = $(this).val();
    возвращает только имя файла без его пути!

    как получить путь?

    вопрос касательно Android, проверено на MAC, результат тот же. Возвращается только имя файла вместо полного пути….

    • radik:

      К сожадению я не знаю ответа и не имею ни MAC ни девайса с Android, что бы проверить. Думаю стоит воспользоваться Google, ответ на ваш вопрос скорее всего уже есть на stackoverflow.com или подобных ему ресурсах.

  7. Dmityr:

    спасибо, пригодилось)

  8. Keks:

    Большое спасибо, очень полезная статья!

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *