【问题标题】:How can I implement instant search within jQuery Accordions如何在 jQuery Accordions 中实现即时搜索
【发布时间】:2019-07-06 14:03:55
【问题描述】:

我对 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 中看到的,似乎唯一仍然无法正常工作的是搜索/突出显示。

【问题讨论】:

  • 你的代码有错误,"{ "message": "SyntaxError: expected expression, got '}'", "filename": "stacksnippets.net/js", "lineno": 49, "colno ": 2 }
  • 欢迎来到 Stack Overflow。 “即时搜索”是什么意思?搜索标题?您希望结果如何显示?
  • @Twisty 我想实现像link 这样的搜索。基本上我想在内容中搜索并在突出显示时打开/关闭手风琴
  • @NathanielFlick jsfiddle 看起来不错。
  • 你看过这篇文章吗,看起来很有帮助:stackoverflow.com/questions/48765912/accordion-jquery-search

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


【解决方案1】:

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

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

将 Fiddle 切换为使用 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() 对正在搜索的文本进行了一些基本的替换,并用&lt;span&gt; 包裹它以突出显示。它接受术语和一个 jQuery 对象,其中包含应搜索和突出显示的文本。

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

当输入搜索并提交表单时,我们会寻找第一次出现的查询,打开它的容器并突出显示文本。

这有点快和肮脏。如果您需要,可以通过几种方式对其进行改进。例如,现在它不区分大小写。因此,如果您搜索testing,您将不会获得任何点击,但如果您搜索Testing,它将起作用。

更新

这有点独立,如果您在 SharePoint 中运行它,而您对 HTML 没有太多控制权,这会很有帮助。

$(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> 

这是两次加载同一个库,首先是“min”版本。我会删除两者中的第二个。

我不知道 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();
});

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

希望对您有所帮助。

【讨论】:

  • 感谢您的帮助!我想我会花一些时间来理解它,甚至在尝试将它应用到 SharePoint 时会花费更多时间。我在 SharePoint 中的方法类似于 [link] (jsfiddle.net/jlriverayuso/wxsfj3h7/24),但尽管手风琴在 SharePoint 中有效,但如果我尝试在外部调用某些东西,它似乎不起作用。为了指导起见,在这种情况下如何应用搜索?
  • 感谢您提供更新的答案。我只是尝试在 SharePoint 站点中运行它。但是它似乎不喜欢它。我看到你删除了 $(document).ready(function(){ GetItems(); });在页面加载时,它从数组中创建了手风琴。这就是我将它嵌入到 SharePoint 页面 jsfiddle.net/jlriverayuso/bn1gs8dr 的方式
  • @Jen 已更新。没错,您需要在最终包装器之前的某个位置为 GetItems(); 添加一行。
  • 感谢您的更新。我做了类似的更改,但没有成功。由于某种原因,什么都不会加载。如果我删除为搜索添加的所有内容并突出显示并保持这样:jsfiddle.net/jlriverayuso/huoLfv0q/5 手风琴加载。你仍然是一个很大的帮助
  • @Jen 添加了另一个更新。需要更多信息来确定为什么它没有按预期工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-15
  • 2011-05-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多