javascriptmousetrap

Dynamically set Mousetrap.bind() key combinations from an object


I'm getting back data from our backend that contains information about keyboard shortcuts. This is a dumbed down version of what I will receive:

    { code: "r", message: "test R" },
    { code: "s", message: "test S" },
    { code: "c", message: "test C"}

The 'Code' specifies which key will activate the keyboard shortcut, and the message is what will be pasted in an input box.

I am using the Mousetrap library, which allows me to write functions like so:

Mousetrap.bind('shift+^+r', function () {
    alert("test");
});

My question is: is there a way to write these functions at runtime based on the data brought back? So for every item in the JSON object, a function will be needed to handle the shortcut.

I've tried this:

    var html = document.getElementById("shortcuts").innerHTML;
    document.getElementById("shortcuts").innerHTML = html + "<script> Mousetrap.bind('shift+^+r', function () { alert('test) })); <\/script>"

I don't know if this is good practice, as I am still quite new to JS, but this was the only thing I could come up with. It doesnt work though.


Solution

  • Sure. Sounds easy enough. Just create a separate function accepting an object, getting both the code and message properties and calling Mousetrap.bind(str, func) on runtime

    function bindKey(input){
        const code = input.code;
        const message = input.message;
    
        const bindStr = "shift+^+" + code; //idk if you need shift here but modify as needed
    
        Mousetrap.bind(bindStr, function(){
              alert(message);
        });
    }
    

    Use via

    bindKey({code: "r", message: "test R"});
    bindKey({code: "c", message: "test C"});
    bindKey({code: "d", message: "test D"});
    

    If you have an array of objects, just loop through them and call bindKey()

    myArray.forEach(bindKey);
    // or
    for (const i of myArray) bindKey(i);
    

    No need to write a script element. Just write the function and call it on runtime. Why you need to render a script tag is beyond me.


    Test below

    function bindKey(input){
       const code = input.code;
       const message = input.message;
    
       const bindStr = "shift+^+" + code; //idk if you need shift here but modify as needed
        
        Mousetrap.bind(bindStr, function(){
              console.log(message);
        });
    }
        
    bindKey({code: "r", message: "test R"});
    bindKey({code: "c", message: "test C"});
    bindKey({code: "d", message: "test D"});
    <script src="https://craig.global.ssl.fastly.net/js/mousetrap/mousetrap.min.js"></script>