0 votes
by (730 points)

I want to add a little search bar in my game where a user can input some keywords and text will appear based on it. For example, if the user inputted something related to their objective in the game, some text will be displayed that can help them win (basically some kind of clue). Here's the HTML I had for the search bar:

<input type="text" name="search" placeholder="Search..">

And the CSS:

input[type~="text"] {
    width: 130px;
    -webkit-transition: width 0.4s ease-in-out;
    transition: width 0.4s ease-in-out;
}

/* When the input field gets focus, change its width to 100% */
input[type~="text"]:focus {
    width: 100%;
}

The problem is, I don't know how to actually make it function. I'm guessing I can do that with Javascript, but I'm not fully experienced in that.

1 Answer

+1 vote
by (61.5k points)
selected by
 
Best answer

This is not a simple process.  Here's a very, very simple implementation you might be able to build off of.  The first part all goes in your story JavaScript area.

window.termList = window.termList || [];

window.SearchTerm = window.SearchTerm || function (h, descr, kw) {
    'use strict';
    
    if (this instanceof SearchTerm) {
        this.handle      = h;
        this.description = descr;
        this.keywords    = kw;
    } else {
        return new SearchTerm(h, descr, kw);
    }
};

SearchTerm.add = function (h, descr, kw) {
    termList.push(new SearchTerm(h, descr, kw));
};

SearchTerm.prototype = {
    
    compare : function (stringArray) {
        var term = this;
        var matches = (function () {
            var ret = 0;
            stringArray.forEach( function (str) {
                if (term.keywords.includes(str)) {
                        ret++;
                }
            });
            return ret;
        }());
        
        return matches;
        
    },
    
    constructor : window.SearchTerm
};

$(document).on('change', 'input[name=search-box]', function (e) {
    var string = $(this).val(),
            matches = [], i, n = -1, highest = 0, content;
    
    string = string.replace(/[^A-Za-z0-9\s]/, ' ');
    string = string.replace(/[\s\s+]/, ' ');
    string = string.trim();
    string = string.split(' ');
    
    termList.forEach( function (term) {
        matches.push(term.compare(string));
    });
    
    for (i = 0; i < matches.length; i++) {
        if (matches[i] > n) {
            n = matches[i];
            highest = i;
        }
    }
    
    if (n <= 0) {
        content = '';
    } else {
        content = termList[highest].handle + ': ' + termList[highest].description;
    }
    
    $('#output')
        .empty()
        .append(content);
});

// add your search terms here...
SearchTerm.add('How to win things', 'first, stop sucking', ['win', 'winning']);
SearchTerm.add('How to lose things', 'first, stop winning', ['lose', 'losing']);

You add a new 'search term' by writing:

SearchTerm.add('name or title', 'a description', ['keywords', 'separated', 'by spaces']);

Then, in your passage:

<input type='text' name='search-box'></input>

<span id='output'></span>

You'll probably want to prettify this with some CSS.

Anyway, when the user types in a string, it'll count the number of times a keyword for each term is entered, and give us that search term if it was tripped the most times.  In ties, the first search term wins.  Using my example winning and losing terms above:

'winning'                                     ->  How to win things: first, stop sucking
'how do i win when i keep losing'             ->  How to win things: first, stop sucking
'how do i win when i keep losing and losing'  ->  How to lose things: first, stop winning

Etc...

As I've mentioned, this is an extremely limited system.  It might get you started, but the functionality you're asking for is not trivial to build.

Welcome to Twine Q&A, where you can ask questions and receive answers from other members of the community.

You can also find hints and information on Twine on the official wiki and the old forums archive.

See a spam question? Flag it instead of downvoting. A question flagged enough times will automatically be hidden while moderators review it.
...