4

I am trying to create a tagging system just like SO has. I have added the tags,now I want to remove them.

MyQuestion:

  • How do I remove the tags appended?
  • how do I make the cross button(a span) look identical to that in SO tagging system?

SO TAGGING

var tags = [];
$("#textBox").keypress(function (e) {
    if (e.which === 13) {
        $(".target").append("<a href='#' class='tag' >"  + this.value+'<span class="cross" onclick="remove_tag()">X</span>'+ "</a>");

        function remove_tag(){
        //what to do here?
        }
        tags.push(this.value);
        this.value = "";
    }
});
HIRA THAKUR
  • 15,044
  • 14
  • 47
  • 82
  • 2
    http://ivaynberg.github.io/select2/ – hjpotter92 Aug 21 '13 at 14:04
  • 1
    naa..I dont need any js for this...i think 25 lines of code would be perfect for such task..check the fiddle,adding is done..removal is remaining – HIRA THAKUR Aug 21 '13 at 14:05
  • in reply to question 2 - looking at the source code they use a sprite image for the X – rtpHarry Aug 21 '13 at 14:09
  • Since you are defining the remove_tag function inside of the keypress callback, it does not fall within the scope of when the onclick event is triggered. Try defining that function outside of where you have it. – Eric Levine Aug 21 '13 at 14:10

4 Answers4

2

Here's my JSFiddle: http://jsfiddle.net/Wky2Z/11/

Basically, listen on the .cross to be clicked, and then remove from array and delete element

//enter something in textbox and press enter....
var tags = [];
$("#textBox").keypress(function (e) {
    if (e.which === 13) {
        $(".target").append("<a href='#' class='tag' >"  + this.value+'<span class="cross">X</span>'+ "</a>");


        tags.push(this.value);
        this.value = "";
    }
});

$('body').on('click','.cross',function(){

    tags.splice($(this).parent('a').html(), 1);
    $(this).parent('a').remove();
});

As for the look of the cross, SO use a CSS Sprite, so you can do the same by making a png or gif or jpeg of the two states, off(grey) and hover(red) and switch the background-position to red with css eg: .cross:hover { background-position:0px -20px }

1

You can delete elements making use of remove(). Also, i would recommend you to make use of jQuery events instead of using inline events. (if you take a look at the source code of stackoverflow you will notice there are no inline javascript calls)

In this case you would need to add an event handler to the document object as you want to assign the events to elements which are not loaded in the DOM from the start.

$(document).on('click', '.tag span', function(){
   $(this).parent().remove();
});

Living example: http://jsfiddle.net/Wky2Z/7/

Update

I updated the example removing the element from the list of tags too: http://jsfiddle.net/Wky2Z/8/

Added a data-value for the tag links:

$(".target").append("<a href='#' class='tag' data-value='" + this.value + "' >"  + this.value+'<span class="cross">X</span>'+ "</a>");

And modified the click event:

$(document).on('click', '.tag span', function(){
   $(this).parent().remove();
   var removeItem = $(this).parent().data('value');

   tags = $.grep(tags, function(value) {
       return value != removeItem;
   });
});
Alvaro
  • 37,936
  • 23
  • 138
  • 304
1

For a full jQuery solution you can remove the inline remove_tag function and use jQuery on function. it works for dynamically created elements too.

Attach an event handler function for one or more events to the selected elements.

Here you can get the parent element of the deleted element and remove it from the DOM using remove.

To "sync" the array with the current situation you can use grep to delete the item from the array; note the removedItem variable used to get the text only of the parent excluding the children from the text.

Code:

//enter something in textbox and press enter....
var tags = [];
$(document).ready(function () {

    $('body').on('click', 'span.cross', function () {
        var removedItem = $(this).parent().contents(':not(span)').text();
        $(this).parent().remove();
        tags = $.grep(tags, function (value) {
            return value != removedItem;
        });
    });

    $("#textBox").keypress(function (e) {
        if (e.which === 13) {
            $(".target").append("<a href='#' class='tag' >" + this.value + '<span class="cross">X</span>' + "</a>");

            tags.push(this.value);
            this.value = "";
        }
    });
});

Demo: http://jsfiddle.net/IrvinDominin/pDFnG/

Irvin Dominin
  • 29,799
  • 9
  • 75
  • 107
  • Basically is the same I suggested but you are using `contents` instead of using a `data` attribute. – Alvaro Aug 21 '13 at 15:19
0

Here's the updated link: http://jsfiddle.net/Wky2Z/6/

Move remove_tag outside of keypress event handle and pass a this pointer to it for quick solution:

//enter something in textbox and press enter....
var tags = [];

function remove_tag(x) {
    $(x).parent('a').remove();
}
$(function () {
    $("#textBox").keypress(function (e) {
        if (e.which === 13) {
            $(".target").append("<a href='#' class='tag' >" + this.value + '<span class="cross" onclick="remove_tag(this)">X</span>' + "</a>");

            tags.push(this.value);
            this.value = "";
        }
    });
});
hjpotter92
  • 71,576
  • 32
  • 131
  • 164