tim peterson
tim peterson

Reputation: 24305

Positioning a text input on top of a textarea's cursor position (javascript, Textarea autcompleting)

I'd like to make an autocomplete where if one types an "@" they are offered an autocomplete list of names.

I'm using jQueryUI autocomplete and the only problem with my solution ( http://jsfiddle.net/aUfrz/22/ ) is that the autocomplete-able text input needs to be placed on top of the textarea cursor position and not to the right as it currently stands.

Here's my JS that's in the JSFiddle:

$(document.body).on('keypress', 'textarea', function(e) {
   var names = [
        "johnny",
        "susie",
        "bobby",
        "seth"
    ],
    $this=$(this),
    char = String.fromCharCode(e.which);

    if(char == '@') {
       console.log('@ sign pressed');
       var input=$('<input style="position:relative; top:0px; left:0px;background:none;border:1px solid red" id="atSign" >');
       $this.parent().append(input);
       input.focus();
       input.autocomplete({
        source: names,
        select: function (event, ui) {
            console.log('value selected'+ui.item.value);
            //$this.val('@'+ui.item.value);
            $this.insertAtCaret(ui.item.value);
            $this.focus();
            input.remove();
        } //select
    });  //autocomplete
  } //if 
}); // keypress

HTML:

<textarea></textarea>​

Please note that I have NOT shown here a jQuery plugin I used to insert the selected autocomplete suggestion at the caret position: insertAtCaret() which I found at this other SO question.

Upvotes: 5

Views: 2190

Answers (2)

tim peterson
tim peterson

Reputation: 24305

This other SO answer which mentions this pretty slick jQuery plugin asuggest is what i'm going to go with. Thanks @asad for your help.

Here's the JSFiddle of the final product using asuggest(): http://jsfiddle.net/trpeters1/xjyTW/2/

here's the JS from this JSFiddle:

$.fn.asuggest.defaults.delimiters = "@";
$.fn.asuggest.defaults.minChunkSize = "0";  

$(document.body).on('keypress', 'textarea', function(e) {
  var names = [
    "johnny",
    "susie",
    "bobby",
    "seth"
  ],
  $this=$(this),
  char = String.fromCharCode(e.which);

   if(char == '@') {
     $this.asuggest(names);
     var v='';
     if($this.click()) { console.log('clicked textarea');           
       v=$this.val(); console.log('texarea value'+v);           
       for(var i=0; i<names.length;i++ ){ 
         if(v.indexOf('@'+names[i]) != -1){
           names.splice(i,1);  console.log('names spliced away: @'+names[i]);              
         } // if indexOf
       } //for
     } //if click
   } //if @
}); //keypress​

HTML:

<textarea></textarea>​

Upvotes: 0

user1726343
user1726343

Reputation:

One way to get the caret position is to multiply the pixel width of each character by the character offset of the caret. Here is a somewhat crude example that demonstrates. The x offset from the textarea is calculated like this:

e.target.value.length*13

EDIT: Here is a greatly improved version. An important discovery was that in monotype font faces the ratio between the width and height is 8/13.

In the screenshot below, you can see that the input appears at the caret position when I press @.

A screenshot showing how it looks in my browser.

And here is a screenshot in Chrome, showing the same behavior

enter image description here

Upvotes: 2

Related Questions