Emulate SO Tag Editor

I am trying to embed the Tag Editor field in my application, just like SO does. Right now I got this:

EDIT: I encoded this into a jQuery plugin at: https://github.com/fernandotenorio/tagme.git

Fiddle

http://jsfiddle.net/FernandoTen/PnYuF/

HTML

<div style="margin-left: auto; margin-right: auto; width: 400px;"> <span style='color: #333; font-size: small'> Tags [az AZ 0-9 # + . -] </span> <div id='tags_container'> <span id='tags_queue'></span> <input type='text' id='tf' /> </div> </div> 

Js

 $(document).ready(function () { var rexp = /[^a-zA-Z0-9#+\.\-]/ var left = 37; var right = 39; var del = 8; var space = 32; var comma = 188; var minlen = 3; var maxlen = 15; var current_tag = null $('#tf').focus().attr('maxlength', maxlen) $('#tags_container').click(function () { $('#tf').focus() }) $('#tf').keydown(function (e) { var code = e.keyCode ? e.keyCode : e.which ? e.which : e.charCode; var txt = $(this).val().trim() // handle navigation between tags if ((code === left || code === right) && txt.length === 0) { if (!current_tag) { if (code === left) current_tag = $('#tags_queue span').last() else current_tag = $('#tags_queue span').first() if (current_tag.length > 0) current_tag.css('background-color', '#9FC2D6') } else //current tag exists { if (code === left) current_tag = current_tag.css('background-color', '#B8D0DE').prev() else current_tag = current_tag.css('background-color', '#B8D0DE').next() if (current_tag.length > 0) current_tag.css('background-color', '#9FC2D6') // hit last/first, clean current_tag else { current_tag.css('background-color', '#B8D0DE') current_tag = null } } } }); $('#tf').keypress(function (e) { var token = String.fromCharCode(e.which) var code = e.keyCode ? e.keyCode : e.which ? e.which : e.charCode; if (token.match(rexp) && (code !== del) && (code !== left) && (code !== right)) return false; }); $('#tf').keyup(function (e) { var code = e.keyCode ? e.keyCode : e.which ? e.which : e.charCode; var txt = $(this).val().trim() if (code === del && txt.length === 0 && current_tag) { current_tag.remove() current_tag = null return } // clean current_tag, user is typing if (current_tag && (code !== left) && (code != right)) { current_tag.css('background-color', '#B8D0DE') current_tag = null } if (txt.length > maxlen) txt = txt.substring(0, maxlen) if (txt.match(rexp)) {- $(this).val("") return } else if (code === space || code === comma) { if (txt.length < minlen) return; var tag = $('<span></span>', { 'class': 'tag' }).html(txt).append($('<a></a>', { 'class': 'close_tag', html: '&times', click: function () { $(this).parent().fadeOut(function(){ $(this).remove() current_tag.css('background-color', '#B8D0DE') current_tag = null }) } })) $('#tags_queue').append(tag) $(this).val("") } }); 

})

CSS

 div#tags_container { border: 1px solid #ccc; padding-bottom: 5px; border-radius: 5px; background-color: beige; overflow: hidden; } input#tf { border: 1px solid orange !important; outline: none !important; background-color: transparent !important; height: 30px; margin-top: 2px; padding-left: 5px; } a.close_tag { margin-left: 5px; color: #fff; } a.close_tag:hover { cursor: pointer; } span.tag { background-color: #B8D0DE; color: #111; margin-left: 5px; margin-top: 5px; padding: 5px; float: left; border-radius: 5px; } span.tag:hover { background-color: #9FC2D6; } span#tags_queue { margin-right: 5px; vertical-align: middle; } 

The problem is, how can I handle hidden content with the arrow keys, how does SO do this? It seems like I should handle the cursor position inside the text fields and follow the events with the left arrows and the right arrow ... and there also click on the completed tags.

I can think of the following solutions (anti-SO):

  • remove white-space: nowrap from the white-space: nowrap div and let the div β€œgrow” as the user adds more tags.

  • Add overflow: scroll to div tags_container (very ugly!)

So, I appreciate any new ideas on how to approximate the behavior of SO tags. Thanks!

+8
javascript jquery dom html css
source share
1 answer

Reinvent the wheel is bad practice: take a look at the excellent jQuery Tag-it code, it implements the material that you work on.

+3
source share

All Articles