1
\$\begingroup\$

I recently asked a question here, where I was trying to implement some extra functionality into the tag-it plugin, where the user should be able to add tags to the input by clicking on them in a "selection area". They should also be able to remove tags (send them back to the selection area) by clicking on the tag again.

Demo

enter image description here

Shortly thereafter I answered that question with an updated version of the code, so I thought I would create a new question in the hopes that I could get some feedback on my new approach.

Usage

in document.Ready

We pass an array to populate the selection area, specify whether or not the user should be allowed to add their own tags, and pass in the elements we will be using for the tag areas. I also added a colourTags option so that the extension knows to try and colour the tag backgrounds (this is of course not perfect at the moment, as it just uses the colour name. I need to add a list to convert these names to hex codes).

// Build Colour selector
initialiseTagSelector({
    tagArray: availableColourTags,
    readOnly: true,
    tagInput: $('#colourTagInput'),
    tagField: $('#colourTagField'),
    tagSelector: $('#colourTagSelection'),
    colourTags: true
});

HTML / CSHTML

<div class="form-group">
    @Html.LabelFor(model => model.ColourTags, htmlAttributes: new { @class = "control-label col-md-2" })
    <div class="col-md-5">
        @Html.HiddenFor(model => model.ColourTags, new { @class = "form-control", @name = "tags", @id = "colourTagField" })
        <ul id="colourTagInput" class="form-control"></ul>
        @Html.ValidationMessageFor(model => model.ColourTags, "", new { @class = "text-danger" })
    </div>

    <div class="col-md-5">
        <ul id="colourTagSelection"></ul>
    </div>
</div>

TagSelector.js

tagAdded

This method is called whenever a tag is added to either the selection area or the input area. It basically just finds the required tag with selectTag and then calls styleTag to add some styling (currently just sets the background colour for colour tags).

var tagAdded = function (options, tagArea, tagName) {
    var tagLi = selectTag(tagArea, tagName);
    styleTag(options, tagLi, tagName);
}

selectTag

returns the element for the given tag name in the given area. It would be great if this was not needed, but can't find a way of finding the tag using tag-it.

function selectTag(tagArea, tagName) {
    return tagArea.find('.tagit-label:contains("' + tagName + '")').parent();
}

styleTag

Styles the given tag (tagLi) based on the options

function styleTag(options, tagLi, tagName) {
    if (options.colourTags) { tagLi.css({ 'background': tagName }).addClass('colour-tag'); }
}

initialiseTagSelector

initialises our inputs. One tag area for selection, and one for the inputting through the form.

Once initialised, we add our tag selection to the selection area, ignoring any which already exist in the input area (this is to handle page refreshes).

function initialiseTagSelector(options) {
    options.tagInput.tagit({
        readOnly: options.readOnly,
        onlyAvailableTags: options.readOnly,
        availableTags: options.tagArray,
        singleField: true,
        singleFieldNode: options.tagField,
        afterTagAdded: function (evt, ui) {
            if (!ui.duringInitialization) {
                tagAdded(options, options.tagInput, options.tagInput.tagit('tagLabel', ui.tag));
            }
        },
        onTagClicked: function (evt, ui) {
            options.tagInput.tagit('removeTag', ui.tag);
        },
        afterTagRemoved: function (evt, ui) {
            options.tagSelector.tagit('createTag', options.tagSelector.tagit('tagLabel', ui.tag));
        }
    });

    options.tagSelector.tagit({
        readOnly: true,
        onlyAvailableTags: true,
        availableTags: options.tagArray,
        singleField: true,
        afterTagAdded: function (evt, ui) {
            if (!ui.duringInitialization) {
                tagAdded(options, options.tagSelector, options.tagSelector.tagit('tagLabel', ui.tag));
            }
        },
        onTagClicked: function (evt, ui) {
            alert('click');
            options.tagSelector.tagit('removeTag', ui.tag);
        },
        afterTagRemoved: function (evt, ui) {
            options.tagInput.tagit('createTag', options.tagSelector.tagit('tagLabel', ui.tag));
        }
    });

    for (i = 0; i < options.tagArray.length; i++) {
        var tagName = options.tagArray[i];
        var tagLi = selectTag(options.tagInput, tagName);

        if (tagLi.length) {
            styleTag(options, tagLi, tagName);
        } else {
            options.tagSelector.tagit('createTag', tagName);
        }
    }
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.