Inline Code Assistance for Form Fields with jquery.codeassist

October 22nd, 2010 | Categories: JavaScript, jQuery, Web Development | Tags: , , , , , , ,

I'm working on a project that required some apparently previously unexpected UI controls. One of them, I decided should be made into a jQuery plugin and get some feedback from the community. I call it jquery.codeassist.

OK... so what the hell does it do?

The plugin creates a code assist menu within textarea and input fields, which allows users to select from a list of suggested values. This effect is triggered by the entry of a key character such as %, $ or [

So far, only %, $ and [ (with an optional closing key of ]) are supported--though, with some tweaks, I know I can get it to accept any input.

OK... but really, what the hell does it do?

It was built for the purpose of allowing users to enter dynamically replaceable code bits into textareas and input fields. A use case example would be if you are allowing users to create a page template or message template that will need to be filtered for the audience or some other situation involving different values for different pieces of data at a time. A user can enter in the code bits, which you can replace behind the scenes in the template.

OK... so is there a real world example?

Since the impetus for this plugin comes from a proprietary and as of yet unseen stealthy startup, I'm not at liberty to show the awesome reason why I found it necessary to create this plugin. But here's a totally crappy and simple demo so you can see what the hell I'm actually talking about:
Crappy, Simple Demo

And you can download, fork and whatnot on github:
Source on GitHub

Issues I had with the implementation

Mouse position

The thing that is bugging me most at the moment is that I wanted the menu to appear where the mouse is. Simple enough, right? Just take a look at the triggered event pageX and pageY, right? Well, that would work if I was attaching to a mouse event--but the trigger for the menu is a key event, which doesn't care about the position of the mouse. So to get around this, I've got a listener that's caching the mouse coordinates so we can look at it when we need to:

// this is stupid but I can't find a better way to get the current mouse position
// since the key events don't contain the pageX and pageY 
// so following it arround and caching the position :(
$(document).mousemove(function(e){
	codeassist.pageX = e.pageX;
	codeassist.pageY = e.pageY;
});

I am genuinely annoyed about this.

Cursor position

For sane browsers, you can simply access element.selectionStart to get the index that the cursor is positioned within the text. However, for IE, you have to hack up a nasty solution:

... // up here, we've defined el as the input, v as the current value of the input, and t = $(this), etc..
var before = ''; // text before cursor
if (el.selectionStart!==undefined){ // sane browser
	before = v.substring(0,el.selectionStart);
}else{ // IE
	t.focus();
	var range = document.selection.createRange();
	range.moveStart ('character', -v.length);
	before = v.substring(0,range.text.length);
}
  1. Bryanlynn
    November 3rd, 2010 at 04:09

    Is it possible to use the key "<" as a bracket?

    • November 4th, 2010 at 16:07

      There are a couple of issues with the current implementation. The keyCode for '<' (at least in FireFox) is showing up as 0, which won't work with the current way of detecting the key that was pressed. The way it's built out now was intended to support a particular simple set--but this could be expanded with a little modification, which I might do today :)Essentially, rather than detecting the keydown/keypress keyCode, you could find the cursor position within the field, examine the last character that was typed explicitly (in combination with e.shiftKey, e.ctrlKey, etc--to support non-visual typed key triggers) and use that instead. That way, it would be much easier to support any key press combination without worrying about keyCode values at all.Additionally, while we are on the topic of cursor position. For the original implementation, it was useful to pop the hint at the cursor position (partially because the click to add is an optional trigger and partially because it just worked for the situation)--but it isn't ideal since the cursor might be totally off-screen if the user is a keyboard jockey. However, grabbing the pixel position of the cursor within a textfield is a pain the royal when you have to consider browser and text-size variation. I explicitly didn't want to pop the helper as a side or bottom attachment to the textarea or input--but I might make that a config option.

    • November 4th, 2010 at 17:31

      see the latest now on github for this addition: https://github.com/atomantic/jquery.codeassist

      demo: http://atomantic.github.com/jquery.codeassist/

      Keep in mind that this is not intended to be an HTML creation helper (there are lots of more advanced libraries for that)--however, if you wanted to support and as helpers you could create a set like:

      $('textarea').codeassist({
      key:'',
      list:[
      'h1',
      'p',
      '/h1',
      '/p'
      ]
      });

      But keep in mind that this isn't smart about it--there's no detection built in to autoclose or detect which html element you intend to close, etc--like I said, there are other libraries for that :)

  2. November 4th, 2010 at 16:06

    There are a couple of issues with the current implementation. The keyCode for '<' (at least in FireFox is showing up as 0, which won't work with the current way of detecting the key that was pressed. The way it's built out now was intended to support a particular simple set--but this could be expanded with a little modification, which I might do today :)

    Essentially, rather than detecting the keydown/keypress keyCode, you could find the cursor position within the field, examine the last character that was typed explicitly (in combination with e.shiftKey, e.ctrlKey, etc--to support non-visual typed key triggers) and use that instead. That way, it would be much easier to support any key press combination without worrying about keyCode values at all.

    Additionally, while we are on the topic of cursor position. For the original implementation, it was useful to pop the hint at the cursor position (partially because the click to add is an optional trigger and partially because it just worked for the situation)--but it isn't ideal since the cursor might be totally off-screen if the user is a keyboard jockey. However, grabbing the pixel position of the cursor within a textfield is a pain the royal when you have to consider browser and text-size variation. I explicitly didn't want to pop the helper as a side or bottom attachment to the textarea or input--but I might make that a config option.

You must be logged in to post a comment.