无限滚动的Select2组

时间:2019-02-11 10:33:23

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

我正在使用带有无限滚动的select2组选项,并且每页10的数据都是通过Ajax调用来的。这会出现一些问题,假设用户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;
  }
});

enter image description here

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

4 个答案:

答案 0 :(得分: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;
}

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

答案 1 :(得分:1)

已接受的答案对我不起作用,我不知道为什么该起作用。 $.each的返回不会从templateResult()函数返回。

这是对我有用的方法。

  1. getNestedChildren(list)不需要在JavaScript端构建嵌套列表。相反,在服务器端构建它要容易得多。
  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;
    }

});

答案 2 :(得分:0)

问题可能出在数据上

您致电用户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

答案 3 :(得分:0)

我刚刚找到了一个更好的解决方案,不会导致(重复的)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加载和对来自不同帖子类型的帖子进行分组。