Create Delicious Tag Field Using JQuery

March 12th, 2011 by aditia rahman / 3 Comments  

     

Delicious is one of the popular social bookmarking, it make us easier to save our important links, and I amaze cause how easy to use tagging field when we want to save new link, right now I want to create something like that, well actually not really similar, I’m not implemented all the features.

jquery delicious tag

Delicious tagging field, not a pure input tag element, it is a div box that contain list box, so when you search this it use the TextListBox keyword, user will see it as input field, but actually it is a div box with ul and li tag.

View Demo | Download Source

The HTML

This is the html element, for default position, the input type is located on the last list, when user input a tag the new list will be created before the list that contain input tag.

<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>
The JQuery

When I create this post unlike any other tagging field system which separated tag by comma, delicious separated each tag word by white space. So we need to check every keyboard input, after write a tag and white space pressed new tag will be created it will stored into array, for checking purpose in case user insert the same tag.

Deleting a tag

There are three method for deleting a tag, first by clicking the “x” mark on each tag, second by pressing the backspace key it will delete a tag on the left and last by pressing the delete key it will delete a tag on the right. After deleting a tag, the deleted tag will be removed from array.

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;

        // move left (left arrow pressed)
        if (keyCode == 37 && textVal == '') {
            $("#newTagInput").insertBefore($("#newTagInput").prev());
            $("#inputTag").focus();
        }

        // move right (right arrow pressed)
        if (keyCode == 39 && textVal == '') {
            $("#newTagInput").insertAfter($("#newTagInput").next());
            $("#inputTag").focus();
        }

        // delete prev tag (backspace pressed)
        if (keyCode == 8 && textVal == '') {
            deletedTag = $("#newTagInput").prev().find(".a_tag").html();
            removeByValue(arrayTags, deletedTag);
            $("#newTagInput").prev().remove();
            $("#inputTag").focus();
        }

        // delete next tag (delete pressed)
        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) {
                // user still typing a tag
                inputWidth = inputWidth + 7;
                $(this).attr("style", "width:"+inputWidth+"px");
                $("#newTagInput").attr("style", "width:"+inputWidth+"px");
            } else if (keyCode == 32 && (textVal != '')) {
                // user apply new tag
                var isExist = jQuery.inArray(textVal, arrayTags);

                if (isExist == -1) {
                    // insert new tag (visible to user)
                    $(insertTag(textVal)).insertBefore("#newTagInput");

                    // insert new tag to js array
                    arrayTags[index] = textVal;
                    index++;
                }
                inputWidth = 16;
                $(this).attr("style", "width:"+inputWidth+"px");
                $("#newTagInput").attr("style", "width:23px")
                $(this).val("");
            } else {
                $(this).val("");
            }
        }
    });
});

Actually there are another features that I’m not implement in this example, they are updating an existing tag by clicking on the tag name or by using up arrow key, and autocomplete feature.

The 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;
}

View Demo | Download Source

jquery delicious tag capture

Other Resources

http://incite.github.com/jquery-yummi/

http://pines.sourceforge.net/ptags/

http://devthought.com/projects/mootools/textboxlist/

http://roberto.open-lab.com/2010/02/10/a-delicious-javascript-tagging-input-field/

        submit to reddit Delicious

3 Comments Leave a Comment Subscribe RSS

  • zu says:

    Hey thanks for this – works very much like the delicious one. Just missing the auto-complete and tag editing as you’ve said.

  • Behzad says:

    Thanks for this, but it seems it has some problems with @ character, try to make some tags which has @ in them, then delete icon will not work on them, also you can make as much as repeated tags which have @ in them, like 1@1 1@1 1@1

    Thanks anyway

  • Vijay Rana says:

    This is a very useful front end code for tagging system. Is there a mysql backend code to store these tags properly in different tables . Preferably in the “Toxi” schema format as presented in this link :

    http://www.pui.ch/phred/archives/2005/04/tags-database-schemas.html

    Thanks for this wonderful code

Leave a Comment