Aurelia TypeScript Samples

multi-level-menu

The multi-level menu sample shows how you can quickly create a hierarchical menu when building an Aurelia SPA website.

The multi-level menu helps users navigate through a hierarchy of pages.

multi-level-menu working

This menu structure and its associated router navigation is easy to configure:

import aur = require("aurelia-router");
import mlmps = require("./MultiLevelMenuPipelineStep");

export class App {
    static inject = [aur.Router];

    constructor(public router: aur.Router) {
        this.router.configure((config) => {
            config.title = "Aurelia VS/TS";
            config.addPipelineStep("modelbind", mlmps.MultiLevelMenuPipelineStep);
            config.map([
                { route: ["", "home"], moduleId: "views/home", nav: true, title: "home", settings: { level: 0, show: true } },
                { route: ["item-1"], moduleId: "views/item-1", nav: true, title: "item 1", settings: { level: 0, show: true } },
                { route: ["item-1-1"], moduleId: "views/item-1-1", nav: true, title: "item 1.1", settings: { level: 1, show: false } },
                { route: ["item-1-2"], moduleId: "views/item-1-2", nav: true, title: "item 1.2", settings: { level: 1, show: false } },
                { route: ["item-2"], moduleId: "views/item-2", nav: true, title: "item 2", settings: { level: 0, show: true } },
                { route: ["item-2-1"], moduleId: "views/item-2-1", nav: true, title: "item 2.1", settings: { level: 1, show: false } },
                { route: ["item-2-2"], moduleId: "views/item-2-2", nav: true, title: "item 2.2", settings: { level: 1, show: false } },
                { route: ["item-2-2-1"], moduleId: "views/item-2-2-1", nav: true, title: "item 2.2.1", settings: { level: 2, show: false } },
                { route: ["item-2-2-2"], moduleId: "views/item-2-2-2", nav: true, title: "item 2.2.2", settings: { level: 2, show: false } },
                { route: ["item-2-3"], moduleId: "views/item-2-3", nav: true, title: "item 2.3", settings: { level: 1, show: false } }
            ]);
        });
    }
}

The level property is used to establish the hierarchy. The show property controls the visibility of the route in the menu. The router navigation pipeline step looks at the target navigation and sets the route visiblity accordingly. The navigation helper provides a button to navigate up a level from the current route, and invokes the corresponding navigation commmand to the router.

Steps to get running:

  1. View running project
  2. Make sure you have Visual Studio 2015: Free Comunity Edition or higher

    TypeScript 1.5 is included in this install.

  3. Run Visual Studio
  4. Open solution in multi-level-menu
  5. Run solution using chrome browser

Some background on the sample:

For this sample, we'll choose to use an existing AMD bundle of the Aurelia libraries and the RequireJS loader.

Lets dive in and look at some code.

Technical Implementation

The level property is used to establish the hierarchy. The show property controls the visibility of the route in the menu. The router navigation pipeline step looks at the target navigation and sets the route visiblity accordingly. The navigation helper provides a button to navigate up a level from the current route, and invokes the corresponding navigation commmand to the router.

Router Pipeline Navigation Step

The step is a class. The step is added to the router configuration.

There is not much to the code for the step. Most of the work is delegated to the utility functions.

import auf = require("aurelia-framework");
import aur = require("aurelia-router");
import mlmu = require("./MultiLevelMenuUtil");

export class MultiLevelMenuPipelineStep {
    run(routingContext: aur.NavigationContext, next: { (): void; cancel(): void; }) {
        var targetRouteIndex = mlmu.MultiLevelMenuUtil.getTargetRouteIndex(routingContext.router, routingContext.plan.default.config.moduleId);
        mlmu.MultiLevelMenuUtil.setForTarget(routingContext.router, targetRouteIndex);
        return next();
    }
}

navigation helper view

<template>
    <button class="btn btn-info" click.delegate="navigateUp()">------^------</button>
</template>

navigation helper view model

import auf = require("aurelia-framework");
import aur = require("aurelia-router");
import mlmu = require("./MultiLevelMenuUtil");

export class MultiLevelMenuHelper {

    public router: aur.Router;

    static metadata = auf.Behavior.withProperty("router");

    navigateUp() {
        mlmu.MultiLevelMenuUtil.goUp(this.router);
    }
}

Utility Functions

code to add a step to the router pipeline