【问题标题】:Retrieve two lists, sort and compare values, then display all the results检索两个列表,排序和比较值,然后显示所有结果
【发布时间】:2016-05-09 07:34:54
【问题描述】:

我在 SharePoint 2013 Online 中有两个列表。我需要获取用户输入的键(字符串)的匹配值,排序并将两个列表显示为一个。如果我能够使用 SQL 创建视图就足够简单了。最好的解决方案似乎是只显示两个列表。

我尝试过使用 SPD 链接源,但“链接字段”选项从不显示,并且无预览 SPD 很糟糕(MS 是怎么想的?)。工作流程不可行。可以在“数据表视图”中编辑列表项(客户要求)。查找需要选择以显示相关字段。

我可以获取两个列表并分别显示它们。

我有什么:

List 1                          List 2
fruit apple  type rome          fruit apple  state washington
fruit pear   type bartlett      fruit pear   state oregon
fruit grapes type red           fruit orange state florida

我想要什么:

fruit apple  type rome      state washington 
fruit grapes type red 
fruit orange                state florida
fruit pear   type bartlett  state oregon

我遗漏了两件事(也许更多)一个可用于排序的数组和一个用于匹配两个列表上的水果的比较。实际列表可能有 50-120 个项目(每个)需要匹配。

所有物品都应退回。如果有匹配,数据应该在同一行。如果不是,则应显示空白。

下面的代码通过一个 html 页面显示,其中每个表格单元格的 ID 与下面脚本中的单元格引用相匹配。它没有排序,行不匹配。

$(function() {
    $.ajax({
    url: "sharepointlist/_api/web/lists/GetByTitle('List1')/items",

    type: "GET",
    headers: { "accept": "application/json;odata=verbose"
      }, 
    }).success(function (data) {

        var title = '';
        var type = '';
         $.each(data.d.results, 
        function (key, value) {

        title += "Title: " + value.Title + "<br/>";
        type += "Type: " + value.Type  + "<br/>";
        }); 

    $("#tdtitle").html(title);
    $("#tdtype").html(status);

$.ajax({
    url: "sharepointlist/_api/web/lists/GetByTitle('List2')/items",

    type: "GET",
    headers: { "accept": "application/json;odata=verbose"
      }, 
    }).success(function (data) {

        var title2 = '';
        var state = '';
         $.each(data.d.results, 
        function (key, value) {

        title2 += "Title2: " + value.Title + "<br/>";
        city += "State: " + value.State + "<br/>";
        }); 

    $("#tdsecond").html(title2);
    $("#tdstate").html(city);

【问题讨论】:

  • 这显然需要一些数据映射。具体问题是什么?

标签: javascript jquery list sorting sharepoint


【解决方案1】:

您似乎正在尝试对从 REST 查询返回的列表项执行“加入”操作。如果是这样,您可以考虑以下方法

function getListItems(webUrl,listTitle,selectProperties){
   return $.getJSON( webUrl + "/_api/web/lists/GetByTitle('" + listTitle + "')/items?$select=" + selectProperties.join(','))
   .then(function(data){
        return data.value.map(function(item){
             return selectProperties.reduce(function(result, key) { 
                 result[key] = item[key]; 
                 return result; 
             },{});    
        });
    });    
}


function joinListItems(left, right, key) {
    if(left.length == 0 || right.length == 0)
        return new Error("No data was found");


    var columns = Object.keys(left[0]).concat(Object.keys(right[0]));

    var createRow = function(left,right){
        var row = {};
        columns.forEach(function(key){
          row[key] = null;
        });
        var values = left != null ? left : right;
        for(var name in values) row[name] = values[name];
        return row;
    };
    var updateRow = function(existingRow,values){
        for(var name in values) existingRow[name] = values[name];
    };

    return left.concat(right).reduce(function(result, current, index){ 

      if(index < left.length){ 
           result.rows.push(createRow(current,null));   
           result.keys[current[key]] = index;
      }
      else {
           var rowIdx = result.keys[current[key]];
           if(typeof rowIdx !== 'undefined'){
               updateRow(result.rows[rowIdx],current);
           }
           else {
               result.rows.push(createRow(null,current));
           }
      } 

      return result;
    },{rows: [], keys: {}}).rows;

}



$.when(
    // Get List1
    getListItems( _spPageContextInfo.webAbsoluteUrl, "List1",['Title','Type']),
    // Get List2
    getListItems( _spPageContextInfo.webAbsoluteUrl, "List2",['Title','State'])

)
.then(function(items1,items2){
    var key='Title';
    var result = joinListItems(items1,items2,key);

    result = result.sort(function(a, b){
        return a.Title.localeCompare(b.Title);
    });

    console.log(JSON.stringify(result,null,2));
    //displayResults(result);
});


//print results (from comment section) 
function displayResults(items){
   var title = ''; 
   var type = ''; 
   $.each(items, function (index, item) { 
       title += "Title: " + item.Title + "<br/>"; 
       type += "Type: " + item.Type + "<br/>"; 
   });
}

您还可能会发现 this thread 很有帮助,专门讨论 加入操作。

结果

[
  {
    "Title": "fruit apple",
    "Type": "type rome",
    "State": "state washington"
  },
  {
    "Title": "fruit grapes",
    "Type": "type red",
    "State": null
  },
  {
    "Title": "fruit orange",
    "State": "state florida",
    "Type": null
  },
  {
    "Title": "fruit pear",
    "Type": "type bartlett",
    "State": "state oregon"
  }
]

排序功能更新

替换:

 result = result.sort(function(a, b){
    return a.Title.localeCompare(b.Title);
});

result = result.sort(function(a, b){
    if(!a.Title) a.Title = "";
    if(!b.Title) b.Title = "";
    return a.Title.localeCompare(b.Title);
});

【讨论】:

  • 是的。那是我的目标。我需要研究你的解决方案。你展示的结果正是我想要的。
  • Vadim,这似乎是一个干净的解决方案,可以轻松扩展。分离很好。我花了一段时间才明白我的意思。一切似乎都在进行到最后。 'items1,items2' 似乎需要定义?代码运行,列表被检索——但没有数据(查看控制台)。我收到一条错误消息“无法获取未定义或空引用的属性‘localeCompare’”,它告诉我?没有数据。不知道如何纠正这一点。其他示例 (MS) 使用不同的变量方法。
  • 瓦迪姆,就是这样。我有两个标题为空的项目。谢谢!
  • 我错过了最后一步 JSON 正确返回, -- $.each() 以下工作(其中“result”是保存数据的变量) var title = '';变种类型 = ''; $.each(result, function (index, value) { title += "Title: " + value.Title + "
    "; type += "Type: " + value.Type + "
    " ; });
  • Vadim,您会编辑您的解决方案以在输出中包含最后一部分吗?这样一来,其他人可以看到一个格式很好的块,而不是我评论中的糊状版本。
【解决方案2】:

我会将任务分为两部分。

首先,您需要合并从GET 调用中检索到的数据。

您可以考虑以某种方式为此使用 Promise:

$.when(
    // Get List1
    $.get("sharepointlist/_api/web/lists/GetByTitle('List1')/item").then( function(data) {
        return data.d.results;
    }),

    // Get List2
    $.get("sharepointlist/_api/web/lists/GetByTitle('List2')/items").then( function(data) {
        return data.d.results;
    })

).then(processData);

function processData(list1, list2) {
    var res = list1.concat(list2);
}

现在您需要处理您的数据。首先,您按Title 对新数组进行排序。

newData = newData.sort(function(a, b){
    return a.Title.localeCompare(b.Title);
});

现在您需要遍历已排序的数据并组合具有相同标题的对象。

res = res.reduce(function(a, b) {
    var t = a.slice(-1)[0]; //it's like getting last element
    if (t && t.Title === b.Title) {
        if (b.State) {
            t.State = b.State;
        } else {
            t.Type = b.Type;
        }
    } else {
        a.push(b);
    }
    return a;
}, []);

现在只需将新数据分配给 DOM。

更新:

使用 jQuery $.extend() 连接元素时合并所有属性的示例。

res = res.reduce(function(a, b) {
            var t = a.slice(-1)[0]; //it's like getting last element
            if (t && t.Title === b.Title) {
                $.extend(t, b);
            } else {
                a.push(b);
            }
            return a;
        }, []);

PS:jQuery $.extend() 忽略,为空或未定义的属性。

带有硬编码 JSON 文件的 Plunkr 工作解决方案的链接。

https://plnkr.co/edit/gYJjyT8lCCNTe6EAlSYB

【讨论】:

  • 我会尝试并告诉你。谢谢!
  • @teamnorge,这是一种正确的方法,但我想提出一些建议 1)我建议使用 $.getJSON 而不是 .$.get 以 json 格式返回结果 2)可能像我的示例中演示的那样实现更通用的连接算法会更好
  • teamnorge,谢谢你让我开始。 $when 是关键。我将您的代码放入我的设置中并尝试了它,但要么我无法获取数据,要么(在我用 $ajax 块替换干净、简单的 $get 之后),我得到了对象,对象(可以解决这个问题)和然后在 ').then(processData); 处出现语法错误线。检查并重新检查,但找不到我的错误。该样本似乎也不适合我。只是不是我的一天。不过进步了,多亏了你们俩。
猜你喜欢
  • 1970-01-01
  • 2014-11-25
  • 1970-01-01
  • 2013-11-20
  • 2019-01-30
  • 2015-07-19
  • 1970-01-01
  • 1970-01-01
  • 2018-09-20
相关资源
最近更新 更多