baker
baker

Reputation: 211

jQuery object literal or module pattern with jQuery plugins

Let's say we have something like this with the jQuery select2 plugin:

$(function() {

  $('.select2').select2({
    minimumInputLength: 1,
    ajax: {
      dataType: 'json',
      cache: true,
      url: getUrl,
      data: getData,
      processResults: getProcessResults
    }
  });

  function getUrl() {
    return 'http://beta.json-generator.com/api/json/get/4JZYSpOHM';
  }

  function getData(params) {
    return {
      q: params.term
    };
  }

  function getProcessResults(data) {
    return {
      results: data
    };
  }

});
.select2 {
  width: 100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/js/select2.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/css/select2.min.css" rel="stylesheet" />

<select class="select2"></select>

But we wanna use an object literal or the module pattern for the jQuery feature and plugin like this:

var myAjax = {

  init: function() {
    var _this = this;

    $('.select2').select2({
      minimumInputLength: 1,
      ajax: {
        dataType: 'json',
        cache: true,
        url: _this.getUrl,
        data: _this.getData,
        processResults: _this.getProcessResults
      }
    });
  },

  getUrl: function() {
    return 'http://beta.json-generator.com/api/json/get/4JZYSpOHM';
  },

  getData: function(params) {
    return {
      q: params.term
    };
  },

  getProcessResults: function(data) {
    return {
      results: data
    };
  }
  
};

$(document).ready(myAjax.init);
.select2 {
  width: 100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/js/select2.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/css/select2.min.css" rel="stylesheet" />

<select class="select2"></select>

How can we do that?

Sources:

https://learn.jquery.com/code-organization/concepts/

https://select2.github.io/examples.html#data-ajax

Upvotes: 1

Views: 490

Answers (1)

Rory McCrossan
Rory McCrossan

Reputation: 337743

The issue you have is that this within the init function will refer to the document, as you run it under the document.ready handler. To fix this you can use the myAjax variable directly to call its properties and methods. Try this:

var myAjax = {
  init: function() {    
    $('.select2').select2({
      minimumInputLength: 1,
      ajax: {
        dataType: 'json',
        cache: true,
        url: myAjax.getUrl(),
        data: myAjax.getData,
        processResults: myAjax.getProcessResults
      }
    });
  },
  getUrl: function() {
    return 'http://beta.json-generator.com/api/json/get/4JZYSpOHM';
  },
  getData: function(params) {
    return {
      q: params.term
    };
  },
  getProcessResults: function(data) {
    return {
      results: data
    };
  }
};

$(document).ready(myAjax.init);
.select2 {
  width: 100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/js/select2.min.js"></script>

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/css/select2.min.css" />
<select class="select2"></select>

I'd also suggest you change the name of the object as myAjax isn't very semantic given its purpose.

Upvotes: 1

Related Questions