Search code examples
angularjscordovaionic-frameworkangular-directive

Combine Ionic `onHold` and Angularjs `ng-click` to select element


In my current ionic App, I have some box that I want to select them exactly in the form of select chat in Telegram, That means:

1. At first I start select box by OnHold gesture in ionic, This work correctly.

2. After that I want to select or deselect box by click on each of them, This is not working

There is JSFiddle

HTML

<ion-content>
  <div class="box" select-box>box 1</div>
  <div class="box" select-box>box 2</div>
  <div class="box" select-box>box 3</div>
</ion-content>

JS

var app = angular.module('app', ['ionic']);
app.directive("selectBox", ["$ionicGesture", "$rootScope",
  function($ionicGesture, $rootScope) {
    return {
      scope: {},
      restrict: "A",
      link: function(scope, elem, attrs) {

          // onHold => start select box by `onHold` => working good
          $ionicGesture.on('hold', function() {
            elem.addClass("selected");
            $rootScope.startSelect = true; // to enable select box by click
          }, elem);

          // after start select box in `onHold` gesture => 
          // select box by click => not working
          if ($rootScope.startSelect) {
            elem.on("click", function() {
              if (elem.hasClass('selected')) {
                elem.removeClass("selected");
              } else {
                elem.addClass("selected");
              }
            });
          }

        } // link function

    } // return
  }
]); // directive

app.controller('MainCtrl', ["$scope", "$rootScope",
  function($scope, $rootScope) {
        $rootScope.startSelect = false;
  }
]);

CSS

.box {
  padding: 10px;
  margin: 15px;
  background: #FFF;
  width: 200px;
  margin: 15px auto;
}

.selected {
  background: red;
  color: #FFF;
}

Now, How to do this? Thanks in advance


Solution

  • From AngularJS documentation:

    Directives that want to modify the DOM typically use the link option to register DOM listeners as well as update the DOM. It is executed after the template has been cloned and is where directive logic will be put.

    Therefore, link is executed only once at the beginning. And so is the part where you check this: if ($rootScope.startSelect) {...}. You'll have to check if this value is true inside another listener for it to be executed every time. You can use tap gesture, for example:

    $ionicGesture.on('tap', function() {
      if ($rootScope.startSelect) {
        if (elem.hasClass('selected')) {
          elem.removeClass('selected');
        } else {
          elem.addClass('selected');
        }
      }
    }, elem);
    

    Notice that $rootScope.selected will remain true after the first hold event, so taping will act as a select too. Don't know if this is the functionality you look for.

    Here's an updated fiddle with your example: http://jsfiddle.net/browomk2/2/