JavaScript

Expandable list component for AngularJS (1.5)

Posted on by  
Richard Rijnberk

For several of my projects I required a list where input items could be dynamically added and removed. Because i saw uses for this over and over i created a component which i'm sharing with you here. The component ended up like the code below. Where i used a template generation function in order to create the ul and li elements. I'm using the angular.element function to create nodes as a method of preference.

function mpExpandableListController(){
    var vm = this;

    vm.add = add;
    vm.manipulatable = true;
    vm.remove = remove;

    // If items was not declared, create new array.
    if(!vm.items) {
        vm.items = [];
    }

    // If the items array is empty, create first item.
    if(vm.items.length === 0) {
        add();
    }

    /**
     * Add an item to the item list.
     */
    function add(){
        vm.items.push({});
        setManipulatable();
    }

    /**
     * Remove an item from the item list.
     * @param item The item to remove
     */
    function remove(item){
        vm.items.splice(vm.items.indexOf(item), 1);
        setManipulatable();
    }

    /**
     * Set the flag which designates that the list may be manipulated.
     */
    function setManipulatable() {
        vm.manipulatable = vm.items.length > 1;
    }
}

/**
 *
 * @param $element The element as declared in the HTML
 * @param $attrs The attributes for said element
 * @returns {string} A template for this component.
 */
function template($element, $attrs){
    var container = angular.element('<ul>'),
        item = angular.element('<li ng-repeat="item in list.items">'),
        footer = angular.element('<li>');

    container.addClass($attrs.universalClass);
    item.addClass($attrs.itemClass);
    footer.addClass($attrs.footerClass);

    item.html($element.find('item').html());
    footer.html($element.find('footer').html());

    container.append(item);
    container.append(footer);

    return container[0].outerHTML;
}

var mpExpandableList = {
    bindings: {
        footerClass: '@',
        itemClass: '@',
        items: '=',
        universalClass: '@'
    },
    controller: mpExpandableListController,
    controllerAs: 'list',
    template: template
};

angular
    .module('my.project')
    .component('mpExpandableList', mpExpandableList);

Continue reading →

Easy installation of Karma (Testacular) test runner on Windows

Posted on by  
Emil van Galen

NOTE: this post was written for Karma 0.8 which required a manual installation of PhantomJS.
However this blog post is still relevant for installing the NodeJS and NPM pre-requisites.
As of 0.10 both PhantomJS and Chrome will be automatically installed by the launcher plugins.
Installation instructions for Karma 0.10 can be found here (a "Local installation" is preferred).
Furthermore instructions on how to install plugins (introduced as of 0.10) can be found here.

Recently I decided to switch from the “Jasmine Maven Plugin” (using the Mozilla Rhino JavaScript “emulator”) to the Karma (previously called Testacular) test runner. The big advantage of Karma opposed to the “Jasmine Maven Plugin” is that it uses actual browsers (like Chrome, Firefox, Safari and even IE) to execute the tests. This blogpost describes the installation and configuration of Karma on Windows. To install Karma you first need to install NodeJS and its NPM (NodeJS Package Manager). Additionally you could install PhantomJS, a “headless” web-kit browser, to run your JavaScript tests from the command-line without spawning unwanted browser windows. Instead of using PhantomJS as a replacement for testing against real browsers you could use it to run tests on your local development machine while your continuous integration server could then run your tests on “all” relevant browsers.

Continue reading →

Safe-guarding AngularJS scopes with ECMAScript 5 "Strict Mode"

Posted on by  
Emil van Galen

Having a history as a Java developer I prefer declaring the complete JavaScript object at once through an object literal; in a similar fashion as your would declare a class in Java. In my opinion adding new properties "on the fly" to a JavaScript object is a very bad practice:

var jsLibrary = { name: 'AngularJS' };
// adds a new property "homepage" to the existing object...
jsLibrary.homepage = 'http://www.angularjs.org/';

Continue reading →

shadow-left