Steven
Steven

Reputation: 19425

How do I assign a jQuery object to a variable?

So I have two autocomplete containers. Instead of writing code twice, I will use the same autocomplete call.

But in order to triger correct autocomplete (read: populate correct result list), I need to assign it to a variable. I've done this a long time ago, but I have forgotten how I did it.

So I have the following:

  autocomplete: function () {
    var autocompleteInput = null;
    var autocompleteResultList = null;

    $('.autocomplete').on("input", function (e) { // I have 2 of these
      autocompleteInput = $(this);  // This is the input i'm working with
      autocompleteResultList = autocompleteInput.closest('.autocomplete-result');
      resourcesData(autocompleteInput.val());
    }).on('focus', function (e) {
      autocompleteInput.val(''); //Cannot read property 'val' of null
    }).on('blur', function (e) {
      autocompleteResultList.removeClass('is-active');
    });
  }

My HTML x 2 (short version)

      <div class="autocomplete-wrapper">
        <input class="autocomplete" type="text" >
        <input class="resource-id" type="hidden">
        <div class="autocomplete-result"></div>
      </div>

I'm pretty sure it' some basic jQuery knowledge in regards of setting a variable = a jQuery object (autocompleteInput = $(this);) and how it all works that I've forgotten.

Any help appreciated :)

PS. I'm not using jQuery autocomplete - I've made my own.

Upvotes: 2

Views: 119

Answers (2)

Steven
Steven

Reputation: 19425

So after good help from Patric, Baao and Trincot (and others), I got it working. So just want to share my working solution just incase others are facing similar issues. It's probably not the most elegant solution, but it's working :)

let resources = {
  init: function () {
    this.searchResources();
  },

  searchResources: function () {
    var self = this;

    $('.autocomplete').on("input", function (e) {
      let term = $(this).val();
      if(term.length > 1){
        self.autocomplete($(this));
      }
    }).on('focus', function (e) {
      $(this).val('');
    }).on('blur', function (e) {
      $(this).closest('.autocomplete-result').removeClass('is-active');
    });
  },

  autocomplete: function(obj){
    let url = 'http://localhost.no:8080/resources%TERM';
    url = url.replace('%TERM', '/' + $(obj).val() );

    var resultList = $(obj).siblings('.autocomplete-result');
    let source = $('#autocomplete-list').html();
    let template = Handlebars.compile (source);

    $.ajax({
      method: "GET",
      url: url,
      dataType: "json",
      success: function(result) {
        let content = template({resources: result.data});
        $(resultList).html(content);

        $('.autocomplete-list-item').on('click', function (e) {
          $(obj).siblings('input.resource-id').val($(this).data('resource-id'));
          $(obj).val($(this).data('resource-name'));
          $(resultList).removeClass('is-active');
          console.log($(this).data('resource-id'));
          console.log($(this).data('resource-name'));
        });
      },
      error: function(err){console.log(err);}
    }).done(function () {
      var resultList = $(obj).siblings('.autocomplete-result');

      if(!$(resultList).hasClass('is-active')){
        $(resultList).addClass('is-active')
      }
    });
  }
};

One of my input fields looks like this:

      <div class="input-field column is-6 autocomplete-wrapper">
        <input id="autocomplete-owner" class="autocomplete" autocomplete="off" type="text" >
        <label for="autocomplete-owen">Prosjektleder</label>
        <input id="resource-id-owner" class="resource-id" type="hidden" name="resource-id-owner">
        <div class="autocomplete-result"></div>
      </div>

Upvotes: 0

trincot
trincot

Reputation: 350202

You have to abandon the variables that you share across the different event callbacks. But since they are easy to derive, just do that in each event handler itself.

Some things to note:

  • The closest method only looks to parents, not to siblings, so use the siblings method instead (or if your structure is slightly different than in your question, maybe .closest(".autocomplete-wrapper").find(".autocomplete-result")).
  • resourcesData is currently not provided with any information about where it should populate the data, so you should pass it an extra argument for it to know where to populate, and deal with that argument in that function.

Suggested code would then be:

autocomplete: function () {
    $('.autocomplete').on("input", function (e) {
        // extra argument
        resourcesData($(this).val(), $(this).siblings('.autocomplete-result'));
    }).on('focus', function (e) {
        $(this).val('');
    }).on('blur', function (e) {
        $(this).siblings('.autocomplete-result').removeClass('is-active');
    });
}

Upvotes: 3

Related Questions