如何在jQuery手风琴中实现即时搜索

时间:2019-02-12 20:35:00

标签: javascript jquery json jquery-ui sharepoint-2013

我对JavaScript真的很陌生,我正在尝试将Json数据绑定到一个手风琴,但是到目前为止,我似乎仍然无法正确完成它。 jsfiddle

我还能如何在手风琴中立即搜索?

var contacts = [{
    "Title": "Change Management",
    "Definition": "Collective term for all approaches to prepare and support individuals, teams, and organizations in making organizational change. The most common change drivers include: technological evolution, process reviews, crisis, and consumer habit changes; pressure from new business entrants, acquisitions, mergers, and organizational restructuring. It includes methods that redirect or redefine the use of resources, business process, budget allocations, or other modes of operation that significantly change a company or organization. Organizational change management (OCM) considers the full organization and what needs to change,[3] while change management may be used solely to refer to how people and teams are affected by such organizational transition. It deals with many different disciplines, from behavioral and social sciences to information technology and business solutions. In a project-management context, the term "change management" may be used as an alternative to change control processes where in changes to the scope of a project are formally introduced and approved."
  },
  {
    "Title": "Testing glossary",
    "Definition": "Testing Text 1 Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum"
  },
  {
    "Title": "More info",
    "Definition": "Testing Text 1 but because those who do not know how to pursue pleasure rationally encounter consequences that are extremely painful. Nor again is there anyone who loves or pursues or desires to obtain pain of itself, because it is pain, but occasionally circumstances occur in which toil and pain"
  },
  {
    "Title": "Category 2",
    "Definition": "Testing Text 1 Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."
  }
];

var departmentlist = new Array();
$.each(contacts, function(i, contact) {
  //insert the departments
  if (contact.Title != null && $('#' + contact.Title).length == 0) {
    $('#accordion').append('<h3 id=' + contact.Title + '><a href="#">' + contact.Title + '</a></h3>');
    departmentlist.push(contact.Title);
  }
  //insert contacts in the accordion
  $('#' + contact.Title).after('<p><a' + contact.Definition + '</a></p>');
});
$.each(departmentlist, function(i, list) {
$("#" + list).nextUntil("h3").wrapAll("<div></div>");
});
});
$(function() {
      $("#accordion").accordion({
        collapsible: true,
        active: false,
      });
<link href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/themes/base/jquery-ui.css" rel="stylesheet"/>

<div id="contactlist">
  <div id="accordion">

  </div>
</div>

更新2

使用@Twisty的以下code worked。这是我目前在SharePoint Site中看到的,似乎唯一仍然无法使用的是搜索/突出显示。

1 个答案:

答案 0 :(得分:1)

请考虑以下可能的解决方案。

工作示例:https://jsfiddle.net/Twisty/6v4h7fL3/73/

切换小提琴以使用jQuery 3.3.1和jQuery UI 1.12.1。如果可能,最好使用最新版本。代码应与未经测试的旧版本一起使用。

HTML

<div id="contactlist">
  <form id="search-form" class="ui-widget">
    <p class="ui-widget-content">
      <label for="term">Search:</label> <input type="text" id="term" class="ui-widget ui-corner-all" /> <button type="submit" id="btn-go" class="ui-widget ui-button ui-corner-all">Find</button>
    </p>
  </form>
  <div id="accordion">
  </div>
</div>

添加了“搜索”字段表单。对submit使用表单事件回调可以使用户点击 Enter 或单击按钮。我怀疑许多像我这样的用户输入了某些内容,然后按 Enter

JavaScript

$(function() {
  var departmentlist = [];
  var a = $("#accordion");

  function wrapText(term, obj) {
    var myText = obj.html().toString();
    var re = new RegExp(term, "g");
    var wObj = $("<span>", {
      class: "found ui-state-highlight"
    }).html(term);
    var w = wObj.prop("outerHTML");
    var newText = myText.replace(re, w);
    console.log("Wrap:", re, myText, newText);
    obj.html(newText);
  }

  $.each(contacts, function(i, contact) {
    //insert the departments
    if (contact.Title != null && $('#' + contact.Title).length == 0) {
      var header = $("<h3>", {
        id: contact.Title
      }).html(contact.Title).appendTo(a);
      var details = $("<div>").appendTo(a);
      $("<p>").html(contact.Definition).appendTo(details);
      departmentlist.push(contact.Title);
    }
  });

  a.accordion({
    collapsible: true,
    active: false,
  });

  $("#search-form").submit(function(e) {
    e.preventDefault();
    var q = $("#term").val();
    $.each(contacts, function(k, v) {
      if (v.Definition.indexOf(q) >= 0) {
        // Found
        console.log("'" + q + "' found under " + v.Title + " (" + k + ")");
        // Collapse all
        a.accordion("option", "active", false);
        // Active Section with found item
        a.accordion("option", "active", k);
        a.find(".found").removeClass("found ui-state-highlight");
        wrapText(q, $(".ui-accordion-content-active"));
        return false;
      }
    });
  });
});

wrapText()在某种程度上替代了要搜索的文本,并用<span>对其进行了包装以突出显示。它接受该术语和一个jQuery Object,其中包含应搜索并突出显示的文本。

我改进了您使用的构造代码,使其更像jQuery。一切构建完成后,我们将应用.accordion()

输入搜索并提交表单后,我们将查找查询的第一个匹配项,打开其容器并突出显示文本。

这有点麻烦。如果需要,可以通过几种方式进行改进。现在,例如,这种情况太敏感了。因此,如果您搜索testing,则不会有任何匹配,但如果您搜索Testing,它将起作用。

更新

这有点独立,如果您在不受HTML太多控制的SharePoint中运行它,这将很有帮助。

$(function() {

  function GetItems() {
    var siteURL = _spPageContextInfo.webServerRelativeUrl;
    //var siteURL = "https://reqres.in/api/unknown" //Non-SharePoint URL
    $.ajax({
      url: siteURL + "/_api/web/lists/GetByTitle('glossary of terms')/items", //change the list name
      type: "GET",
      dataType: "json",
      headers: {
        Accept: "application/json;odata=verbose"
      },
      success: function(data) {
        if (data.d.results.length > 0) {
          GenerateAccordionFromJson(data.d.results, true, $("#accordion"));
          $("#accordion").accordion({
            collapsible: true,
            active: false,
          });
        } else {
          $('#accordion').append("<span>No Records Found.</span>");
        }
      },
      error: function(error) {
        console.log(JSON.stringify(error));
      }
    });
  }

  function wrapText(term, tObj) {
    var oldText = tObj.html();
    var re = new RegExp(term, "g");
    var newText = oldText.replace(term, "<span class='found highlight'>" + term + "</span>");
    tObj.html(newText);
  }

  function GenerateAccordionFromJson(json, search, tObj) {
    if (search == undefined) {
      search = false;
    }
    if (tObj == undefined || tObj.length < 1) {
      tObj = $("<div>", {
        class: "items",
        id: "accordion" + ($("#accordion").length ? "-" + $("#accordion").length : "")
      }).appendTo($("body"));
    }
    if (search) {
      var form = $("<form>", {
        class: "search-form"
      }).submit(function(e) {
        e.preventDefault();
        var q = $(".search-term", this).val();
        var aObj = $(this).next("div");
        var stacks = [];

        $(".found").removeClass("found highlight");

        $(".ui-accordion-content", aObj).each(function(ind, el) {
          stacks.push($(el).text().trim());
        });
        $.each(stacks, function(i, s) {
          if (s.indexOf(q) >= 0) {
            aObj.accordion("option", "active", false);
            aObj.accordion("option", "active", i);
            wrapText(q, $(".ui-accordion-content-active", aObj));
          }
        });
      }).insertBefore(tObj);
      $("<p>").html("Search:").appendTo(form);
      $("<input>", {
        type: "text",
        class: "search-term"
      }).appendTo($("p", form));
      $("<button>", {
        type: "submit",
        class: "search-btn-go"
      }).appendTo($("p", form));
    }
    $.each(json, function(key, row) {
      $("<h3>").html(row.Title).appendTo(tObj);
      $("<div>").html("<p>" + row.Definition + "</p>").appendTo(tObj);
    });
  }
});

更新2

确保在头中加载正确的库。您显示正在使用:

<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script> 

这将两次加载相同的库,首先是“最小”版本。我将删除两者中的第二个。

我不知道SP是否使用jQuery。如果尚未加载,请确保将其包含在标题中。

如果没有,您可以执行以下操作:

<script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js" integrity="sha256-VazP97ZCwtekAsvgPBSUwPFKdrwD3unUfSGVYrahUqU=" crossorigin="anonymous"></script>

正如您提到的,在您的评论中,我忘了包含初始功能的最终运行:

GetItems();

在关闭最后一个包装器之前添加此代码,以确保其被执行。

更新3

尝试以下脚本代码:

$(function() {
  var n = new Date();

  function log(msg) {
    var t = new Date();
    var d = t - n;
    console.log(d, msg);
  }

  function GetItems() {
    var siteURL = _spPageContextInfo.webServerRelativeUrl;
    log("GetItems: Start: " + siteURL);
    $.ajax({
      url: siteURL + "/_api/web/lists/GetByTitle('glossary of terms')/items", //change the list name
      type: "GET",
      dataType: "json",
      headers: {
        Accept: "application/json;odata=verbose"
      },
      success: function(data) {
        if (data.d.results.length > 0) {
          $('#accordion').append(GenerateAccordionFromJson(data.d.results));
          $("#accordion").accordion({
            collapsible: true,
            active: false,
          });
        } else {
          $('#accordion').append("<span>No Records Found.</span>");
        }
      },
      error: function(error) {
        log("GetItems: Error: " + JSON.stringify(error));
      }
    });
    log("GetItems: Complete");
  }

  function GenerateAccordionFromJson(objArray) {
    log("GenAccord: Started");
    var accordionContent = "";
    for (var i = 0; i < objArray.length; i++) {
      accordionContent += '<h3>' + objArray[i].Title + '</h3>';
      accordionContent += '<div><p>' + objArray[i].Definition + '</p></div>';
    }
    log("GenAccord: Complete");
    return accordionContent;
  }

  GetItems();
});

然后您可以查看控制台,并应查看所有正在运行的操作。如果没有详细信息,请查找警报或错误。

希望有帮助。