SharePoint Discussion List Threading view Rating System:
I wanted to do a Rating system for the email threads we have in our SharePoint system. I have written an email thread synchronizer for SharePoint. Of course, SharePoint synchronizes the email but doesn’t thread it properly. I will write a separate blog for it.
This rating system is like this:
Figure 1:
So how did I achieve it?
I haven’t used any c# code (except a web service). What I did was kind of changed the schema.xml file that SharePoint creates for each List. This Schema.xml file is in the appropriate folder in the 12 hive. (12\template\features\customdiscussionboard\schema.xml).
So how and where to change the Schema.xml file?
Since, I know, I need to display my star rating images before View Properties, I was curious to know where and how this is displayed. That is why, I went to Schema.xml file and fiddling it with. I saw a Status Bar field. There I saw this field. So, I changed the Schema.xml file’s StatusBar field and bingo..
This is what I added in the Schema.xml file in Status Bar field:
<!CDATA[
<HTML><![CDATA[<td style="border-style:none" nowrap="TRUE"><div>Please click star to rate: (1 low to 5 high)</div></td>]]></HTML>
<HTML><![CDATA[<td style="border-style:none" nowrap="TRUE">]]></HTML>
<HTML><![CDATA[ <div style="width:55px;"> <img alt="star_1" src="/_layouts/images/star_x_grey.gif" id="star]]></HTML>
<Field Name="ID" />
<HTML><![CDATA[_1" ONCLICK="CurrentEventFunctions.RatingImageClicked(]]></HTML>
<Field Name="ID" />
<HTML><![CDATA[,']]></HTML>
<Column Name="GUID" />
<HTML><![CDATA[',']]></HTML>
<Field Name="FileRef" />
<HTML><![CDATA[',this)"/><img alt="star_2" src="/_layouts/images/star_x_grey.gif" id="star]]></HTML>
<Field Name="ID" />
<HTML><![CDATA[_2" ONCLICK="CurrentEventFunctions.RatingImageClicked(]]></HTML>
<Field Name="ID" />
<HTML><![CDATA[,']]></HTML>
<Column Name="GUID" />
<HTML><![CDATA[',']]></HTML>
<Field Name="FileRef" />
<HTML><![CDATA[', this)" /><img alt="star_3" src="/_layouts/images/star_x_grey.gif" id="star]]></HTML>
<Field Name="ID" />
<HTML><![CDATA[_3" ONCLICK="CurrentEventFunctions.RatingImageClicked(]]></HTML >
<Field Name="ID" />
<HTML><![CDATA[,']]></HTML>
<Column Name="GUID" />
<HTML><![CDATA[',']]></HTML>
<Field Name="FileRef" />
<HTML><![CDATA[', this)" /><img alt="star_4" src="/_layouts/images/star_x_grey.gif" id="star]]></HTML>
<Field Name="ID" />
<HTML><![CDATA[_4" ONCLICK="CurrentEventFunctions.RatingImageClicked(]]></HTML >
<Field Name="ID" />
<HTML><![CDATA[,']]></HTML>
<Column Name="GUID" />
<HTML><![CDATA[',']]></HTML>
<Field Name="FileRef" />
<HTML><![CDATA[',this)"/><img alt="star_5" src="/_layouts/images/star_x_grey.gif" id="star]]></HTML>
<Field Name="ID" />
<HTML><![CDATA[_5" ONCLICK="CurrentEventFunctions.RatingImageClicked(']]></HTML >
<Field Name="ID" />
<HTML><![CDATA[',']]></HTML>
<Column Name="GUID" />
<HTML><![CDATA[',']]></HTML>
<Field Name="FileRef" />
<HTML><![CDATA[', this)" onload="CurrentEventFunctions.RatingLastImageLoad(']]></HTML>
<Field Name="ThreadTopic" />
<HTML><![CDATA[',']]></HTML>
<Field Name ="ID" />
<HTML><![CDATA[',this);return false;"/></div></td>]]></HTML>
]]>
Then, I added the javascript functions in the .master file.
<script language="javascript" type="text/javascript" >
function EventFunctions (loadedimage)
{
this.loadimage=loadedimage;
}
EventFunctions.prototype.RatingLastImageLoad= function(rating,id, imgStar)
{
if (this.loadimage) return; //this is for recursive avoiding
if (rating.indexOf("~")>=0)
{
var index = rating.split("~")[1];
if (index>=0)
{
for (i=1;i<=index;i++)
{
var imgstarmakeorange = document.getElementById("star" + id + "_" + i);
if (imgstarmakeorange != null)
{
this.loadimage=true;
imgstarmakeorange.src = "/_layouts/images/star_x_orange.gif";
this.loadimage=false;
}
}
}
}
}
EventFunctions.prototype.RatingImageClicked =function (id, listid, parentlistid, objstar)
{
if (typeof _spUserId != "undefined")
{
this.loadimage=true;
var intStarindex = objstar.id.split("_")[1];
this.UpdateStars(id, intStarindex);
this.callService(id, listid, parentlistid, _spUserId,intStarindex);
this.loadimage=false;
}
else
alert( "You need to signin to rate");
}
var CurrentEventFunctions = new EventFunctions(false);
EventFunctions.prototype.callService = function (id, listid, parentlistid, UserId,intStarindex )
{
var strUrl = "http://yourserver. com:<port number>/Service.asmx?WSDL";
divWbSvc.useService(strUrl,"divSvc");
var iCallID;
if (divWbSvc.divSvc)
{
iCallID = divWbSvc.divSvc.callService(this.updatePage,"InsertRatingsandReturnRatingAvg",UserId, listid,
parentlistid,intStarindex, id, true);
}
}
EventFunctions.prototype.updatePage = function (str)
{
if (str.error)
{
//alert(str.errorDetail.string);
//handle error
}
else
{
var retVal = str.value;
var retVals = retVal.split("~");
//need to write logic here
}
}
EventFunctions.prototype.UpdateStars = function (starindex, rating)
{
this.loadimage=true;
//get the star value (grey/orange) of the current index
var imgstarindex = document.getElementById("star" + starindex + "_" + rating);
var Arraysrc = imgstarindex.src.split("/");
var intlen = Arraysrc.length;
var imgstarindexvalue = Arraysrc[intlen-1];
//first make everything grey
for (i=1;i<=5;i++)
{
var imgstarmakegrey = document.getElementById("star" + starindex + "_" + i);
if (imgstarmakegrey != null)
imgstarmakegrey.src = "/_layouts/images/star_x_grey.gif";
}
//second make till the image clicked or rating -1 to orange
for (i=1;i<=rating-1;i++)
{
var imgstarmakeorange = document.getElementById("star" + starindex + "_" + i);
if (imgstarmakeorange != null)
imgstarmakeorange.src = "/_layouts/images/star_x_orange.gif";
}
// now check if the image clicked is orange or grey
var imgstarclicked = document.getElementById("star" + starindex + "_" + rating);
if (imgstarindexvalue == "star_x_grey.gif")
imgstarclicked.src = "/_layouts/images/star_x_orange.gif";
else
imgstarclicked.src = "/_layouts/images/star_x_grey.gif";
this.loadimage=false;
}
</script>
You need to add a Grey star and Orange star image under the layouts images folder.
What I have done in my service is I insert the user, listid, folder and ratings and figure out the average rating and store it in the ThreadTopic field (actually append the ThreadTopic field with a delimiter “~”).
PS: I am attaching the images :
This rating system is like this:
Figure 1:
So a user who needs to rate the email message just clicks a star and the average rating will be shown.
So how did I achieve it?
I haven’t used any c# code (except a web service). What I did was kind of changed the schema.xml file that SharePoint creates for each List. This Schema.xml file is in the appropriate folder in the 12 hive. (12\template\features\customdiscussionboard\schema.xml).
So how and where to change the Schema.xml file?
Since, I know, I need to display my star rating images before View Properties, I was curious to know where and how this is displayed. That is why, I went to Schema.xml file and fiddling it with. I saw a Status Bar field. There I saw this field. So, I changed the Schema.xml file’s StatusBar field and bingo..
This is what I added in the Schema.xml file in Status Bar field:
<!CDATA[
<HTML><![CDATA[<td style="border-style:none" nowrap="TRUE"><div>Please click star to rate: (1 low to 5 high)</div></td>]]></HTML>
<HTML><![CDATA[<td style="border-style:none" nowrap="TRUE">]]></HTML>
<HTML><![CDATA[ <div style="width:55px;"> <img alt="star_1" src="/_layouts/images/star_x_grey.gif" id="star]]></HTML>
<Field Name="ID" />
<HTML><![CDATA[_1" ONCLICK="CurrentEventFunctions.RatingImageClicked(]]></HTML>
<Field Name="ID" />
<HTML><![CDATA[,']]></HTML>
<Column Name="GUID" />
<HTML><![CDATA[',']]></HTML>
<Field Name="FileRef" />
<HTML><![CDATA[',this)"/><img alt="star_2" src="/_layouts/images/star_x_grey.gif" id="star]]></HTML>
<Field Name="ID" />
<HTML><![CDATA[_2" ONCLICK="CurrentEventFunctions.RatingImageClicked(]]></HTML>
<Field Name="ID" />
<HTML><![CDATA[,']]></HTML>
<Column Name="GUID" />
<HTML><![CDATA[',']]></HTML>
<Field Name="FileRef" />
<HTML><![CDATA[', this)" /><img alt="star_3" src="/_layouts/images/star_x_grey.gif" id="star]]></HTML>
<Field Name="ID" />
<HTML><![CDATA[_3" ONCLICK="CurrentEventFunctions.RatingImageClicked(]]></HTML >
<Field Name="ID" />
<HTML><![CDATA[,']]></HTML>
<Column Name="GUID" />
<HTML><![CDATA[',']]></HTML>
<Field Name="FileRef" />
<HTML><![CDATA[', this)" /><img alt="star_4" src="/_layouts/images/star_x_grey.gif" id="star]]></HTML>
<Field Name="ID" />
<HTML><![CDATA[_4" ONCLICK="CurrentEventFunctions.RatingImageClicked(]]></HTML >
<Field Name="ID" />
<HTML><![CDATA[,']]></HTML>
<Column Name="GUID" />
<HTML><![CDATA[',']]></HTML>
<Field Name="FileRef" />
<HTML><![CDATA[',this)"/><img alt="star_5" src="/_layouts/images/star_x_grey.gif" id="star]]></HTML>
<Field Name="ID" />
<HTML><![CDATA[_5" ONCLICK="CurrentEventFunctions.RatingImageClicked(']]></HTML >
<Field Name="ID" />
<HTML><![CDATA[',']]></HTML>
<Column Name="GUID" />
<HTML><![CDATA[',']]></HTML>
<Field Name="FileRef" />
<HTML><![CDATA[', this)" onload="CurrentEventFunctions.RatingLastImageLoad(']]></HTML>
<Field Name="ThreadTopic" />
<HTML><![CDATA[',']]></HTML>
<Field Name ="ID" />
<HTML><![CDATA[',this);return false;"/></div></td>]]></HTML>
]]>
Then, I added the javascript functions in the .master file.
<script language="javascript" type="text/javascript" >
function EventFunctions (loadedimage)
{
this.loadimage=loadedimage;
}
EventFunctions.prototype.RatingLastImageLoad= function(rating,id, imgStar)
{
if (this.loadimage) return; //this is for recursive avoiding
if (rating.indexOf("~")>=0)
{
var index = rating.split("~")[1];
if (index>=0)
{
for (i=1;i<=index;i++)
{
var imgstarmakeorange = document.getElementById("star" + id + "_" + i);
if (imgstarmakeorange != null)
{
this.loadimage=true;
imgstarmakeorange.src = "/_layouts/images/star_x_orange.gif";
this.loadimage=false;
}
}
}
}
}
EventFunctions.prototype.RatingImageClicked =function (id, listid, parentlistid, objstar)
{
if (typeof _spUserId != "undefined")
{
this.loadimage=true;
var intStarindex = objstar.id.split("_")[1];
this.UpdateStars(id, intStarindex);
this.callService(id, listid, parentlistid, _spUserId,intStarindex);
this.loadimage=false;
}
else
alert( "You need to signin to rate");
}
var CurrentEventFunctions = new EventFunctions(false);
EventFunctions.prototype.callService = function (id, listid, parentlistid, UserId,intStarindex )
{
var strUrl = "http://yourserver. com:<port number>/Service.asmx?WSDL";
divWbSvc.useService(strUrl,"divSvc");
var iCallID;
if (divWbSvc.divSvc)
{
iCallID = divWbSvc.divSvc.callService(this.updatePage,"InsertRatingsandReturnRatingAvg",UserId, listid,
parentlistid,intStarindex, id, true);
}
}
EventFunctions.prototype.updatePage = function (str)
{
if (str.error)
{
//alert(str.errorDetail.string);
//handle error
}
else
{
var retVal = str.value;
var retVals = retVal.split("~");
//need to write logic here
}
}
EventFunctions.prototype.UpdateStars = function (starindex, rating)
{
this.loadimage=true;
//get the star value (grey/orange) of the current index
var imgstarindex = document.getElementById("star" + starindex + "_" + rating);
var Arraysrc = imgstarindex.src.split("/");
var intlen = Arraysrc.length;
var imgstarindexvalue = Arraysrc[intlen-1];
//first make everything grey
for (i=1;i<=5;i++)
{
var imgstarmakegrey = document.getElementById("star" + starindex + "_" + i);
if (imgstarmakegrey != null)
imgstarmakegrey.src = "/_layouts/images/star_x_grey.gif";
}
//second make till the image clicked or rating -1 to orange
for (i=1;i<=rating-1;i++)
{
var imgstarmakeorange = document.getElementById("star" + starindex + "_" + i);
if (imgstarmakeorange != null)
imgstarmakeorange.src = "/_layouts/images/star_x_orange.gif";
}
// now check if the image clicked is orange or grey
var imgstarclicked = document.getElementById("star" + starindex + "_" + rating);
if (imgstarindexvalue == "star_x_grey.gif")
imgstarclicked.src = "/_layouts/images/star_x_orange.gif";
else
imgstarclicked.src = "/_layouts/images/star_x_grey.gif";
this.loadimage=false;
}
</script>
You need to add a Grey star and Orange star image under the layouts images folder.
What I have done in my service is I insert the user, listid, folder and ratings and figure out the average rating and store it in the ThreadTopic field (actually append the ThreadTopic field with a delimiter “~”).
PS: I am attaching the images :
Comments
Post a Comment