Skip to content

Allowed the list property to accept a function. #17153

Open
mikehofm wants to merge 2 commits intoLeaVerou:gh-pagesfrom
mikehofm:gh-pages
Open

Allowed the list property to accept a function. #17153
mikehofm wants to merge 2 commits intoLeaVerou:gh-pagesfrom
mikehofm:gh-pages

Conversation

@mikehofm
Copy link
Copy Markdown

@mikehofm mikehofm commented Jul 20, 2018

This allows users to easily generate the autocomplete items dynamically. For example, you can implement intellisense-style autocomplete, as shown below.

<!DOCTYPE html>
<html>
<head>
    <link rel="stylesheet" href="awesomplete.css" />
    <script src="awesomplete.js"></script>
    <style>#myinput { width: 500px; }</style>
</head>
<body>
    <input id="myinput"/>

    <script>
    var myAwesomplete = new Awesomplete(document.getElementById("myinput"), {
        autoFirst: true,
        minChars: 0,
        filter: (text, input) => text.toLowerCase().includes(parseObject(input)[1].toLowerCase()),
        replace: function(text) { this.input.value = [parseObject(this.input.value)[0], text].filter(x => x.length).join('.'); },
        list: function(input) { 
            var objString = parseObject(input)[0];
            if (objString.length == 0)
                return getProperties(window);

            try { var obj = eval(objString); } catch (err) {};

            return obj ? getProperties(obj) : []; 
        },
        sort: function(a, b) { 
            var input = parseObject(myAwesomplete.input.value)[1];
            var difference = b.startsWith(input) - a.startsWith(input);
            if (difference !== 0)
                return difference;
            
            var inputLc = input.toLowerCase();
            difference = b.toLowerCase().startsWith(inputLc) - a.toLowerCase().startsWith(inputLc);
            if (difference !== 0)
                return difference;

            return Awesomplete.SORT_BYLENGTH(a, b);
        }
    });

    myAwesomplete.input.addEventListener('keydown', function(e) {
        if (e.keyCode == 9)	{ // tab
            e.preventDefault();
            myAwesomplete.select();
        }
        else if (e.key == '.') {
            myAwesomplete.select();
        }
    });

    // Return "obj.someProp.someth" as ["obj.somProp", "someth"]
    function parseObject(text) {
        let index = text.lastIndexOf('.');
        if (index < 0)
            return ['', text];
        else
            return [text.substring(0, index), text.substring(index + 1)];
    }

    function getProperties(obj) {
        var props = [];

        do {
            props = props.concat(Object.getOwnPropertyNames(obj)).filter(x => isNaN(+x));
        } while (obj = Object.getPrototypeOf(obj));

        return [...new Set(props)];	// remove duplicates
    }
    </script>
</body>
</html>

code-complete-example

mikehofm added 2 commits July 19, 2018 18:51
It's passed the current input and should return an array. This makes it easy to have the list generated dynmically as the user types.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant