Tuesday, January 27, 2015


In last post we saw how to use SharePoint Search refiners in REST services. Refiners are very helpful to slice the results and remove irrelevant results. To get more relevant and correct results of search you need to apply multiple refiners. So let's see how you can create query for multiple refiners in REST  service.

In last post we saw an example to refine result on one refine. To make it work for multiple refiner you need to construct query like:

/_api/search/query?querytext='yammer'&refiners='Write,DisplayAuthor,ContentType,FileExtension,FileType'&refinementfilters='and(Write:range(" + frmDISO + "," + toDISO + "),DisplayAuthor:equals(\"" + authorFilter + "\"))'

Pass this query to SharePoint  Search REST and get more relevant results. In above query you can see we have applied two refiners of ‘Write’ and ‘DisplayAuthor’ at a time. And the result will be filtered on the ‘Write’ and ‘DisplayAuthor’.

Happy SharePoint coding.

Sunday, January 25, 2015


In last post we had deep walk through in Search REST service response. In this post we will learn how to get refiners and their various refinement values and tokens.

To get the refiners along with search result construct  REST URL as follows:

URL: /_api/search/query?querytext='yammer'&refiners='Write,DisplayAuthor,ContentType,FileExtension,FileType'

You can use parameter 'refiners' to provide the multiple refiners. In result you will get all refiner values and their tokens in response in RefinementResults section or tag as shown below.



We have seen 'RefinementResults' and 'Refiners' in detail in last post. Now let’s see how to use them and construct the custom filter component for the custom search component.
Each Refiner contains multiple refinements for filters. You can get the Refinement Name, Token and Value which is useful while making refinement on search results. So to get them you need to iterate them like below:

$.each(data.d.query.PrimaryQueryResult.RefinementResults.Refiners.results, function () { 
                          var items = new Array();
                          var title = this.Name;                         
                          $.each(this.Entries.results, function () {
                                    var refinementName = this.RefinementName;
                                    var refinementValue = this.RefinementValue;
                                    if(title == "ContentType" && refinementName.indexOf(" ") != -1)
                                    {
                                                refinementName = refinementName.substring(refinementName.lastIndexOf(" "));
                                                refinementValue = refinementName;           
                                    }
                                    if(title == "Write")
                                    {
                                                refinementValue = this.RefinementToken;
                                    }                                                                                  
                          });                  
      });

In this way you can get all refiners and bind on the page. Next important part remaining of this component is filtering search results on the basis of refiners. To refine the result you need to pass the refinement filters as shown in below example REST URL:

/_api/search/query?querytext='yammer'&refiners='Write,DisplayAuthor,ContentType,FileExtension,FileType'&refinementfilters=’ refinementfilter: refinementfilterValue’

Following is the complete code which demonstrates how to use the filters.

HTML Code:

<script type="text/javascript" src="/Site%20Assets/js/jquery-1.8.3.min.js"></script>
<script type="text/javascript" src="/Site%20Assets/js/knockout.3.2.0.js"></script>
<script type="text/javascript" src="/Site%20Assets/js/FilterSearch.js"></script>
<div class="row">
<div class="col-xs-12 col-sm-4 col-md-4">

<div class="panel-group" id="accordion" role="tablist" aria-multiselectable="true" data-bind="foreach: Refiners">
  <div class="panel panel-default">
    <div class="panel-heading" role="tab" data-bind="attr: { id: HeadID }">
      <h4 class="panel-title">
        <a data-toggle="collapse" data-parent="#accordion" aria-expanded="true" data-bind="attr:{href: HRef, 'aria-controls': ID}">
          <span data-bind="text: Title"> Collapsible Group Item #1 </span>
        </a>
      </h4>
    </div>
    <div data-bind="attr: { id: ID, 'aria-labelledby': HeadID }" class="panel-collapse collapse in" role="tabpanel" >
      <div class="panel-body">

<div class="list-group" data-bind="foreach: RefinerItems">
   <a href="#" class="list-group-item"><span data-bind="text: RefinementName, click: RefinerFliterClick.bind(Title, RefinementValue)"></span></a>
</div>       

      </div>
    </div>
  </div>  
</div>
</div>
<div class="col-xs-12 col-sm-8 col-md-8">
<div class="row">
<div class="col-xs-12 col-sm-6 col-md-6">
<input type="text" class="form-control" placeholder="Search" id="txtSearch">
</div>
<div class="col-xs-12 col-sm-6 col-md-6">
<button type="button" class="btn btn-default" data-bind="click: btnSearchClick">Search</button>
</div>
</div>
<div class="row">
<div style="width:100%;padding-left:10px;" data-bind="foreach: Results">
<div class="row">
  <div class="col-xs-12 col-sm-12 col-md-12" style="border-bottom: 1px solid;padding-bottom:10px;">
<div style="width:100%">
<a href="" data-bind="attr: { href: Url }"><h4><span data-bind="text: Title"> </span></h4></a>
</div>
<div style="width:100%">
<p data-bind="html: HitHighlightedSummary"> </p>
</div>
<div style="width:100%">
<a href="" data-bind="attr: { href: Path }"><span data-bind="text: Path"> </span></a>
</div>
<div style="width:100%">
<span class="label label-default"> Author: <span data-bind="text: Author"> </span> </span>
</div>
  </div>
</div>
</div>
</div>
</div>

</div>

JS Code:

var RESTURL = "/_api/search/query?querytext=";
var DEFLTRFINERURL = "&refiners='Write,DisplayAuthor,ContentType,FileExtension,FileType'";
$(document).ready(function () {
    SearchModel();
});
function SearchModel()
{
 var self = this;
 self.Results = ko.observableArray([]);
 self.Refiners = ko.observableArray([]);
 self.Refiner = function(headID,id, title, items)
 {
 var self = this;
 self.HRef = "#" + id;
 self.HeadID = headID;
 self.ID = id;
 self.Title = title;
 self.RefinerItems = ko.observableArray(items);
 }
 self.RefinerItem = function(title, name, value)
 {
var self = this;
self.Title = title;
self.RefinementName = name;
self.RefinementValue = value;
 }
 self.SearchResult = function(url,title,hitHighlightedSummary,author,path)
 {
 var self = this; 
 self.Url = url;
 self.Title = title;
 self.HitHighlightedSummary = hitHighlightedSummary;
 self.Author = author;
 self.Path = path;
 }
 self.RefinerFliterClick = function(refinerName,refinerfiltervalue)
 {
var url = RESTURL + "'" + $("#txtSearch").val() + "'"; 
var RFINERURL = "&refiners='" + refinerfiltervalue.Title + "'";

if(refinerfiltervalue.Title.toLowerCase() == "write")
{
RFINERURL = RFINERURL + "&refinementfilters='" + refinerfiltervalue.Title.toLowerCase() + ":" + refinerfiltervalue.RefinementValue + "'";
}
else{
RFINERURL = RFINERURL + "&refinementfilters='" + refinerfiltervalue.Title.toLowerCase() + ":equals(\"" + refinerfiltervalue.RefinementValue + "\")'";
}
self.SearchInSharePoint(url + RFINERURL);
 }
 self.btnSearchClick = function()
 {
var url = RESTURL + "'" + $("#txtSearch").val() + "'" + DEFLTRFINERURL; 
self.SearchInSharePoint(url);
 }
 self.SearchInSharePoint = function(url)
 {
 self.Results.removeAll();
 self.Refiners.removeAll();
 $.ajax({
url: url,
type: "GET",
headers: {
"accept": "application/json;odata=verbose",
},
success: function (data) {

$.each(data.d.query.PrimaryQueryResult.RelevantResults.Table.Rows.results, function () {
 self.Results.push(new self.SearchResult(this.Cells.results[6].Value,this.Cells.results[3].Value,this.Cells.results[11].Value,this.Cells.results[4].Value,this.Cells.results[6].Value));
 i++;
});

if(data.d.query.PrimaryQueryResult.RefinementResults != null)
{
var i =1;
$.each(data.d.query.PrimaryQueryResult.RefinementResults.Refiners.results, function () {
 
 var items = new Array();
 var title = this.Name;  
 $.each(this.Entries.results, function () {
var refinementName = this.RefinementName;
var refinementValue = this.RefinementValue;
if(title == "ContentType" && refinementName.indexOf(" ") != -1)
{
refinementName = refinementName.substring(refinementName.lastIndexOf(" "));
refinementValue = refinementName;
}
if(title == "Write")
{
refinementValue = this.RefinementToken;
}

items.push(new self.RefinerItem(title, refinementName,refinementValue));
 });

 self.Refiners.push(new self.Refiner("HeadID" + i,"Collapse" + i,this.Name,items));
 i++;
});
i = 1;
}
},
error: function (error) {  
alert(JSON.stringify(error));
}
 });
}
ko.applyBindings(self);
}

Note: Knock out JS framework has been used while implementation. In order to run this code you need to refer knock out js file.

Happy SharePoint Coding.

Saturday, January 24, 2015


In the journey of Yammer REST APIs we have seen various APIs and their usages. In this post we will see how to like a post. Like in social applications are very important. Though it looks very small it has most impact power. Like makes any post, message, person famous. Its a index which tells how many people agree with you. And without Like any social application is incomplete so is Yammer and its integrated applications.

So let see how to add a like button in our yammer feeds component in SharePoint. Following is the REST url to like the post:

URL: messages/liked_by/current.json?message_id=[MessageId]

Parameter: This REST service needs message id as input to which you want to like.

You need to pass the id of message as a parameter to the REST call. Following is the sample code to like the message. I'd of message is hardcoded which can be set dynamically in actual implementations.

Sample Code:


<script type="text/javascript" data-app-id="[AppId]" src="https://c64.assets-yammer.com/assets/platform_js_sdk.js"></script>
<script type="text/javascript">
yam.getLoginStatus(
function (response) {
if (response.authResponse) {
}
else {
yam.platform.login(function (response) {
if (!response.authResponse) {
}
});
}
});
function Like() { 
yam.platform.request(
 { url: "messages/liked_by/current.json?message_id=[message_id]"
 , method: "POST"
 , success: function (msg) { 
 alert("{Liked it successfully!} "); 
 }
 , error: function (msg) { 
 alert("Post was Unsuccessful..." + msg); 
 }
 }
);  
}
</script>
    <div>
        <b>Like to Message.</b>
    </div>
    <div>
    <button onclick='Like()'>Like!</button>
    </div>

In this way you can implement Liking using Yammer REST services.

Happy Yamming!