Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to dynamically close bracket while typing using JavaScript?

I've seen questions here regarding this same problem except asking how to configure settings for a text-editor. I want to know how to do this in the browser using JavaScript inside an input element or a textarea element.

To expand a little more, while typing, if a user presses (, <, {, or [ I want JavaScript to automatically put a closing element ), >, }, ] according to the one typed, preferably fast enough to add it before the user is likely to type another character.

I'm not that experienced with JavaScript so I'm coming here for help. Here's what I've tried:

$(".editable").keydown(function(e) {
    if(e.which == 219) { // open bracket
        $(".editable").val() += "]"; // close bracket
    }
});

But it throws an error Invalid left-hand assignment Also, this seems like a problem which could have a more efficient/elegant solution/approach to what I tried? Any help would be much appreciated.

jsFiddle

like image 334
Jace Cotton Avatar asked Sep 18 '26 02:09

Jace Cotton


1 Answers

To fix the syntax error, change

$(".editable").val() += "]"; // close bracket

to

$(".editable").val($(".editable").val()+"]"); // close bracket

But this is a cheap solution which

  • would apply the change to all .editable inputs, not just the one in which you type
  • doesn't take into account the position of the cursor (you may type at another position than the end)
  • acts (on keydown) before the value is changed

Here's a better version, also putting the cursor between the brackets, and working on parenthesis and curly brackets :

(function(){
    function insertInto(str, input){
        var val = input.value, s = input.selectionStart, e = input.selectionEnd;
        input.value = val.slice(0,e)+str+val.slice(e);
        if (e==s) input.selectionStart += str.length - 1;
        input.selectionEnd = e + str.length -1;
    }
    var closures = {40:')',91:']', 123:'}'};
    $(".editable").keypress(function(e) {
        if (c = closures[e.which]) insertInto(c, this);
    });
})();

I use keypress to better handle key combinations (on some keyboards, keyup wouldn't easily distinguish between [ and {). And I've put everything into an IIFE to avoid polluting the external namespace.

Demonstration

like image 199
Denys Séguret Avatar answered Sep 19 '26 14:09

Denys Séguret



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!