If you have to support <= IE9, you should not use console.log without a polyfill. If you don’t use a polyfill, console.log will throw an error. Console.log will only be available if the developertools are open:

 

http://stackoverflow.com/questions/5472938/does-ie9-support-console-log-and-is-it-a-real-function/5473193#5473193

Tags:

 

image

 

I want to show HTML to the user, that was stored in a SQL Server Database. The data was queried from the SQL Server Database by using Entity Framework, then the C# model was converted to JSON, by using JSON.net and send to the browser by the ASP .NET web api service.

To show this HTML to the user with AngularJS, I used ngSanitize and the ng-bind-html directive:

(at this moment plunker is down, so I will edit this post in the future to add a plunker).

 

If the HTML contains angular bindings / directives, you can use the compile service to bind the scope to the html fragment:

https://docs.angularjs.org/api/ng/service/$compile

So instead of using the ng-bind-html, you can use this directive:

https://github.com/incuna/angular-bind-html-compile/blob/master/angular-bind-html-compile.js

<!DOCTYPE html>
<html xmlns:ng="http://angularjs.org" id="ng-app" ng-app="spike">
<head>
    <!-- Why is angular added to the html tag? Because IE8 won't work without it. -->
    <title>Spike page</title>
    <meta charset="utf-8">
    <!-- Why is "edge" used? Because we want the highest support for modern standards. -->
    <meta http-equiv="X-UA-Compatible" content="IE=edge">

    <!-- Library scripts -->
    <!--<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>-->
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.6/angular.min.js"></script>
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.6/angular-animate.min.js"></script>
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.6/angular-sanitize.min.js"></script>

    <!-- Live reload script with grunt. -->
    <!--<script src="http://localhost:35729/livereload.js"></script>-->

    <!-- App styles -->
    <style>
        /*
            A small custom reset stylesheet is used, to fix style differences between browsers.
        */
        html, body
        {
            height: 100%;
        }

        body, div, p, ul, li, button
        {
            border: 0;
            -webkit-box-sizing: border-box;
            -moz-box-sizing: border-box;
            box-sizing: border-box;
            font-family: "Open Sans", sans-serif;
            margin: 0;
            outline: 0;
            padding: 0;
        }

        body
        {
            background-color: #F1F1F1;
            padding: 20px;
        }

        .spike-title
        {
            color: #393939;
        }

        .spike-content
        {
            color: #393939;
        }
        .spike-content-with-class
        {
            color: #ff0000;
        }
    </style>

    <!-- App scripts -->
    <script>

        (function ()
        {
            "use strict";

            var app = angular.module("spike", ["ngAnimate", "ngSanitize"]);
        }());

        (function ()
        {
            "use strict";

            var app = angular.module("spike");

            var controller = function ($scope)
            {
                $scope.title = "How to show html embeded inside JSON to the user with AngularJS and ngSanitize.";

                var json = '{ \"html\":\"<br><br><p>Some html in JSON.</p><br><br><p class=\\"spike-content-with-class\\">Some html in JSON with a class attribute.</p>\" }';
                var content = JSON.parse(json);

                $scope.content = content.html;
            };

            app.controller("main", ["$scope", controller]);
        }());
    </script>
</head>
<body>
    <div ng-controller="main">
        <h2 class="spike-title">{{ title }}</h2>
        <div class="spike-content" ng-bind-html="content"></div>
    </div>
</body>
</html>

Tags: , , ,

Roel van Lisdonk on December 12th, 2014

Code can be found here: http://plnkr.co/edit/HkhYo9KVUvzuhvPNDZHA?p=preview

 

image

Tags: ,

Roel van Lisdonk on December 12th, 2014

In windows 10 preview I noticed the F12 developer tools changed.

I think the new F12 developer tools in IE are a really good update from the previous version.

I did not like the buttons on the left. With the tabs on top the ui is much cleaner:

 

image

Tags: ,

Roel van Lisdonk on December 5th, 2014

Demo and Code can be found at: http://plnkr.co/edit/Ht4ud6kyJUzDTQdS9MI2?p=preview

 

image

 

Just for the fun, I added a D3.js chart:

 

image

 

A simple AngularJS wizard that dynamically loads pages (views).

In the plunker each page is a *.html file that is loaded by dynamically setting a viewmodel property “pageTemplateUrl”:

ng-include="pageTemplateUrl"

Each *.html file contains a “page” directive.

In this examples all pages share one “page” directive, so all logic for all pages is stored in the “page” directive, but you can put in, any custom made directive in the “*.html” file, so you can give each page it’s own directive / logic.

 

Index.html

<body>
    <div ng-controller="main">
        <h2 class="main-title">{{ title }}</h2>
        <wizard></wizard>
    </div>
</body>

Wizard.html

<div class="wizard">
    <div>Wizard</div>
    <div class="page page-slide-in" ng-include="pageTemplateUrl"></div>
    <div class="footer flex-horizontal">
        <div class="wizard-footer-left">
            <button ng-disabled="prevShouldBeDisabled()"
                    ng-click="prev()">
                Back
            </button>
        </div>
        <div class="wizard-footer-middle flex-vertical">
            <ul class="steps">
                <li ng-repeat="page in pages"
                    ng-class="{ active: isActive(page), complete: isCompleted(page) }"
                    ng-click="setPageTemplateUrl(page)">
                    <span class="badge">{{ $index + 1 }}</span>
                    {{ page.title }}
                    <span class="chevron"></span>
                </li>

            </ul>
        </div>
        <div class="wizard-footer-right">
            <button ng-disabled="nextShouldBeDisabled()"
                    ng-click="next()">
                Next
            </button>
        </div>
    </div>
</div>

Intro.html (first page in wizard)

<page>
    <div class="page-title">{{ title }}</div>
    <p>
        Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. 
Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.
Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim.
Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu.
In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo.
Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus.
Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu,
consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus.
Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet.
Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui.
</p> </page>

JavaScript

        (function ()
        {
            "use strict";

            var app = angular.module("spike", ["ngAnimate"]);
        }());

        (function ()
        {
            "use strict";

            var app = angular.module("spike");

            var controller = function ($scope)
            {
                console.log("Controller [main] loaded.");
                $scope.title = "Dynamic loading of views as directives in a AngularJS wizard.";
            };

            app.controller("main", ["$scope", controller]);
        }());

        (function ()
        {
            "use strict";

            var directive = function ()
            {
                function link($scope, element, attributes, controller)
                {
                    function initialize()
                    {
                        showPage(0);
                    }

                    function showPage(pageId)
                    {
                        $scope.selectedPageId = pageId;
                        var page = $scope.pages[$scope.selectedPageId];
                        $scope.setPageTemplateUrl(page);
                    }

                    $scope.chartData = [10, 20, 30, 40, 60, 80, 20, 50];

                    $scope.pages = [
                        { 
                            title: "intro"
                        },
                        {
                            title: "modules"
                        },
                        {
                            title: "detail"
                        },
                        {
                            title: "order"
                        }
                    ];

                    $scope.isActive = function (page)
                    {
                        var selectedPage = $scope.pages[$scope.selectedPageId];
                        return (selectedPage.title === page.title);
                    };

                    $scope.isCompleted = function (page)
                    {
                        var index = $scope.pages.indexOf(page);
                        return (index < $scope.selectedPageId);
                    };

                    $scope.next = function ()
                    {
                        showPage($scope.selectedPageId + 1);
                    };

                    $scope.prev = function ()
                    {
                        showPage($scope.selectedPageId - 1);
                    };

                    $scope.nextShouldBeDisabled = function ()
                    {
                        return ($scope.selectedPageId >= $scope.pages.length - 1);
                    };

                    $scope.prevShouldBeDisabled = function ()
                    {
                        return ($scope.selectedPageId <= 0);
                    };

                    $scope.setPageTemplateUrl = function (page)
                    {
                        $scope.selectedPageId = $scope.pages.indexOf(page);
                        $scope.pageTemplateUrl = page.title + ".html";
                    };

                    initialize();

                    console.log("Directive [wizard] loaded.");
                }

                return {
                    restrict: "EA",
                    link: link,
                    templateUrl: "wizard.html"
                };
            };

            angular.module("spike").directive("wizard", [directive]);
        }());

        (function ()
        {
            "use strict";

            var directive = function ()
            {
                function link($scope, element, attributes, controller)
                {
                    var page = $scope.pages[$scope.selectedPageId];
                    $scope.title = page.title;

                    

                    console.log("Directive [page].[" + page.title + "] loaded.");
                }

                return {
                    restrict: "EA",
                    link: link
                };
            };

            angular.module("spike").directive("page", [directive]);
        }());

        (function ()
        {
            "use strict";

            var directive = function ()
            {
                function link($scope, element, attributes, controller)
                {
                    var chart = d3.select(element[0]);
                    chart.append("div").attr("class", "chart")
                     .selectAll('div')
                     .data($scope.data).enter().append("div")
                     .transition().ease("elastic")
                     .style("width", function (d) { return d + "%"; })
                     .text(function (d) { return d + "%"; });

                    console.log("Directive [barsChart] loaded.");
                }

                return {
                    restrict: "EA",
                    replace: false,
                    scope: {data: '=chartData'},
                    link: link
                };
            };

            angular.module("spike").directive("barsChart", [directive]);
        }());

Tags:

Roel van Lisdonk on December 4th, 2014

Infinite scroll library in JavaScript (15kb)
http://darsa.in/sly/examples/infinite.html

With pages:
http://darsa.in/sly/examples/vertical.html

 

image

Tags:

Code can be found here: http://plnkr.co/edit/EgLVcgyPcbu7AngvnnOy?p=preview

image

 

<!DOCTYPE html>
<html>
<head>
    <title>Vanilla javascript spike page.</title>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">

    <!-- App styles -->
    <style>
        html, body {
            height: 100%;
        }

        body, div, p, ul, li {
            border: 0;
            -webkit-box-sizing: border-box;
            -moz-box-sizing: border-box;
            box-sizing: border-box;
            margin: 0;
            outline: 0;
            padding: 0;
        }

        body {
            padding: 20px;
            background-color:#393939;
        }
             
        .bordered {
            color: #F1F1F1;
            display: inline-block;
            width: 180px;
            height: 100px;
            border-right: 1px solid #F1F1F1;
            border-image: linear-gradient(to bottom, #393939 0%,#F1F1F1 25%,#F1F1F1 75%,#393939 100%) 1 stretch;
        }
    </style>

   </head>
<body>
    <div class="bordered">A linear gradient border:</div>
</body>
</html>

Tags:

Roel van Lisdonk on December 3rd, 2014

It is a common practice to use spinalcase in CSS, like the css class “.ada-wizard-marker”.

If you want to use this class in a ng-class directive, where the input is an object, use single quotes, like:

ng-class="{ 'ada-wizard-marker': vm.showToolTip }"

If you don’t use the single quotes, ng-class will not work.

Tags:

Code can be found at:

http://plnkr.co/edit/xarxPAKTXrEIDKUHmapg?p=preview

 

I was asked to show a tooltip with AngularJS in a responsive layout, so I created a Plunker, that will form the base of my code.

Note: resize the screen to test the responsiveness.

 

Initial state

image

Clicked on Tile 3

image

 

HTML

<body>
    <div ng-controller="main">
        <br>
        {{ title }}
        <br>
        Just click on one of the tiles to show the tooltip.
        <br>
        <br>
        <div class="header">
            Modules
        </div>
        <div class="tiles">
            <div class="tile" ng-class="{ marker: tile.showToolTip }"
                 ng-click="onTileClick(tile)"
                 ng-repeat-start="tile in tiles">
                {{ tile.title }}
            </div>
            <div class="wizard fadeSlideIn" ng-show="tile.showToolTip" ng-repeat-end>
                <div class="close">X</div>
                <div>{{ tile.title }}</div>
                <div style="clear: both"></div>
            </div>
        </div>

    </div>
</body>

Tags:

Roel van Lisdonk on November 28th, 2014

 

Creating pure css icons, without using fonts or svg or images.

http://nicolasgallagher.com/pure-css-gui-icons/

 

Holey cow, these icons are created with just CSS, no fonts, no svg, no images not nothing, just the magic of CSS en pseudo elements.

 

screenshot

 

To see this in live action go to: http://nicolasgallagher.com/pure-css-gui-icons/demo/

Press F12 and be amazed:

image

 

How to use pseudo elements in css:

http://www.smashingmagazine.com/2011/07/13/learning-to-use-the-before-and-after-pseudo-elements-in-css/

Tags: