2

I am working to a project with Ionic, AngularJs and PhoneGap. I want to build a directive which adds a button/icon to clean the text of an input.

I am aware that there are a lot of directives out there which do the same things, but I prefer to create it one from scratch. Also, I didn't find one that really satisfies my needs completely.

I didn't had no problem create the directive itself to append the icon, but I wasn't able to bind the click event. Seems like the event is completely ignored.

This is the directive.

(function() {
  "use strict";
  var app = angular.module("myApp");

  app.directive("clearInput", function($compile) {
    return {
      require: 'ngModel',

      link: function(scope, element, attrs) {

        if (element.next().length) {
          element.next().insertBefore(element);
        }

        var tpl = '<i class="icon ion-close-circled placeholder-icon clear-element" ng-show="' + attrs["ngModel"] + '.length>0" ></i>';
        var clear = angular.element(tpl);

        clear.bind('click', function(evt) {
          //This never gets called :(
          alert("You clicked me! Good for you.");
        });

        $compile(clear)(scope);

        element.after(clear);

      }
    }
  })
})();

I've also created a plunker to test it. http://plnkr.co/edit/KVqjpD?p=info

Any help is really appreciated!

Please, notice that I need to bind the click event to an element created at runtime, not to the element already present on the DOM.

  • Sure, because you apply an event on an element you create inside the directive. `element.on('click', function(){ alert('click'); });` should work – gr3g Aug 04 '15 at 15:23
  • Thanks gr3g, bue "element" is actually the input text. I want to bind the click of the created element (the "clear" element, which is the button). If I do what you suggest, the result is that I will fire the event every time the user click on the textbox. – Militello Vincenzo Aug 04 '15 at 15:25
  • Ok, I tought you needed a click event on the actual element. – gr3g Aug 04 '15 at 15:29
  • The code seems to be ok, in fact with 'mousedown' and even 'touch' it's working. Seems like a bug in the 'click' handler, but can not tell. – Szabolcs Páll Aug 04 '15 at 15:31
  • Actually seems to be a duplicate of: http://stackoverflow.com/questions/26463972/angular-directive-binding-click-event-to-outside-element-not-working – Szabolcs Páll Aug 04 '15 at 15:34
  • Thanks @Szabolcs Páll, I'll take a look to that post! It's weird, I tried a lot of things except the easiest one: change the event! – Militello Vincenzo Aug 04 '15 at 15:37
  • I tried what the post suggest, but it didn't work. Also, the thing here is that I am trying to bind an event to an element created and appended to the DOM at runtime. – Militello Vincenzo Aug 04 '15 at 15:44

1 Answers1

3

This appears to be related to the way "ionic deals with setting focus to inputs."

One way to work around this quirk is to wrap the icon in another element:

var tpl = '<span><i class="icon ...></i></span>',

For what it is worth, you could make this more declarative and avoid $compile:

app.directive("clearInput", function() {
  return {
    scope: {
      value: '=',
      label: '@'
    },
    restrict: 'E',
    templateUrl: 'clearinput.html',
    link: function(scope, element, attrs) {
      scope.clear = function() {
        alert('You clicked me! Good for you.');
      }
    }
  }
})

clearinput.html:

<label class="item item-input"> 
  <span class="input-label">{{label}}</span> 
  <input type="text" ng-model="value" id="usrtxt">
  <a ng-click="clear()" ng-show="value.length > 0">
    <span class="icon ion-close-circled placeholder-icon"></span>
  </a>
</label>

usage:

<clear-input label="Name" value="name"></clear-input>

Here is a working demo: http://plnkr.co/edit/13fyLiItfruTSTeVUM3A?p=preview

Community
  • 1
  • 1
j.wittwer
  • 9,497
  • 3
  • 30
  • 32