Bug fix for sendkeys
Fixed a bug where the selection was not set correctly (a regression from when I updated bililiteRange). It's now at version 2.2.
sendkeysFixed a bug where the selection was not set correctly (a regression from when I updated bililiteRange). It's now at version 2.2.
hotkeys with keymapInspired by John Resig's hotkeys, I created a version that uses the modern on, and uses an object rather than a string for the keys (which would be confused with a selector). It also uses my $.keymap codes.
It's written as a plugin to $.keymap.
Initialize it with $.keymap.hotkeys('keydown') (you can also use 'keyup' but that seems much less useful). This modifies the event handling code so that you can listen for specific keys or sequences of keys:
$('input').on('keydown', {keys: '^A'}, function() {alert('Control A was pressed')} );
The original $('input').on('keydown', function() {alert('A key was pressed')} ); is unchanged.
Only one handler per element/key is allowed; adding another handler replaces the old one. Remove it entirely with $('input').off('keydown', {keys: '^A'} );.
It handles selectors correctly (I think) but is subject to the same one handler per element rule:
$('body').on('keydown', {keys: '^A'}, function() {alert('Control A')} );
$('body').on('keydown', 'input', {keys: '^A'}, function() {alert('Control A was pressed in an input')} );
Would first attach the handler for <body> and keys ^A, then replace it with a handler that is only triggered when the target element is an <input> and the event bubbled up to the <body>.
Sequences of keystrokes are indicated by a space-delimited list:
$('body').on('keydown', {
keys: '{up} {up} {down} {down} {left} {right} {left} {right} b a'
},
function() {alert('Konami!')}
);
Listens for the Konami code.
Normally, when listening for a sequence, the keydown events that match are discarded. If you want them to be passed to other handlers, use
allowDefault:
$('body').on('keydown', {
keys: '{up} {up} {down} {down} {left} {right} {left} {right} b a',
allowDefault: true // the arrow keys will still work
},
function() {alert('Konami!')}
);
To prevent other handling on the final event of a sequence, use the usual preventDefault or return false in the handler.
The plugin also triggers two other events: 'keymapprefix' when the event is the prefix of a valid sequence, and 'keymapcomplete' when a sequence is matched. Both are sent with an additional parameter indicating what keys were pressed so far (in $.keymap notation). So:
$('body').on('keymapprefix keymapcomplete', function(event, keys){
alert ('sequence pressed: '+keys);
})
Well, I've finally decided to join the 21st century and get my projects on github. Some of them are useful enough that others have expressed an interest in extending them, and it will force me to have the discipline to use version control consistently. The projects I have on there are:
livesearchContinuing my adventures in developing an online editor, I wanted to be able to do "live" searching: having the text scroll to the sought string as it is being typed. I can use my bililiteRange utilities to find an arbitrary regular expression, but after much hair-pulling, realized that my texthighlight plugin is just too flaky and hack-dependent to be used reliably. So I went a different route: instead of trying to highlight strings in a <textarea>, I overlay a <pre> element desinged to look similar enough to the <textarea> and highlight the string in that with normal HTML. When the user is done typing his search string (signaled by a blur event on the <input> element being typed in), remove the <pre> and select the desired string in the original <textarea>. There's a jump but not as bad as with texthighlight.
See a simple demo, a demo that uses the parameters, and a demo that searches three elements at once.
Continue reading ›textareasI liked the hack that I used in the bililiteRange utilities demo to highlight the ranges in a textarea: creating a "shadow" preelement and using that to set the background of the desired text. It's based on this trick (explained in a ddforum post) by someone with a screen name of Trinithis.
I put it into a jQuery plugin, $.fn.texthighlight(bounds, id, color) that lets you quickly highlight a section of text in a textarea that will scroll with the text (having the highlighting stay with the text as it's edited is a different story; see the source for the bililiteRange utilities demo for that). It is a hack, and remains flaky (especially for Internet Explorer, for which I cannot get white-space: pre-wrap to work consistently).
bounds{Array [start, end]} | "remove" | "delete". Required. The starting and ending character positions to highlight. "remove" removes the given highlighter, and "delete" removes all of them and cleans up the wrapping element and data.id{String}. Optional; if falsy, uses "default". An arbitrary string to identify the highighter for future changing or removing.color{String}. Optional; if falsy, uses "#f0f" (a nice, bright magenta: ). The CSS color to use for the highighting (at 0.25 opacity).After highlighting, triggers a "texthighlight" event, with parameters [span, bounds] where span is a jQuery collection with one item, the highlighter elemeent, and bounds is the array originally passed into the plugin. So $('textarea').on('texthighlight', function (event, span, bounds) {span[0].scrollIntoView()}) will scroll the highlighted area to the top of the window whenever the highlighter is set.
keydown eventsUpdated 2013-03-20 to include the hotkeys plugin.
I've been playing around with creating an online editor, and one thing it needs is keyboard shortcuts. Control keys and the like don't register keypress events, so I have to use keydown to get the event.which (and I have to use jQuery to normalize that across browsers), and then I have a random keyboard code and a bunch of modifier key flags to work with. The W3C once tried to rationalize all this, but no one picked up on it. So I wrote a jQuery plugin to turn the event into a friendlier string (using a notation based on Microsoft's sendkeys). Thus:
$.keymap(event) == 'a'$.keymap(event) == 'A'$.keymap(event) == '^A'$.keymap(event) == '%A'$.keymap(event) == '^%A'$.keymap(event) == '{esc}'$.keymap(event) == '+{esc}'$.keymap(event) == '{multiply}'$.keymap(event) == '^{1}'One thing I wanted to add to my bililiteRange was the ability to scroll the range into view without changing the selection. As with all things having to do with ranges, there's no consistent way to do it, and Internet Explorer does it best (this is the only time you'll hear me say that).
bililiteRange PluginsI created a collection of useful plugins for my bililiteRange, for more sophisticated manipulations. Now you can search the element with a regular expression, and you can keep the range "live", adjusting it when the text is edited.
See the demo. (The dynamic highlighting is off by a few pixels in iOS Safari. I'm still working on that)
Continue reading ›bililiteRangeI've been working on a project that uses bililiteRange a lot, so I added two improvements: plugins and events.
bililiteRange.fn.myplugin = function() {}; or bililiteRange.extend({ myplugin1: function() {}, myplugin2: function(){} }); creates new functions for a bililiteRange (just like with jQuery).
Also, the text method now triggers an input event on the element. Only works on browsers that implement CustomEvent.
jsvk, a jQuery Plugin for VirtualKeyboardI've been using Ilya Lebedev's JavaScript VirtualKeyboard for a while, and even created a small plugin to integrate it with jQuery. But I wanted to make it more jQuery-ish, so I made a new version of jsvk, the plugin to wrap Ilya's code.
See a demo that allows dynamic control of keyboard layout and skin (CSS), and a demo that shows multiple inputs and jQuery UI's draggable.
$('textarea, input').jsvk(opts) to initialize a text-inputing element (cannot handle <div contenteditable> at this point), $('textarea, input').jsvk('off') to detach the keyboard, and $('textarea, input').jsvk() reattach the keyboard leaving the options the same. Note that the VirtualKeyboard itself is a Singleton, so there can only be one open at a time (attaching to one element removes it from another) and that setting opts changes the appearance for every attached keyboard. You can do $('textarea, input').jsvk(opts) on an existing attached keyboard to change the options.
dirjsvk all other calls are held and once it's set any future uses of this option is ignored.kbdiv$(kbdiv)[0]). If not set, creates a new element with $('<div>').insertAfter(this).skincss directory in opts.dir; they are listed in the subversion directory and the right of the online demo.layoutlangfilteropts.layout; if the selected layout is not in the filter list the first layout that is will be chosen.nokeyevents$('#input').jsvk({ dir: '/inc/VirtualKeyboard', skin: 'air_mid' }). Open a VirtualKeyboard with a specific skin but the default layout.$('#input').jsvk('off'). Hide and detach the VirtualKeyboard.$('#input').jsvk(). Show the VirtualKeyboard, with skin and layout unchanged.$('#input').jsvk({layout: 'US US'}). Show the VirtualKeyboard, with skin unchanged but set the language and layout.$('#input').jsvk({langfilter: ['GR', 'BA']}). Show the VirtualKeyboard, but only allow Greek and Bosnian layouts.nokeyevents option.