Collapsible Table module

Last week I was given the task to create a collapsible datatable, which confronted me with some oddities in the dom which I wasn’t aware of.

Get the example at github-collapsible-table

I had given myself the following requirements

  • The code needs to be extensible
  • The table should be just a table, no extra markup
  • It should be easy to rewrite the table for a framework
  • Keep it simple
  • No jQuery

simple collapsible table

Vertical table headers

My first attempt was css transforms, easy to adjust and to implement. However the problem was that I needed extra markup to keep the header in the normal page flow. After some consideration is seemed to me that SVG is the best option, it is scriptable, stylable and it maintains the normal paqe flow. See the snippet below

<th>
  <svg xmlns="http://www.w3.org/2000/svg" width="16" height="150">
    <text text-anchor="end" transform="rotate(90, 12, 0) translate(160,10)">Vertical header
    </text>
  </svg>
</th>

cellIndex to the rescue

I needed to have a proper way to get track of the current clicked cell and it column index. Luckily JavaScript provides a native property element.cellIndex.

Rowspan messing up

One thing to notice is that each subsequent rowspan decreases the cellIndex by one. This needs to be compensated for, in the main script loop. The script loops through all the toggle elements and creates an array with their corresponding cellIndexes. On toggle click these cellIndexes are used to get the cells between two toggle elements and push them into an array. This array can be used to manipulate the cells ( hide/ show ).

Disadvantages

Since each cell is manipulated independently it is not possible to create an block animation. If that is a requirement than markup should be added to create containers for the cells.

React (Redux) Github Browser

After reading the documentation and having watched some of the excellent egghead.io videos about redux I wanted to create something to get a deeper understanding. My main goal was to create a simple application, with some sort of API connection. To keep it simple (read no authentication), I chose for the github connection.

Result

The result, is a simple github-browser. Enter a username to receive a list of repos, click one of the repos to view the repo details and urls.

github-browser

React Redux experience

I still have lot to learn, but I do have a deeper understanding about Redux and I can see the advantages of the immutable states in Redux. It will be more easy to grasp a complex application because of the single state. Besides reduced complexity it will also be more easy to implement cool functionalities like ‘undo delete item’. I would advice to invest in es6 (spread operator and class ) before diving into Redux. You can watch the source and clone it here.

https://github.com/jeroenoliemans/github-browser

Message queue class

Recently at work I needed to implement a message queue. I like the pattern and I think I will need it more often in the future. I recreated the message queue with a class for personal reference and study purposes.

message-queue

I absolutely like some of the new features: for example proper ‘this’ binding with the arrow functions and parameter defaults in function.

Code

you can see the full code below, or get the example from my github account

/**
 * MessageQueue create notification messages
 */
class MessageQueue {


    /**
     * constructor optional container and delay
     */
    constructor(container = document.getElementById('messageContainer'), delay = 5000) {
        this.messageQueue = [];
        this.container = container;
        this.delay = delay;
    }

    clearMessages() {
        this.container.innerHTML = '';
    }

    displayMessages() {
        let messageFrag = document.createElement('div');

        // clear
        this.clearMessages();

        for (let index = 0; index < this.messageQueue.length; index++) {
            let message = document.createTextNode(this.messageQueue[index].text);
            let flash = document.createElement('div');

            flash.classList.add('flash-message');
            flash.classList.add(this.messageQueue[index].msgType);
            flash.appendChild(message);

            messageFrag.appendChild(flash);

        }
        this.container.appendChild(messageFrag);
    }

    remove() {
        this.messageQueue.shift();
        this.displayMessages();
    }

    /**
     * add messages optional type (CSS class)
     */
    add(message, type = 'error') {
        let msg = {
            text: message,
            index: this.messageQueue.length,
            msgType: type,
        };

        setTimeout(() => this.remove(), this.delay);

        this.messageQueue.push(msg);
        this.displayMessages();
    }
}

Feel free to modify and extend the code, to run the code you need to install babel-cli and run the following watch statement

babel messagequeue.js --watch --out-file messagequeue-compiled.js