Archive | SharePoint

Sharepoint 2010 URL for a Calendar’s Week and Month Views

This may be a post for myself, and everyone may already know this, but I couldn’t find it quickly in a google search. I wanted to have a link to the “Week” view of a SharePoint 2010 calendar, but could not find the parmters to pass. Here they are:

?CalendarPeriod=week
?CalendarPeriod=month
?CalendarPeriod=day

And to have a specific day:

?CalendarDate=8/24/2012

How I went about creating two related lists using JavaScript, Client Object Model and SharePoint 2010-Part3

This is the final part of these previous, posts. They setup everything (I hope) so give them a quick peak.

At this point we have the following:

  • We are editing a “new” meeting item in the MeetingList’s EditFrom.aspx page
  • We have a modal dialog box open that contains the AttendeeList’s NewForm.aspx
  • A QueryString has been passed to the modal dialog page with the related ID and List ID

Now I want to take the QueryString values and put them into the correct fields in the AttendeeList’s NewForm.aspx page (and hide these fields so the can’t be messed with) (also remember that this is all taking place in a modal dialog):

  • First I am going to hide the fields that are going to contain the related List and related item ID
 $('nobr:contains("RelatedList")').closest('tr').hide();
 $('nobr:contains("RelatedItem")').closest('tr').hide();
 
  • Next I need to loop thought the QueryString and grab all the values passed, and if they match the name of an exiting field, I am going to add them to the input box of the field (taken from here). Since the QueryString values RelatedList and RelatedItem match the hidden fields above, their values get put into their input boxes.
LoopThroughQueryString()
function LoopThroughQueryString() {
    var queryString = unescape(location.search);
    if (!queryString) {
        return {};
    }
    queryString = queryString.substring(1);
    var pairs = queryString.split("&");
    for (var i = 0; i < pairs.length; i++) {
        var keyValuePair = pairs[i].split("=");
	$('input[type=text][title='+ keyValuePair[0]+ ']').each(function() {
        $(this).val(keyValuePair[1]);
        });
    }
}
  • Now, when I hit save int he modal dialog, the MeetingList’s related item’s ID and related list ID are added to the new attendee.

Goal met. Two lists with related items. Phew that was a lot.

How I went about creating two related lists using JavaScript, Client Object Model and SharePoint 2010-Part2

In Part1, I talked about how I wanted to relate items in two lists using the ID of an item in the first list. The setup for this article is here, hopefully it makes sense.

At this point, I have a  MeetingList item that I am editing, and the ID of the current item is in the current QueryString. This is becasue I used this code in the previous post to redirect to this page:

window.location.href = "/Lists/MeetingsList/EditForm.aspx?ID="+ oListItem.get_id();

Now I want to add an attendee to this meeting. Here are the steps of how I went about this:

  • I needed to add a “Add new attendee” button to the MeetingList EditForm.aspx page.  I used this jQuery method to add a new row after an existing field.

NewAttendeesRow='<tr id="NewAttendeesRow"><td nowrap="true" valign="top" width="190px" class="ms-formlabel">Add Attendees</TD><td valign="top" class="ms-formbody" width="400px"><img src="/MediaLibrary/plus_icon.gif"> Add NEW attendee</div></td></tr>';

$('nobr:contains("Meeting Subject")').closest('tr').after(NewAttendeesRow); //There is an exisitng field in the MeetingList named "Meeting Subject"

  • This button, when clicked would fire off a function to open a modal dialog box which will create the related attendee/item in the AttendeeList

$('#NewAttendeesRow').click(function() {
ExecuteOrDelayUntilScriptLoaded(openModalDialog,"SP.js");
});

function openModalDialog() {
    var options = SP.UI.$create_DialogOptions();
    options.url = "/Lists/NewAtendee/NewForm.aspx?IsDlg=1&RelatedList="+_spPageContextInfo.pageListId+"&RelatedItem="+GetQueryStringParams('ID');
    options.dialogReturnValueCallback = Function.createDelegate(
                        null, modalDialogClosedCallback);
    SP.UI.ModalDialog.showModalDialog(options);
}
  • This code above opens a modal dialog and passes two values via the QueryString values, the RelatedList and the RelatedItem.
    • The RelatedList value comes from the parent list (MeetingList) using the built in variable _spPageContextInfo.pageListId
    • The RelatedItem value comes from the QueryString of the current MeetingList item we are editing using this function (not sure where I found this)
function GetQueryStringParams(sParam)
{
    var sPageURL = window.location.search.substring(1);
    var sURLVariables = sPageURL.split('&');
    for (var i = 0; i < sURLVariables.length; i++)
    {
        var sParameterName = sURLVariables[i].split('=');
        if (sParameterName[0] == sParam)
        {
            return sParameterName[1];
        }
    }
}
  • We end up with the MeetingList’s EditFrom.aspx page, and a modal dialog box that contains the AttendeeList’s NewForm.aspx, with related ID and related List being passed to it.

Part 3 will finish off my workaround.

How I went about creating two related lists using JavaScript, Client Object Model and SharePoint 2010-Part1

I was struggling with how I could create two lists in SharePoint  2010 that were related.

Scenario: Let’s say that you want to have a list of meetings (we will call it MeetingsList), with each meeting having the potential of unlimited number of attendees. How can I do this in SharePoint? It is not possible to have Attendee-1 to Attendee-∞ (infinity) as fields in the MettingsList. I needed to move the attendees to their own list (we will call it AttendeeList). But how do I related the attendees to the meeting?

My work around: The trick was that I needed to know the MeetingsList item’s ID before I created the related attendees. I could not figure a way to get that ID until after the MeetingsList item was saved. The work around that I came up with was that I would create the item when a person clicked the “new” button, and then redirect them to EDIT the newly created item. Then I could add an item to the AttendeeList with ID of the current item being edited in the MeetingsList. Hope that makes sense. Steps and code:

  • Create a list that contains the meeting specifics – MeetingsList
  • Create a second list that will contain the attendees – AttendeeList
  • Use my Delegate Control method to insert JavaScript (code kept in a document library) into  the top of any page as described here
  • Add the following to the top of the NewForm.aspx page:
$(document).ready(function() {
	ExecuteOrDelayUntilScriptLoaded(createListItem,"SP.js");
});
function createListItem() {
    var clientContext = SP.ClientContext.get_current();
    var oList = clientContext.get_web().get_lists().getByTitle('MeetingsList');
    var itemCreateInfo = new SP.ListItemCreationInformation();
    this.oListItem = oList.addItem(itemCreateInfo);
    oListItem.update();
    clientContext.load(oListItem);
    clientContext.executeQueryAsync(Function.createDelegate(this, this.onQuerySucceeded), Function.createDelegate(this, this.onQueryFailed));
    }

function onQuerySucceeded() {
window.location.href = "/Lists/MeetingsList/EditForm.aspx?ID="+ oListItem.get_id();
}

function onQueryFailed(sender, args) {
    alert('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());
}

All this Client Object Model code does is create a new item in the MeetingList list, and then redirect the browser to edit that item. Now, on the EditForm.aspx page, I know the item ID of the item I am editing and I can use this ID to create a new related item in the AttendeeList. Next steps are in part 2.

How I am using a Delegate control, code in a Document library, and jQuery to customize SharePoint 2010

In this post, I showed how to put a delegate control at the top over every page, and in the control add the links to the jQuery libraries. This is nothing new, there are many articles that show how to do this. I took this a step further and I included code to do the following:

  1. Determine the current page’s relative URL (where the delegate control is running) and put that value in a Variable
  2. Take that variable and change the relative URL’s forward slashes (“/”) to underscores (“_”), and change “.aspx” to “.txt”
  3. Look for a file in a document library with a name that matches the variable created above and insert it’s contents into the additional page header

For example if  I am browsing to http://sharepoint.company.com/Lists/Announcements/AllItems.aspx, and there is a file in the desiganted Document library named “_lists_announcements_allitems.txt” then it’s contentens will show up in the addition page header.

Some of the benefits I have found with my methods

  1. All client side code is kept in one place, and you can easly figure out which file is being used on each page
  2. The Document Library can have versioning, so you can rollback changes
  3. Linked CEWP can be kept in the same place
  4. It is easy to edit text, js and css files in SharePoint Designer, rather than in CEWP
  5. Now it is a snap to chop up a NewForum.aspx via jQuery
  6. It is easy to extend the code so that a file is included across all pages, making it easy to add a new js library to the entire site

Here is the code I am using in the Delegate Control (ascx)

string CurrentSiteRelativeURL = CurrentUrl.ToLower().Replace(CurrentWeb.Url.ToLower(), "");
string CustomFileName = CurrentSiteRelativeURL.Replace("/", "_");
string PageSpecificHeaderIncludes = CurrentWeb.Url + "/DocumentLibraryWithCodeInIt/" + CustomFileName.Replace(".aspx", ".txt");

Response.Write("<!--PageSpecificHeaderIncludes:" + PageSpecificHeaderIncludes + "-->");
    if (CurrentWeb.GetFile(PageSpecificHeaderIncludes).Exists == true)
    {
        SPFile tempFile = CurrentWeb.GetFile(PageSpecificHeaderIncludes);
        StreamReader reader = new StreamReader(tempFile.OpenBinaryStream());
        string myText = reader.ReadToEnd();
        reader.Close();
        Response.Write(myText);
    }

Anyone else doing anything like this? Thoughts?

How to add custom JavaScript code to all SharePoint 2010 pages (DelegateControl)

As I said in this post, there are plenty of articles on how to do this. This is more of a note for myself, as I have to “re-learn” this every time I need to customize SharePoint.

There are 2 ways (that I know of) that you can add code to every page in SharePoint 2010, 1 by the AdditionalPageHead delegate control, or ,2 by Custom Action. This article is about #1 (see #2 here) using the AdditionalPageHead delegate control.

  • Start Visual Studio, and create a new Empty SharePoint Project (uncheck the Create Directory for Solution because you salways create the destination directory yourself)
  • Deploy as a Farm Solution (I have not figured what you can and can’t do with sandboxed solutions yet)
  • RightClick the Project and Add –> New item –> User Control –Name it. This will create a new folder named ControlTemplates and inside will be your User Control. Looks like this

  • Edit the new ascx file and add the code you want to put at the top of every page, for example:
<script type="text/javascript" src="/path/to/jquery.js"></script>
  • RightCLick the Project and select Add Empty Element and name it at the bottom
  • add the following to the elements.xml file. The final should look like this below:
  <Control Id="AdditionalPageHead"
          Sequence="90"
          ControlSrc="~/_CONTROLTEMPLATES/DelegateControl/DelegateControl.ascx" />

Package everything up and you will now see your reference to jQuery on the top of all pages.

PowerShell script to copy a SharePoint Document Library to a Local Path

I wanted to have a PowerShell script that downloaded A Document Library’s contents to a local folder. This is what I put together.

Function JBM-SharePoint-CopyDocumentLibraryLocal {
PARAM([Parameter(Mandatory=$true)]$SiteURL,
    [Parameter(Mandatory=$true)]$DocumentLibrary,
    [Parameter(Mandatory=$true)]$Destination)
$spWeb = Get-SPWeb -Identity http://$SiteURL
$list = $spWeb.Lists[$DocumentLibrary]
foreach ($listItem in $list.Items)
{
    $DestinationPath = $listItem.Url.replace("$DocumentLibrary","$Destination").Replace("/","\")
    write-host "Downloading $($listItem.Name) -> $DestinationPath"

    if (!(Test-Path -path $(Split-Path $DestinationPath -parent)))
    {
        write-host "Createing $(Split-Path $DestinationPath -parent)"
        $dest = New-Item $(Split-Path $DestinationPath -parent) -type directory
    }
    $binary=$spWeb.GetFile($listItem.Url).OpenBinary()
    $stream = New-Object System.IO.FileStream($DestinationPath), Create
    $writer = New-Object System.IO.BinaryWriter($stream)
    $writer.write($binary)
    $writer.Close()
}
$spWeb.Dispose()