19 Feb 2015

Exploring Boostrap Angular UI components

Default blog image

By Philippe Leefsma

AngularJs is starting to impose itself as the reference JavaScript framework to develop SPA - Single Page (Web) Applications. And probably for a reason, that stuff acts like magic :)

Boostrap, another world famous framework for building websites, allows you to quickly create nice looking UI components.

I'm working on building a demo website featuring our viewing technology entirely relying on Angular-friendly components, so today I'm taking a look at two Bootstrap libraries offering Angular UI directives:

    - UI Boostrap

    - AngularStrap

Both offer some pretty cool UI components and you can directly test them on their webpage, which makes it very explicit to see what you can achieve.

I decided to pick up one and integrate our viewer in it to see how they can get along: a nice one is the Bootstrap UI Carousel, a component that displays a collection of slides rotating on a timer. You can see a plunker demo of the carousel there. Not that I don't like kittens, but I think 3D models on the web are cooler ;)

The integration ended up being more challenging and instructive than I initially thought. Here are the highlights of the sample:

Following code illustrates how to perform a jsonP call from the angular controller:

 1 //jsonP call to get total number of models in the Gallery
 2 function getGalleryModelCount(onSuccess) {
 4   var url = 'http://gallery.autodesk.io/api/models/count';
 6   $http.jsonp(url + "?callback=JSON_CALLBACK").
 7         success(function(data, status, headers, config) {
 8             onSuccess(data.count);
 9         }).
10         error(function(data, status, headers, config) {
11             console.log('Error: ' + status);
12         });
13 }

This is needed because invoking the Gallery REST API from a different domain requires a cross domain call. Also needed, the activation of cors and jsonp on my node.js server:

 1 var app = express();
 3 //CORS middleware
 4 var cors = function (req, res, next) {
 6     res.header("Access-Control-Allow-Origin", "*");
 8     res.header("Access-Control-Allow-Headers", 
 9       "Origin, X-Requested-With, Content-Type, Accept");
11     res.header('Access-Control-Allow-Methods',
12         'GET,PUT,POST,DELETE');
14     next();
15 }
17 app.use(cors);
19 app.set("jsonp callback", true);

An angular filter is also required because I bind the iframe ng-source to a scope.member, so the url as to be trusted...

1 // needs that filter to bind iframe ng-src to scope member
2 app.filter('trustAsResourceUrl', ['$sce', function($sce) {
3     return function(url) {
4         return $sce.trustAsResourceUrl(url);
5 }}]);

Just for fun, I wanted to set up a listener for the carousel slide changed event, that thread gives a pretty exhaustive solution:

 1 // a directive to watch carousel slide changed event
 2 app.directive('onCarouselChange', function ($parse) {
 3     return {
 4         require: 'carousel',
 5         link: function (scope,
 6                 element,
 7                 attrs,
 8                 carouselCtrl) {
 9             var fn = $parse(attrs.onCarouselChange);
10             var origSelect = carouselCtrl.select;
11             carouselCtrl.select =
12                 function (nextSlide, direction) {
13                   if (nextSlide !== this.currentSlide) {
14                         fn(scope, {
15                             nextSlide: nextSlide,
16                             direction: direction
17                         });
18                 }
19                 return origSelect.apply(this, arguments);
20             };
21         }
22     };
23 });

Here is the full code of the final result and the live demo: that carousel will fetch iframe slides of models from my Gallery, you can hit the "Add Slide" button to randomly add a new model slide.

style="height: 490px; width: 490px">

on-carousel-change="onSlideChanged(nextSlide, direction)">

Interval, in milliseconds:
Enter a negative number or 0 to stop the interval.


Related Article