Showing posts with label JQuery. Show all posts
Showing posts with label JQuery. Show all posts

Tuesday, September 24, 2013

Format SharePoint People Picker as Hyperlink on Infopath Display list form

I wanted to display the people picker value in a list form as a hyperlink in SharePoint. By default, it was just a text field on the display form. In a normal SharePoint list form, this field can be modified to disable output escaping so that it formats as an html. I was totally unsure how to accomplish this, and pressed for time, I decided to write a script to format it as a hyperlink. If you know how to do this in InfoPath, please share!

Place this script in a content editor webpart on the display list form:

<script type='text/javascript' src='/js/jquery-1.7.2.min.js'></script>
<script type="text/javascript">

//make sure document is loaded first
$(document).ready(function() { 
 setTimeout(formatUserField,'1000');
});

function formatUserField()
{
 $("span[ScriptClass='CustomControl']").each(function(){
  var curValue = $(this).text();
  var newhtml = "<a href='javascript:void(0)' onclick='PopUpEmail(\"" + curValue + "\");return false;'>"+ curValue +"</a>";
  $(this).html(newhtml);
 });
}

function PopUpEmail(username)
{
    var p_recipient = username;
    var p_cc = "";
    var p_subject =  "";
    var p_body =  "";
    var objO = new ActiveXObject('Outlook.Application');     
    var objNS = objO.GetNameSpace('MAPI');     
    var mItm = objO.CreateItem(0);     
    mItm.Display();     
    mItm.To = p_recipient;
    mItm.Cc = p_cc;
    mItm.Subject = p_subject;
    mItm.Body = p_body;     
    mItm.GetInspector.WindowState = 2;
}

</script>

Friday, May 3, 2013

Filter SharePoint list with Partial Postback to page

The other day, I wanted to filter a list view web part, triggered from a drop down list on my page. I couldn't connect to a standard out of the box filter web part because the dropdown values were populated with values retrieved from a web service. Every time I select a new value from the drop down, I wanted to automatically filter the sharepoint list with that value, without doing a full postback and refreshing the page (similar to the effect of when you filter a list from the list column options).

To start things off:
  • I created a document library and created a new column called "DocType" with a few choices:
    • Letter
    • Memo
    • Email
  • I made sure the DocType column appeared on my default view (this will be the view I use to do my filtering later)
  • I uploaded a few documents into my library, and provided the DocType for each
  • On my site page, I added the list view web part for this Document Library
  • From the AJAX Options under the list view web part settings:
    • Check off Enable Asynchronous Update
    • Show Manual Refresh Button
  • Using IE developer tools, find the element for the refresh icon with the id of ManualRefresh


Copy the outer anchor tag's onclick event (this event triggers a partial post back to the page)

  • Add a form web part to the same page
  • Grab the ID in the __doPostBack call and replace it in this script, and put the script into the form web part and save.
<div style="width:400px; height:20px; margin:0px auto; padding-bottom:20px; font-family:Verdana,Arial,Helvetica,Sans-serif;font-size:10pt;">
 Select Doc Type: 
 <select id="ddlDocType">
  <option></option>
  <option>Letter</option>
  <option>Memo</option>
 </select>
</div>


<script type='text/javascript' src='/assets/js/jquery-1.7.2.min.js'></script>
<script type="text/javascript"> 

$(document).ready(function(){
 //on the dropdown change event, call FilterMyList
 $("#ddlDocType").change(function(){
  FilterMyList();;
 });
});


function FilterMyList()
{
//get the selected value of the drop down
 var selectedDocType = $("#ddlDocType").val();
 if(selectedDocType == "" )
 { 
 //clears the filter
  __doPostBack("ctl00$m$g_95403266_84ab_485e_be73_8857b5d90f63$ctl02", "NotUTF8;__filter={DocType=" + "##dvt_all##"  + "}");
  return;
 }
 //filters the list on the selected docType
 __doPostBack("ctl00$m$g_95403266_84ab_485e_be73_8857b5d90f63$ctl02", "NotUTF8;__filter={DocType=" + selectedDocType + "}");
}  
</script>


Now, when you select a value from the dropdown, it should automatically filter the list without a full postback
 

Wednesday, May 1, 2013

SharePoint Calendar Overlay - Color code documents and display direct links to document library

I wanted to have a color coded view of documents in a SharePoint calendar, that would be populated from a document library. Also, the link on each item in the calendar would point directly to the document itself. We will also want to make sure that all documents for that date are expanded by default.


End Result: (on hover, you'll see that the hyperlink has changed to the direct link to the document)



 
  1. In a document library, create a column that you want to categorize your documents. I chose to create a choice field called "Document Type" and gave it 3 choices:
    1. RFP
    2. Proposal
    3. Contract
  2. In the same library, create a date column that you will use to show the documents in a calendar. I chose to create a date field called "Due Date"
  3. Upload your documents, and provide the Document Type and the Due Date for each.




  1. In the libray, create a Calendar view for each particular Document Type
    1. For the name of the view, input the document type
    2. For the Begin and End date, select the Due Date field
    3. For the month view, week view and day view titles, select the Document Type field from the drop down.
    4. Filter this view on the desired Document Type


  1. Now that all the views have been created, go to the Calendar (a team site should already have one, if it doesn't, create one).
  2. On the Calendar, select the Calendar tab from the ribbon and click on the Calendars Overlay
  3. From there, click New Calendar
    1. Give the calendar the name of the Document Type
    2. Select a color
    3. From the list drop down, select the document library that you configured earlier
    4. Select the Calendar view corresponding to the Document Type
    5. Repeat for each document type

Now all the documents will appear on the calendar, color coded based on Document Type and displayed based on Due Date

Next up: We will need to create a script, that we will use to override the CalendarNotify so that we can manipulate the hyperlinks on our Calendar to point directly to the document, instead of the list form
  1. Create a javascript file and store it in your assets library
    1. Add a reference to jQuery and SPServices
Add the following script

<style>

/* hide the collapse/expand on load (we will make it expand in script) */
.ms-cal-nav{display:none;}

/*hide the time */
.ms-acal-time {
 DISPLAY: none
}

.ms-acal-sdiv {
 MARGIN-LEFT: -58px
}

.ms-acal-sdiv A {
 POSITION: absolute; WIDTH: 100%; LEFT: 0px
}

.ms-acal-title {
 HEIGHT: 35px; PADDING-TOP: 0px
}

TABLE.ms-acal-vcont TBODY TR TD A {

 DISPLAY: none !important

}


</style>

<script type='text/javascript' src='/assets/js/jquery-1.7.2.min.js'></script>
<script type='text/javascript' src='/assets/js/jquery.SPServices-0.7.1a.min.js'></script>
<script type="text/javascript">



// load our function to the delayed load list
_spBodyOnLoadFunctionNames.push('changeCalendarEventLinkIntercept');


// hook into the existing SharePoint calendar load function
function changeCalendarEventLinkIntercept()

{
  var OldCalendarNotify4a = SP.UI.ApplicationPages.CalendarNotify.$4b;

  SP.UI.ApplicationPages.CalendarNotify.$4b = function () 
    {
      OldCalendarNotify4a();
      changeCalendarEventLinks();
    }
}

var thisSite = L_Menu_BaseUrl; //defined in SharePoint pages

function changeCalendarEventLinks()
{

 //expand all in the day
 $("a[evtid='expand_collapse']").each(function(){
  $(this)[0].click();
 });

 $(".ms-acal-sdiv").each(function(){
  var aLink = $(this).find("a");
  var href = aLink.attr("href");
  var linkSubs = href.split("ID=");
  var itemId = linkSubs[1];
  var listName = linkSubs[0].replace(thisSite +"/","");
  listName = listName.replace("/Forms/DispForm.aspx?","");
  GetListData(listName, itemId, aLink);

 });

 //necessary if date has more than 1 document
 $(".ms-acal-mdiv").each(function(){
  var aLink = $(this).find("a");
  var href = aLink.attr("href");
  var linkSubs = href.split("ID=");
  var itemId = linkSubs[1];
  var listName = linkSubs[0].replace(thisSite +"/","");
  listName = listName.replace("/Forms/DispForm.aspx?","");
  GetListData(listName, itemId, aLink);

 });

 $('td[evtid=day]').removeAttr('evtid');
 $('th[evtid=week]').removeAttr('evtid');
}



//go out and get the file name of the document, so that the link to the calendar will be a direct link to the document

function GetListData(listName, itemId, aLink){

 var linkRef = "";
 var camlFields = "<ViewFields><FieldRef Name='ID'/><FieldRef Name='FileLeafRef'/></ViewFields>";
 var camlQuery = "<Query><Where><Eq><FieldRef Name='ID'/><Value Type='Text'>" + itemId + "</Value></Eq></Where><OrderBy><FieldRef Name='ID'/></OrderBy></Query>";
 var items_Returned = null;

 $().SPServices({

  operation: "GetListItems",
  async: true, //make asynchronous so it doesn't lock up page
  listName: listName,
  listName: listName,
  CAMLQuery: camlQuery,
  CAMLViewFields: camlFields, 
  CAMLRowLimit: 1, 
  completefunc: function (xData, Status){

   items_Returned = xData;
   //alert(xData.responseText);

   var rows_Item = items_Returned.responseXML.getElementsByTagName('z:row');

   if(rows_Item.length == 0 )
   {
 //for chrome
    rows_Item = items_Returned.responseXML.getElementsByTagName('row');
   }

   for (var i = 0; i < rows_Item.length; i++)   
   {
    linkRef = rows_Item[i].getAttribute('ows_FileLeafRef');
    linkRef = linkRef.split(";#")[1];
    var newlinkRef = thisSite + "/" + listName + "/" + linkRef;

    aLink.attr("href", newlinkRef).attr("title", aLink.text());
   }
  }
 });
}

</script>





Next, we will create page that we will used to modify the rendering of the calendar and open a direct link to the document
  1. Create a page, and drop the Calendar list view web part (make sure to select the view for the Calendar you just created)
  2. Add a content editor web part to the page, and specify the link to a javascript file, which we just created
Enjoy!

Tuesday, June 26, 2012

Full Text Search in SharePoint on multiple document libraries using SPServices

A while ago, I needed a way to do a full text search of several SharePoint document libraries and display it in one page in a friendly way. I decided to use SPServices to do my querying and output the results using Javascript.

This script does a full text search on the keywords passed into an input box on the current scope of the site. After getting the query results, it then iterates through each search result and displays only the results where the path matches the list names passed in.

Documents in 2 different libraries:











Search output:














Refined search output:









Steps:
1. Ensure search is configured and working on your site
2. Add this script to a content editor web part on your page (View Code)
3. Update the script tags with the location of SPServices and JQuery on your site
4. Make sure to update the listUrl div with the correct list paths that you would like to restrict the output to









<div id="divSearch">
	<div>
		<b>Search Keyword: </b><br/><input type="text" id="tbSearch" size="50%" />
		<input type="button" id="btnSearch" value="Search Policies" onclick="RunSearch();" />
	</div>
</div>

<div id="divErrorMsg"></div>
<div id="divSearchResults"></div> 
<div id="divTestQueryResult"></div>
<div id="divTestQuery"></div>

<script language="javascript" type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script type="text/javascript" language="javascript" src="/policy/SiteAssets/js/jquery.SPServices-0.7.2.min.js"></script>

<script type="text/javascript"> 

//author: sparsee
//DCSharePointchick.blogspot.com
/**configurable**/
var m_searchCap = 5000;
var m_listUrls = "https://site/policy/Procedure;https://site/policy/Policy;https://site/policy/Supplement;";
var m_displayQueryResults = false;
/**************/

var m_searchQueryForList = "";
var m_arrSearchResults = new Array();
var m_searchResultCount = 0;
var m_output = "";

var imgTxt = '<img src="_layouts/images/ictxt.gif" BORDER=0>';
var imgDoc = '<img src="/_layouts/images/icdocx.gif" BORDER=0>';
var imgPdf = '<img src="_layouts/images/pdf16.gif" BORDER=0>';
var imgDefault = '<img src="_layouts/images/STS_ListItem16.gif" BORDER=0>';

$(document).ready( function() 
{
	//get document properties
	var listUrls = m_listUrls;
	listUrls = listUrls.slice(1,listUrls.length);  
	listUrls = listUrls.substring(0, listUrls.length-1); 
	var arrlistUrls = listUrls.split(';');

	for( var y = 0; y < arrlistUrls.length; y++)
	{
		var curUrl = arrlistUrls[y];
		
		if( curUrl != null && curUrl != "" )
		{
			var url = curUrl.toLowerCase();
			if( m_searchQueryForList != "" )
			{
				m_searchQueryForList += "OR CONTAINS(Path, '\""+ url +"*\"')";
			}
			else
			{
				m_searchQueryForList += "CONTAINS(Path, '\""+ url +"*\"')";
			}
		}
	} 
	
	$("#tbSearch").keyup(function(){
		RunSearch();
	});
});


function RunSearch()
{
	$("#divSearchResults").html("Searching...");
	$("#divErrorMsg").html("");
	m_arrSearchResults = new Array();

	var tbSearch = document.getElementById("tbSearch").value; 

	var myQuery = "<QueryPacket xmlns='urn:Microsoft.Search.Query' Revision='1000'>" + 
		"<Query>" + 
		"<Range><Count>" + m_searchCap + "</Count></Range>" +
		"<Context>" +
		"<QueryText language='en-US' type='MSSQLFT'>" +
		"SELECT Title, Rank, Size, Author, HitHighlightedSummary, Description, Path, Write FROM Scope() WHERE FREETEXT('" + tbSearch + "') AND (" + m_searchQueryForList + ") ORDER BY \"Rank\" DESC" +
		"</QueryText>" +
		"</Context>" +
		"</Query>" +
		"</QueryPacket>";


	$().SPServices({
		operation: "Query",
		async: true,
		queryXml: myQuery,
		//debug: true,
		completefunc: function (xData, Status) {

			$("#divSearchResults").html("Searching...");
			$("#divErrorMsg").html("");
			m_arrSearchResults = new Array();


			if (Status != "success") 
			{
				DisplayErrorMesssage(Status);
				return;
			}

			var queryResult = $(xData.responseXML).find("QueryResult").text();

			if( m_displayQueryResults )
			{
				$("#divTestQueryResult").text(queryResult);
				$("#divTestQuery").text("<br/>" + myQuery);
			}
			else
			{
				$("#divTestQueryResult").text("");
				$("#divTestQuery").text("");
			}

			$(xData.responseXML).find("QueryResult").each(function() 
			{  
				var xml = $("<xml>" + $(this).text() + "</xml>");  
				xml.find("Document").each(function() 
				{  
					var curPath = $("Action>LinkUrl", $(this)).text().toLowerCase();  

					var curTitle = "";  
					$(this).find("Property").each(function() 
					{  
						if ($("Name", $(this)).text() == "TITLE") 
						{  
							curTitle = $("Value", $(this)).text(); 
						}  
					});  

					var curHithighlighted = "";
					$(this).find("Property").each(function() 
					{  
						if ($("Name", $(this)).text() == "HITHIGHLIGHTEDSUMMARY") 
						{  
							curHithighlighted = $("Value", $(this)).text(); 
						}  
					});  

					var curWrite = "";
					$(this).find("Property").each(function() 
					{  
						if ($("Name", $(this)).text() == "WRITE") 
						{  
							curWrite = $("Value", $(this)).text(); 
						}  
					});  
		 
					var curAuthor = "";
					$(this).find("Property").each(function() 
					{  
						if ($("Name", $(this)).text() == "AUTHOR") 
						{  
							curAuthor = $("Value", $(this)).text(); 
						}  
					});   
		
					var arrayRows = new Array();
					arrayRows.push([curTitle, curPath, curHithighlighted, curWrite, curAuthor]);

					m_arrSearchResults.push([ curTitle, arrayRows ]);
				});  
			});
			
			PrintOutput();
		}
	});
}

function PrintOutput()
{ 
	m_searchResultCount = 0;
	m_output = '<table class="section-body">';
	
	var tb = document.getElementById("tbSearch").value; 

	for( var x = 0; x < m_arrSearchResults.length; x++ )
	{
		var searchTitle = m_arrSearchResults[x][0];
		var arrayRows = m_arrSearchResults[x][1];

		if( arrayRows.length > 0 )
		{
			var tableID = '"' + x + 'Table"';
			
			m_output += "<tr><td><table id=" + tableID + " class='tablesorter section-table table_summary' width='800px' style='margin-top:0px !important;'>";

			for( var y = 0; y < arrayRows.length; y++)
			{			
				var row = arrayRows[y];
				
				var title = row[0];
				var path = row[1];
				var highlighted = row[2];
				var write = row[3];
				var author = row[4];

				highlighted = GetFormattedHighlightedText(highlighted);
				title = GetHighlightedTitle(title, tb);
				title = GetFormattedTitle(path, title);

				write = GetFriendlyDate(write);

				var highlightedPath = GetHighlightedPath(path, tb);

				m_output += PrintRow(path, title, highlighted, highlightedPath, write, author);
				m_searchResultCount++;  
			}
			
			m_output += "</table></td></tr>";
		}
	}

	var returnedResults = "<br/><span style='color:red'>Showing Results for: <b>" + document.getElementById("tbSearch").value + "</b></span> (Returned: <font color='green'>" + m_searchResultCount + "</font> results)";

	m_output += "</table>";
	m_output = returnedResults + m_output;

	$("#divSearchResults").html(m_output);
}

function PrintRow(path, title, highlighted, highlightedPath, write, author)
{
	var row = '<tr><td><a href="' + path + '" target="_blank">' + title + '</a></td></tr>' + 
	'<tr><td>' + highlighted + '</td></tr>' +
	'<tr><td><a style="color:green;" href="'+ highlightedPath + '">' + highlightedPath +'</a><font color="grey"> - ' + author + ' - ' +  write + '</font></td></tr>';
	
	return row;
}

function GetFormattedTitle(path, title)
{
	if( path.indexOf(".pdf") >= 0 )
		title = imgPdf + title;
	else if( path.indexOf(".doc") >= 0 )
		title = imgDoc + title;
	else if( path.indexOf(".txt") >= 0 )
		title = imgTxt + title;
	else
		title = imgDefault + title;
		
	return title;
}

function GetHighlightedTitle(title, searchText)
{
	if( searchText != "" )
		return highlight(title, searchText);
	else
		return title;
}

function GetHighlightedPath(path, searchText)
{
	if( searchText != "" )
		return highlight(path, searchText);
	else
		return path;
}

function highlight( data, search ) { return data.replace( new RegExp( "(" + preg_quote( search ) + ")" , 'gi' ), "<b>$1</b>" ); } 
function preg_quote( str ) {  return (str+'').replace(/([\\\.\+\*\?\[\^\]\$\(\)\{\}\=\!\<\>\|\:])/g, "\\$1"); } 


function GetFormattedHighlightedText(highlighted)
{
	if( highlighted != null )
	{
		highlighted = highlighted.replace("<c0>", "<font color='green'><b>");
		highlighted = highlighted.replace("</c0>", "</b></font>");

		highlighted = highlighted.replace("<c1>", "<font color='green'><b>");
		highlighted = highlighted.replace("</c1>", "</b></font>");

		highlighted = highlighted.replace("<c2>", "<font color='green'><b>");
		highlighted = highlighted.replace("</c2>", "</b></font>");

		highlighted = highlighted.replace("<c3>", "<font color='green'><b>");
		highlighted = highlighted.replace("</c3>", "</b></font>");

		highlighted = highlighted.replace("<c4>", "<font color='green'><b>");
		highlighted = highlighted.replace("</c4>", "</b></font>");

		//highlighted = "<i>" + highlighted + "</i>";

		return highlighted;
	}
	return "";
}

function GetFriendlyDate(dateField)
{
	var datetimeparts = dateField.split('T');
	var dateparts = datetimeparts[0].split('-');
	var month = dateparts[1];
	var date = dateparts[2];
	var yr = dateparts[0]

	var formatteddateandtime = month + "/" + date + "/" +  yr ;
	
	return formatteddateandtime;
}

function DisplayErrorMesssage( errorMsg )
{
	$("#divErrorMsg").html("Error occurred. " + errorMsg );
}

function CheckSubmit() 
{
    if (event.keyCode == 13) 
	{
		$("#btnSearch").focus();
    }
}
</script>