1

I'm trying to work with the this keyword in the following jQuery plugin, however I don't want to access the this of the click event, but the this of the plugin.

How do I do that? currently I get the following error in the Plugin.prototype.toggleTranslationMode function:

Cannot read property 'enableTranslationMode' of undefined

;
(function($, window, document, undefined) {
  var pluginName = 'translationMode',
    defaults = {
      //marker: "value"
    };

  function Plugin(element, options) {
    this.element = $(element);
    this.options = $.extend({}, defaults, options);
    this._defaults = defaults;
    this._name = pluginName;
    this.init();
  }

  Plugin.prototype.init = function() {
    this.getTranslationData();
    this.createMarkup();
    this.addEvents();
  };

  Plugin.prototype.getTranslationData = function() {
    this.elementIndex = this.element.data('element-index');
    this.translationIndex = this.element.data('translation-index');
    this.original = this.element.data('translation-original');
    this.translation = this.element.data('translation-trans');
    this.translationType = this.element.data('translation-type');
  }

  Plugin.prototype.createMarkup = function() {
    this.element.addClass('translation-container');
    this.element.wrapInner('<span class="editor"></span>');
    this.editor = this.element.find('.editor');
    this.addMarker();
  }

  Plugin.prototype.addMarker = function() {
    this.element.append('<div class="translation-marker">' + this.elementIndex + '-' + this.translationIndex + '</div>');
    this.marker = this.element.find('.translation-marker');
  };

  Plugin.prototype.enableTranslationMode = function() {
    console.log('translation mode enabled')
    this.element.addClass('translation-modal-visible');
    this.element.append('<div class="translation-modal">Original String:' + original + '</div>');
  }

  Plugin.prototype.disableTranslationMode = function() {
    console.log('translation mode disabled')
    this.element.removeClass('translation-modal-visible');
    this.element.find('.translation-modal').remove();
  }

  Plugin.prototype.addEvents = function() {
    this.disableLinksAndButtons();
    this.toggleTranslationMode();
  }

  /*
   * EVENTS
   */

  Plugin.prototype.toggleTranslationMode = function() {
    this.element.on('click', this.marker, function(e) {
      if ($(this).hasClass('translation-modal-visible')) {
        this.disableTranslationMode();
      } else {
        this.enableTranslationMode();
      }
    })
  }

  Plugin.prototype.disableLinksAndButtons = function() {
    $("a, button").on('click', function(e) {
      e.preventDefault();
    });
  }

  $.fn[pluginName] = function(options) {
    return this.each(function() {
      if (!$.data(this, 'plugin_' + pluginName)) {
        $.data(this, 'plugin_' + pluginName,
          new Plugin(this, options));
      }
    });
  }
})(jQuery, window, document);

jQuery(function($) {
  $('[data-translation-index]').translationMode();
});
emjay
  • 1,491
  • 5
  • 17
  • 35

1 Answers1

0

this inside event handler belongs to the element on which the event is called. You are trying to access this.element. enableTranslationMode inside your click event handler and expect it to be the same as outside(the prototype function scope). This will not be the case.

You can save the outside this as another variable and access it inside. But in your case I think you can directly access this.enableTranslitionMode since you are looking for the element itself.

Tushar Shahi
  • 16,452
  • 1
  • 18
  • 39