Archive for the ‘jQuery’ Category

Now that sendkeys is fixed to work with contenteditable and I've analyzed Lebedev's VirtualKeyboard to allow typing on the physical keyboard, updating the hebrewKeyboard plugin was straightforward. I had to learn a fair amount about the difference between keyup, keydown, and keypress events, but I think everything works. Check it out!

The $.fn.sendkeys Plugin

This is now obsolete. sendkeys is at version 4, and is documented at "Rethinking $.fn.sendkeys".

I wanted to make a general-purpose onscreen keypad, and wasted a huge amount of time trying to find a way to simulate a keypress. $(element).trigger("keypress",...) won't work. Neither will keyup or keydown. For security reasons, I guess, you can't tell an element to pretend a key was pressed. The browser is too worried that you will access menus or something.

So I wrote my own plugin and named it after Microsoft's sendkeys which does similar things. For any editable element elem, $(elem).sendkeys(string) inserts string at the insertion point or selection. It's the insertion point sensitivity that makes it more sophisticated than elem.value += string.

It depends on my bililiteRange routines to manage the selections in a cross-browser way.

Downloads

See $.fn.sendkeys on github.

See bililiteRange on github.

See the demo.

Continue reading ‘Improved sendkeys’ »

I have no idea when I would ever want to use these, but they are very cool.

<h4>Click Me</h4>
<div id="texteffect" style="width: 200px;height: 200px; border: 1px solid purple; background: #abcdef; cursor: pointer; padding: 2px; overflow: hidden">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur libero sem, fringilla in posuere a, cursus nec felis. Integer eu mi in tortor malesuada pretium vel sed augue. Donec eget convallis tellus. Aenean vehicula nisl ac justo facilisis et bibendum mauris aliquam. Fusce quis dolor sapien, et lacinia lorem.
</div>
var text = '';
$('#texteffect').click(function(){
  if (text){
    $(this).effect('type', {text: text, word: true}, 2500);
    text = '';
  }else{
    text = $(this).text();
    $(this).effect('backspace', {text: '', word: true},  2500);
  }
});

Update: Connie Wiolowan of allanguages.info has made some comments and I've updated the post to reflect them. Thanks!

Connie also created a jQuery plugin for the virtual keyboard; see the comment for details.

I like Ilya Lebedev's JavaScript VirtualKeyboard a lot. It's clever, got an elegant UI, allows you to remap the physical keyboard to any language you want, and has an active and responsive support forum. But it's got a few quirks that make it hard to use with jQuery.

  • Virtually no documentation. You have to read the source to get anywhere. But here's a brief introduction (assuming you use jQuery):
    1. Download the package from SourceForge, unzip the tarball and put the whole folder (don't mess up the organization!) somewhere accessible.
    2. Include the script with <script type="text/javascript" src="/path/to/files/vk_loader.js" ></script>.
    3. Have a blank <div> in your HTML that will house the keyboard. I'll use <div id="jsvk" /> in these instructions.
    4. Have one or more <input type="text" >s or <textarea>s that will accept the keyboard input.
    5. In your $(document).load function, include the statement VirtualKeyboard.show($('input')[0], $('#jsvk')[0]).
    6. Other useful functions include VirtualKeyboard.hide() that hides the keyboard and removes it from the DOM, VirtualKeyboard.attachInput($('input')[0]) that leaves the keyboard visible where it was but associates a new input element with it, and VirtualKeyboard.detachInput() that leaves the keyboard visible but removes the association with an input element.
    7. VirtualKeyboard.open is a synonym for VirtualKeyboard.show and VirtualKeyboard.close is a synonym for VirtualKeyboard.hide.
  • The VirtualKeyboard is a Singleton. This means that you can only have one keyboard shown on a page, and the "skin" (the CSS of the keyboard) is fixed at initialization even if you move it around and associate it with different input elements. It also means that if you use the keyboard for different input elements, changing the language for one changes it for all of them. You can get around this by putting the keyboard into its own document and using iframes or popup windows, and the code includes samples for both of those.
  • The package is huge. The "compacted" version is 4 MB. Most of that is the development files, so it's not like every page downloads megabyte files (the largest downloaded file is the keyboard layout package, about 390K), but it's still huge.
  • Part of the reason that it's so big is that it does everything. Lebedev has put an entire Javascript library into this package, including its own event manager that overrides jQuery's. So you can't do $('input').click(function(evt){}) on elements that are attached to the keyboard. You have to use his EM.addEventListener(self.element[0],'click', function(evt){}).
  • Options are too clever by half: he parses the <script src="/path/to/vk_loader.js?query-string> query string to get them. So to set the initial layout and the skin, I used <script type="text/javascript" src="/path/to/vk_loader.js?vk_layout=IL%20Hebrew&vk_skin=flat_gray" ></script>. Options are:
    • vk_skin: name of folder in the /css folder in the package to use for the CSS
    • vk_layout: name of the keyboard layout. The available names are listed on the right hand side of the home page or the project developement page

But these are really minor issues for such a great package, and adapting it to use jQuery isn't that hard (I'm using my textpopup plugin as a base):


<div id="example">
	Example: <br/><input style="float:left"/><input style="float:right"/>
	<br style="clear:both"/>
</div>

var keyboard = false; // VirtualKeyboard is a singleton, so we have to make sure there's just one container
$.ui.textpopup.subclass("ui.jsvk", {
	_createBox: function(){
		if (keyboard) return keyboard;
		var self=this;
		self._super();
		keyboard = self.theBox;
		VirtualKeyboard.open(self.element[0], self.theBox[0]);
		EM.addEventListener(self.element[0],'keypress', function(e){
			if (e.getKeyCode()==27) self.hide();
		});
		return self.theBox;
	},
	show: function(){
		VirtualKeyboard.attachInput(this.element[0]);
		this._super();
	},
	hide: function(){
		VirtualKeyboard.detachInput();
		this._super();
	}
});

$('#example input:eq(0)').jsvk({position: 'bl'});
$('#example input:eq(1)').jsvk({position: 'br'});

I had a terrible time getting the positioning for my textpopup to come out right and my solution was hacky and didn't work consistently. It seems that everyone had that problem, and the jQuery UI team solved it (yay!) for version 1.8. Enter the enhanced position. It does all the work for me and allows for much greater flexibility. One downside is that it won't work on invisible (display: none) elements, so I have to hack it with x.css({display: 'block', visibility: 'hidden'}).position(positionOptions).css({display: 'none', visibility: 'visible'}).

The other downside is that the display animation isn't as elegant: my hack involved appending the popup directly after the input box and setting the css so that the correct edge was fixed to the input box. This meant that changing the size of the popup automatically moved it into position, and the animation always appeared to grow out of the input box. Now the position is fixed absolutely, and the standard show always grows from the upper left corner. You have to manually set the animation or reposition the box. A small sacrifice for "just works."

Well, they released jQuery UI 1.8 two days ago, and now everything is broken. I understand why the changes were made, but it sure is inconvenient. Plugins and posts updated so far:

And on top of that, chili stopped working with jQuery 1.4 and I haven't fixed it yet. Andrea Ercolino was nice enough to send me an updated version, but I haven't gotten around to installing it yet.

Update: got chili to work!

So much for using my spare time to learn Scheme!

This page is obsolete. Please see my github page.

I like Maxime Haineault's timepickr. But I found it was written for jQuery 1.2, and didn't trigger events correctly with the current jQuery. It also had more dependencies than I wanted, to the extent that the minified version is 49k large, and had some CSS quirks in Internet Explorer that I couldn't figure out without dissecting the whole thing. So I dissected it and rebuilt it smaller, updated for jQuery 1.3. I didn't put back a lot of the options that I didn't need, so it's not exactly an improvement. But it works for me.

Download the code.

I also added the ability to use hoverIntent so you can roll the mouse over the intervening buttons without triggering them:

Continue reading ‘Updating timepickr’ »

Updated 2012-12-26 with a much better algorithm for detecting stylesheet loading.

So let's say I want to create elements that match a jQuery UI theme (in my case, I was using a <canvas> element and wanted to copy colors). I could try to parse the CSS file directly, but that runs afoul of the same-origin security problem (I use Google's CDN to get the jQuery UI stylesheets, as in http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.0/themes/smoothness/jquery-ui.css). I could go through the document stylesheets to find the relevant styles, but there's an easier way; just create an element with the desired classes and query that:

var background = $('<div class="ui-state-default">').css('background-color');
Continue reading ‘Copying jQuery UI styles and Detecting CSS Loading’ »

I added keyboard accessibility to flexcal, based on the AOL style guide. Tabbing into the trigger for a textpopup makes it pop. The focus remains on the input element and requires another tab to put the focus on the calendar (a bit awkward to require two tabs but I didn't want to have the input element lose focus every time it gets it), and the escape key (or tabbing out) hides it.

Unfortunately, control-page up/down if used by Firefox to change its tabs and I can't override that, so I use alt-page up/down to skip years. Alt-left/right arrow changes calendars.

Unfortunately, the tabbing in and out doesn't work in Chrome; after tabbing out when the focus returns to the input element it won't leave. I'm not sure what the problem is. And it uses tabindex=0 which isn't supported by Safari at all. I think I will leave it as is and wait for the browsers to catch up to me.

Just checking. No reason it shouldn't work with the jQuery UI themeswitcher. The slot machine animation has a white background, which looks off with some themes. The text color for the dates unfortunately is (by the CSS specificity rules) overridden by the blog's text color, so dark themes are near unreadable.

Slot Machine Transition

Cycle Transitions