Skip to content

New flexcal

After some prompting by those actually using it, I paid more attention to my flexcal date picker plugin, adding features like buttons, drop-down menus and formatted dates. The documentation is on my github pages at, and the code is on github at All other posts about it are obsolete.

The current stable version is 3.4.

Animating arbitrary values with jQuery

jQuery's animate is useful for animating CSS properties, but there are times that you want to take advantage of the bookkeeping that jQuery provides to animate, with easing functions etc., but not to change an animatable property. The flip plugin for Mike Alsup's cycle2 has a clever hack to animate some otherwise unused property instead:

<input type=button value="Click Me" id=rotatebutton />
<div id=rotatetest style="height: 100px; width: 100px; background: #abcdef" >Whee!</div>

  $('<div>'). // create an unused element (could use a preexisting one to save some time and memory)
    animate({lineHeight: 360}, // we aren't really using lineHeight; we just want something numeric.
      //We want it to go from 0 (the default for anything that has a value of 'auto' to 360
      duration: 2000,
      easing: 'easeOutElastic', // use jQuery and jQuery UI to manage the animation timing
      step: function (now){
        $('#rotatetest').css('transform', 'rotate('+now+'deg)'); // use the number that animate gives us

Running pages locally

I want to start using github pages for documentation, which would allow me to host them on github but still edit them locally and just push the edits. The problem is debugging. Anything that relies on AJAX is a security risk if I'm trying to get local files, so browsers reject any $.get('localfile.json'). I understand the restriction, but it makes development very annoying. There are proposals to allow some kind of package, with only descendents of the current file, but everyone is too scared that users will download something to their Documents folder and expose themselves.

So the only solution seems to be to set up a local http server and use that. The simplest I've found (not very fast, but I don't need that) is to use python's http.server. First, install python (choco install python works), and then in my PowerShell profile I have a line:

function svr { Start-Process "C:\tools\python\python.exe" "-m http.server" }

So I navigate to my desired folder, run svr, and it starts a python window running the server. localhost:8000 is the URL of the folder the server is running on.

New jquery.ui.subclass.js

I finally updated my jQuery widget subclassing code to use the newest version of jQuery UI, which incorporated a lot of the original ideas I outlined back in 2010. The new documentation is now on my github pages, and I've updated the flexcal posts to reflect it.

It is a breaking change; instead of $.namespace.widgetname.subclass('namespace.newwidgetname', {methods...}) you use the real jQuery UI way: $.widget('namespace.newwidgetname', $.namespace.widgetname, {methods...}).

I've also changed all my flexcal-related widgets to the bililite namespace, per jQuery UI guidelines. It's now $.bililite.flexcal instead of $.ui.flexcal, and so on for all the fields in that (like $.bililite.flexcal.tol10n).

Hope not too many people are inconvenienced.

New jQuery plugins, $.repo and $.getScripts

See the code.

jQuery plugin to allow using to get the latest commit of a github repo

github won't let you hotlink to their site directly; sends its content with a X-Content-Type-Options:nosniff header, so modern browsers won't accept it as javascript. gets around that by pulling the raw file and re-serving it with more lenient headers, but the rate is throttled so you can't use it on public sites. isn't throttled but is cached, permanently. Once a given URL is fetched, it stays in the cache and if the file is updated on github, it won't be on . So having a script tag <script src=""> lets you get the script from github, but even when the master branch is updated, the script retrieved will remain the same.

The answer is to use a specific tag or commit in the script tag: <script src=""> and change that when the underlying repo is updated. But that is terribly inconvenient.

For stable libraries, that's not a problem, since they should be tagged with version numbers: and that's probably what you want. However, if you always want the latest version, that won't work.

$.repo uses the github API to get the SHA for the latest commit to the master, and returns a $.Deferred that resolved to the appropriate URL (with no trailing slash):

$.repo('user/repo').then(function (repo){

The github api is also rate-limited (to 60 requests an hour from a given IP address), so the repo address is cached for fixed period of time (default 1 hour), with the value saved in localStorage.

$.repo('user/repo', time); // if the cached value is more than time msec old, get a new one
$.repo('user/repo', 0); // force a refresh from github's server


$.getScript is useful, but it is asynchronous, which means that you can't load scripts that depend on one another with:


You have to do:

	return $.getScript('second.js');
	return $.getScript('third.js');
	// use the scripts

$.getScripts(Array) abstracts this out, so you can do:

$.getScripts(['first.js', 'second.js', 'third.js']).then(function(){
	// use the scripts

It's basically a very simple script loader.

Improved flexcal

Two new additions to flexcal, which is now at version 2.2. See the code and a demo, that uses my new github pages.

Mouse Wheel

The calendar now responds to wheel events, changing the month with scroll up/down and changing the calendar tab with scroll left/right. I initially tried to throttle it since my trackpad was too sensitive, but that made it too slow. I'm not sure waht to do about that. It works well with an actual mouse wheel, thoug.

Keith Wood's Calendars

Keith Wood is maintaining the jQuery plugin that eventually became the official jQuery UI datepicker. His version, however, handles multiple calendar systems, much like flexcal (though I like my plugin, of course). His code is on github, and the documentation is on his personal site. He has support for many calendar systems, and I wanted to let flexcal use that. I don't use his datepicker code, just the calendar systems.

I'm using a naming convention of language-calendar, like he-jewish for a calendar localized to hebrew, using a Jewish lunar calendar. It's the opposite of Woods, who uses calendar-language, like islamic-ar for a calendar localized to arabic, using the Islamic lunar calendar. For my names, the default language is en and the default calendar system in gregorian. Thus, islamic would be an English language Islamic calendar, and zh-TW would be a Taiwanese Chinese Gregorian calendar (my parser is smart enough to not be confused by the extra hyphen). The language codes are ISO 639 two-letter codes.

There is a new function, $.ui.flexcal.tol10n(name) that creates a localization object with appropriate language and calendar system. It is designed to be transparent; doing

  calendars: ['ar-islamic']

will look in the existing $.ui.flexcal.l10n object for 'ar-islamic', then try to find it in the jQuery UI datepicker localizations (if those are loaded) (note that jQuery UI only uses Gregorian calendars), then Woods's calendars if they exist.

You can use the bridge directly if you want; $.ui.flexcal.tol10n(name) returns a localization object that you can modify as desired and then pass to flexcal.

To use this, you need to include the necessary script files: jquery.calendars.js for the basic code, (like jquery.calendars.islamic.js) for the calendar-system-specific routines (these are all in English), and (like jquery.calendars.islamic-ar.js)for the language-specific localization, or jquery.calendars.language.js for language-specific localization using the Gregorian calendar.

Of note, the text that is used for the "Next Month" and "Previous Month" is localized for the datepicker, not the underlying calendar system, so if you want that included automatically, also include the jquery.calendars.picker-name.js. I have a little hack in flexcal so you do not have to include the entire jquery.calendars.picker.js package; just include the jquery.calendars.picker-mock.js before including the localization code.
It should be clear which files to include if you look at the list.


His calendar code also has some nice formatting options, which flexcal does not have out of the box, though it is possible with some work. I'd like to get a bridge to work with my code as well.
Some other options that would be nice include: setting the first day of the week (now is fixed at Sunday) and having the option of showing or selecting days from other months.

Creating a PowerShell shortcut

I'm sure there must be an easier way to run a program from PowerShell, but I haven't found anything simpler than

& "C:\Program Files (x86)\Notepad++\notepad++.exe"

with the ampersand and the full path. I could add "C:\Program Files (x86)\Notepad++" to $env:PATH, but I'd still have to type notepad++.exe file. I wanted some way to make a shortcut to a program name without having to create a new file, either a .LNK or .BAT file.

Turns out you can do this with PowerShell functions:

function npp { & "C:\Program Files (x86)\Notepad++\notepad++.exe" $args }

lets me run Notepad++ from PowerShell without nearly so much typing. Stuck that in my Profile.ps1 and now I'm happy.
Hope this turns out to be useful to someone.

Updated $.fn.status

I've added the ability to use the console with my status plugin, so you can do

  run: $.post(url, {data: data}).then(
    function() { return 'Data Saved' },
    function() { return new Error('Data Not saved') }

And the output will go to the console rather than to an element on the page.
For simple output to the console, this is far more complicated than console.log, but it works with the rest of the status options. Input is with window.prompt, since I don't know how to get input from the console.

Rethinking $.fn.sendkeys

See the demo.
See the source code, which depends on bililiteRange.

Modern browsers won't let synthetic events (triggered with dispatchEvent) execute their default actions (meaning the action that would occur if the event was triggered by a user action). The Event object has a read-only field called isTrusted that is false for anything but unmodified user-initiated events. These are called "trusted events", and I understand the justification, but they go too far. It makes it impossible to implement a virtual keyboard, since triggering keydown or keypress events aren't trusted and won't insert the character (the default action).

Fortunately, bililiteRange and especially bililiteRange.sendkeys can insert characters and do other manipulations on the page. So I created a jQuery plugin that uses bililiteRange.sendkeys to catch keydown events and implement them as well as possible.
Just include the source code and keydown events get a new default handler (so it can be cancelled by preventDefault) that looks at the key field. If it is a single character, that character is inserted at the selection. If it is more than one character long, it is assumed to be a sendkeys command like ArrowLeft and is sent as sendkeys('{'+key+'}').
I used the modern Event.key rather than Event.which, so I don't have to translate keyCodes. If you need to use the old way, see my keymap plugin.

Thus now, $('textarea').trigger({type: 'keydown', key: 'A'}) will work as expected, as will $('textarea').trigger({type: 'keydown', key: 'Backspace'}).

The actual plugin

Under the hood, this uses a very simple jQuery plugin that just calls bililiteRange.sendkeys(). It also turns '\n' in the string into '{Enter}', which I thought would be useful but has actually not turned out that way. Putting the '\n' in braces ('{\n}' prevents the replacement.
The plugin itself is:

$.fn.sendkeys = function (x){
  x = x.replace(/([^{])\n/g, '$1{enter}'); // turn line feeds into explicit break insertions, but not if escaped
  return this.each( function(){


	var index = $(this).parents('th').index();
$('div.test input:button').click(function(){
	$('.output.selected').sendkeys($('div.test input:text').val());
$('div.wrap input:button').click(function(){
	var tag = $('div.wrap select').val();
$('.phonepad input').click(function(){
	$('.output.selected').trigger({type: 'keydown', key: || this.value});
	bililiteRange(this); // initialize the selection tracking
}).on('keydown', function(evt){
	if ($('#overridepad').is(':checked')){
		alert (evt.key);
}).on('keypress', function(evt){
	$('#keypress').text($('#keypress').text()+' '+evt.which);
}).on('sendkeys', function(evt){
	$('#sendkeys').text($('#sendkeys').text()+' '+evt.which);
}).on('focus', function(){
	var index = $(this).parents('td').index();

	<table style="width: 100%" border="2" id="demo" >
					<input type="radio" class="selectoutput" name="selectoutput" checked="checked" />
					<input type="radio" class="selectoutput" name="selectoutput" />
					<input type="radio" class="selectoutput" name="selectoutput" />
					<code>&lt;div contenteditable&gt;</code>
					<input type="radio" class="selectoutput" name="selectoutput" />
				<td><input type="text" class="output selected" /></td>
				<td><textarea class="output"></textarea></td>
				<td><div class="output" contentEditable="true"></div></td>
				<td><div class="output" >This is not editable text</div></td>
<div class="phonepad">
<input type="button" name="ArrowLeft" value="&larr;"/><input type="button" name="ArrowRight" value="&rarr;"/><input type="button" name="Backspace" value="BS"/><input type="button" name="selectall" value="All"/><br/>
<input type="button" value="7" /><input type="button" value="8" /><input type="button" value="9" /><br/>
<input type="button" value="4" /><input type="button" value="5" /><input type="button" value="6" /><br/>
<input type="button" value="1" /><input type="button" value="2" /><input type="button" value="3" /><br/>
<input type="button" value="*" /><input type="button" value="0" /><input type="button" value="#" /><input type="button" name="Enter" value="&crarr;"/>
<label>Alert on keydown event: <input type=checkbox id=overridepad /></label>
<div class="test"><input type="text" /><input type="button" value="test"/></div>
<div class="wrap"><select><option>em</option><option>strong</option><option>del</option></select><input type="button" value="Wrap Selection"/></div>

<div id="keypress">keypress event.which:</div>
<div id="sendkeys">sendkeys event.which:</div>
<div style="clear:both" />

The phone pad keys use $().trigger({type: 'keydown', key: key}). The test button does $().sendkeys(textbox.value). The wrap button does $().sendkeys('<tag>{selection}{mark}</tag>'). Note that the trigger code does not affect the non-editable DIV, while sendkeys does.
The "Alert on keydown event" checkbox attaches a handler to the keydown event which calls event.preventDefault, showing that the text entry and keypress events do not occur.


bililiteRange.text() works well to insert text into ranges, but I wanted to be able to simulate other keys, ala Microsoft's SendKeys. bililiteRange.sendkeys() does exactly that. It basically executes text(string, 'end') but interprets any text between braces ('{key}') as a command representing a special key. For security reasons, the browser won't let you do anything outside of the text of the page itself, but I've implemented the following (the key names are from the proposed DOM3 standard)::

Delete backwards
Delete forwards
Move the insertion point to the right
Move the insertion point to the left
Insert a newline, with bililiteRange.insertEOL(). Warning: In contenteditable elements, Enter is flaky and inconsistent across browsers. This is due to the flakiness of contenteditable itself; I can't figure out what to do about this.

For backwards-compatibility with older versions, the following synonyms also work: backspace, del, rightarrow, leftarrow and enter.

So, for example, bililiteRange(el).sendkeys('foo') replaces the current range with 'foo' and sets the range to just after that string. bililiteRange(el).sendkeys('foo{Delete}{ArrowLeft}{ArrowLeft}') replaces the current range with 'foo', removes the character just after that string and sets the range to between the 'f' and the 'o'.

To manipulate the selection, use the usual bililiteRange methods. Thus, to simulate a backspace key, use bililiteRange(el).bounds('selection').sendkeys('{Backspace}').select().
To insert a '{', use an unmatched brace, bililiteRange(el).sendkeys('this is a left brace: {'), or {{}, as in bililiteRange(el).sendkeys('function() {{} whatever }');.

If anyone knows how to implement an up or down arrow, or page up/down, please let me know.

Other Commands

To make life easier for me, there are a few other "keys" that implement specific actions:

Select the entire field
Insert a '\t' character. $().sendkeys('\t') would work just as well, but there are circumstances when I wanted to avoid having to escape backslashes.
Insert a '\n' character, without the mangling that {enter} does.
Inserts the text of the original selection (useful for creating "wrapping" functions, like "<em>{selection}</em>").
Remembers the current insertion point and restores it after the sendkeys call. Thus "<p>{mark}</p>" inserts <p></p> and leaves the insertion point between the tags.

So to wrap the text of a range in HTML tags, use range.sendkeys('<strong>{selection}</strong>'). To create a hyperlink, use range.sendkeys('<a href="{mark}">{selection}</a>') which leaves the range between the quote marks rather than at the end.


Adding new commands is easy. All the commands are in the bililiteRange.sendkeys object, indexed by the name of the command in braces (since that made parsing easier). The commands are of the form function (rng, c, simplechar) where rng is the target bililiteRange, c is the command name (in braces), and simplechar is a function simplechar (range, string) that will insert string into the range. is set to the original text of the range, and is the argument for bililiteRange.bounds() that will be used at the end.

So, for example:

bililiteRange.sendkeys['{tab}'] = function (range, c, simplechar) { simplechar(rng, '\t') };
bililiteRange['{Backspace}'] = function (range, c, simplechar){
  var b = rng.bounds();
  if (b[0] == b[1]) rng.bounds([b[0]-1, b[0]]); // no characters selected; it's just an insertion point. Remove the previous character
  rng.text('', 'end'); // delete the characters and update the selection
bililiteRange.sendkeys['{selectall}'] = function (range, c, simplechar) { rng.bounds('all') };

So to have a reverse-string command:

bililiteRange['{reverse}'] = function (range, c, simplechar){
  simplechar(range, range.sendkeysOriginalText.split('').reverse().join(''));

Or, to annoy the anti-WordPress crowd, a Hello, Dolly command:

bililiteRange['{dolly}'] = function (range, c, simplechar){
  var lyrics = [
    "Hello, Dolly",
    "Well, hello, Dolly",
    "It's so nice to have you back where you belong",
    "You're lookin' swell, Dolly",
    "I can tell, Dolly",
    "You're still glowin', you're still crowin'",
    "You're still goin' strong"];
  simplechar (range, lyrics[Math.floor(Math.random() * lyrics.length)];


After each printing character (not the specials, unless they call simplechar) it triggers a keydown event with event.which, event.keyCode and event.charCode set to the Unicode value of the character.
After the entire string is processed, it triggers a custom sendkeys event with event.which set to the original string.