Archive for September 26, 2012

CREATING A CUSTOM PAGE LAYOUT IN SHAREPOINT 2013

This article explains how to create custom page layouts in SharePoint 2013.  For more information on the SharePoint 2013 page model,see this Microsoft article.

Planning Out Your Page Layout

For this example, we’re going to recreate a chunk of a page on our web site (www.navantis.com):

image

In our previous article, we created Master Page that defined the header, footer and global style sheets for this page.  Now we’re going to create a page layout that follows this basic format.  The content will be dynamic so that you could create as many pages as you like based on this layout. 

In our page layout, we’re going to define the following areas as “field controls”.  We’re going to create them all in a single content container and lay them out explicitly in order to reflect our design:

image

The breadcrumb on the top left we can use SharePoint’s breadcrumb trail and we will embed the newsletter subscription into the page layout because we don’t want this to be explicitly defined into the layout.

Defining Your Content Type

So before we do the HTML work, let’s create a content type (a definition for content fields) that defines each of these fields for our page.  Based on the above plan, we need the following fields:

  • LargeHeadline
  • RightHandBlurb
  • LeftLinkList
  • LeftColumnTitle
  • LeftColumnText
  • RightColumnText

In each case, these will be HTML controls.  SharePoint 2013 allows you to define other types of content for these fields such as images.  Images in SharePoint 2013 can be rendered in specific dimensions and SharePoint 2013 will dynamic render any image to that specified to ensure they fit nicely into your defined layout.

To create a content type, go to Site Settings –> Site Content Types (under Web Designer Galleries).  If you look at Page Layout Content Types you will see existing ones for Article, Catalog, Welcome Page, etc.  We’re going to create a content type for our layout.  Click on Create and type in a name for your new content type:

Under Parent Content Type, you can select the parent your content type will inherit from.  If you look at the existing page layout content types, they inherit from the content type Page.  Page is in the group Publishing Content Types.  You can also specify the group you want to place your new content type – you could add it to the existing Page Layout Content Types group or create your own custom group.

image

When you have created your new content type, SharePoint 2013 will display the columns that were inherited automatically from the Page content type.  Lets add some new ones to represent our custom fields.  Click on the Add from new site column and let’s add each field:

image

For each column, we can specify the type.  For those fields we want to explicitly style, we can use the Single Line of Text option to have the content author put in plain text that will be formatted by the template.  For those fields that we want to provide more control to the content author, we can specify the field as Full HTML content and then content author will be able to put in any HTML using the rich text editor.    For our fields, let’s use this approach:

  • LargeHeadline – Single line of text
  • RightHandBlurb – Multiple lines of text
  • LeftLinkList – Full HTML
  • LeftColumnTitle – Single line of text
  • LeftColumnText – Full HTML
  • RightColumnText – Full HTML

image

For each field, create a site column.

Now we have fields to store the content, let’s now create a Page Layout.

Creating a Page Layout

To create a page layout, go to the Design Manager and Click on 6. Edit Page Layouts.  Click on Create a Page Layout.  Give your page layout a name, pick your master page and your content type you just created.

image

If you preview your page layout, you will see it doesn’t look like much – we need to update the HTML around the field controls to properly format the layout.

Publishing Your Page Layout

Before you can use your page layout, it has to be published.  To publish your page layout, go to Site Settings –> Master pages and page layouts.  You will see two files – one is HTML and one is ASPX.  in SharePoint 2013, the HTML is now the master and you can edit it using an HTML editor.  SharePoint 2013 then generates the ASPX file automatically.  To publish your layout, click on the HTML file and then Publish:

image

This will publish both the HTML and ASPX files, now making them available to create a page based on your layout.

Creating a Page

To create a page based on our new layout, go to New Page. 

image

If you then go to Page –> Page Layouts you will find our new Page Layout in the list of available Page Layouts.  When you switch the page layout, you should now see all the fields that we created earlier in our content type.

You can fill in your content either by typing it in or copying and pasting it from either your existing web site or from office documents such as Word.  The copy and paste has improved dramatically over previous versions!

Here is my content now filled out:

image

Now we can publish our page…

image

Our content is there, but the layout doesn’t reflect what we want…so now edit the HTML to update our layout.

Customizing Page Layouts

Page layouts in SharePoint 2013 are just HTML files with a lot of additional markup to specify where the controls are going to be injected.  We can now customize the HTML file through the design manager.  You can simply grab a copy of the HTML file, make your changes and re-upload your file and SharePoint 2013 will do the rest.  There are two ways to grab the file:

  • Go to Design Manager –> 3. Upload Design Files and map a network drive to your master page directory.
  • Go to Site Settings –> Master pages and page layouts and you can download your file.

After iterating a few times with the page layout and moving the snippets provided by SharePoint 2013 into the appropriate spots, we now have a nicely formatted page:

image

All the content within the main page area is fully managed by SharePoint can be easily changed by a content author.

image

CREATING A NEW MASTER PAGE IN SHAREPOINT 2013

This article explains how to create a Master Page in SharePoint 2013 from an existing HTML page with associated graphics, scripts, CSS files, etc.  This article is targeted primarily at designers who want to start customizing their SharePoint 2013 site with minimal fuss.  In SharePoint 2013, designers can now use HTML, CSS and JavaScript to create dynamic pages where in previous versions it required an ASP.NET developer.  This article shows a step by step example.

For this example, I have used our own web site as a starting point: 

http://www.navantis.com/Portals_Collaboration.html

image

We’re going to convert this page into a master page for use in SharePoint 2013.

Planning Out Your Master Page

A Master Page in SharePoint represents the chrome elements of a page, e.g. those areas of the site that stay the same from page to page and the associated master styles, scripts, fonts, images, etc. that should be included on every page of your site. 

For our page, we want these chunks of content in our master page as well as all the governing style sheets, JavaScript, images, etc.:

image

image

The content in the middle of the page is what will governed dynamically by SharePoint using a combination of Page Layouts and dynamic content.

Before moving to SharePoint, create a stripped down HTML file that has the chrome isolated with the appropriate images, CSS, JavaScript, etc. in folders.

image

The dynamic content is going to go where it says, “Dynamic content will go here”.  My folder structure looks like this:

image

Ok, now that we’re organized, we can create our Master Page in SharePoint 2013.

Creating a SharePoint 2013 Account

Currently, you can download and install the SharePoint 2013 beta software locally, or you can create a cloud based account.  I have used the cloud based account route because its easy and free for the moment.  Go to http://www.microsoft.com/office/preview/en/office-365-enterprise to signup for an account and you will have your own SharePoint 2013 environment in the cloud.

The same instructions should work on a local version of SharePoint 2013 as well.

Creating a Publishing Site Collection

When you are first granted a SharePoint 2013 account, you are allocated a public facing web site and a collaboration site.  You can use your public facing web site, but I recommend you create a separate Publishing Site Collection for development purposes as Microsoft only allows one public facing web site in the current cloud environment.  To create a new Publishing Site Collection, go to Admin –> SharePoint –> Site Collections and click on the New Private Site Collection button. 

image

Now that you have a Publishing Site, you can start to customize it with your new Master Page.  Your default home page will look like this:

image

The Design Manager

If you click on “Design your site”, this will bring you to SharePoint 2013’s new Design Manager:

image

You can also reach this screen by clicking on the settings menu at the top right hand of the page and clicking on Design Manager

image

Mapping to the Master Page Directory

Click on 4. Edit Master Pages and you will see a screen like this:

image

We’re going to Convert an HTML file to a SharePoint master page.  Click on that link and you will see this dialogue box:

image

This directory is the folder containing Master Page and Page Layouts as well as their dependent assets (CSS files, scripts, images, etc.).  The easiest way to manage this folder is to map a network drive in Windows to this folder.  To do this go to Windows Explorer, right click on your computer and select Map Network Drive.  Copy and paste the URL for the location of this directory (it’s at the top of this dialogue box) and put in your login credentials.  You should then get a drive letter that maps to this folder and you can copy and paste files from your local machine into SharePoint directly.

NOTE: You will get an error when you map the network drive if you don’t have the “Keep me signed in” checkbox selected when you sign into Office 2013.  Sign out, delete your cookies, and re-authenticate with this box checked and it will work.

image

With a mapped network drive, we can simply copy our template and dependent files into this folder. 

NOTE: SharePoint 2013 will allow you to create folders in this directory, so this might help in keeping organized to create a separate folder as the root of your master page and its files.

NOTE: If you cannot map the drive, you can also upload files through the UI by going to Site Settings and Clicking on  Master pages and page layouts.

image

When you click on this you will access the same master page library that is used by the Design Manager.

image

If you click on files you can then upload documents and create folders through the browser UI.

Creating a Master Page from HTML

Now that we have uploaded our files, we’re going to create a Master Page.  SharePoint 2013 can take your HTML file and convert it into a ASP.NET Master Page automatically.  When it does this, it will link the HTML and Master Page together so that if you change your HTML file it will sync these changes into the Master Page.  This allows designers to now work in their comfort zone with HTML, CSS, JavaScript, etc.

Go to the Design Manager.  Click on 4. Edit Master Pages and then click on Convert an HTML File  to a SharePoint master page.

image

Select your HTML file and click insert. 

If you go to the Design Manager, you will also now see your Master Page in the list of Master Pages:

image

NOTE: SharePoint 2013 expects your HTML to be XML Compliant. If you have older or non-compliant HTML you will get an error. Fix your file and try again.

If you click on the Master Page, it will take you to a preview page.  At the bottom of the page you will see a Yellow Box that represents the place holder where dynamic content is going to be inserted…We’re going to now move that place holder into where we want it to replace our dummy text in the middle of the page.

Download the HTML file from the SharePoint 2013 environment (you can just copy and paste it if you have a mapped network drive) and open it in your HTML editor and you will see that SharePoint 2013 has decorated your HTML with a number of tags.  These tags are used by SharePoint 2013 as markup to specify where to put to insert content when it generates the Master Page.  You can edit and add HTML around them and add new snippets to the HTML to add dynamic navigation, content containers, metadata etc. 

In your newly improved HTML file, you will see tags in the header (used to insert metadata, title and other header information), at the top of the body (used to insert the ribbon), and at the bottom you will find a div called “ContentPlaceHolderMain”. 

This is a content place holder and is used by the Page Layout to inject content dynamically.  You can move this place holder into the appropriate spot in your HTML to insert the content correctly.

image

Publishing Your Master Page

The last step is we need to publish our master page – its currently in draft.  If you don’t publish it you won’t see it in the Site Master Page Settings drop down menu.  To publish your page, go to Site Settings –> Master pages and page layouts and then find your HTML file.  Hit the publish button on the ribbon. 

NOTE: If you try to publish the master page itself you will get an error because it is linked to the master HTML file.  If you publish the HTML file, the master page is automatically published as well.

Assigning Your Master Page to your Site

Now that your master page is published, you can assign it to your site.  All pages in your site will adopt this new chrome.  Publish sites have two types of pages: 1) publishing pages and 2) system pages.  Publishing pages are traditional web pages and System pages are views of lists, document libraries and other administrative pages.  You can assign your master page to either type of pages.

To assign your master page, go to Site Settings –> Master Page (under Look and Feel) and select your master page from the drop down list (if its not there then you probably didn’t publish it successfully or it has errors).  Your site will now adopt your new look and feel!

Here is my default site with the Master Page site assigned.

image

How to change the local path in TFS 2010?

Have been using TFS 2010 for a while, I consider it a pretty stable and good Development environment for .Net Development. It might be frustrating at time, but once you get comfortable using it, its pretty neat. One of things people get frustrated with is to figure out how to change the local path of your working directory. In TFS they something called Workspaces which is actually your Local working folder. You can have more than one workspace. Within a Workspace you can have the Local Working Folder path mapped to your Source Control Folder. TFS also allows you to edit your Workspace and the Local Folder Paths within it.

How to change the local path in source control explorer?
How to change the local path in team foundation?
How to change the local path in team explorer?
How to change the local path in tfs 2008?
How to change the local path in tfs 2010?

To change your Local Path do this:

Step 1:

In your Visual Studio 2010 Goto File à Source Control à Workspace (Make sure your Visual Studio is connected to your TFS server) Refer to figure below.

Step 2:

Next you should see the following window. Select the Workspace you want to Edit and click on the Edit button.

Step 3:
Next you should see the Edit Workspace Window. Change the Local Folder Path by clicking on the …

That’s it. You are done. You have changed the Local Path of your working folder in TFS.

Hope that was useful!

SharePoint – ListField Iterator

This control renders each field in a list item with an appropriate control. A single line text field will be rendered as a text box while a lookup field will be rendered as combo box.
This control resides in the Microsoft.SharePoint.WebControlsnamespace of theMicrosoft.SharePoint.dll.
You  can use this control in a custom application page or in a custom Edit, New and Display form.
In its simplest way you can declare the control as follows:
                        ControlMode="New" ListId="{e2886b6e-4d63-4063-a02c-eac7fb3aef79}" />

This renders the first list item as follows:

You can set different properties of the ListFieldIterator control:

  • ListId: This property must contain the id – which is a Guid – of the list you want to display.
  • ControlMode: Defines whether the controls are displayed in display mode, edit mode or new mode.
  • ExcludeFields: Specify the fields that don’t need to be rendered. Separate each field with ;#
  • Item: In code behind, you can retrieve the current list item by using this property.
  • ItemId: in code behind, you can retrieve the id of the current list item. But you can also decide which item to render by setting this attribute declaratively.
            ControlMode="Edit" ListId="{e2886b6e-4d63-4063-a02c-eac7fb3aef79}" ItemId="2" />

  • List: In code behind, you can retrieve the current list by using this property.
  • Template: you can set this property if you have deployed your own custom template to the 12\TEMPLATE\CONTROLTEMPLATES folder.

Interacting with other fields from a custom field

 Today I will show you how you can create the interaction itself between the fields.

It requires some little tricks, but after we solve the exercise you will see that it is not so complicate and in the forthcoming post I will show you some very powerful example to demonstrate you the usability of this technique.

The main point of the interaction is to get the reference to the other field controls. As I did last time, I will first introduce an interesting approach that – sad but true – does not work.

On the forms the fields are rendered within a ListFieldIterator control. Individual fields of type SPField can be addressed through the Fieldscollection (inherited from FormComponent) of this class that returns an SPFieldCollection. SPField class has a property calledFieldRenderingControl that returns BaseFieldControl. Since the actualListFieldIterator can be accessed through the parent chain of the actual field control, at the first sight it seems to be a good idea to get the reference for another field using the following really long line of code:

BaseFieldControl fieldControl = ((Microsoft.SharePoint.WebControls.ListFieldIterator)this.Parent.Parent.Parent.Parent.Parent).Fields[fieldName].FieldRenderingControl;

Unfortunately that is not so simple. Although we got a valid reference to a field control, if you try to manipulate its properties, or just to read them, it turns out to be an other instance, not the one displayed on the forms. That is because theFieldRenderingControl returns a new instance of a subclass of theBaseFieldControl, that has really no relation to the actual form.

What other ways there are to get the reference field control? We know that it is a control on the page, but we don’t want to iterate through all of the controls just to find the field. Fortunately theBaseFieldControl class implements a specific interface IValidator and thus included in the Validators collection of the Page class. That is really nice, and we will depend on this behavior in a later post when implementing custom runtime validation of fields.

But for now it is enough to get the reference to the field control using a custom method like this:

  1. protected BaseFieldControl GetFieldControlByName(String fieldNameToSearch)
  2. {
  3.     String iteratorId = GetIteratorByFieldControl(this).ClientID;
  4.     foreach (IValidator validator in Page.Validators)
  5.     {
  6.         if (validator is BaseFieldControl)
  7.         {
  8.             BaseFieldControl baseField = (BaseFieldControl)validator;
  9.             String fieldName = baseField.FieldName;
  10.             if ((fieldName == fieldNameToSearch) &&
  11.                 (GetIteratorByFieldControl(baseField).ClientID == iteratorId))
  12.             {
  13.                 return baseField;
  14.             }
  15.         }
  16.     }
  17.     return null;
  18. }
  19.  
  20. private ListFieldIterator GetIteratorByFieldControl(BaseFieldControl fieldControl)
  21. {
  22.     return (Microsoft.SharePoint.WebControls.ListFieldIterator)this.Parent.Parent.Parent.Parent.Parent;
  23. }

In this method we iterate through the validators on the page, and do some checks in the following order:

  1. Is the field derived from the BaseFieldControl class?
  2. Is the field name the same we are looking for?
  3. An extra check just to be sure: is the field rendered in the sameListFieldIterator as the current field control. Without this check it is possible to have multiple forms on the same page having fields with the same name. We really don’t want to interact with fields in other forms. At least, not now…

Let’s see some simple practical example for usage of this method. Of course, in a production environment you should add some extra logic for null values, exception handling and tracing/logging, but I try to keep it simple now. All of the code snippets are for the field control class that is derived from the BaseFieldControl class.

In the first example we set the field control mode to display. That can you use to prevent users to modify the field value, for example based on the user’s permissions or the value of other field.

  1. protected void SetFieldReadOnly(String fieldName)
  2. {
  3.     BaseFieldControl fieldControl = GetFieldControlByName(fieldName);
  4.     fieldControl.ControlMode = SPControlMode.Display;          
  5. }

Sometimes it is required to hide the field value too. The next example hides the field having the specified name using the same technique we used to inject invisible field to the form.

  1. protected void HideField(String fieldName)
  2. {
  3.     BaseFieldControl fieldControl = GetFieldControlByName(fieldName);
  4.     fieldControl.Visible = false;
  5.     fieldControl.Parent.Parent.Visible = false;
  6. }

You can also set values of other fields using the same technique as illustrated in the code snippet below for a text field.

  1. protected void SetFieldValue(String fieldName, String fieldValue)
  2. {
  3.     TextField fieldText = (TextField)GetFieldControlByName(fieldName);
  4.     fieldText.Value = fieldValue;
  5.     fieldText.Text = fieldValue;
  6. }

You might ask why I don’t show you the simplest case: reading field value. That is because it is really not so simple, and I will describe it in details in a forthcoming post.

It might be useful to use these and similar methods in your custom field control and use that as the boilerplate class for more advanced fields.

The next code snippet assumes that you have a custom list with fields Field1, Field2, Field3, Field4 (all of these of type Single line of text), the default Title field and Field5 of type Choice with valuesValue1, Value2 and Value3. Furthermore, I suggest you to create your custom field as a “hidden” field as described here.

I’ve created an item in the list before adding our new field to the list columns. The following figure shows the values of the fields on the edit form. You can see there is nothing special on that:

image

We call the methods in the edit and new control modes of the field from the OnLoad method of the field control:

  1. if ((ControlMode == SPControlMode.Edit) || (ControlMode == SPControlMode.New))
  2. {
  3.     HideField(“Field1”);
  4.     SetFieldReadOnly(“Field3”);
  5.     SetFieldReadOnly(“Field5”);
  6.     SetFieldValue(“Field4”, “text”);
  7. }

After building, deploying, and adding the new field to the list, you should see the results immediately on the edit form:

image

It seems to be working perfectly, but if you would like to create you will notice that there is a minor issue with the code. Field3 should be empty, but it contains the text Field3 field value. The other read only field, Field5 of type Choice is displayed correctly.

image

There was a problem with setting the fields read only.

Since then I’ve found the source of the incorrect value in the display (read only) mode of the field on the new form and provide a workaround for that issue here, that is unfortunately a bit of hacking.

First, I should note, that as I observed, the value displayed in this case has no effect on the value saved into the item, but default values have also no effect. Furthermore, when the item is opened and saved in the edit mode, the former field values might be also lost.

I found that when the field control mode is set to display on the new form in our case, the value of the PreviewValueTyped property of the related field is displayed. That is FieldName field value. for the text fields (replace FieldName with the actual field name), 1,234.56 for numeric fields, the actual date and time for date type fields, default value or if there is no default value, the first option for choice fields.

The source of the issue seems to be is that the ItemFieldValueproperty and the ListItemFieldValue property of the BaseFieldControlreturn the value of the PreviewValueTyped if the ItemId property is zero, that is the case for a new item. I should note that the obfuscated RenderFieldForDisplay method also references thePreviewValueTyped property. I’ve tried a hack and set the ItemId to –1, and it seems to solve part of the issue, the field value is displayed correctly.

But the values of the affected fields in the item are still not saved correctly, since setting the ItemId to –1 has a side effect that it resets the ItemFieldValue and the ListItemFieldValue properties to null. To correct this behavior I backed up the value of theListItemFieldValue property before setting the ItemId to –1, and restore it at the end. I cannot omit setting the ItemId to –1, since while the ItemId is zero, setting the value of the ListItemFieldValueproperty has no effect.

  1. protected void SetFieldReadOnly(String fieldName)
  2. {
  3.     BaseFieldControl fieldControl = GetFieldControlByName(fieldName);
  4.     Object value = fieldControl.ListItemFieldValue;
  5.     fieldControl.ControlMode = SPControlMode.Display;
  6.     if (ControlMode == SPControlMode.New)
  7.     {
  8.         fieldControl.ItemId = -1;
  9.         fieldControl.ListItemFieldValue = value;
  10.     }
  11. }

After these modifications the new form works as expected, but there is an issue with the edit form. Even the correct values are displayed, empty text is saved for text field, and the first item is set for the choice field when saving the item.

This issue was solved by placing the code from the OnLoad method to the OnInit method of the field control.

An important note finally. It is mandatory to place the custom field that tries to access other fields using the GetFieldControlByNamemethod introduced in the former post after the last field it references. You can change the field order using the Change Field Order page(List Settings / Column ordering), or you can do it using code. If you don’t do that this way, the method will not find the field on the page, as it is added only after the current field is loaded.

Completely Empty the SharePoint 2007/2010 Recycle Bin

If you have lots of stuff in your SharePoint Recycle Bin and want to empty it all, here’s a quick tip:

  1. Navigate to the recycle bin page (e.g., http://localhost/_layouts/recyclebin.aspx)
  2. In the address bar, type “javascript:emptyItems()” (minus the quotes)
  3. Press Enter. You will be asked if you really want to empty the recycle bin.
  4. Click OK to empty it; click Cancel to leave it alone.

It’s much faster to empty it this way if you have multiple pages of “stuff” in your recycle bin.

[Update: This tip works with both SharePoint 2007 and SharePoint 2010.]

Working with SharePoint 2010 search web service

In this article we will discuss how to user search web service in SharePoint 2010. We will search by using SharePoint search web service. Also you can check about FAST search here. SharePoint 2010 search is very useful and advanced in SharePoint 2010.
There are different search web services available for SharePoint search and SharePoint Enterprise Search. The service url for sharepoint search is:

http://[URL]/_vti_bin/spsearch.asmx
The web service url for sharepoint enterprise search is:
http://[URL]/_vti_bin/search.asmx
For this demo we will use client object model and we will bind the search result to a datagridview in a windows application.
You can put a Textbox where user can put the search text, a button and a datagridview where user can see the search result as output. see the figure for reference.

In the next step we need to add reference to the web service.
For this Right click on the project and click Add service reference. This will open the Add Service Reference dialog box. On that box click on Advanced… as shown in the figure below:

This will open the Service Reference Settings dialog box, from there click on Add Web Reference… as shown in the figure below.

The above step will open the Add Web Reference dialog box.

In that window enter the URL of the web service and click on the green arrow. This will search and found the web service if present. Then click on Add Reference as shown in the figure below:

This finishes our reference to the web service.
Now open the Button click code.
First give reference to the web service like:
using SearchPOC.QueryWebServiceProxy;
Here we will use the QueryService class and pass the DefaultCredentials as the parameter.
Then it will take an XML as an search input parameter which is shown in the full code below.
Then here in this example we are calling the QueryEx method which returns the results as a DataSet. We also can use Query method which returns results as an XML document.
Full code:


private void btnSearch_Click(object sender, EventArgs e)
        {
            try
            {                      
            QueryService queryService = new QueryService();
            queryService.Credentials = System.Net.CredentialCache.DefaultCredentials;
            StringBuilder queryXml = new StringBuilder();
            queryXml.Append(““);
            queryXml.Append(““);
            queryXml.Append(““);
            queryXml.Append(““);
            queryXml.Append(“urn:Microsoft.Search.Response.Document.Document”);
            queryXml.Append(“
“);
            queryXml.Append(“
“);
            queryXml.Append(““);
            queryXml.Append(“5000“);
            queryXml.Append(“
“);
            queryXml.Append(““);
            queryXml.Append(““);
            queryXml.Append(txtSiteURL.Text);
            queryXml.Append(“
“);
            queryXml.Append(“
“);
            queryXml.Append(“
“);
            queryXml.Append(“
“);
            System.Data.DataSet queryResults = queryService.QueryEx(queryXml.ToString());
            dataGridView1.DataSource = queryResults.Tables[0];
            }
            catch (Exception ex)
            {
                string s = ex.InnerException.ToString();
            }
        }