rich_textarea

Rich_TextArea is a jQuery plugin replacement for the venerable HTML TEXTAREA that adds arbitrary triggered autocompletes along with the insertion of rich “embedded objects” included images, links, or any other markup.

Demo:  demo here.

Source:  Available on GITHUB and is licensed under the MIT license.

Screenshot:

rich_textarea_screenshot.png

It features:

  • multiple configurable triggered autocompletes using jquery.ui.autocomplete
  • insertion of ‘rich markup embedded objects’ such as images, links, etc.
  • embedded objects are treated as atomic objects from the point of view of cursor movement, mouse selection, backspaces, deletion, etc.
  • the content area is reduced to plain text with embedded [o=..] tags representing the embedded objects.

Embedded objects are treated as single entities. As a result there are quite a number of cases that need to be addressed as the user edits:

  • the user clicks on an embedded object. Regardless of which node in the object the user clicks on, the caret must be positioned before the wrapping element and the object highlighted.
  • if the user positions the caret immediately before or after an object on the same line, the object should be highlighted.
  • if the user positions the caret immediately before or after an object on the same line and then press the arrow key again, the caret should be positioned on the other side of the object.
  • If the user presses the UP or DOWN arrow keys and the caret would otherwise be positioned inside an embedded object, the caret should be positioned at the beginning of the object and the object highlighted.
  • if the users selects a range with the mouse (i.e. click and drag) and either end of the selected range is inside an object the range should be extended to include the selected objects.
  • If the user presses DELETE immediately before an object or BACKSPACE immediately after an object, the object should be deleted.

All of this is complicated by the fact that different browsers have different ideas ofwhere the caret can be positioned. In addition, different browsers implement the contenteditable area differently.

Integrating jquery.ui.autocomplete was also less straight forward than expected. The default behavior of autocomplete is to replace the entire contents of whatever editable area it is attached to. (i.e. you select something from the drop down list, everything in the DIV is replaced by the selected it. Not Good(tm).)

Additionally, there is no direct support in autocomplete for a trigger character. So all the support to recognize when a trigger character, such as an @, has been entered and then pulling out the trigger word, passing that in to autocomplete and then replacing the trigger word the user entered with the rich text object has to be done manually.

This is complicated by the fact that the user may edit the trigger word as they type. Consider a trigger word “test1″. If:

  • the user types @te
  • presses space to cancel the autocomplete
  • presses ENTER to open up a new line
  • enters st.
  • then moves the caret to before the s.
  • now press BACKSPACE twice
The autocomplete should fire. This is complicated by the fact that in this scenario in WebKit browsers there will be two text nodes “te” and “st”. 
If the user clicks on a trigger (as you can see in the demo) the autocomplete list should be displayed.
If the user types and enters a trigger character but the trigger character is not preceded by:
  • a space
  • a break
  • the beginning of a container
Then no autocomplete menu should be displayed. (imagine entering test@test.com)
If an autocomplete is triggered the user should be able to continue typing leaving what they typed in the content.
There are a number of other cases the continue to complicate matters.

So, all in all, what should have been trivially easy has turned into a much bigger effort than expected.