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

Using CSOM in a Windows 8 app for SharePoint Online

Working with the Client-Side Object Model is rather easy and that’s why I looked for a solution to use it in a Windows 8 app.

There are two assemblies to be referred for working with the CSOM.

  • Microsoft.SharePoint.Client.dll
  • Microsoft.SharePoint.Client.Runtime.dll

Creating the app

Let’s start by creating a new Class Library for Windows Store apps.
In here we add the references to the SharePoint assemblies.
In our Windows 8 app, we add a reference to our newly created class library.

Untitled

To be able to invoke methods on SharePoint Online using the Client-Side Object Model (CSOM), we need to authenticate first.
The authentication is based on this solution found on MSDN Blogs:
http://blogs.msdn.com/b/omarv/archive/2012/10/25/windows-8-store-apps-office-365-enterprise-preview-sharepoint-online.aspx

When the app starts,┬áthe app will try to retrieve the credentials from the password vault to connect to SharePoint. If the credentials from the password vault are empty, you’ll get the input fields to pass your credentials and login.

After the login is done, the cookies are stored in a CookieContainer. We need to pass this cookies to the CSOM ClientContext.

context.ExecutingWebRequest += delegate(object sender, WebRequestEventArgs e)
{
    e.WebRequestExecutor.WebRequest.CookieContainer = Cookies;
};

Now that we are loged in and that the cookies are passed to the ClientContext, we can do what ever we want using CSOM code.

In this example we will retrieve the site title.

BasicPage

SPClient client = new SPClient();
client.SiteUrl = AuthUtility.Current.SiteUrl.ToString();
client.Cookies = AuthUtility.Current.CookieContainer;
TextBlockTitel.Text = client.GetSiteTitle();

Class using the CSOM

public class SPClient
{
	public string SiteUrl { get; set; }
	public CookieContainer Cookies { get; set; }

	public string GetSiteTitle()
	{
		string Title = string.Empty;
		ClientContext context = null;

		try
		{
			using (context = new ClientContext(SiteUrl))
			{
				try
				{
					context.ExecutingWebRequest += delegate(object sender, WebRequestEventArgs e)
					{
						e.WebRequestExecutor.WebRequest.CookieContainer = Cookies;
					};
				}
				catch
				{
					if (context != null) context.Dispose();
					throw;
				}

				context.Load(context.Web);
				context.ExecuteQuery();
				Title = context.Web.Title;
			}
		}
		catch
		{
			throw;
		}

		return Title;
	}
}

You can download the sample code here. Enjoy!