【问题标题】:Select2 group with Infinite scroll无限滚动的 Select2 组
【发布时间】:2019-02-11 10:33:23
【问题描述】:

我正在使用无限滚动的 select2 组选项,数据来自 Ajax 调用每页 10。这里出现了一些问题,假设用户 1 有 15 个数据,用户 2 有 15 个数据,最初 10 个数据来自用户1 和下一页 10(用户 1 的 5 个数据和用户 2 的 5 个数据)。数据获取没有问题,但问题是用户 1 组显示双倍。如何防止双重显示到我的 select2 选项组?有没有办法再做一个选项组?

HTML 代码

<div class="container">
  <form id="frm">
    <h1>Solution 1</h1>
    <div class="row">
      <div class="col-4">
        <div class="form-group">
          <label for="tagInput">Get data by ajax calling</label>
          <select class="form-control" id="pictures_tag_input">
</select>
          <small class="form-text text-muted"><p class="text-info">Infinite Scroll</p></small>
        </div>
      </div>
    </div>
  </form>
</div>

JS 代码

$(document).ready(function() {
  // solution 1
  //example.com/articles?page[number]=3&page[size]=1
  http: $("#pictures_tag_input").select2({
    placeholder: "Search for options",
    ajax: {
      url: "https://jsonplaceholder.typicode.com/users/1/todos",
      dataType: "json",
      global: false,
      cache: true,
      delay: 250,
      minimumInputLength: 2,
      data: function(params) {
        // console.log(params.page || 1);
        return {
          q: params.term, // search term
          _page: params.page || 1,
          _limit: 10 // page size
        };
      },
      processResults: function(data, params) {
        params.page = params.page || 1;
        var datx = getNestedChildren(data);
        // console.log(datx);

        return {
          results: datx,
          pagination: {
            more: true
          }
        };
      } //end of process results
    } // end of ajax
  });

  function getNestedChildren(list) {
    var roots = [];
    for (i = 0; i < list.length; i += 1) {
      node = list[i];

      if (roots.length === 0) {
        var obj = {
          text: "User " + node.userId,
          children: [{ id: node.id, text: node.title }]
        };
        roots.push(obj);
      } else {
        var obj = {
          text: "User " + node.userId,
          children: [{ id: node.id, text: node.title }]
        };
        var rootArray = $.map(roots, function(val, i) {
          var vl = "User " + node.userId;
          if (val.text === vl) return val;
          else return undefined;
        });
        if (rootArray.length > 0) {
          var obj1 = {
            id: node.id,
            text: node.title
          };
          rootArray[0].children.push(obj1);
        } else {
          roots.push(obj);
        }
      }
    }
    return roots;
  }
});

Demo https://codepen.io/mdshohelrana/pen/MLVZEG

【问题讨论】:

    标签: javascript jquery-select2 jquery-select2-4


    【解决方案1】:

    试试下面的代码

    templateResult: function(data) {
     if (typeof data.children != 'undefined') {
      $(".select2-results__group").each(function() {
       if (data.text == $(this).text()) {
        return data.text = '';
       }
      });
     }
     return data.text;
    }
    

    注意:需要从服务器端进行分组,否则您必须从客户端制作主详细信息。

    【讨论】:

    • 这个解决方案对我不起作用。你能解释一下为什么它应该起作用吗?
    【解决方案2】:

    接受的答案对我不起作用,我不明白为什么应该这样做。 $.each 中的返回不会从 templateResult() 函数返回。

    这是一种对我有用的方法。

    1. 没有必要在javascript 端通过getNestedChildren(list) 构建嵌套列表。相反,在服务器端构建它要容易得多。
    2. 可以使用 templateResult 选项自定义下拉列表(选项和 optgroups)中搜索结果的外观。我通过此选项删除了重复的 optgroup 和标签。

    检查代码的templateResult: formatOptions, 部分

    $(document).ready(function() {
        $("#pictures_tag_input").select2({
            placeholder: "Search for options",
            templateResult: formatOptions,
            ajax: {
                url: "https://jsonplaceholder.typicode.com/users/1/todos",
                dataType: "json",
                global: false,
                cache: true,
                delay: 250,
                minimumInputLength: 2,
                data: function(params) {
                    return {
                        q: params.term,
                        _page: params.page || 1,
                        _limit: 10
                    };
                },
                processResults: function(data, params) {
                    params.page = params.page || 1;
    
                    return {
                        results: data,
                        pagination: {
                            more: true
                        }
                    };
                } //end of process results
    
            } // end of ajax
        });
    
        function formatOptions(item, container, $el) {
            // optgroups section
            if (item.children && item.children.length > 0) {
                // don't format the repeated optgroups!
                if ($(".select2-results__group").text() === item.text) {
                    return;
                }
    
                if ($('[aria-label="' + item.text + '"]').length > 0) {
                    return;
                }
    
                // the first occasion of the given optgroup
                return $el;
            }
    
            // options section
            // here you can implement your own logic
            // if you want to customise the output of the options
            $el.addClass('something-special-result result');
    
            return $el;
        }
    
    });
    

    【讨论】:

      【解决方案3】:

      也许问题是数据的来源

      您调用用户 1 .... 服务器返回 1

      您调用用户 2 .... 服务器返回 1

      您调用用户 3 .... 服务器返回 2

      您调用用户 4 .... 服务器返回 2

      您调用用户 5 .... 服务器返回 3

      您调用用户 6 .... 服务器返回 3

      curent_user = 1;
      $(document).ready(function() {
        http: $("#pictures_tag_input").select2({
          placeholder: "Search for options",
          ajax: {
            url: "https://jsonplaceholder.typicode.com/users/1/todos",
            dataType: "json",
            global: false,
            cache: false,
            minimumInputLength: 2,
            data: function(params) {
             console.log("params",params || 1);
              return {
                q: params.term, // search term
                _page: curent_user,
                _limit: 10 // page size
              };
            },
      
            processResults: function(data, params) {
              curent_user += 2;
              var datx = getNestedChildren(data);
              console.log("data: ", data);
      
              return {
                results: datx,
                pagination: {
                  more: true
                }
              };
            } //end of process results
          } // end of ajax
        });
      
        function getNestedChildren(list) {
          var roots = [];
          for (i = 0; i < list.length; i += 1) {
            node = list[i];
      
            if (roots.length === 0) {
              var obj = {
                text: "User " + node.userId,
                children: [{ id: node.id, text: node.title }]
              };
              roots.push(obj);
            } else {
              var obj = {
                text: "User " + node.userId,
                children: [{ id: node.id, text: node.title }]
              };
              var rootArray = $.map(roots, function(val, i) {
                var vl = "User " + node.userId;
                if (val.text === vl) return val;
                else return undefined;
              });
              if (rootArray.length > 0) {
                var obj1 = {
                  id: node.id,
                  text: node.title
                };
                rootArray[0].children.push(obj1);
              } else {
                roots.push(obj);
              }
            }
          }
          return roots;
        }
      });
      

      所以如果你跳过一步

      您调用用户 1 .... 服务器返回 1

      您调用用户 3 .... 服务器返回 2

      您调用用户 5 .... 服务器返回 3

      【讨论】:

      • 这不是数据问题兄弟,我的页面大小为10。每次ajax获取数据10。但是select2无法重新排列选项组。这是问题所在。获取页面数据后如何重新排列选项组?
      • 查看我的代码,不要使用 params.page,使用变量 current_user,我在这里尝试并工作...
      • 您的代码不符合我的要求,我需要每页 10 个数据并重新排列 select2 组选项。
      【解决方案4】:

      我刚刚找到了一个更好的解决方案,它不会导致(重复的)optgroup 被呈现为空选项:

      processResults: function( json, params ){
      
          setTimeout( function() {
      
              var $prevOptions = false;
              var $prevGroup = false;
      
              // loop
              $('.select2-results__option[role="group"]').each(function(){
      
                  // vars
                  var $options = $(this).children('ul');
                  var $group = $(this).children('strong');
      
                  // compare to previous
                  if( $prevGroup && $prevGroup.text() === $group.text() ) {
                      $prevOptions.append( $options.children() );
                      $(this).remove();
                      return;
                  }
      
                  // update vars
                  $prevOptions = $options;
                  $prevGroup = $group;
      
              });
      
          }, 1 );
      
          return json;
      
      }
      

      Advanced Custom Fields 为他们的 WordPress 插件使用完全相同的代码来解决这个问题,ajax-load 和来自不同帖子类型的帖子分组。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-05-09
        • 2015-12-21
        • 1970-01-01
        • 2016-09-02
        • 1970-01-01
        • 2021-09-24
        • 2016-04-03
        相关资源
        最近更新 更多