Создаем элегантное поле для ввода меток

Проект Delicious является достаточно популярным сервисом для хранения закладок. С его помощью легко сохранять важные ссылки. В данном проекте есть очень удобный инструмент - поле для ввода меток при сохранении ссылки. В нашем уроке мы сделаем интерфейс для подобного инструмента с использованием jQuery, который можно будет использовать в своих проектах.

demosourse

 

HTML

Поле ввода меток проекта Delicious является не просто элементом ввода меток. В действительности оно является элементом div box с тегами  ul и li. Мы сделаем почти такую же структуру в нашем уроке. Элемент ввода располагается в последнем элементе списка. Когда пользователь вводит новую метку, новый элемент списка будет создаваться до тега li, в котором располагается элемент ввода.

<div id="boxTags">
  <input type="hidden" id="hiddenTags"/>
  <ul id="ulTags" style="clear:both;">
      <li id="newTagInput"><input type="text" id="inputTag"/></li>
  </ul>
  <div style="clear:both;"></div>
</div>

 

jQuery

В проекте Delicious метки разделяются пробелом, а не запятой. Мы будем проверять ввод с клавиатуры и после ввода названия метки и нажатия пробела новая метка будет вставлена в массив arrayTags после проверки на повтор.

Удаление метки

Есть три способа, которыми можно удалить метки. Первый - нажать кнопку “x” на каждой метке. Второй - удалить метку слева от курсора ввода с помощью клавиши backspace.  Третий - удалить метки справа от курсора ввода с помощью клавиши delete. После удаления метки, она удаляется из массива.

Перемещение курсора ввода

Курсор ввода можно переместить по списку меток с помощью клавиш стрелок. Так можно удалить из списка нужную метку, которая может находиться в начале списка.

var arrayTags = [""];	// Массив, который содержит метки
var index = 0;
 
// Удаление элемента из массива
function removeByValue(arr, val) {
    for(var i=0; i<arr.length; i++) {
        if(arr[i] == val) {
            arr.splice(i, 1);
            break;
        }
    }
    index--;
}

// Удаление метки из списка 
function removeTag(el) {
    tag = $(el).prev().html();
    $("#tag-"+tag).remove();
    removeByValue(arrayTags, tag);
    $("#inputTag").focus();
}
 
$(document).ready(function() {
    var inputWidth = 16;
 
    // Вставка метки в список
    function insertTag(tag) {
        var liEl = '<li id="tag-'+tag+'" class="li_tags">'+
                    '<span href="javascript://" class="a_tag">'+tag+'</span>&nbsp;'+
                    '<a href="" onclick="removeTag(this); return false;"'+
                    ' class="del" id="del_'+tag+'">&times;</strong></a>'+
                    '</li>';
        return liEl;
    }
 
    $("#inputTag").focus().val("");
    $("#hiddenTags").val("");
 
   // Проверяем нажатие клавиши 
    $("#inputTag").keydown(function(event) {
        var textVal = jQuery.trim($(this).val()).toLowerCase();
        var keyCode = event.which;
 
        // Перемещаемся влево (нажата клавиша влево)
        if (keyCode == 37 && textVal == '') {
            $("#newTagInput").insertBefore($("#newTagInput").prev());
            $("#inputTag").focus();
        }
 
        // Перемещаемся вправо (нажата клавиша вправо)
        if (keyCode == 39 && textVal == '') {
            $("#newTagInput").insertAfter($("#newTagInput").next());
            $("#inputTag").focus();
        }
 
        // Удаляем предыдущую метку (нажата клавиша backspace)
        if (keyCode == 8 && textVal == '') {
            deletedTag = $("#newTagInput").prev().find(".a_tag").html();
            removeByValue(arrayTags, deletedTag);
            $("#newTagInput").prev().remove();
            $("#inputTag").focus();
        }
 
        // Удаляем следующую метку (нажата клавиша delete)
        if (keyCode == 46 && textVal == '') {
            deletedTag = $("#newTagInput").next().find(".a_tag").html();
            removeByValue(arrayTags, deletedTag);
            $("#newTagInput").next().remove();
            $("#inputTag").focus();
        }
 
        if ((47 < keyCode && keyCode < 106) || (keyCode == 32)) {
 
            if (keyCode != 32) {
                // Пользователь все еще вводит метку
                inputWidth = inputWidth + 7;
                $(this).attr("style", "width:"+inputWidth+"px");
                $("#newTagInput").attr("style", "width:"+inputWidth+"px");
            } else if (keyCode == 32 && (textVal != '')) {
                // Пользователь создает новую метку
                var isExist = jQuery.inArray(textVal, arrayTags);
 
                if (isExist == -1) {
                    // Вставляем новую метку (видимый элемент)
                    $(insertTag(textVal)).insertBefore("#newTagInput");
 
                    // Вставляем новую метку в массив JavaScript
                    arrayTags[index] = textVal;
                    index++;
                }
                inputWidth = 16;
                $(this).attr("style", "width:"+inputWidth+"px"); // Ширина элемента будет соответствовать длине ввода
                $("#newTagInput").attr("style", "width:23px")
                $(this).val("");
            } else {
                $(this).val("");
            }
        }
    });
}); 

CSS

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

* {
    font-family: Arial;
}
#boxTags {
    border: 1px solid #d3d3d3;
    width: 500px;
    padding: 10px 10px 0 10px;
    margin: 0 auto;
    margin-top: 10px;
}
#ulTags {
    padding: 0;
    margin: 0;
}
#ulTags .li_tags {
    border: 1px solid #e3e3e3;
    background: #e3e3e3;
    display: inline;
    float: left;
    list-style: none;
    margin: 0 10px 10px 0;
    padding: 0 3px 4px 5px;
}
#ulTags .li_tags:hover {
    border-color: #0099cc;
}
#newTagInput {
    display: inline;
    float: left;
    list-style: none;
    margin: 0 10px 10px 0;
    padding: 0 2px 2px 0;
    width: 23px;
}
.a_tag {
    color: #000000;
    text-decoration: none;
    font-size: 12px;
}
.a_tag:hover {
    color: #000000;
}
.del {
    font-size: 12px;
    text-decoration: none;
    font-weight: bold;
    padding: 1px 4px 1px 4px;
    background: #0099cc;
    color: #ffffff;
    position: relative;
}
.del:hover {
    background: #ff0000;
}
input[type="text"] {
    width: 23px;
    border: 1px solid #ffffff;
    font-size: 12px;
    outline: none;
}

Готово!

Данный урок подготовлен для вас командой сайта ruseller.com
Источник урока: superdit.com/2011/03/12/create-delicious-tag-field-using-jquery/
Перевел: Сергей Фастунов
Урок создан: 22 Марта 2011
Просмотров: 25341
Правила перепечатки


5 последних уроков рубрики "jQuery"

или авторизуйтесь, чтобы добавлять комментарии, оценивать уроки и сохранять их в личном кабинете
  • 22 Марта 2011 14:04
    alekseyshavrak
    Как сделать чтобы они сохранялись в базе????
    • 22 Марта 2011 14:15
      Kapi
      записать их в базу
    • 22 Марта 2011 15:21
      Fizik
      INSERT INTO base_name VALUES (some='some') А если меток много будет, то вначале загони их в масив, а потом используя foreach добавляй в базу....
  • 22 Марта 2011 15:26
    kasumi
    1. А как на счёт редактирования тега? 2. Это поле ввода, так? А в поле ввода при щелчке в любом его месте, оно должно ставить в текст курсор, а ставится лишь в нескольких пикселях от предыдущего тега или от начала, если тегов нет. Очень несовершенное поле для тегов. (ну, меток - не суть)
    • 27 Октября 2013 00:14
      hidest
      Можно легко исправить это, даже не трогая скрипт. Задаем диву-родителю фиксированную ширину и overflow: hidden;. Полю input задаем ширину равную ширине родителя с добавлением !important, чтобы повысить приоритет этого стиля.
  • 22 Марта 2011 19:19
    budzin
    Спс
  • 24 Марта 2011 11:44
    ghbrjkbcn
    Мне понравился этот урок планирую реализовать такое на стороне клиента только можно было бы построит SQL запрос что бы Записывал всё в базу и потом я уже сам выведу только я понять не могу несколько моментов например по удалению это класно реализовано а вот что касается добавления и после чего онавления страницы тут я думаю надо сделать запрос помогите у меня проект на грани выхода в сеть и хотелось бы такое то-же реализовать пишите сюда.
  • 26 Марта 2011 19:08
    Platinum_d
    круто!!! Вот это теги! Я себе тож такие на сайт хочу.
  • 3 Июля 2011 23:07
    apakc
    если сюда прикрутить ajax autocomplete будет хорошо, а так набить меток можно миллионом способов
  • 29 Мая 2014 11:36
    azimov
    Какая переменная будет содержать эти теги?
  • 3 Июля 2015 23:19
    Данила Мокрунов
    azimov, переменная arrayTags. В js скрипте смотри.
  • 4 Июля 2015 00:01
    Данила Мокрунов
    Я, например, чтобы передать значение поля меток делал так.. После
    arrayTags[index] = textVal;
    index++;
    
    добавить.
    $("#hiddenTags").val(arrayTags);
    
    И у вас поле будет заполнено метками через запятую.
  • 4 Июля 2015 00:05
    Данила Мокрунов
    Но не забывайте обновлять input value после удаления метки.
    • 26 Сентября 2016 04:32
      Radioactive
      написал бы, обновление input)
^ Наверх ^