Angular Material : Custom Autocomplete directive

Standard

Customize Angular autocomplete directive, register within your controller and other data services and use it throughout your project. I have consolidated it through directive in-order to overcome boilerplate code in multiple module controllers. Different controller can utilize this directive by passing list through data attribute and passing caller controller method to invoke on selected item through filter-search attribute. For html code clone my repo from github.

Github Link

Angular Code:

(function () {
    'use strict';

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

    app.controller('autocompleteController', function () {
        
        var vm = this;

        vm.selectedItem = "";

        vm.dataList = [{ text: 'ABC', value: 1 },
                        { text: 'XYZ', value: 2 },
                        { text: 'Foo', value: 3 },
                        { text: 'Bar', value: 4 }];

        vm.showSelectedItem = function (valueReturnByDirective) {
            vm.selectedItem = valueReturnByDirective;
        }

    });

})();

Angular HTML Code:

<search-combo data="vm.dataList" filtersearch="vm.showSelectedItem"></search-combo>

Autocomplete Directive:

(function () {
    'use strict';

    angular
        .module('app')
        .directive('searchCombo', searchCombo);

    function searchCombo() {
        var directive = {
            restrict: 'EA',
            templateUrl: '/scripts/app/autoSearchDirective.html',
            scope: {
                data: '=',
                filtersearch: '&'
            },
            controller: autoCompleteController,
            controllerAs: 'vm',
            bindToController: true
        };

        return directive;
    }

    autoCompleteController.$inject = [];

    function autoCompleteController() {

        var vm = this;

        init();

        /////////////////////Implementation///////////////////////////////

        function init() {
            vm.datalist = vm.data; 
            vm.filterSearch = vm.filtersearch;

            vm.config = {};
            vm.config.disabled = false;
            vm.config.noCache = false;
            vm.searchText = "";
            vm.selectedItem = "";
            vm.selectedItemChange = selectedItemChange;
            vm.searchTextChange = searchTextChange;
            vm.querySearch = querySearch;

        }

        function querySearch(query) {
            var results = query ? vm.datalist.filter(createFilterFor(query)) : vm.datalist;
            return results;
        }

        function createFilterFor(query) {
            var lowercaseQuery = angular.lowercase(query);

            return function filterFn(data) {
                return (angular.lowercase(data.text).indexOf(lowercaseQuery) === 0);
            };

        }

        function searchTextChange(text) {
            console.log('Text changed to ' + text);
        }

        function selectedItemChange(item) {
            if (item)
                vm.filterSearch()(vm.selectedItem);
            else
                vm.filterSearch()("");
        }

    }

})();

Loader Directive Html:

<md-autocomplete ng-disabled="vm.config.disabled "
                 md-no-cache="vm.config.noCache"
                 md-selected-item="vm.selectedItem"
                 md-search-text-change="vm.searchTextChange(vm.searchText)"
                 md-search-text="vm.searchText"
                 md-selected-item-change="vm.selectedItemChange(item)"
                 md-items="item in vm.querySearch(vm.searchText)"
                 md-item-text="item.text" md-min-length="0"
                 placeholder="Search item here">
    <md-item-template>
        <span> {{item.text}} </span>
    </md-item-template>
    <md-not-found>
        No record matching "{{vm.searchText}}" were found.
    </md-not-found>
</md-autocomplete>

Output:

Captursse

Angular Material: Custom Loader directive

Standard

Customize Angular loader service, register within your controller and other data services and use it throughout your project. I have consolidated it through directive and service in-order to overcome boilerplate code. For html code clone my repo from github.

Github Link

Angular Code:

(function () {
    'use strict';

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

    app.controller('progressController', function (loaderService) {

        var vm = this;
        
        vm.showLoader = loaderService.getLoaderValue();

        vm.show = function () {
            vm.showLoader = loaderService.showLoader();
        };

        vm.hide = function () {
            vm.showLoader = loaderService.hideLoader();
        };
    });

})();

Angular HTML Code:

<loader></loader>

Loader Service:

(function () {
    'use strict';

    angular
        .module('app')
        .factory('loaderService', loaderService);

    loaderService.$inject = [];

    function loaderService() {

        var loaderStatus = "";

        var service = {
            showLoader: showLoader,
            hideLoader: hideLoader,
            getLoaderValue: getLoaderValue
        };

        return service;

        ////////////////////////////Implementation//////////////////////////////////////

        function showLoader() {
            loaderStatus = "indeterminate";
            return loaderStatus;
        }

        function hideLoader() {
            loaderStatus = "";
            return loaderStatus;
        }

        function getLoaderValue() {
            return loaderStatus;
        }
    }

})();

Loader Directive:

(function () {
    'use strict';

    angular
        .module('app')
        .directive('loader', loader);

    function loader() {
        var directive = {
            restrict: 'EA',
            templateUrl: '/scripts/app/loaderDirective.html',
        };

        return directive;
    }

    loaderController.$inject = [];

    function loaderController() {

        var vm = this;

        init();

        /////////////////////Implementation///////////////////////////////

        function init() {
           
        }
    }

})();

Loader Directive Html:

<md-progress-circular md-mode="{{vm.showLoader}}"></md-progress-circular>

Output:

Screenshot_3

Angular Material : Custom Dialog Service

Standard

Customize Angular dialogue service, register within your controller and other data services and use it throughout your project. For html code clone my repo from github.

Github Link

Angular Code:

(function () {
    'use strict';

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

    app.controller('dialogController', function (confirmAlert) {

        var vm = this;
        
        vm.confirm= function () {
            confirmAlert.confirmBoxResponse(
                'Would you like to delete?',
                'Record will be deleted ',
                'Delete',
                callBack,
                "Hello World");
        };

        function callBack(param) {
            vm.result = param;
        }

    });

})();

Toaster Service:

(function () {
    'use strict';

    angular
        .module('app')
        .factory('confirmAlert', confirmAlert);

    confirmAlert.$inject = ['$mdDialog'];

    function confirmAlert($mdDialog) {

        var service = {
            confirmBoxResponse: confirmBoxResponse
        };

        return service;

        ////////////////////////////Implementation//////////////////////////////////////

        function confirmBoxResponse(title, content, confirmText, successCb, successCbParam) {
            var confirm = $mdDialog.confirm()
                      .title(title)
                      .textContent(content)
                      .ariaLabel('Lucky day')
                      .ok(confirmText)
                      .cancel('Cancel');

            $mdDialog.show(confirm).then(function () {
                successCb(successCbParam);
            }, function () {
                //pressed cancel
            });
        }

    }

})();

Output:

Screenshot_2

Angular Material: Custom Toast Service

Standard

Customize Angular toast service, register within your controller and other data services and use it throughout your project. For html code clone my repo from github.

Github Link

Angular Code:

(function () {
    'use strict';

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

    app.controller('toastController', function (toastAlert) {

        var vm = this;
        
        vm.defaultToaster = function () {
            toastAlert.defaultToaster('Toast Activated');
        };

        vm.customToaster = function () {
            toastAlert.customToaster('Toast Activated', '3000', 'bottom left');
        };
    });

})();

Toaster Service:

(function () {
    'use strict';

    angular
        .module('app')
        .factory('toastAlert', toastAlert);

    toastAlert.$inject = ['$mdToast'];

    function toastAlert($mdToast) {

        var service = {
            customToaster: customToaster,
            defaultToaster: defaultToaster
        };

        return service;

        ////////////////////////////Implementation//////////////////////////////////////

        function customToaster(content , delay, position) {
            $mdToast.show(
              $mdToast.simple()
                .textContent(content)
                .position(position)
                .hideDelay(delay)
            );
        }

        function defaultToaster(content) {
            $mdToast.show(
              $mdToast.simple()
                .textContent(content)
                .position('bottom right')
                .hideDelay(3000)
            );
        }
    }
})();

 

Screenshot_1

GitHub Terminal Commands

Standard

To add new files to the repository or add changed files to staged area:

$ git add <files>

To commit them:

$ git commit

To commit unstaged but changed files:

$ git commit -a

To push to a repository (say origin):

$ git push origin

To push only one of your branches (say master):

$ git push origin master

To fetch the contents of another repository (say origin):

$ git fetch origin

To fetch only one of the branches (say master):

$ git fetch origin master

To merge a branch with the current branch (say other_branch):

$ git merge other_branch

Note that origin/master is the name of the branch you fetched in the previous step from origin. Therefore, updating your master branch from origin is done by:

$ git fetch origin master
$ git merge origin/master

You can read about all of these commands in their manual pages (either on your linux or online), or follow the GitHub helps:

Entity Framework: Use Expression Trees to Build Dynamic Queries or Filter using Expression tree

Standard

Expression trees represent code in a tree-like data structure, where each node is an expression, for example, a method call or a binary operation such as x < y.

You can compile and run code represented by expression trees. This enables dynamic modification of executable code, the execution of LINQ queries in various databases, and the creation of dynamic queries. Entity Framework or LINQ to SQL operates with expression trees to construct SQL queries from lambda expressions.

Look at below syntax:

void Delete<T>(Expression<Func<T, bool>> expression) where T : class, new()

A “predicate” is any device that says “yes” or “no” to the question “is this thing a member of that set?” So a predicate for the set “integers even positive integers” would be x=> x > 0 && x % 2 == 0.

This method probably has the semantics of “delete from the collection all members of the collection that are in the set identified by the predicate”.  The predicate is passed to the method in the form of an expression tree, which is a way of passing the structure of the predicate in a manner that can be analyzed at runtime and transformed.

  • Use Expression<Func<EntityName, bool>> rather than Expression<Predicate<EntityName>>, because that’s what Queryable.Where expects
  • Pass it directly in .Where, combining them using multiple .Where calls instead of &&.Unfortunately there’s no way to use Predicate<T> in EF linq since it’s impossible to map it on SQL query. This can be done with Expressions only because they can be parsed and converted to SQL.In fact there are 4 language features that made linq possible:
    1. Extension methods
    2. Type inference
    3. Closures
      and for linq2sql especially
    4. Expressions

    Code Example

public Course EditCourse(Course obj)
{
   return courseRepo.Update(obj, x => x.CourseId == obj.CourseId);
}
public virtual T Update(T obj, Expression<Func<T, bool>> match)
{
     using (var context = new PluralSightContext())
     {
        if (obj == null)
           return null;
 
         T existing = context.Set<T>().SingleOrDefault(match);
 
         if (existing != null)
         {
              context.Entry(existing).CurrentValues.SetValues(obj);                    
              context.SaveChanges();
         }
         return existing;
      }
}

So now map Expression<Func<T, bool>> in above example: bool is return type and T refers to Course Entity, so Expression x => x.CourseId == obj.CourseId stores the info about that expression and that there’s a T x, that you’re accessing the property CourseId (T corresponds to Course entity)

Calling the == operator with the int value provided by user. When EF looks at that, it might turn it into something like [Course_Table].[CourseID_Column] == parameter value

MSDN Reference Link

MSDN Reference Link2

 

AngularJS: Prevent changes in parent scope until Save operation is performed in modal

Standard

It happens usually when ever you are using ng-repeat in parent page and pass that row data to Modal for editing purpose, any changes made in modal is reflected directly in parent page grid without saving the modal updated data.

2016-02-18 09_01_34-HomePage

As you can see I am changing Course name and it is reflected directly in grid at main page.

Solution:

What you would need is to clone your model, prior to showing your edit modal, and when a user clicks on closeModal() you would reassign your model to the cloned value.

function DialogController($mdDialog, courseData) {
 
            var vmPop = this;
            initPopUp();
 
            function initPopUp() {
                vmPop.course = [];
                if (courseData)
                    vmPop.course = angular.copy(courseData);
            }
  }

As you can see I am passing courseData to dialog modal controller, before assigning it to modal scope variable (vmPop.course), I am creating a copy of source, which is an object and then assigning it to vmPop.course variable.

Angular Docs for angular.copy