Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to disable ngTouch conditionally and fallback to ng-click

How can I use ngTouch but selectively disable it for some elements? That is, for certain elements I'd like to use the original ngClick directive instead of the one that ngTouch provides. Something like this:

 <button ng-click-original="myClickFn()">click me</button>
like image 601
Gil Birman Avatar asked Jan 10 '23 16:01

Gil Birman


1 Answers

Issue is that once you include ngTouch module in the dependency its version of ngClick ngTouch.directive('ngClick' will override the original ngClickDirective of angular core. So all the clicks will be handled by ngTouch's version of ng-click so you would need to decorate the ngCLick in your module to handle your scenario. I can think of couple of approaches here:-

Approach 1 - Create your own directive

How about creating an ng-click-orig probably don't prefix it with ng since it is a custom directive.

.directive('ngClickOrig', ['$parse', function($parse) {
      return {
        compile: function($element, attr) {
          var fn = $parse(attr["ngClickOrig"]);
          return function handler(scope, element) {
            element.on('click', function(event) {
              scope.$apply(function() {
                fn(scope, {$event:event});
              });
            });
          };
        }
     };
 }]);

Demo


Approach 2:- With decorator for ng-Click directive

Another way create a decorator on ngClickDirective, look for specific attribute say notouch and perform regular click or use the original one provided by ngTouch.

.config(function($provide){
   //Create a decoration for ngClickDirective   
   $provide.decorator('ngClickDirective', ['$delegate','$parse', function($delegate, $parse) {
        //Get the original compile function by ngTouch
        var origValue = $delegate[0].compile();
        //Get set the compiler
        $delegate[0].compile = compiler;
        //return augmented ngClick
        return $delegate;

       /*Compiler Implementation*/
       function compiler(elm, attr){
          //Look for "notouch" attribute, if present return regular click event, 
          //no touch simulation
          if(angular.isDefined(attr.notouch)){
            var fn = $parse(attr["ngClick"]);
            return function handler(scope, element) {
              element.on('click', function(event) {
                scope.$apply(function() {
                  fn(scope, {$event:event});
                });
              });
            }
          }
          //return original ngCLick implementation by ngTouch
          return origValue;
         }
   }]);
});

Just as a note decorator will not run until the directive is used for the first time and it will run only once.

Example Usage:-

   <button ng-click="myClickFn()" notouch>click me</button> <-- see notouch attribute -->
   <button ng-click="myClickFnTouch()">click me</button>

Demo-Decorator

like image 162
PSL Avatar answered Jan 12 '23 07:01

PSL