Question

how to modify the tag-it ui plugin https://github.com/aehlke/tag-it (version v2.0) so it only allows selection of x numbers of tags and how to allow only tags that are in the "availableTags-option"?

this question (or the first part of it) is already asked and aswerd in the past but for previous version of the plug-in.

Was it helpful?

Solution

first add custom options (maxTags and onlyAvailableTags) to the plugin file like so...

options: {
            itemName          : 'item',
            fieldName         : 'tags',
            availableTags     : [],
            tagSource         : null,
            removeConfirmation: false,
            caseSensitive     : true,
            maxTags           : 9999,//maximum tags allowed default almost unlimited
            onlyAvailableTags : false,//boolean, allows tags that are in availableTags or not 
            allowSpaces: false,
            animate: true,
            singleField: false,
            singleFieldDelimiter: ',',
            singleFieldNode: null,
            tabIndex: null,
            onTagAdded  : null,
            onTagRemoved: null,
            onTagClicked: null
        }

next replace the _isNew function with this one...

_isNew: function(value) {
            var that = this;
            var isNew = true;
            var count = 0;
            this.tagList.children('.tagit-choice').each(function(i) {
                count++;

                if (that._formatStr(value) == that._formatStr(that.tagLabel(this))|| count >= that.options.maxTags) {
                    isNew = false;
                    return false;
                }
                if (that.options.onlyAvailableTags && $.inArray(that._formatStr(value),that.options.availableTags)==-1) {
                    isNew = false;
                    return false;
                }

            });
            return isNew;
        }

Now you can use the options when you initialize tagit. only the sampleTags are allowed with a maximum of 3 tags

$(function(){
            var sampleTags = ['php', 'coldfusion', 'javascript', 'asp', 'ruby', 'python'];

            //-------------------------------
            // Tag events
            //-------------------------------
            var eventTags = $('#s_tags');
            eventTags.tagit({
                availableTags: sampleTags,
                caseSensitive: false,
                onlyAvailableTags: true,
                maxTags:3,

            })

        });

OTHER TIPS

You can just provide this parameter to .tagit:

beforeTagAdded: function(event, ui) {
  if($.inArray(ui.tagLabel, availableTags)==-1) return false;
}

where availableTags is your autocomplete array.


Regarding @snuggles query below, I believe (my limited familiarity with the json protocols notwithstanding) you could probably do something like this:

//define autocomplete source
var returnedUsers, jsonUrl = "http://[your server]/user_lookup";
$.getJSON(jsonUrl,function(json){
        returnedUsers = json; // or whatever handler you need to use               
}); 

// instantiate tagit

$("#ccList").tagit({
     availableTags: returnedUsers,
     beforeTagAdded: function(event, ui) { 
     // only allow existing values
     if($.inArray(ui.tagLabel, returnedUsers)==-1) return false;
     // limit length
     if ($(".tagit-choice").length >= 5) return false;
});

Update 2013-03-13:

First, re-reading the OP, I'm now not clear on if I'm really answering the question, as they specifically asked how to modify the tag-it plugin in order to accomplish the two tweaks. If the OP really wants to modify the plug-in, that's fine, but as I said before, it seems lame that you would have to--and you don't!

So here's how to accomplish both things without modifying the plugin :)

first, you do have to have some sort of global array to put stuff into, if there's a better way to do that, lmk, but otherwise:

var returnedUsers = [];

Then:

    $("#ccList").tagit({
    autocomplete: {
        source: function( request, response ) {
            $.ajax({
                url: "http://[your server]/user_lookup",
                dataType: "json",
                data: {
                    term: request.term
                },
                success: function( data ) {
                    returnedUsers = data;
                    response( $.map( data, function( item ) {
                        return {
                            label: item,
                            value: item
                        }
                    }));
                },
                error: function(xhr, status, error) {
                    returnedUsers = [];
                }
            });
        }
    },
    beforeTagAdded: function(event, ui) {
        if ($.inArray(ui.tagLabel, returnedUsers)==-1)
            return false;
        if ($(".tagit-choice").length >= 5)
            return false;
    }
});

So basically you have to point the autocomplete.source at a function in which you handle all the ajax stuff and build your own list. Note that doing this allows you some flexbility in what you return from your cgi back end (ie, it doesn't have to be an array of strings, it could be an array of hashes which you parse and build into a custom list). Also note that this would not be needed if only I could find a way to access the list of returned values from the more basic autocomplete function in the 'beforeTagAdded' event--something Jack implied was possible but did not elaborate on.

Once you've build the array of things to display you return it using the response() function. At the same time now you have a copy of that list in 'returnedUsers', which you can use in the 'beforeTagAdded' function. Also, it's simple to limit the number of tags you allow in the box by just counting how many are already in there and returning false if it's >= to that number. Not sure if that's the best way to get the count, but it definitely works.

I know this is old, and I'm sure any expert would find a million ways to do it better than me, but I haven't found anyone that's laid out how to work around this issue better than what I've outlined without actually changing the plugin, which I do not prefer to do. HTH!

jQuery UI Tag-it! @version v2.0 (06/2011).

Go to file tag-it.js

And find the function createTag

And following code in the beginning.

    if (that.options.maxTags) {
      if ($('.tagit li').length > that.options.maxTags) {
        alert('Maxmium ' + that.options.maxTags + ' tags are allowed')
        return false;
       }
    }

And in the page

$("#myTags").tagit({
  maxTags: 8
});

This will limit the tags to 8 tags. You can change the number to any to limit that much number of tags.

Find tagLimit in tag-it.js and set the number which you want to limit with. I limited with 5. Default value is null.

removeConfirmation: false, // Require confirmation to remove tags.
tagLimit : 5, -

I improved @kaspers answer with new updated library. make some changes in library 1. add new option in options onlyAvailableTags : false,

  1. put check in createTag method of

     if (this.options.onlyAvailableTags &&$.inArray(this._formatStr(value),this.options.autocomplete.source)==-1)
    {
     return false;
    }
    

then call tagit like this. Now tag it library supports tagsLimit. So we dont need to customize it.

       $(function(){
        var sampleTags = ['php', 'coldfusion', 'javascript', 'asp', 'ruby', 'python'];

        //-------------------------------
        // Tag events
        //-------------------------------
        var eventTags = $('#s_tags');
        eventTags.tagit({
            availableTags: sampleTags,
            caseSensitive: false,
            onlyAvailableTags: true,
            tagLimit: 3,

        })

    });
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top