panorama-ed / maximize-select2-height

Let your Select2 dropdowns take advantage of the space on the page.
52 stars 20 forks source link

Doesn't work with custom template #11

Closed linotex closed 3 years ago

linotex commented 6 years ago

I get data from ajax and have custom template. After render all items (event 'change.select2' or 'change'), I call magic method 'maximizeSelect2Height' but it reset to default template(((

let city = $("#city");
city.select2({
        templateResult:function(state) {

            if (!state.id) {
                return '';
            }
            return $('<span><b>' + state.text + '</b><br><span style="font-size: 12px;color: #444">'+state.d_name+'</span><br><span style="font-size: 12px;color: #444">'+state.r_name+'</span></span>');
        },

        ajax: {

            delay:250,

            url:city.attr('data-url-city'),

            transport: function (params, success, failure) {

                if(params.data.term === undefined || params.data.term === '')
                {
                    let json_str = $.cookie('last_selected_cities');

                    let arr = [];

                    if(json_str !== undefined)
                    {
                        arr = JSON.parse(json_str);
                    }

                    success(arr);

                } else {

                    params.data = {search:params.data.term, limit:city.attr('data-limit')};
                    var $request = $.ajax(params);

                    $request.then(success);
                    $request.fail(failure);

                    return $request;
                }
            },
            processResults: function (data) {
                return {
                    results: data
                };
            },

        }

    });
   city.on('change', function () {
        city.select2().maximizeSelect2Height(); //reset to default template
    });

Thanks a lot!

JacobEvelyn commented 6 years ago

Thanks for the report, @linotex! Is this something you'd be interested in investigating? (The code is only 56 lines, plus comments.)

Since we don't use templateResults, we probably won't prioritize investigating this soon, unfortunately.

JacobEvelyn commented 4 years ago

Hi @linotex! I finally had a chance to dig into this (and it seems like this might be what @xbaha is reporting in #19). I was able to reproduce some of the weirdness with the following code snippet:

<html>
  <head>
    <link
      href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.5/css/select2.min.css"
      rel="stylesheet"
    />
    <script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.5/js/select2.min.js"></script>
    <style>
      html,
      body,
      select {
        font-family: sans-serif;
        font-size: 18px;
        line-height: 18px;

        padding-left: 10px;
        margin-left: 0;
      }

      body {
        /*width: 100%;*/ /* Uncomment for horizontal scrollbar (see README). */
        background-color: #f1edc2;
      }
    </style>
  </head>
  <body>
    <div style="position: absolute; top: 600px; left: 200px">
      <select id="test_thing_1" style="width: 200px">
      </select>
    </div>
    <script>
      // maximize-select2-height v1.0.3
      // (c) Panorama Education 2018
      // MIT License
      !function(t){"use strict"
      var e=t(window),n=t(document),o=function(o,i){return t.extend({cushion:i&&n.width()>e.width()?30:10},o)},i=function(n,i,c,r,s){var u,h,l
      return s?u=window.document.documentElement.clientHeight+e.scrollTop()-i.offset().top:(l=t("#select2-"+n+"-container").parent().parent().parent().offset().top,h=c.height()-i.height(),u=l-e.scrollTop()-h),u-o(r,s).cushion}
      t.fn.maximizeSelect2Height=function(e){return this.each(function(n,o){t(o).on("select2:open",function(){setTimeout(function(){var n=t("#select2-"+o.id+"-results"),c=n.parent(),r=c.parent(),s=r.hasClass("select2-dropdown--below"),u=i(o.id,n,r,e,s)
      c.css("max-height",u),n.css("max-height",u),t(document).trigger("scroll")})})})}}(jQuery)

      $(function() {
        let city = $("#test_thing_1");
        city.select2({
          templateResult: function(state) {
            console.log(state);
            if (!state.id) {
              return "";
            }
            return $(
              "<span><b>" +
                state.text +
                '</b><br><span style="font-size: 12px;color: #444">' +
                state.d_name +
                '</span><br><span style="font-size: 12px;color: #444">' +
                state.r_name +
                "</span></span>"
            );
          },

          ajax: {
            delay: 250,

            url: "https://jsonplaceholder.typicode.com/todos",
            data: function(params) {
              return { userId: params.term };
            },

            processResults: function(data) {
              return {
                results: data.map(d => {
                  return {
                    id: d.id,
                    text: d.title,
                    d_name: d.completed + d.id,
                    r_name: d.userId + d.completed
                  };
                })
              };
            }
          }
        });
        city.on('change', function () {
             city.select2().maximizeSelect2Height(); //reset to default template
        });
      });
    </script>
  </body>
</html>

But I'm not sure why you're calling maximizeSelect2Height() on the change event. You should be calling it on the initial select2() call, like select2(...).maximizeSelect2Height(). Does that help?

JacobEvelyn commented 3 years ago

Hi @linotex! I haven't heard back in a while so I'm going to close this issue. I don't think I understand why you're calling select2() again on the change event. Feel free to re-open this issue if we can be more helpful!