Showing posts with label controls. Show all posts
Showing posts with label controls. Show all posts

Monday, 6 June 2016

Creating a Star Control in HTML using Angular Js


In this article we are going to see how to create a Star Rating control in the HTML as Element or as Attribute using the Angular js. To do this we are going to take create the Directive in Angular js, First Let we see what kind of element or Attribute we are going to create and what kind of output it will give ?

Below Code Snippet is we trying to do





Output:




From the Code we can render a Star Control, using the some of the properties it will have some  behavior change.

custom-rating is the act as element or attribute for render a star control, it have few options
readonly : set true for this attribute if you want the star control as readonly
max : set the number of star you want to render
star-size : size of the star control
rating-value : specify the rating value of a control
on event is there to trigger for the change in the star value when user clicked, then use the 
on-rating-changed with a function passing parameter in the name of rating , which consists the value, now you can trigger the value to the server.

Now we start to build the directive.

Add the following jquery in the HTML.


    <script type="text/javascript" src="js/jquery-1.11.1.min.js"></script>

    <script type="text/javascript" src="js/angular.min.js"></script>

Then start writing coding in Angular.

Create a Module and controller

First step is create a module in separate js file and include in the HTML.

        var myApp = angular.module('myApp', []);

        myApp.controller('BlogController'function ($scope, $window) {
            $scope.sample = 'Blog Testing';

            $scope.rating = 5;
            $scope.rating2 = 1;

            $scope.saveRating = function (rating) {
                console.log('Rating selected ' + rating);
            };

            $scope.Sample = function (rating) {
                console.log('sample ' + rating);
            };

        });


Create a Directive

        myApp.directive('customRating'function () {
            return {
                restrict: 'AE',
                template: '<ul class="rating">' +
                         '<li ng-repeat="star in stars"  ng-class="star" ng-                                                click="toggle($index)">\u2605</li>' +
                         '</ul>',
                scope:
                {
                    ratingValue: '=',
                    max: '=',
                    readonly: '@',
                    starSize: '=',
                    onRatingChanged: '&'
                },
                link: function (scope, element, attrs) {

                   
                    var updateStars = function () {
                        scope.stars = [];
                        for (var i = 0; i < scope.max; i++) {
                            scope.stars.push({ filled: i < scope.ratingValue });
                        }
                    };

                    element.css('font-size', scope.starSize);

                   
                    scope.toggle = function (index) {
                        if (scope.readonly && scope.readonly === 'true') {
                            return;
                        }
                        scope.ratingValue = index + 1;

                        scope.onRatingChanged({ rating: index + 1 });
                    };

                   
                    scope.$watch('ratingValue'function (oldval, newval) {
                        if (newval) {
                            updateStars();
                        }
                    })

                }

            }
        });




So now when include the custom js in the Html, we can able to render the Star control .Now when ever user change the value in one star it affects others because of binding, at the same time we are trigger the changes to the server.



From this article you can learn how to render a star control tag in Html using Angular Js.




UI-Sortable directive not works for the drag while sorting between the elements on the first drag or first click using jquery 2.0.0 and Angular js - Resolved


In this article we are going to see a bug, which is present in the jquery,because of that it affects the Angular ui-sortable directive.now let we see about the sorting between the elements by dragging using angular js, To do this we need following references.


<script type="application/javascript" src="js/jquery-2.0.0.min.js"></script>
<script type="application/javascript" src="js/jquery-ui.min.js"></script>
<script type="application/javascript" src="js/bootstrap.min.js"></script>
<script type="application/javascript" src="js/angular.min.js"></script>
<script type="application/javascript" src="js/angular-ui.min.js"></script>

  
In this sample we take two different kind of sorting elements, one with static element, another with dynamic elements i.e adding elements at runtime using angular js

Code:

       <div style="float: left; margin: 20px">
            <h3>
                static element</h3>
            <ul ui-sortable="sortoptions" class="well" style="width: 400px">
                <li style="" class="well li">LG</li>
                <li style="" class="well li">Samsung</li>
                <li style="" class="well li">Videocon</li>
                <li style="" class="well li">Onida</li>
            </ul>
        </div>

        <div style="float: left; width: 400px; margin: 20px">
            <h3>
                dynamic element</h3>
            <ul id="sortid" ui-sortable="sortoptions" class="well">
                <li class="well alterli" ng-repeat="item in Items">{{item.name}}</li>
            </ul>
        </div>




Output:

Above dynamic element tag not able to drag and sort on first attempt, because of jquery 2.0.0



From the elements, both can be sort using dragging but there is a one issue with the second element, the second rendered elements can't able to drag on the first attempt, but it can drag and sort in second attempt, this issue only occurs in Jquery 2.0.0 when elements are rendered dynamically using ng-repeat. But it works correctly when using Jquery less than or above 2.0.0, This is working correctly for static declared elements Now we are going to see how to fix this issue, to drag the dynamically rendered elements in the first attempt for jquery 2.0.0 version


Why this issue occurs in dynamically rendered elements ?
           When adding the directive ui-sortable to the root tag, that particular element is rendered first,before the rendering of the child elements, because of this behavior drag is fails on the first attempt, it cant able to recognize the event. on the second attempt it success for the dynamic added elements.

How to fix this issue ?

For dynamic rendered elements,  adding a new directive along with ui-sortable directive, add the directive init-sort which i mention before , it will take care remaining things,now your elements are drag and sortable on the first attempt itself.

Directive: 
        samApp.directive('initSort'function ($compile) {
            return {
                restrict: 'A',
                scope: {
                    initSort: '='
                },
                transclude: false,
                link: function (scope, element, attrs) {
                    var firsttime = 0;
                    element.on('mouseover'function () {
                        if (firsttime == 0) {
                            element.sortable("refresh");
                            firsttime = 1;
                            console.log('Triggered');
                        }
                    });
                }
            };
        });



HTML
        <div style="float: left; width: 400px; margin: 20px">
            <h3>
                dynamic element</h3>
            <ul id="sortid" ui-sortable="sortoptions" init-sort class="well">
                <li class="well alterli" ng-repeat="item in Items">{{item.name}}</li>
            </ul>
        </div>



Output:



Full Code:
HTML 


<body ng-app="samApp">
    <div ng-controller="sampleController">

        <div style="float: left; margin: 20px">
            <h3>
                static element</h3>
            <ul ui-sortable="sortoptions" class="well" style="width: 400px">
                <li style="" class="well li">LG</li>
                <li style="" class="well li">Samsung</li>
                <li style="" class="well li">Videocon</li>
                <li style="" class="well li">Onida</li>
            </ul>
        </div>

        <div style="float: left; width: 400px; margin: 20px">
            <h3>
                dynamic element</h3>
            <ul id="sortid" ui-sortable="sortoptions" init-sort class="well">
                <li class="well alterli" ng-repeat="item in Items">{{item.name}}</li>
            </ul>
        </div>

    </div>
    <script type="application/javascript" src="js/jquery-2.0.0.min.js"></script>
    <script type="application/javascript" src="js/jquery-ui.min.js"></script>
    <script type="application/javascript" src="js/bootstrap.min.js"></script>
    <script type="application/javascript" src="js/angular.min.js"></script>
    <script type="application/javascript" src="js/angular-ui.min.js"></script>
    <script type="application/javascript" src="ang/samApp.js"></script>


</body>


Angular JS

        /**
        * Created by Rajesh on 20-08-2014.
        */

        var samApp = angular.module('samApp', ['ui']);

        samApp.controller('sampleController'function ($scope) {

        $scope.Items = [
                   { name: 'Rajesh' },
                   { name: 'Suresh' },
                   { name: 'Aneesh' },
                   { name: 'Gokul' }
             ];

            
        $scope.sortoptions = {
                update: function (event) {

                },
                stop: function (e, ui) {
                    console.log('stop item', ui.item.scope());
                    console.log('stop item', ui.item.sortable);
                    var item = ui.item.sortable.moved;
                    var fromIndex = ui.item.sortable.index;
                    var toIndex = ui.item.sortable.dropindex;
                    console.log(item, fromIndex, toIndex, $scope.dropTarget);
                },
                start: function (e, ui) {
                    console.log('start item', ui.item.scope());
                }
            };



        });

        samApp.directive('initSort'function ($compile) {
            return {
                restrict: 'A',
                scope: {
                    initSort: '='
                },
                transclude: false,
                link: function (scope, element, attrs) {
                    var firsttime = 0;
                    element.on('mouseover'function () {
                        if (firsttime == 0) {
                            element.sortable("refresh");
                            firsttime = 1;
                            console.log('Triggered');
                        }
                    });
                }
            };
        });




From this post you can see how to drag the elements in the first attempt when JQuery is 2.0.0.


Create a focused and focusonload directive in Angular js HTML5


In this article we are going to see how to create a directive which will focus the element on page load and focus the element when change the property value. The  directive is a attribute, so we are going to create a two directive elements now.

var dirApp = angular.module('dirApp',[]);

dirApp.controller('dirController', function ($scope) {

    $scope.status = false;
    $scope.status1 = false;

    $scope.infocus=function()
    {
        $scope.status1 = true;
    };

    $scope.outfocus = function(){
      $scope.status1 = false;
    };

});



Create the directive :

dirApp.directive('focusOnLoad', function () {
   return{
     restrict:'A',
     link: function (scope, element, attrs, cntrl) {
         element[0] .focus();
     }
   };
});


dirApp.directive('focused', function ($timeout) {
   return{
       restrict:'A',
       scope:{
           focused:'=focused'
       },
       link: function (scope,element,attrs) {

           scope.$watch('focused', function () {
               console.log(scope.focused);
               if(scope.focused){
                   element[0].focus();
               }
               else{
                   element[0].blur();
               }
           });

           element.on('blur', function () {
               $timeout(function () {
                   scope.focused = false;
               });


           });

           function Apply(scope, fn) {
               (scope.$$phase || scope.$root.$$phase) ? fn() : scope.$apply(fn);
           }

           element.on('focus', function () {
              Apply(scope,function(){
                  if(!scope.focused)
                  scope.focused = true;
              });
           })

       }
   };
});


How to use the directive ?

Now use the directive as attribute in needed element , if we want a element which should be focused on load , so place the focus-on-load directive element.

Next we need an attribute which will be focused on property valued changed as True or False.
focused="status1"



Code:










output:




Create a Notification indicator custom element tag, which attaches to any element in the HTML5



In this article we are going to see a custom element, which will indicates the notification and there messages by attaches to any element in the HTML.

Normally we will see that an notification in many sites which is present in the top right corner of that page by indicating the number, so to do that kind of notification element we have to do the following things, this element will attaches to any element other than the elements which not have an separate closing tags.

Notification with different styles






Different in the notificaiton type and value                







See how the notification element is attaches to all element tags






From the above design now you can see the notification design which is present in the right corner of the each element. we can change the some properties of the notification element like changing the forecolor ,backcolor, type of the element like circle, square, and can change the value by click the buttons or moving the Range indicator. Now we see how to create a element like that and attaches to the any element.


/**

 * Created by Rajesh on 22-09-2014.

 */



(function () {



    var ngControls = angular.module('ngControls',[]);

    ngControls.directive('notifyIndicator', function () {

        return{

            restrict:'E',

            scope:{

                data:'=',

                bgcolor:'@',

                fgcolor:'@',

                elementType:'@'

            },

            template:'<div style="text-shadow: 0 1px 1px rgba(0,0,0,.3);
            -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, .7);
            box-shadow:0 1px 1px rgba(0, 0, 0, .7);
            background-color:{{backgroundColor}};
            width:{{elementSize}}px;height:{{elementSize}}px;
            border-radius: {{type}};color: {{foreColor}};font-size: 9px;
            position: relative;font-weight: bold;right: -{{Right}}px;
            top: -{{Top}}px;
           display: table;vertical-align: middle;">' +

           '<div style="display: table-cell;vertical-align: middle;
            text-align: center;
            padding-left: 3px;padding-right: 3px">{{value}}</div></div>',

            link: function (scope, element, attrs, cntrl) {

                scope.elementSize = 14;
                scope.value = '';
                scope.backgroundColor = '';
                scope.foreColor = '';
                scope.type = 'Circle';
                scope.Right = 0;
                scope.Top = 0;

                function Apply(scope, fn) {
                 (scope.$$phase || scope.$root.$$phase) ? fn() : scope.$apply(fn);
                }


                function SetBgColor() {
                    if(scope.bgcolor==undefined){
                        scope.backgroundColor = 'Red';
                    }
                    else{
                        scope.backgroundColor = scope.bgcolor;
                    }
                }

                function SetFgColor() {
                    if(scope.fgcolor==undefined){
                        scope.foreColor = 'white';
                    }
                    else{
                        scope.foreColor = scope.fgcolor;
                    }
                }

                function SetElementType() {
                    if(scope.elementType == undefined){
                        scope.type = '50%';
                    }
                    else{
                        if(scope.elementType=='circle'){
                            scope.type='50%';
                        }
                        else{
                            scope.type = '30%';
                        }
                    }
                }


                function SetData() {
                    if(scope.data != undefined){
                        scope.value= scope.data;
                    }
                    else{
                        //element.html('');
                    }
                }

                SetBgColor();

                SetFgColor();

                SetElementType();

                SetData();


                scope.$watch('elementType', function () {
                    Apply(scope, function () {
                        SetElementType();
                    })
                });

                scope.$watch('fgcolor', function () {
                    Apply(scope, function () {
                        SetFgColor();
                    });
                });

                scope.$watch('bgcolor', function () {
                    Apply(scope, function () {
                        SetBgColor();
                    });
                });


                element.parent().css('display','inline-block');
                scope.Right = element.parent()[0].offsetWidth-8;
                scope.Top = element.parent()[0].offsetHeight-8;

                scope.$watch('data', function () {
                    Apply(scope,function(){
                        if(scope.data!=undefined ) {
                            if(scope.data>-1 && scope.data<10){
                                scope.Right = element.parent()[0].offsetWidth-8;
                                scope.Top = element.parent()[0].offsetHeight-8;
                            }

                            else if (scope.data > 9 && scope.data < 100) {
                                scope.elementSize = 16;
                                scope.Right = element.parent()[0].offsetWidth-10;
                                scope.Top = element.parent()[0].offsetHeight-8;
                            } 
                     
                           else if (scope.data>=100 && scope.data<1000){
                                scope.elementSize = 19;
                                scope.Right = element.parent()[0].offsetWidth-12;
                                scope.Top = element.parent()[0].offsetHeight-10;
                            }

                            else if(scope.data>=1000 && scope.data<10000){
                                scope.elementSize = 21;
                                scope.Right = element.parent()[0].offsetWidth-16;
                                scope.Top = element.parent()[0].offsetHeight-11;
                            }

                            else{

                                scope.Right = element.parent()[0].offsetWidth-16;
                                scope.Top = element.parent()[0].offsetHeight-12;

                            }

                        }

                        else{

                        }

                        scope.value = scope.data;
                    });
                });
            }
        };

    });





})();
So how to use the above module in our app.




var valueApp = angular.module('valueApp',['ngControls']);



now we have to design the HTML


  


From the above you can learn how to design a new custom control like notification element.