AngularJS clear input field module

A simple module that adds a clear button to input fields.
Check how it works on plunker.

You can find the module on github:
https://github.com/nclsptrs/angular-clear-input

Or you can use this directive:

(function() {
    'use strict';

    angular.module('appName').directive('clearable', clearable);

    function clearable() {
        var directive = {
            restrict: 'A',
            require: 'ngModel',
            link: link
        };
        return directive;

        function link(scope, elem, attrs, ctrl) {
            elem.addClass('clearable');
            elem.bind('input', function() {
                elem[toggleClass(elem.val())]('x');
            });
            elem.on('mousemove', function(e) {
                if(elem.hasClass('x')) {
                    elem[toggleClass(this.offsetWidth - 25 < e.clientX - this.getBoundingClientRect().left)]('onX');
                }
            });
            elem.on('click', function(e) {
                if(elem.hasClass('onX')) {
                    elem.removeClass('x onX').val(undefined);
                    ctrl.$setViewValue(undefined);
                    ctrl.$render();
                    scope.$digest();
                }
            });
            function toggleClass(v) {
                return v ? 'addClass' : 'removeClass';
            }
        }
    }

    var style = document.createElement('style');
    style.type = 'text/css';
    style.innerHTML =
        '.clearable {' +
        'background-image: url(data:image/gif;base64,R0lGODlhBwAHAIAAAP///5KSkiH5BAAAAAAALAAAAAAHAAcAAAIMTICmsGrIXnLxuDMLADs=);' +
        'background-repeat: no-repeat;' +
        'background-attachment: initial;' +
        'background-position: right -10px center;' +
        '}' +
        '.clearable.x {' +
        'transition: background 0.4s;' +
        'background-position: right 10px center;' +
        '}' +
        '.clearable.onX {' +
        'cursor: pointer;' +
        '}';

    document.getElementsByTagName('head')[0].appendChild(style);

})();

Now add the “clearable” attribute to your input field.

<input type="text" data-ng-model="myModel" clearable />

<textarea data-ng-model="myModel" clearable></textarea>

AngularJS drawing directive with touch events

app.directive("drawing", function(){
    return {
        restrict: "A",
        link: function(scope, element, attrs){
            var rectSize = element[0].width;
            var ctx = element[0].getContext('2d');

            ctx.fillStyle="#FFFFFF";
            ctx.fillRect(0,0,rectSize,rectSize);

            var mobileoffsetX = 100;
            var mobileoffsetY = 30;

            var drawing = false;
            var lastX, lastY;

            var start  = 'mousedown',
                move   = 'mousemove',
                end    = 'mouseup';

            if (Modernizr.touch === true) {
                start  = 'touchstart';
                move   = 'touchmove';
                end    = 'touchend';
            }


            element.bind(start, function(event){
                if(start == 'touchstart') {
                    event.preventDefault();
                }

                if(event.offsetX!==undefined){
                    lastX = event.offsetX;
                    lastY = event.offsetY;
                } else if(event.pageX!==undefined) {
                    // Firefox compatibility
                    lastX = event.pageX - event.currentTarget.offsetLeft;
                    lastY = event.pageY - event.currentTarget.offsetTop;
                } else {
                    // Mobile compatibility
                    lastX = event.originalEvent.targetTouches[0].pageX - mobileoffsetX;
                    lastY = event.originalEvent.targetTouches[0].pageY - mobileoffsetY;
                }

                ctx.beginPath();
                drawing = true;

            });


            element.bind(move, function(event){
                if(move == 'touchmove') {
                    event.preventDefault();
                }

                if(drawing){
                    if(event.offsetX!==undefined){
                        currentX = event.offsetX;
                        currentY = event.offsetY;
                    } else if(event.pageX!==undefined) {
                        currentX = event.pageX - event.currentTarget.offsetLeft;
                        currentY = event.pageY - event.currentTarget.offsetTop;
                    } else {
                        currentX = event.originalEvent.targetTouches[0].pageX - mobileoffsetX;
                        currentY = event.originalEvent.targetTouches[0].pageY - mobileoffsetY;
                    }

                    draw(lastX, lastY, currentX, currentY);

                    lastX = currentX;
                    lastY = currentY;
                }
            });

            element.bind(end, function(event){
                drawing = false;
            });

            function reset(){
                element[0].width = element[0].width;
            }

            function draw(lX, lY, cX, cY){
                ctx.moveTo(lX,lY);
                ctx.lineTo(cX,cY);
                ctx.lineWidth = 3;
                ctx.strokeStyle = '#000000';
                ctx.stroke();
            }
        }
    };
});

Demo

Angular upwards scroll module

I’ve written an angular module from previous post about the upwards scrolling.
You can find it on github:
https://github.com/nclsptrs/angular-upwards-scroll

AngularJS nested controllers with “controller as” syntax

Instead of using the $scope object, use this.

app.controller('FirstCtrl', function() {
  this.name = 'FirstCtrl';
});

app.controller('SecondCtrl', function() {
  this.name = 'SecondCtrl';
});

app.controller('ThirdCtrl', function() {
  this.name = 'ThirdCtrl';
});
<div ng-controller="FirstCtrl as first">
  <p>{{first.name}}</p>
  
  <div ng-controller="SecondCtrl as second">
	<p>
	  {{first.name}}<br/>
	  {{second.name}}
	</p>
	
	<div ng-controller="ThirdCtrl as third">
	  <p>
		{{first.name}}<br/>
		{{second.name}}<br/>
		{{third.name}}
	  </p>
	</div>
  </div>
</div>

example

Pie chart progress bar in AngularJS

Based on: Simple pie chart progress bar in canvas element

HTML:

<style>
.chart {
  position:relative;
  margin:80px;
  width:220px;
  height:220px;
}
.chart > canvas {
  display:block;
  position:absolute;
  top:0;
  left:0;
}
.chart > span {
  color:#555;
  display:block;
  line-height:220px;
  text-align:center;
  width:220px;
  font-family:sans-serif;
  font-size:40px;
  font-weight:100;
  margin-left:5px;
}
</style>

<body ng-controller="MainCtrl">
  <div class="chart" pie-chart-progress-bar="Percent"></div>
</body>

AngularJS controller and directive:

app.controller('MainCtrl', function($scope, $timeout) {
  $scope.Percent = 0;
  var Count = function() {
      $scope.Percent++;
      
      if($scope.Percent < 100) {
          $timeout(Count, 10);
      }
  };
  Count();
});


app.directive('pieChartProgressBar', function() {
  return {
    restrict: 'A',
    scope: {
        percent: "=pieChartProgressBar"
    },
    link: function (scope, elem, attr, ctrl) {
      var el = elem[0];
      var options = {
        size: 220,
        lineWidth: 15,
        rotate: 0
      };

      var canvas = document.createElement('canvas');
      var span = document.createElement('span');

      if (typeof(G_vmlCanvasManager) !== 'undefined') {
        G_vmlCanvasManager.initElement(canvas);
      }

      var ctx = canvas.getContext('2d');
      canvas.width = canvas.height = options.size;

      el.appendChild(span);
      el.appendChild(canvas);

      ctx.translate(options.size / 2, options.size / 2);
      ctx.rotate((-1 / 2 + options.rotate / 180) * Math.PI);

      var radius = (options.size - options.lineWidth) / 2;

      var drawCircle = function(color, lineWidth, percent) {
        percent = Math.min(Math.max(0, percent || 1), 1);
        ctx.beginPath();
        ctx.arc(0, 0, radius, 0, Math.PI * 2 * percent, false);
        ctx.strokeStyle = color;
        ctx.lineCap = 'round'; // butt, round or square
        ctx.lineWidth = lineWidth;
        ctx.stroke();
      };

      drawCircle('#efefef', options.lineWidth, 100 / 100);

      scope.$watch('percent', function(value) {
        span.innerText = value + '%';
        drawCircle('#555555', options.lineWidth, value / 100);
      });
  
    }
  }
});

live preview

AngularJS upwards infinite scroll

HTML:

<style>
	.upwards-scroll-container {
		height: 300px;
		border: 1px solid black;
		overflow-y: scroll;
	}
</style>

<div data-ng-controller="UpwardsScroll">
	<div class="upwards-scroll-container" upwards-scoll="LoadMore()">
		<ul>
			<li ng-repeat="i in items">{{i.text}}</li>
		</ul>
	</div>
</div>

AngularJS controller and directive:

angular.module('myapp').controller('UpwardsScroll', function($scope, $http) {
    var counter = 1;
    var limit = 50;
	$scope.items = [];	
    $scope.LoadMore = function() {
        for (var i = 0; i < limit; i++) {
            $scope.items.unshift( { text: counter } );
            counter++;
        }
    };
    $scope.LoadMore();
});

angular.module('myapp').directive('upwardsScoll', function ($timeout) {
    return {
        link: function (scope, elem, attr, ctrl) {
            var raw = elem[0];

            elem.bind('scroll', function() {
                if(raw.scrollTop <= 0) {
                    var sh = raw.scrollHeight;
                    scope.$apply(attr.upwardsScoll);

                    $timeout(function() {
                        elem.animate({
                            scrollTop: raw.scrollHeight - sh
                        },500);
                    }, 0);
                }
            });

            //scroll to bottom
            $timeout(function() {
                scope.$apply(function () {
                    elem.scrollTop( raw.scrollHeight );
                });
            }, 0);
        }
    }
});

live preview