Category Archives: jquery

musical intervals trainer, web version

last weekend, I wrote an intervals trainer app for practicing recognising intervals.

I want other people to use it, but haven’t got a Google development account yet so can’t upload an app.

So, today, I improved the app and made a web-accessible version.

try it out!

it’s designed to move up from very simple intervals (major/minor 2nd intervals, with only natural notes) to more difficult intervals (diminished/augmented, with double sharps and flats), but it’s also designed to only get more difficult at a rate that /you/ can manage.

to do this, the app uses a “levels” system, where each level has one more extra type of interval or note type, and you are tested on them. over 50% of the time, the question will be from the level you’re on, and the rest of the time, the question will be randomly chosen from every other level that you have already passed.

get 10 in a row correct, and you go to the next level.

but, get 5 wrong in a row, and you go down a level.

at the moment, there are 24 levels – all the way up to augmented 8ths – can you get through all the levels?

give it a try!

separating buttons in jquery-ui dialog

By default, the jQuery-UI dialog will place buttons on the right side of the popup:

This causes a problem because if you have “OK” right next to “Delete”, and you click the wrong one, well …

The obvious solution is to move the “Delete” to the opposite side.

To do that, add the following two lines after creating the dialog:

$('.ui-dialog-buttonset').css('float','none');
$('.ui-dialog-buttonset>button:last-child').css('float','right');

Now the buttons are on opposite sides:

onchange in ckeditor

I needed to track changes to source in a CKeditor instance, as my recent work uses a lot of “on-the-fly” updating.

Using Alfonso’s onChange plugin, it was a simple matter to capture changes when in WYSIWYG mode.

But that doesn’t work in source mode.

Assuming you’re using the jQuery extension for CKeditor (and if not, why not?), you can capture source mode changes by adding this to your CKeditor’s config.js:

$('textarea.cke_source').live('keyup', function() {
  $(this)
    .closest('.cke_wrapper')
    .parent()
    .parent()
    .prev()
    .ckeditorGet()
    .fire('change');
});

jQuery maskImage plugin

I had a need today to write some code which involved masking one image with another, dynamically.

There is no simple way to do this in JavaScript. The nearest I came to finding working code online that does it was edge.js, but that’s not free.

So, I wrote my own.

demo

Download: zip (25k), bz2 (24k)

In the demo, what’s happening is that an image such as this:

is being used as a mask for another image:

to create a masked image:

For Firefox and Chrome and other recent browsers, it works using pure JavaScript (even works on the iPhone).

For Internet Explorer (sigh) you need to do a little bit of server-side setup.

Basically, on the server-side, make sure you have PHP installed, with the iMagick extension, then make the ‘cache’ directory writable by the server.

To use, insert an image into your document:

<img id="image-id" src="an-image.png" alt="" />

And then apply the mask using jQuery:

$('#image-id').maskImage({src:"the-mask.png"});

Simple, innit! That’s a few hours of my own life dedicated to saving a few minutes of yours ;-)

new API for WebME

As I said in the last post, an API would be required to make the system more testable and more consistent.

I started straight away and wrote up something quickly. Over the next week, it solidified into something that appears to cover any needs that I have.

So here’s how the API works:

Requests are sent to a URL which is generated like this:

/a
[/p=plugin-name]
/f=function-name
[/other-parameters]

The plugin name is optional. Leaving it out means you want to call a core function.

Parameters can be added by adding /key=value pairs to the URL.

An example URL might be this:

/a/f=login/email=kae@verens.com

Sending that, with a POST parameter for the password, will log me in.

To log out, I can use this URL:

/a/f=logout

Simple!

Function Names

mod_rewrite is used to direct a request through a script which tears the URL apart into parameters.

If a p parameter is given, the function is named after the plugin, rewritten to match the WebME coding standard.

For example, if the URL is /a/p=comments/f=editComment, then the “comments” part is rewritten as Comments, and ‘_’ and “editComment” are appended to form the function name “Comments_editComment”, which is called and the result returned to the browser.

For double-barrel plugin names, such as “image-gallery”, the name is rewritten to “ImageGallery”.

If no p parameter is given, then the request is a core function, and “Core_” is prepended to the function name.

For example, the login URL above, /a/p=login calls the function Core_login.

If a function name begins with “admin”, it is an admin function (see below for more on this).

File names

If no plugin name is supplied, then the core API file, /ww.incs/api-funcs.php is loaded. This contained common API functions that might be used by any core script or plugin.

If a plugin name is supplied, then the API file is expected to be located at /ww.plugins/plugin-name/api.php for common functions, and /ww.plugins/plugin-name/api-admin.php for admin functions.

For core functions, common functions are at /ww.incs/api-funcs.php and admin functions are at /ww.incs/api-admin.php

Security things

Having a central point for RPC means that we can apply security rules in one place and know that they cover all scripts. Before-hand, I would sometimes come across scripts and realise that they were open for abuse if someone knows that magic URL incantation. I would silently curse myself or whoever had written the script and fix it up. Now, though, having one single point of entry means I can secure everything at once.

If a function name starts with “admin”, then the script checks to see if the user is logged in and is a member of the administrators group. If not, the API will return an error. It’s as simple as that!

Of course, this doesn’t stop abuse by people that are logged in as admins or who are victims of XSS, but it helps stop a few problems caused by developers not noticing their scripts were open to use by anyone at all.

Conclusion

So now, when people are creating new plugins for WebME, the following could be used as a bare-bones directory structure:

/ww.plugins/plugin-name/plugin.php    details, server-side functions
/ww.plugins/plugin-name/api.php       common RPC functions
/ww.plugins/plugin-name/api-admin.php admin RPC functions
/ww.plugins/plugin-name/admin.js      admin scripts in JS

testing KV-WebME

I’ve been working on my CMS for about 10 years. It’s monstrously huge (41,000 lines, not including external libraries), and for most of those 10 years, I’ve been too busy building it to concentrate on niceties such as comments, testing, code formatting, etc.

This has caused problems in the past. As most programmers know, when you change any one thing, it has a ripple effect and can break things in places that don’t seem obvious at all.

Recently I’ve been remedying this. I’ve been religiously using PHPCS to make sure my code is neat and consistent, and I’ve started writing a test suite.

The most difficult part of the testing is that the CMS is composed of many separate technologies. If it was just a plain old HTML and PHP application, then PHPUnit would be enough, or maybe Selenium.

The problem is, though, that the system uses a large amount of AJAX – especially in the administration areas. No single testing system would do it all.

Another problem has to do with AJAX itself. In jQuery, you can speak to the server by writing something like this:

$.post('/a/server/script.php', {
  "id": 2
}, function(res) {
  // do stuff
}, 'json');

This makes it incredibly simple to speak to any server-side script at all on the server, and promotes it. It becomes tempting when writing new functionality to build new server-side scripts specifically for the new client-side stuff.

This has the effect that there is no single point for RPC (remote procedure calls) which can be tested, making it very difficult to be sure you have covered all potential problems.

To help solve this problem, I’ve recently started converting WebME’s coding style so all RPC is done through a single API (application programming interface) script.

This has a few extra effects which are beneficial:

  • Having a single point of entry into the system makes it easier to secure it.
  • Having an API promotes the construction of a solid method of adding functionality to it – there’s no need to start from scratch anymore, potentially building disparate scripts that are hard to abstract. Instead, it’s now easy to force the code to match a minimum spec.
  • APIs tend to have specific rules for how parameters are passed into it, making it easier to remember what the right parameters are when writing new client-side code. Also, it makes it easier to “guess” what the right parameters are if you’ve forgotten.

The main benefit, though, is that it makes it much easier to test. The URL of the API always stays the same, and the only thing that changes is the parameters sent to the URL. Previously, each separate script would have a different URL and could have any parameter scheme at all.

So, currently, I’m writing tests that use the API directly, speaking to the server directly through URL calls. After I’ve finished writing all of those (hah! if ever), I can get on to testing that JavaScript.

2010

I’ve the most awful memory.

While trying to remember what the hell I’d done in the last year, I came up with nothing.

Luckily, I have a spare brain in the form of my facebook friends, who came up with this list for me:

  • I started a new company, KV Sites, which will be up and running properly within a month or so, and will be selling affordable CMS websites and programming.
  • I got grade 2 in piano. I’m still waiting for an examiner for grade 3 (which I wanted to do in September). I’ll be doing grade 4 in March.
  • I got my first grading in Genbukan Ninjutsu.
  • I finished another book, CMS Design using PHP and jQuery. I hope it is as well-received as the previous book, jQuery 1.3 with PHP. btw, Packt would like me to remind people that the book “Mastering phpMyAdmin [...] for effective mysql management” (reviewed here and here) has been updated to version 3.3.x.
  • I am building up to a new release of my CMS, WebME, which, despite the last downloadable version being from early 2009, has actually been very actively updated. It should be ready for release tomorrow, right on time for 2011!
  • I wrote and released two jQuery plugins: k3dCarousel, and SaorFM (which I hope to vastly improve in 2011).
  • I also built a first attempt at a clavichord made from plywood. I’ve got some new tuning pegs and redesigned the keyboard, so will hopefully be able to record on it soon.

I’m hoping 2011 turns out to be awesomer and that my head will be able to remember it all!

jQuery stars plugin

I was asked to replicate a “star” effect, where stars appear in various areas around a page and then disappear after a while. I won’t bother linking to the original site as it will be gone shortly, but this is what I came up with:

demo

To use this on your own site, simply download the script, link to it in your page, then add this piece of JavaScript.

$('body').stars();

If you want to use the star image I created, download it to the same directory and tell the plugin where it is:

$('body').stars({
  "i":"stars.png"
});

3d carousel bug-fix and slight improvement

plugins.jquery.com page.

I’ve improved the plugin slightly. It now pauses when you mouse-over it, I’ve improved the left/right arrows, and I’ve fixed a bug to do with image aspect ratios.

I’ve yet to upgrade the demo. See here for the original description of the plugin

jQuery k3dCarousel plugin

I needed a “3D” carousel to rotate images. The currently available jQuery plugins for this purpose were either too large, too restricted (showing only 4 at a time is not good enough), or too old (not working in jQuery 1.4+).

So I wrote my own.


demo

In our CMS, WebME, this is available in the Image-Transition plugin. (If you’re interested in using WebME, you can either download it through SVN, or talk to us about our reseller deals.)

How the thing works, is that you add a list of images to an element like this:

<div id="k3dCarousel">
	<img src="images/concrawood.jpg" />
	<img src="images/fernheasty.jpg" />
	<img src="images/mcnallys.jpg" />
	<img src="images/northernstandard.jpg" />
	<img src="images/soccertours.jpg" />
	<img src="images/soundinsulation.jpg" />
	<img src="images/textaroom.jpg" />
	<img src="images/windhoist.jpg" />
</div>

Then link to the jQuery library and the jquery.k3dCarousel plugin:

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script src="jquery.k3dCarousel.min.js"></script>

And then tell jQuery to run the plugin after all the images have loaded:

<script>
	$(window).load(function(){
		$('#k3dCarousel').k3dCarousel();
	});
</script>

If you want, you can vary the speed of the cycle by changing the sT (spin-time) variable, or the wT (wait time), which govern how long it takes for the images to move from point to point, and how long they pause once reaching there:

<script>
        $(window).load(function(){
                $('#k3dCarousel').k3dCarousel({
                        wT: 500,
                        sT: 100
                });
        });
</script>

Interested yet? Download it (tar.bz2, zip)