Question

I am using tag-it so users can create tags for their posts.

It currently lets them type anything but I have a list of banned words in the form of JSON. How could i implement this into the tagit plugin so when a users typed word matched one of the banned words it throws up an error.

How can i check to see if ui.tag exists in swearWords.json?

Here is my current code:

$('#methodTags_text').tagit({
    availableTags: sampleTags,
    tagLimit:3,
    maximumInputLength: 10,
    fieldName: "item[tags][]",
    beforeTagAdded: function(event, ui) {
       // if ui.tag exists in swearWords.json
       // Then output error
       $('#banned_error').html('You can use this word.')
    }
});          

swearWords.json

["word1","word2","word3","word4","word5"]

using François Wahl answer I managed to get a working solution...

$('#methodTags_text').tagit({
    availableTags: sampleTags,
    tagLimit:3,
    maximumInputLength: 10,
    removeConfirmation: true,
    fieldName: "item[tags][]",
    beforeTagAdded: function(event, ui) {
           if (!ui.duringInitialization) {
                var word = eventTags_text.tagit('tagLabel', ui.tag);
                if($.inArray(word , words) > -1){
                    $('#banned_error').html('You cant use this word.');
                    $("#methodTags_url").tagit("removeTagByLabel", word);
                } else {$('#banned_error').html('');}   
           }
    }
});

ALSO to get external json in var

var words = (function () {
    var words = null;
    $.ajax({
        'async': false,
        'global': false,
        'url': "swearWords.json",
        'dataType': "json",
        'success': function (data) {
            words = data;
        }
    });
    return words;
})(); 
Was it helpful?

Solution

Given the words are in an array you can use jQuery inArray() do this:

var words = ["word1","word2","word3","word4","word5"]

beforeTagAdded: function(event, ui) {
    // if ui.tag exists in swearWords.json
    // Then output error
    var word = "word4"; // I'm assuming you get the word from some control though.
    if($.inArray(word , words) > -1){
       $('#banned_error').html('You can use this word.')
    }
}

DEMO - Checking entered word is in array


Code from DEMO:

<input id="word" type="text"></input>
<button id="checkWord" type="button">Check Word</button>
var words = ["word1","word2","word3","word4","word5"]

$("#checkWord").on("click", function(){
    var word = $("#word").val();

    if($.inArray(word, words) > -1){
       alert("You cannot use this word");
    }
});

OTHER TIPS

try this

swearWords.each(function(i,val){
   if(ui.tag == val){
      $('#banned_error').html("You can't use this word.")
  }else{
     //do your stuff
  }
}

I think, you can use something like this:

beforeTagAdded: function(event, ui) {
  if (!this._swearWords) {
    // send synchonous XHR to load banned words.
    var xhr = null;
    if (window.XMLHttpRequest) {
        xhr = new window.XMLHttpRequest();
    }
    else if (window.ActiveXObject) {
        xhr = new window.ActiveXObject('Microsoft.XMLHTTP');
    }

    if (!xhr) {
        return;
    }

    xhr.open('GET', 'swearWords.json', false);
    xhr.send(null);
    this._swearWords = JSON.parse(xhr.responseText);
  }

  if (tag in this._swearWords) { // I don't know how to get tag...
    // if ui.tag exists in swearWords.json
    // Then output error
    $('#banned_error').html('You can use this word.')
  }
}

It is better and faster to use Object, not Array for definition of banned words.

{'word1': 1, 'word2': 1, 'word3':1}

Then you can use in operator for detection. If you use Array you (or jQuery) have go through array in loop to check existence of the item. Remember that Array.indexOf is not implemented e.g. in IE8.

I am appending solution for cases where you are attaching tagit to class vs. id (as in repeaters i.e search results). When you are attaching to class you have to access tagit within context in order to be able to remove your tag if it fails validation, e.g.

    $(".recTags").tagit({
        afterTagAdded: function (event, ui) {
            if (!ui.duringInitialization) {
                // some validation
                if (ui.tagLabel.length <= 50) {
                    $('#tag_error').html('');
                    // do something
                } else {
                    $('#tag_error').html('Tag "'+ ui.tagLabel +'" is too long [50 character limit].');
                    ui.tag.parent().tagit("removeTagByLabel", ui.tagLabel);
                }
            }
        }
    });

Important piece for me was figuring out how to invoke removeTagByLabel, from which element:

ui.tag.parent().tagit("removeTagByLabel", ui.tagLabel);

I could not use beforeTagAdded event, because ui.tag.parent() does not exist at this point, since tag is not added to the DOM yet, hence check is within afterTagAdded. I am sure there are other ways to do this, but this works for me.

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