Friday, May 9, 2014

Search SharePoint List items using jQuery/JavaScript and Web Service

You can use jquery/javascript to search items from a SharePoint list. You can define you CAML query and based on that result will be displayed. Lists.asmx web service is used in this case. You can use this to search items both on SharePoint online or on-premises versions.

List.asmx service is called and post method is called provided with soap envelope and in return we get the list items in from of xml. You can also highlight the searched keyword in the result.

You can use the below script in content editor or script editor web part. A input box and a button will be created when you use the script. Type any word in text box and click the search button to search items within a SharePoint list.
I have used this code on SharePoint 2013 online using script editor web part. Just copy and paste the below script into script editor web part. Replace the yellow  text as per your requirements. I used the CAML query to search items that contains the specified keyword in the Title field of the list, you can use your own CAML query.

Usage

<input type="text" style="width:350px" id="txtSearch" />
<input type="button" style=" font-size:15px;font-family:'Segoe UI Light','Segoe UI','Segoe',Tahoma,Helvetica,Arial,sans-serif; background-color:#0072C6; color:white" id="btnSearch" value="Search" onclick="return search();" />
<style>
.highlight {
    background-color: #FFFF88;
}
</style>
  <script type="text/javascript" src="https://jqueryjs.googlecode.com/files/jquery-1.3.2.min.js"></script>
<script type="text/javascript">

/*
 *This is jQuery Highlight plugin to highlight the result text

 */

jQuery.extend({
    highlight: function (node, re, nodeName, className) {
        if (node.nodeType === 3) {
            var match = node.data.match(re);
            if (match) {
                var highlight = document.createElement(nodeName || 'span');
                highlight.className = className || 'highlight';
                var wordNode = node.splitText(match.index);
                wordNode.splitText(match[0].length);
                var wordClone = wordNode.cloneNode(true);
                highlight.appendChild(wordClone);
                wordNode.parentNode.replaceChild(highlight, wordNode);
                return 1; //skip added node in parent
            }
        } else if ((node.nodeType === 1 && node.childNodes) && // only element nodes that have children
                !/(script|style)/i.test(node.tagName) && // ignore script and style nodes
                !(node.tagName === nodeName.toUpperCase() && node.className === className)) { // skip if already highlighted
            for (var i = 0; i < node.childNodes.length; i++) {
                i += jQuery.highlight(node.childNodes[i], re, nodeName, className);
            }
        }
        return 0;
    }
});

jQuery.fn.unhighlight = function (options) {
    var settings = { className: 'highlight', element: 'span' };
    jQuery.extend(settings, options);

    return this.find(settings.element + "." + settings.className).each(function () {
        var parent = this.parentNode;
        parent.replaceChild(this.firstChild, this);
        parent.normalize();
    }).end();
};

jQuery.fn.highlight = function (words, options) {
    var settings = { className: 'highlight', element: 'span', caseSensitive: false, wordsOnly: false };
    jQuery.extend(settings, options);
 
    if (words.constructor === String) {
        words = [words];
    }
    words = jQuery.grep(words, function(word, i){
      return word != '';
    });
    words = jQuery.map(words, function(word, i) {
      return word.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
    });
    if (words.length == 0) { return this; };

    var flag = settings.caseSensitive ? "" : "i";
    var pattern = "(" + words.join("|") + ")";
    if (settings.wordsOnly) {
        pattern = "\\b" + pattern + "\\b";
    }
    var re = new RegExp(pattern, flag);
 
    return this.each(function () {
        jQuery.highlight(this, re, settings.element, settings.className);
    });
};

</script>


<script type="text/javascript">
            function search()
     
          {


           $("#tasksUL").empty();
          var qry= document.getElementById("txtSearch").value
  var soapEnv =
            "<soapenv:Envelope xmlns:soapenv='http://schemas.xmlsoap.org/soap/envelope/'> \
                <soapenv:Body> \
                     <GetListItems xmlns='http://schemas.microsoft.com/sharepoint/soap/'> \
                        <listName>List Title from items to be searched</listName> \
                        <viewFields> \
                            <ViewFields> \
                               <FieldRef Name='Title' /> \
 <FieldRef Name='ID' /> \
                           </ViewFields> \
</viewFields> \
<query> \
<Query> \
<Where> \
<Contains> \
         <FieldRef Name='Title' /> \
         <Value Type='Text'>"+qry+"</Value> \
      </Contains> \
      </Where> \
</Query> \
</query> \
</GetListItems> \
                </soapenv:Body> \
            </soapenv:Envelope>";

        $.ajax({
            url: "YoursiteUrl/_vti_bin/lists.asmx",
            type: "POST",
            dataType: "xml",
            data: soapEnv,
            complete: processResult,
            contentType: "text/xml; charset=\"utf-8\""
        });

  }
 



    function processResult(xData, status) {
// show searching text and image when search button is clicked
var loadhtml="<div id='loading' class='ms-dlgLoadingTextDiv'><span style='padding-top: 6px; padding-right: 10px;'><img width='24' height='24' title='This animation indicates the operation is in progress. Click to remove this animated image.' src='/_layouts/15/images/gears_anv4.gif?rev=36'/></span><span class='ms-core-pageTitle ms-accentText'>Searching...</span></div>";

    var totalRows = parseFloat($(xData.responseXML).find('[nodeName="rs:data"]').attr("ItemCount"));
if(totalRows=="0")
{
 $("#loading").remove();
$("#tasksUL").before("<div  id='loading'  style='color:red;font-size:15px'>No matching records found. Please refine your search.</div>");
return true;
}
$("#tasksUL").before(loadhtml);
        $(xData.responseXML).find("z\\:row").each(function() {

// creating hyperlink for each item to display form of that list item
var lnk="<a href='Your lists url/DispForm.aspx?ID=" + $(this).attr('ows_ID') + "'>"+ $(this).attr("ows_Title") +"</a>";

            var liHtml = "<li>"+ lnk+"</li>";

// 2 second delay and show searching text and image also highlight the result with the searched keyword
setTimeout(function(){
 $("#loading").remove();
   $("#tasksUL").append(liHtml);
  $("#tasksUL > li").highlight(document.getElementById("txtSearch").value);
}, 2000);
   
        });

    }

$(document).ready(function(){
// check if enter button is pressed and then search button clicked event is called
    $('#txtSearch').keypress(function(e){
      if(e.keyCode==13)
      $('#btnSearch').click();
    });
});
</script>
// show search result in the ul 
<div id="search_result">
<ul id="tasksUL"/>
</div>

Use this and please let me know your valuable comments
Cheers, Happy Coding :)

1 comment:

  1. i have changed the list name but kept the title as it is. but while searching only loading div appears. Also, i noticed every time you click onto the search button multiple div for loading appears

    ReplyDelete