Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

bootstrap material design and Aurelia

I have been working on this for awhile and I cannot get this working, I am about ready to throw the computer out the window!

Using Aurelia's skeleton-nav install bootstrap-material-desing using jspm install bootstrap-material. Then add it as an import below bootstrap in your app.js

import 'bootstrap';
import 'bootstrap/css/bootstrap.css!';
import 'bootstrap-material';

@inject(Router)
export class App {

The css and js import fine, but initializing the js is where the problem comes in. You initial it by calling $.material.init(), this code adds ripple effects so when you click on a button you get a ripple or wave like animation and this is where the problem comes in, getting $.material.init() to work in Aurelia correctly

1) After some help on gitter you can use the attach() callback to run this code but this only works per class, so each page/class I would have to add

//attached() {
//    $.material.init();
//}

As an alternative to the above someone on gitter suggested using the router pipeline to call it, I tried this and still could not get it to load on each page, when adding it to the pipeline following the docs I added like this

config.addPipelineStep('modelbind', BSMaterial);

then

class BSMaterial {
    run(routingContext, next) {
        $.material.init();
      console.log('bsmaterial fired');
        return next();
        //
    } }

This works partially, if you click on the navigation links then you get the ripple effects, but try clicking on the submit button no ripple effects, so it seems not to be applying to each class but just the router, I guess

Another problem is with another effect of bs material, you can add a css class to an input control called

floating-label

, then when you click on the input control the placeholder text moves up and then on lost focus it moves back down, but with Aurelia you can see the placeholder text is already moved up. If you remove the value.bind, ie remove value.bind="firstName" then the placeholder animates as it should both on onfocus and lostfocus, so something is happening with value.bind that is interfering.

It can't be this difficult to get something as simple as this material design jquery plugin to work, I am not even trying to interact with Aurelia yet, I just want it to work like you would adding it to a normal html page via script tags. I know it's me just not understanding Aurelia yet.

Any help getting this working would be great.

Current app.js trying to use the pipeline method

import {inject} from 'aurelia-framework';
import {Router} from 'aurelia-router';

import 'bootstrap';
import 'bootstrap/css/bootstrap.css!';
import 'bootstrap-material';

@inject(Router)
export class App {

    constructor(router) {
        this.router = router;
        this.router.configure(config => {
            config.title = 'Aurelia';
            // config.addPipelineStep('authorize', AuthorizeStep); // Add a route filter to the authorize extensibility point
            config.addPipelineStep('modelbind', BSMaterial); // Transparently creates the pipeline "myname" if it doesn't already exist.
            //  config.addPipelineStep('modelbind', 'myname'); // Makes the entire `myname` pipeline run as part of the `modelbind` pipe
            config.map([
                {route: ['', 'welcome'], moduleId: './welcome', nav: true, title: 'Welcome'},
                {route: 'test', moduleId: './test', nav: true, title: 'Test'},
                {route: 'flickr', moduleId: './flickr', nav: true},
                {route: 'child-router', moduleId: './child-router', nav: true, title: 'Child Router'}
            ]);
        });
    }
}
class AuthorizeStep {
    run(routingContext, next) {
       // debugger;
        //   debugger;
        // Check if the route has an "auth" key
        // The reason for using `nextInstructions` is because
        // this includes child routes.
        if (routingContext.nextInstructions.some(i => i.config.auth)) {
            var isLoggedIn = /* insert magic here */false;
            if (!isLoggedIn) {
                return next.cancel(new Redirect('login'));
            }
        }

        return next();
    }
}
//attached() {
//    $.material.init();
//}
class BSMaterial {
    run(routingContext, next) {
        $.material.init();
      console.log('bsmaterial fired');
        return next();
        //
    }
}

welcome.html

<template>
  <section>
    <h2>${heading}</h2>

    <form role="form" >
      <div class="form-group">
        <label for="fn">First Name</label>
        <input type="text" value.bind="firstName" class="form-control floating-label" id="fn" placeholder="first name">
      </div>
      <div class="form-group">
        <label for="ln">Last Name</label>
        <input type="text" value.bind="lastName" class="form-control floating-label" id="ln" placeholder="last name">
      </div>
      <div class="form-group">
        <label>Full Name</label>
        <p class="help-block">${fullName | upper}</p>
      </div>
  <a href="javascript:void(0)" class="btn btn-default">Default</a>
    </form>
  </section>

</template>
like image 590
dan Avatar asked Mar 17 '23 06:03

dan


1 Answers

as of this github issue bootstrap-material can use arrive.js to initialize dynamically added elements. I've tried it with the navigation-skeleton app and it worked for me (tried form buttons and floating labels).

Following the navigation-skeleton structure, I've just imported it into main.js:

import 'bootstrap';
import 'uzairfarooq/arrive';
import 'FezVrasta/bootstrap-material-design';

Then initialize bootstrap-material in app.js in the attached callback:

export class App {
    configureRouter(config, router){
        config.title = 'Aurelia';
        config.map([
            { route: ['','welcome'],  name: 'welcome',      moduleId: 'welcome',      nav: true, title:'Welcome' },
            { route: 'users',         name: 'users',        moduleId: 'users',        nav: true, title:'Github Users' },
            { route: 'child-router',  name: 'child-router', moduleId: 'child-router', nav: true, title:'Child Router' }
        ]);

        this.router = router;
    }
    attached() {
        $.material.init();
    }
}

See if it helps. :-)

Regards, Daniel

edit: arrive.js makes use of Mutation Observers (see the link for browser compatibility) - this could be an issue with IE <11. There are polyfills for that, which I have not tried yet. For example: megawac/MutationObserver or Polymer/MutationObservers

like image 146
Daniel Avatar answered Mar 23 '23 06:03

Daniel