Preventing a click event in a custom gesture directive


#1

Hey there. Trying to implement a custom tap-hold gesture using some code I found here on the forums… Tap-hold is used to open a modal on a specific element, which also has a click element (for navigating to a different view). The tap-hold actually works great and opens the modal like it should, but unfortunately the ng-click handlers also get fired at the end of the tap-hold (on release), which closes the modal and navigates to the item’s template. I am trying to prevent this click thus far with limited success. See here:

JS

app.directive('myOnHold', function($ionicGesture) {
  return {
    restrict: 'A',
    scope: {
      onHold: '&myOnHold'
    },
    link: function (scope, element, attr) {
      // var onHold = scope.onHold;
      console.log(element);

      var handleHold = function(e) {
        // Access e.gesture for gesture related information
        console.log('Hold: ', e.gesture);
        console.log(e);
        e.preventDefault(); // does nothing
        e.gesture.preventDefault();  // also does nothing
        scope.onHold();  // taken from original var above
      };

      var holdGesture = $ionicGesture.on('hold', handleHold, element);

      scope.$on('$destroy', function() {
        $ionicGesture.off(holdGesture, 'hold', handleHold);
      });
    }
  }
});

HTML

<form ng-submit="addTag(newTagText)" data-ajax="false">
      <label class="tagLabel" ng-click="clickTag()" my-on-hold="tagMenu($index, tag); $event.preventDefault()" ng-repeat="tag in templates.categories track by $index" style="{{tag.selectedStyle}}">
    
         <p>{{tag.name}}<span ng-show="!tag.active">*</span></p>
         <input type="checkbox" ng-model="tag.checked" id="checked" class="hiddenButton">    
      </label>
      <label>
           <div style="border-left: none; border-top: none; border-bottom: none; border-right: 40px solid #f8f8f8">
                <input type="text" id="inputText" ng-model="newTagText" placeholder="new tag category...">
            </div>
      </label>

Any ideas would be much appreciated.

Thanks,
Marc


#2

In beta 7, we exposed gestures on directives. So you could have on-tap="someFunction()" and on-hold="anotherFunction()" and they won’t conflict with each other.


#3

Hm. Weird. This Codepen does not work for me. I don’t get any tap or hold events registered. Using the latest Chrome for testing. I also tried updating my codebase with Beta8 (I was on Beta6), and no luck there in the browser either. Haven’t tried a build yet though…


#4

OK, looked a bit more closely and I see that there are only gesture events registered on the edit button in the header (I was trying to work with the contact names). Anyway… works great in the Codepen. However, not working in my codebase. HTML as follows:

<form ng-submit="addTag(newTagText)" data-ajax="false">
    <label class="tagLabel" on-tap="clickTag()" on-hold="tagMenu($index, tag)" ng-repeat="tag in templates.categories track by $index" style="{{tag.selectedStyle}}"> <!-- style="{{tag.selectedStyle}}" -->

        <p>{{tag.name}}<span ng-show="!tag.active">*</span></p>
        <input type="checkbox" ng-model="tag.checked" id="checked" class="hiddenButton">
    </label>
    <label>
    <div style="border-left: none; border-top: none; border-bottom: none; border-right: 40px solid #f8f8f8">
        <input type="text" id="inputText" ng-model="newTagText" placeholder="new tag category...">
    </div>
    </label>
</form>

Does it only work on buttons for some reason? I am trying to make it work on a checkbox input label.

Thanks.


#5

No it should work well on any element. Try replacing the label with a div instead. Ionic uses the labels to set focus to the inputs, so that could be messing things up


#6

Nope, the label/div issue is not the problem. I have narrowed it down, though. What I didn’t tell you before is that this is all happening inside a slide box. See the following:

<ion-content has-header="true" >  
    <label class="tagLabel" on-tap="tapMe()" on-hold="holdMe()">holdMe
    <input type="checkbox"></input>
    </label>
    <ion-slide-box on-slide-changed="slideChanged(index)">

        <ion-slide>
            <div>

                <label class="tagLabel" on-tap="clickTag()" on-hold="tagMenu($index, tag)" ng-repeat="tag in templates.categories track by $index" style="{{tag.selectedStyle}}"> 
                    <p>{{tag.name}}<span ng-show="!tag.active">*</span></p>
                    <input type="checkbox" ng-model="tag.checked" id="checked" class="hiddenButton">
                </label>

                <form ng-submit="addTag(newTagText)" data-ajax="false">
                    <div>
                    <div style="border-left: none; border-top: none; border-bottom: none; border-right: 40px solid #f8f8f8">
                        <input type="text" id="inputText" ng-model="newTagText" placeholder="new tag category...">
                    </div>
                    </div>
                </form>
            </div>
            <br/>
            <br/>
            <br/>
            <br/>
        </ion-slide>
        <!-- TWO MORE SLIDES -->
    </ion-slide-box>

</ion-content>

The label inside the content tag but before the slide box registers taps and holds just fine. Nothing inside the slide box registers a tap or hold. Is this a bug? A known limitation? Something I’m still doing wrong here?

Thanks.


#7

It shouldn’t. Seems to work for me.

But I am using the nightly builds. Want to put together a same codepen? I can try to copy and past, but you’ll be able to best recreate the situation.


#8

Well, I gave up on fiddling with it and tried the nightlies. Voila, it works. So I would say with some confidence that it’s broken in certain situations in Beta8.