0

I have a function, simplified like this:

var fooFunction = function($container, data) {
  $container.data('foobarData', data);

  $container.on('click', 'a', function(e) {
    var data = $(e.delegateTarget).data('foobarData');
    var $target = $(e.currentTarget);

    if (typeof data.validateFunction === 'function' && !data.validateFunction(e)) {
      return;
    }

    e.preventDefault();
    e.stopPropagation();

    // Do stuff
    console.log(data.returnText);
  });
};

fooFunction('.same-container', {
  validateFunction: function(event) {
    return $(e.currentTarget).closest('.type-companies').length ? true : false;
  },
  returnText: 'Hello Company!',
});

fooFunction('.same-container', {
  validateFunction: function(event) {
    return $(e.currentTarget).closest('.type-humans').length ? true : false;
  },
  returnText: 'Hello Human!',
})

I am using event delegation on the same container (.same-container) with a custom validateFunction() to validate if the code in // Do stuff should run.

For each fooFunction() initiation, I have some different logic that will get called on // Do stuff. The issue is that those two event delegations conflict. It seems that only one of them is called and overwrites the other one.

How can I have multiple event delegations with the option to define via a custom validateFunction which one should be called. I use preventDefault() + stopPropagation() so on click on a <a>, nothing happens as long as validateFunction() returns true.

Barmar
  • 741,623
  • 53
  • 500
  • 612
S Osten
  • 15
  • 1
  • 5

1 Answers1

0

The problem is that you're overwriting $(e.delegateTarget).data('foobarData') every time.

Instead, you could add the options to an array, which you loop over until a match is found.

var fooFunction = function($container, data) {
  var oldData = $container.data('foobarData', data);
  if (oldData) { // Already delegated, add the new data
    oldData.push(data);
    $container.data('foobarData', oldData);
  } else { // First time, create initial data and delegate handler
    $container.data('foobarData', [data]);
    $container.on('click', 'a', function(e) {
      var data = $(e.delegateTarget).data('foobarData');
      var $target = $(e.currentTarget);
      var index = data.find(data => typeof data.validateFunction === 'function' && !data.validateFunction(e));
      if (index > -1) {
        var foundData = data[index]

        e.preventDefault();
        e.stopPropagation();

        // Do stuff
        console.log(foundData.returnText);
      }
    });
  }
}
Barmar
  • 741,623
  • 53
  • 500
  • 612
  • Thanks for the help! That my `.data()` was called twice and therefore the second call overwrites the first one, I did not see! This will fix it! Thanks! – S Osten Jul 12 '18 at 20:13