0

I'm trying to create suggested tags, first i take input string while the user is typing, then check for words from a long list of words in an array, if word exists in the first array, check other arrays categories that this word falls into, then append some tag in an input.

First Problem: So far i can only check if a string contains a word, i don't know how to search an array so i can find words in a given string that match words in an array.

Second Probelm

After first word if found on keyup, any other keyup runs the script whereas i want it to wait for another second match.

CODE HERE

$(document).on('keyup','.Post_TextArea',function(){
    post_val = $(this).val();
    if ($(this).val().length > 5){
        var string_g = 'tempo';
        var web_array = ['html', 'css', 'JavaScript'];
        var music_array = ['tempo', 'blues', 'rhythm'];
                if (post_val.toLowerCase().indexOf(string_g) >= 0){
                    if ($.inArray(string_g, web_array) !== -1){
                        $('.tags_holder').append('<span class="Tag_Style">Web</span>');
                    } else if ($.inArray(string_g, music_array) !== -1){
                        $('.tags_holder').append('<span class="Tag_Style">Music</span>');
                    } 
                    }
        }
    })
1
  • 1
    look at using filter() for first issue and match the strings in callback Commented Jul 4, 2014 at 16:55

2 Answers 2

2

There are several things that you can do to solve your problem:

  • Create re-usable components
  • Ensure each function does a single task

Here's my take on the problem.

Define your configuration

We can create a taxonomy for categorizing your words. In this case, we can group the words in an array and classify them by the key.

var taxonomy = {
    'web': ['html', 'css', 'javascript'],
    'music': ['tempo', 'blues', 'rhythm']
};

Defined your function

Here we create two functions. What we want to achieve are:

  • A predicate that checks for the word contained in the taxonomy
  • Function that returns the classification of the words

Below is a predicate to check if a word is contained within a wordList. We can use this with our check on whether or not a word is a 'tagged' word.

function contains(wordList) {
    return function(word) {
        return (wordList.indexOf(word) > -1);
    };
};

Below is a function that returns the list of tags of words from the input. The key to this is using the some() function, which should be more light weight than the filter() function.

function getTags(input, taxonomy) {
    var words = input.match(/\w+/g);

    return Object.keys(taxonomy)
          .reduce(function(tags, classification) {
              var keywords = taxonomy[classification];
              if (words.some(contains(keywords)))
                  tags.push(classification);
              return tags;
          }, []);
};

Connect to jQuery

Now that we have the core code, we can connect this to jQuery.

$(function() {
    $('#input').on('keyup', function() {
        $('#tags').empty();
        var tags = getTags($(this).val(), taxonomy);
        tags.forEach(function(tag) {
            $('#tags').append($('<li>').text(tag));
        });
    });
});

Working Demo

See this jsFiddle for a live demo. Note: this should work only on IE9+, as the some(), keys(), and forEach() functions are not support in IE < 9.

Sign up to request clarification or add additional context in comments.

Comments

0

I suggest you don't use a set of arrays, use a "map" instead - it's slightly less memory efficient but it's trivial to implement and very computationally efficient:

var tags = {
    'html': 'web', 'css': 'web', 'javascript': 'web',
    'tempo': 'music', 'blues': 'music', 'rhythm': 'music'
};

function suggestTags(input) {
    var result = { };
    var words = input.toLowerCase().split(/\s+/);
    words.forEach(function(word) {
        if (word in tags) {
            result[tags[word]]++;
        }
    }
    return Object.keys(result);
};

IMHO, an important point here is that the above is independent of any DOM manipulation. You'll get cleaner code by separating your word searching from your DOM logic.

NB: some of the above uses ES5 functions - use a "shim" to support them in older browsers if required.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.