How to modify jquery tag-it plugin: limit number of tags and only allow available tags
Asked Answered
S

6

13

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.

Shick answered 21/9, 2011 at 13:0 Comment(0)
S
14

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,

            })

        });
Shick answered 21/9, 2011 at 13:0 Comment(3)
Somehow this solutions still allows my first tag not to be contained in the available tags.Designedly
Unfortunately this only works if you use the availableTags-option. If you override autocomplete.source it does not work.Furey
@Designedly It eems to work if you move the check to createTag function instead of _isNewPatrolman
T
7

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;
});
Truthvalue answered 25/2, 2013 at 17:12 Comment(0)
M
3

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!

Muchness answered 12/3, 2013 at 22:36 Comment(4)
If you want to get Jack's attention, leave a comment on his answer starting with @Jack.Corps
Thanks Aaron, unfortunately my rank is so low that I can't comment on anyone elses answers :(. However, I actually think I have a better solution than what I posted above that solves my problem (and answers the OPs question). I will post that when I'm sure it's working. I'd still love to know if Jack has more specifics though...Muchness
it'll be a bit awkward for me to put the code here, I'll add to my answerTruthvalue
This will work too but I prefer editing a few lines of the plugin then adding a global variable manually for each taggit instance.Shick
T
2

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.

Trackless answered 14/12, 2015 at 9:52 Comment(1)
tagLimit setting now prevents additional tags.Friedrick
F
1

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, -
Fat answered 19/6, 2016 at 19:42 Comment(0)
P
0

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,

        })

    });
Pastor answered 21/1, 2014 at 7:28 Comment(1)
I could only get this working by changing the array source to this.options.availableTagsPatrolman

© 2022 - 2024 — McMap. All rights reserved.