Unable to show "Searching" when using select2 (Loading remote data)
Asked Answered
P

4

6

Refer to https://select2.github.io/examples.html, text "Searching" is shown when the remote data is loading. However, I don't know why "undefined" is shown in my case.

This is the css file.

<div class="col-sm-9">
  <select class="js-data-example-ajax form-control" style="width:100%;">
    <option value="select2/select2" selected="selected">select2/select2</option>
  </select>
</div>

And the setting of ajax call

$(".js-data-example-ajax").select2({
      ajax: {
        url: "/search/products",
        dataType: 'json',
        delay: 250,
        data: function (params) {
          return {
            q: params.term,
            page: params.page
          };
        },
        processResults: function (data, page) {
          return {
            results: data.items
          };
        },
        cache: true
      },
      minimumInputLength: 1,
      templateResult: formatProduct, 
      templateSelection: formatProductSelection
    });

Result:

enter image description here

Pedropedrotti answered 12/1, 2015 at 9:43 Comment(3)
is search/products definitely returning valid json?Cryohydrate
yes, the search result is shown properlyPedropedrotti
I'm having the same issue. While loading, I have a "undefined" shown there. If you remember the solution you found, @tony.0919, that would be amazing!Portentous
S
1
function formatRepo (repo) {
    if (repo.loading) return repo.text;

    var markup = '<div class="clearfix">' +
    '<div class="col-sm-1">' +
    '<img src="' + repo.owner.avatar_url + '" style="max-width: 100%" />' +
    '</div>' +
    '<div clas="col-sm-10">' +
    '<div class="clearfix">' +
    '<div class="col-sm-6">' + repo.full_name + '</div>' +
    '<div class="col-sm-3"><i class="fa fa-code-fork"></i> ' + repo.forks_count + '</div>' +
    '<div class="col-sm-2"><i class="fa fa-star"></i> ' + repo.stargazers_count + '</div>' +
    '</div>';

    if (repo.description) {
      markup += '<div>' + repo.description + '</div>';
    }

    markup += '</div></div>';

    return markup;
  }

  function formatRepoSelection (repo) {
    return repo.full_name || repo.text;
  }

  $ajax.select2({
    ajax: {
      url: "https://api.github.com/search/repositories",
      dataType: 'json',
      delay: 250,
      data: function (params) {
        return {
          q: params.term, // search term
          page: params.page
        };
      },
      processResults: function (data, params) {
        // parse the results into the format expected by Select2
        // since we are using custom formatting functions we do not need to
        // alter the remote JSON data, except to indicate that infinite
        // scrolling can be used
        params.page = params.page || 1;

        return {
          results: data.items,
          pagination: {
            more: (params.page * 30) < data.total_count
          }
        };
      },
      cache: true
    },
    escapeMarkup: function (markup) { return markup; },
    minimumInputLength: 1,
    templateResult: formatRepo,
    templateSelection: formatRepoSelection
  });

complete code which loads repositories in select 2 you can alter this code according to your requirements enter image description here

my select box with multiple select

<select id="to_users" name="to_users" class="form-control js-data-example-ajax" multiple="multiple">
                                                        </select>

you can format results

processResults: function(data, page) {
                    // parse the results into the format expected by Select2.
                    // since we are using custom formatting functions we do not need to
                    // alter the remote JSON data
                    return {
                        results: $.map(data, function(obj) {
                        return { id: obj.user_id, text: obj.name };
                    })
                        //results: data
                    };
                },

if you are formatting results to select2 behaviour then disable code

/*  escapeMarkup: function(markup) {
                return markup;
            }, // let our custom formatter work

            templateResult: formatRepo, // omitted for brevity, see the source of this page
            templateSelection: formatRepoSelection // omitted for brevity, see the source of this page*/
Selfabsorbed answered 23/4, 2015 at 6:15 Comment(0)
P
1

Please try

function formatRepo(repo) {
  if (repo.value == undefined) {
    repo.value = 'Loading...'
  }
  var markup = '<div class="clearfix">' + repo.value + '</div>'

  return markup;
}
Ptisan answered 24/11, 2016 at 3:49 Comment(0)
P
0

There is a possible workaround for the above issue. Feel free to make comments.

Here is the code I've written before, let say the return JSON is {"items":[{"id":1,"name":"Product1"},{"id":2,"name":"Product2"}]}

var formatProduct = function(data){
   return '<div>'+(data.name)+'</div>';
}

I've modified the code as follow and the 'Searching...' text shows again:

var formatProduct = function(data){
   return '<div>'+(data.name || data.text)+'</div>';
}

In select2.js, line 798, when the data is remotely loading

this.template(data, option);

this.template directs to select2.js line 1058

Results.prototype.template = function (result, container) {
  var template = this.options.get('templateResult');
  container.innerHTML = template(result);
};
// result is an object indicating whether the data is loading.
// {disabled: true, loading: true, text: "Searching…"}

the template here takes the custom parameter 'templateResult' and generate the text, therefore, the custom function must contain data.text, otherwise it returns underfined.

Pedropedrotti answered 12/1, 2015 at 16:8 Comment(0)
R
0

In my case it was the formatProduct function (it has a different name in my code, but it's the same thing). Let's say you call formatProduct for templateResult:

templateResult: formatProduct

In this case you have to check what formatProduct returns, like:

function formatProduct(product) {
           return product.name || product.text;
         }

In my case I was returning always product.name and the "Searching" text was under product.text, so I had to check to display it when no product was being found yet.

Rutan answered 24/4, 2016 at 20:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.