jQuery

If you want to implement some logic when a user clicks outside of an element (e.g. closing a dropdown), the most use solution is to add a click listener on both the document and the element and prevent propagation in the click handler of the element e.g.:

If you use other libraries with add their own click handlers, it might break some of the functionality when stopping event propagation (see this article for more info). In order to implement this functionality in a way which doesn’t mess with the event propagation, you only need a click handler on the document and check whether the click target is the element or one of its children e.g. using the jQuery function closest:

If you want to avoid jQuery and implement it in a pure JavaScript way with no additional dependencies, you can use addEventListener to had an event handler on the document and implement your own function to replace closest e.g.:

The findClosest function just checks whether the provided function returns true when applied to the element and if not recursively calls itself with the parent of the element as parameter until there no parent.

If instead of using the element id, you want to apply this to all elements having a given class, you can use this function as second argument when calling findClosest:

I’ve been using AngularJS for some time now and find declarative templates, the testability and dependency injection great.What I especially like is that the fact that AngularJS prescribes and dictates quite a lot, you are forced to bring some structure to the code of your application. This tends to reduce the velocity of the degeneration you often observe in larger JavaScript projects, where chaos slowly takes over.

But one of the things which was bothering me was that I always ended up adding some libraries/modules and forgetting to add them to my index.html. And sometimes after the list of loaded scripts grew quite a lot, figuring out where to insert this new script tag is really a pain.

Introducing RequireJS

So I decided some time ago to start using RequireJS to bring order in what was slowly becoming a mess. RequireJS does exactly what’s missing when you only rely on the AngularJS dependency injection: a file loader which supports dependencies and a way to define dependencies non-angular scripts (plain old JavaScript files).

Defining your AngularJS modules as RequireJS AMD modules with dependencies just means wrapping them in a call to the define function e.g.:

You also need to manually bootstrap your application to make sure that RequireJS loads all required dependency first. This is done by removing the ng-app attribute from your index.html and instead calling angular.bootstrap in main.js e.g.:

This will load AngularJS, then load your app and then bootstrap your application.

Introducing RequireJS is actually quite some work (if all your files and modules are already there) but not really complex. The main issue I have faced was that there is no explicit dependencies between AngularJS and JQuery, so they might be loaded in any random order. If AngularJS is loaded before jQuery, it will revert to using jqLite which is definitely not sufficient for jQuery UI. This will lead to strange errors occuring. So what you need to do is make sure that jQuery is loaded before AngularJS. This can either be done by setting priorities in your RequireJS configuration (only works with RequireJS 1.x) or by making jQuery a dependency of AngularJS (in the shim section of RequireJS 2.x – see example above).

OK, after all small problem were solved and my application was running again, I looked back at what I had done and realized that even though I didn’t ever had to add a script tag to my main HTML file, it wasn’t yet as great as I thought it would be before I started moving to RequireJS. First, I still have to manage dependencies on 3 levels:

Dependencies between files i.e. file load order

Dependencies between AngularJS modules

Dependencies to individual controllers or providers

The first kind of dependencies is now managed by RequireJS instead of having me manage it in index.html. The other two have not changed.

Moreover, my application still looked like a big monolithic application at runtime since even though the file load order was now computed by RequireJS based on dependencies, I was still loading all files and interpreting them at application start. No matter whether some modules, controllers, directives… might only be needed much later or for specific users not at all.

Introducing Lazy Loading

So I started looking into lazy loading. Luckily I quickly realized that the step introducing RequireJS in my application hadn’t been useless. It is indeed possible to lazy load controllers, directives and such in AngularJS without resorting to using RequireJS. But you then need to manage the JavaScript files containing them and their dependencies to external libraries manually. With RequireJS, all you need to do to have all required files loaded before registering the lazy loaded controllers, views and such is to wrap it all in a require call.

There are different levels of lazy loading which can be achieved in AngularJS (having different levels of difficulty and restrictions).

Dynamically Loading Controllers and Views

The first level of lazy loading is dynamically loading controllers and views to an already loaded AngularJS module. To associate views with controllers, you would typically put your routing code in a module’s config function:

This means that everything will be loaded at once at runtime using the $routeProvider object. The referenced controller must have already been registered or you will get an error while defining the routing. Lazy loading the views (i.e. the referenced template URL) is supported out of the box but the JavaScript code for your controllers needs to be loading upfront.

To allow lazy loading, you will need to use the resolve property (additionally to the templateUrl) and also make sure that your controllers are properly registered once the JavaScript file is loaded. So using RequireJS to load the scripts and their dependencies, your code would look like this:

This makes sure that your controller doesn’t need to present immediately but that the resolver function will be called when this route is activated. The resolver function returns a promise we create using $q.defer. In order to load all required files and AMD modules, we wrap the logic in this function in a require block. Once the loading of the script and all dependencies is done, our callback is called which just resolves the deferred object.

Now, there is still a problem. All files will be loaded but you won’t be able to use the new controllers because they were created after startup. In order to have them properly registered, you will need to overwrite a few functions of your angular module to use compiler providers (such as $controllerProvider) instead (this needs to be done before using the $routeProvider). So you’re application js file would look like this:

Now you will see that when you activate this view, not only the HTML template file will be loaded on the fly, but also the JavaScript file containing your controller. And your controller will be accessible from the view.

This approach works well and doesn’t require much additional code but it only works if the controller you’re lazy loading is controller on an existing module. And even if it is the case, you’ll notice it doesn’t work that well, when the controllers you are lazy loading bring their own dependencies (other modules with controllers and directives).

Registering AngularJS modules dynamically

So to have a more robust and versatile solution, we need to be able to register and activate AngularJS modules dynamically (and the modules on which they are dependent).

In order to do it, we first need to understand what happens when you load a new module at startup. A module contains the following data which are relevant when you want to dynamically activate it:

A list of dependencies: module.requires

An invoke queue: module.invokeQueue

A list of config blocks to be executed on module load: module.configBlocks

A list of run blocks to be executed after injector creation: module.runBlocks

When a module is registered, AngularJS checks whether all referenced modules are available.

Whenever you call a function on your module (e.g. config, run, controller, directive, service…), it just pushes the provided function to a queue. In case of config, the queue is module.configBlocks. For run, it goes to module.runBlocks. For the others, it’s module.invokeQueue.

On module load, AngularJS will concatenate the run blocks (but without executing them yet), run the invoke queue and then run the config blocks. Once the modules are loaded, all run blocks will be executed.

When loading modules dynamically, the phase when modules are usually loaded is over, so even though the JavaScript files are loaded by RequireJS, the modules will not be properly initialized. So we just need to perform manually what’s usually done automatically by AngularJS.

Module Dependencies

So the first step is to make sure that modules on which this module is dependent are activated first. So the function to load a module would start like this:

Registering pluggable views

Now that we can we can register modules dynamically, we’re only one step away from defining views which can be plugged into our application. Imagine you have an application, with multiple views showing different (possibly unrelated) data. If you want others to be able to extend your application, you need to provide a way to define a pluggable view and load all such views setting the appropriate routes and providing some model which can be used to display the corresponding navigation links.

In order to store all data required for configuring the routing and creating the navigation links, we’ll be using an object (viewConfig). The routing (assuming you’re using ngRoute) is then configured this way:

viewConfig.viewUrl: it’s the relative routing URL e.g. “/admin”
viewConfig.templateUrl: it’s the relative URL for the HTML template of the view e.g. “views/admin/admin.html”
viewConfig.controller: it’s the name of the controller for the view e.g. “AdminController”
viewConfig.navigationText: it’s the text displayed on the navigation link e.g. “Administration”
viewConfig.requirejsName: it’s the name of the RequireJS AMD module e.g. “admin”
viewConfig.requirejsConfig: it’s the object to be added to the RequireJS configuration e.g. { paths: { ‘admin’: ‘views/admin/admin’ } }
viewConfig.moduleName: it’s the name of the module being loaded e.g. “app.admin”
viewConfig.cssId: it’s the ID of the link tag created to load the CSS stylesheet e.g. “admin-css”
viewConfig.cssUrl: it’s the relative URL of the CSS stylesheet file e.g. “views/admin/admin.css”

In order not to have to define all these parameters every time we call the function to register the view, we’ll first define some defaults to be set when some of these parameters are not explicitly set:

Since the way the navigation links are displayed pretty much depends on how you do it in your markup, our provider will not do it itself but just store the corresponding information and provide it through the provider:

In this example, the pluggable views registered are hardcoded in my application but having a separate file containing the view configuration is fairly easy and would be a way to make your views truly work as plugins.

So that’s it for this post. We’ve build an provider which allows us to register views on the fly considering their dependencies and allowing the navigation bar or panel to be extended. Of course, you’ll still need to add some error handling, some logic to make sure that modules you depend on do not get activated multiple times… But this is all for a next post.

Note that this currently only works with Firefox. Support for Chrome and Internet Explorer is not yet available and it’s not yet known when it will be available.

The new Battery Status API allows you from a web page to access information about the battery status of the device rendering it. It is not only useful in order to show the current status but to implement battery status dependent logic e.g. increasing polling interval using Ajax or disabling animations in order to preserve the battery, or auto-saving in case the device goes out of power, prevent the user from performing long running operation which might not be able to finish because of the low remaining battery level.

First we’ll create the HTML and CSS in order to get an empty battery display looking like this:

The HTML code couldn’t be simpler. We just need a battery div:

<div id="battery"></div>

Now we need to display a border around the div and a smaller rectangle after it:

By setting the width of .battery-level in pixels (or in percent which is the same since the element is 100 pixels wide) to the battery level in percents, we’ll get the right display:

Of course, one would expect our battery level display to show the level in a different color depending whether the battery is almost empty or not. So let’s introduce three CSS classes which will show the level in green, yellow or red:

In CSS, I can set the style of the first cell and of the last cell of each row like this:

div.tr div:first-child { }
div.tr div:last-child { }

To select them with jQuery:

jQuery("div.tr div:first-child")
jQuery("div.tr div:last-child")

Easy, right ? So where’s the problem ?

Well the problem is that is that it only worked by chance and as soon as I extended the generated html code, it broke. I needed to add some additional divs at the end of every line in the grid but have them be invisible. So basically, since the new divs where invisbile, the current last div would still have to be styled in a special way although it wasn’t the last div child anymore. So I just modified my CSS and jQuery selectors like this:

div.tr div.td:last-child { }

jQuery("div.tr div.d:last-child")

And the same for th as well. But it doesn’t work. What happens is that div.tr div.td:last-child doesn’t mean select the last child of div.tr being a div.td. It means select the last child of div.tr if it is a div.td. So since the last child of div.tr was not a div.td anymore, it failed.

So what I needed was a selector like :last-child-of-type. Well actually there is a selector :last-of-type. Unfortunately, it also failed using it since this selector doesn’t work with classes i.e. you can use div:last-of-type as selector but not div.class:last-of-type. So :last-of-type is useful to select the second div in this case:

But not in our case. So what can be done ? Well, the way I went for (which just involved replacing an append by a prepend) was to move the hidden divs to the beginning of the row. So now I could use :last-child again. And since I was selecting the first line only with jQuery, I used the following:

So it’d be great if :last-of-type could support classes or if there was a :last-of-class. But until there is, you can work around it with jQuery using a loop. In CSS, unfortunately, there seems to be no way to do it. The only way to select this last element of a type using CSS selectors is to assign it a class with javascript or while generating the HTML code and then selecting this class using CSS.

Well, this will not work. The condition will always return false and you’ll never see that the checkbox is checked.

There are a few different ways to get this piece of information. Instead of “$(this).attr(‘checked’)”, you can use any of the following conditions.

First “checked” is not an attribute of our checkbox but a property. In some versions of jQuery, calling attr(‘checked’) will return true/false, in others it will return checked or not and in others it will return the checked attribute set when creating the checkbox. Here a table from the jQuery documentation:

So since it’s not actually an attribute but a property, the obvious solution is to use the prop function:

if ($(this).prop('checked')) {...} else {...}

Since checked is a property, you can also get the first object returned by $(this) and evaluate the checked property:

if ($(this).get(0).checked) {...} else {...}

While at it, you can switch back to a pure JavaScript solution:

if (document.getElementById('mycheckbox').checked) {...} else {...}

Another option is to use the :checked selector:

if ($(this).is(':checked')) {...} else {...}

Or if it looks to simple and you like it more complex:

if ($('#mycheckbox:checked').val() !== undefined) {...} else {...}

Well, I guess I’ve shown you enough different ways to do this. You just have to choose which one you like best. My personal favourite is using the prop function. But I guess the more pure JavaScript, the faster but I doubt your users will ever notice the difference (except if they have to work with millions of checkbox but in this case I’d sue your UI designer).

Unfortunately, this does work in Firefox but not in Internet Explorer (the click is not triggered). For it to work in Internet Explorer, you need to use keydown instead of keypressed. So I changed it to look like this:

Now it works in IE and Firefox. The only problem left was that in Firefox, the event is further propagated. In this case, the search box is activated.

I first thought I needed to add an event.preventDefault() and/or event.stopPropagation() but it didn’t help. The trick is actually to add a keypressed event handler which will return false if Ctrl-E is pressed:

Checkboxes are kind of the most boring elements on a web page since the browsers always display them the same. Another problem is that the checkbox itself is pretty small. Of course it’s not a real problem for such checkboxes:

Please send me more spam

You can click on the checkbox itself or on the label to toggle it. So the small size of the checkbox itself is not an issue. But when you have something like this, it’s more of a problem:

Identification code:

Display name:

Activated:

Even if you wrap the checkbox in a label for it, you can still click anywhere near the checkbox to toggle it but it’s not visible to the user that it’s possible.

A better solution would be to have some alternative representation of the checkbox e.g. as a switch. It’s also important to be able to adapt the size of the switch. Here’s how it should look like in the end (the first one is the normal size and the second one is twice as large):

Since you cannot style the checkbox itself, we’ll have to add a new element and hide the checkbox. Additionally, since some scripts will read the state of the checkbox, we need to keep the checkbox in there (even if not displayed) and we need to make sure that the state of the switch and the state of the check are in sync.

The easiest way to do it is to use a label. As can be see above if a label is created for a checkbox, clicking on the label toggles the checkbox. So the basic idea is to:

add a label for the checkbox

hide the checkbox

style the label to look like a switch

have a styling of the label based on the state of the checkbox

For the last point, we’ll leverage a special kind of CSS selector which selects elements that are placed immediately after a given element. This is done with a plus sign between the two elements:

input[type="checkbox"] + label

This would select the labels immediately following a checkbox. Using this we can style the labels depending on the state of the checkbox.

So first we need some HTML to have a checkbox:

<input class="switch" id="check1" type="checkbox" />

Note that I’ve used the class “switch” in case you do not want to turn all checkboxes into switches but only some of them. If you do want to turn them all into switches, just remove this class from all selector in the CSS and jQuery code in the rest of this post.

Your checkbox should also need to have an ID to be referenced by the label. Now let’s add the label dynamically using jQuery:

I’d rather use JavaScript and CSS pseudo-classes than polute my HTML code with elements which are only needed for styling. But I guess others may see it in a different way and rather use pure CSS and HTML than introduce some JavaScript.

Now we have this all in place, we just need to style the checkboxes and labels. An easier way to do it would be to use a background image. But I tend to avoid using images except for icons. And also if the element has to have a variable size, I definitely try to avoid images. The goal in this post is anyway no do show you how to make nice looking backgrounds with CSS only so we’ll stick to a plain two color background.

The first step is to hide the checkboxes we’ll turn into switches:

input[type="checkbox"].switch {
display: none;
}

Now we want the label to look like a switch, so have a border, be rounded on the left and right and have a background color depending on its state (e.g. red for not checked and green for checked):

The inline-block is a great invention. For those who still don’t know it, it’s a kind of float on steroids. It means it handles width and height just like a block element. But is displayed inlined with the surrounding elements just like inline elements. So this means that the label will have a width and height although it doesn’t have a text and that the round element we’ll add afterwards will be displayed in it.

Note that we’ve defined the width in ems. This allows us to make the element scale when we increase the font size.

Now, we’ll use pseudo-classes to dynamically add a round element which will be moved from left to right when the checkbox is checked:

So the content is empty because we do not want to display some text but only have a background and borders displayed.

box-sizing is used so that the width and height defined do already contain the borders. We want this element to be half the width of the containing label and to be round (so same height and width). Since the width of the label is defined in ems, the height and width of this element also have to be defined in ems. But since we need the border to always be 1 pixel (defining it also in ems makes it look terrible when the size is increased), we should define the width and height to be 0.8em – 1px. This is not possible. So we use box-sizing to say that the 0.8em already contains the border.

Note that box-sizing, requires a prefix for all versions of Firefox (both mobile and desktop) and required a prefix for Safari until version 5.0, for iOS Safari until version 4.3, for Blackberry Browser version 7.0, Android Browser until version 3.0. Also not that Internet Explorer version 7.0.

When the checkbox is checked, we want to change the background color and move the round element to the right. Changing the background color is easy. The trick to move it to the right is to add a padding to the label. But adding the padding will make the label larger so at the same time we have to reduce the width of the label:

This means that when changing the padding and width the transition will be distributed over 300 milliseconds. You could also add the change of background color but I felt it looks kind of strange because it looks like it changing to some kind of brownish color between red and green. Also, for this CSS property there are also browser specific prefixes:

I’m currently working on a new software and I am working on both an administration page and a home page for the software. I also made a login page. Currently the login page looks kind of strange because it basically only has a few elements and takes up almost the whole screen (except a header, a navigation bar and a footer). So the screen is much too big for the few elements I have in there. So I decided to move the login page to a floating login dialog which is much smaller and thus looks better. Here is a short tutorial how to build such a dialog with HTML, CSS and jQuery.

First, you need to understand what dialogs in this context are. Dialogs are usually implemented in such a way that you have an HTML element floating on top of the page. In order to have it not displayed in the page or below the page, you need to define a z-index which defines where the element is displayed on the Z axis. This is done in CSS with the following:

Here a short explanation about the different CSS properties set above:

display: none => the dialog is not displayed when you open the page containing it but only when you click on some login link.

left: 50% / top: 50% => we want to have the dialog centered on the screen. This defines that the top left corner of the dialog will be in the middle of the screen. This means we’ll have to add some negative left and top margins when we display the dialog in order to have the middle of the dialog centered (the exact offset of course depends on the height and width of the displayed dialog.

position: fixed => this means that the position of the dialog doesn’t depend on the position of other elements but has a fixed position on the screen. Also note that the default value for position is static and with this set, the z-index will be ignored. So it’s important to set it to fixed.

z-index: 99999 => All elements with a z-index smaller than 99999 will be displayed below the dialog. If elements have no z-index defined, they inherit the z-index of their parent and if none is defined for any element, they all have a z-index of 0.

To make it look nicer, we’ll also had the following to the CSS for .dialog_popup:

To go from the top left corner to the middle of the dialog, we’re defining a negative top and left margin corresponding to half the height and width of the dialog. We also add 4 pixels to the height and width because of the 2 pixels border on all 4 sides of the dialog.

If you want the dialog to be displayed faster, you should reduce the 200 parameter in the fadeIn call. If it’s too fast for you, increase it.

Now that everything looks nice, we’ll also add an overlay below the dialog, so that we can make the page under the dialog darker. This way it is clear to the user, that he/she has to focus on the dialog and not the page in the background anymore. So first we need to add a div for the overlay e.g. after the definition of the dialog:

<div id="dialog-overlay" title="Click here to close the dialog">

This overlay is also hidden when the page is first displayed (just like the dialog itself) and will be displayed when the link is clicked. The overlay should cover the whole page, be dark and semi-transparent.

This makes the page in the background still visible but not really readable. If it’s too dark for you, just reduce the opacity: 0 means transparent, 1 means opaque (i.e. the page is not visible anymore).

Now that we’ve defined the overlay below the dialog, we need to have it display at the same time as the dialog itself. This is done by adding the following line just above the similar line making the dialog appear:

$('#dialog-overlay').fadeIn(200);

And we want both to disappear when the close button is clicked. Actually we also want both to disappear when you click on the overlay (so outside of the dialog). It is easy to do it with jQuery:

Now I wanted to have the active page somehow highlighted so that the user can clearly see where he is. So first I defined some styles for this highlighting (basically just making it bold and underlined):

So what I needed now was some JavaScript to check the currently loaded URL and check which of the navigation links should be highlighted. All URLs start with http://localhost/demo/index.php. So I just needed to check the 4th part of the location path, find the navigation link related to that (so basically the link which ends with the same 4th part). Additionally if you go to http://localhost/demo/index.php you are shown the Home page even though the URL doesn’t end with /home. So I also needed to handle this special case.

So first I needed a JavaScript function to get the last part of the URL. Here I just needed to split the path using a slash as a separator and get the last one. There is just one exception: if the URL ends with a slash, I do not get the last one but the second to last (so that I do not get an empty result):

It basically says to find a link in the navigation (i.e. nav a) having a href attribute (i.e. nav a[href…]) ending with (i.e. href$=) “/home”.

Of course if your URLs look different e.g. if you have query parameters or it is not the last part of the URL which is relevant for the link selection, you’ll need to adapt the getLastPart function. If it is not the last part of the URL which is relevant, you’ll also need to use a different selector.

I needed to have a very lightweight and easy to use javascript table filter. The idea was to add a second row to the table header (below the column names) and have there a text input in each cell of this new row. When you write something in there and press Return, it will filter out all rows not containing this string in this particular column. You should also be able to combine filters for different columns.

Let’s implement it as a jQuery plugin. First we need a name… We’ll call the file jquery.filtertable.js and the function we define in the plugin will be filtertable:

Second, the name of the column where the filter string will be searched for

Of course using the column name is not always a good idea. It’s be better to use an ID or an index. An index is kind of difficult to use especially if columns are moved around. And since the column might not have an ID but will most probably have a name/header, I went for the name.

So the first thing we need to do is to map the column name to an internal index:

We use cookies to personalise content and ads, to provide social media features and to analyse our traffic. We also share information about your use of our site with our social media, advertising and analytics partners.OkRead more