Category: Web Controls

What is the _layouts/15/start.aspx in SharePoint 2013

SharePoint 2013 immediately redirects you to an application page start.aspx when you call a website.

If you’ve ever wondered why, keep on reading…image

image

The pictures will also look familiar to you. So what happened? Why the start.aspx?

The start.aspx inherits Microsoft.SharePoint.ApplicationPages.MDSStartPage. That page simply looks, if the SPContext.Current.Site.CompatibilityLevel is above 14. If not, it’ll redirect to web.Url. That is the behavior, we know from previous versions of SharePoint.

Additionally it adds some caching information to the Response, and loads a JavaScript called… start.js. That file contains a method $_global_start, which is executed after the file has been loaded. There are some steps the JavaScript executes. Next I’ll try to tell you what the most important steps are.

The arrow basically shows what happens if a user requests a page, where the new logic has been implemented.

image

Next, I will write a little bit about each step. Don’t expect an in-deep explanation. This is just an overview to satisfy the first curiosity.

The Start.js

Show “Working on it…” either full-size for a newly called page, or a smaller one on the right side

But who calls the script? The answer is: the mighty masterpage.

The script does some magic to the Url. I’ll check for updates, which have to be loaded an passed to the client and modify the Url (inserts _layouts/15/start.aspx). If you want to take a closer look on what the script does, set a Breakpoint with e.g. Firebug on the line “function AsyncDeltaManager$_navigate(url, anchorName, bUpdatehash) {“ and reload a page.

The v5.master

SharePoint 2013 brings a new masterpage, which is called v5.master. That masterpage contains a control of type StartScript.

<SharePoint:StartScript runat="server" />

The TagPrefix SharePoint reflects the namespace Microsoft.SharePoint.WebControls. So lets look into the class.

The StartScript WebControl

If the current Page is of type DeltaPage, the class adds some JavaScript to the Page.

To shorten up here as well: If there is a hash in the Url (#), the script will tell the AsyncDeltaManager (from start.js) to hook up to the submit event and tell it where it needs to redirect in case of a postback.

That’s basically all the WebControl is doing.

The DeltaPage

The DeltaPage inherits System.Web.UI.Page. It decides, whether to render the full page, or just a delta. This is called the “Minimal Download Strategy”. There are already some interesting posts about this available. SharePoint 2013 – Introduction to the Minimal Download Strategy (MDS) or Minimal Download Strategy in SharePoint 2013

protected override void Render(HtmlTextWriter writer)
{
    if (this.RenderDelta)
    {
        this.RenderForRenderDelta(writer);
    }
    else
    {
        this.RenderToBase(writer);
    }
}

RenderDelta will look if the current page is the StartPage (that means there is no Page on which to depend)  or if SPContext.Current.Web.EnableMinimalDownload has not been enabled. RenderForRenderDelta add “pageStartRedirect” to the response. I won’t go into the details of this, because I simply haven’t looked into it deep enough for a blog post.

Summary

This image should visualize the steps.

image

Please keep in mind, that this post is written with a research on SharePoint 2013 preview!

There are plenty more features which I’d like to take a deeper look into. Let’s hope I find the time to do so 🙂

Control.ClientID has wrong value

An ASP.NET Controls has a ClientID property. SharePoint Controls inherit from the ASP.NET Controls. The property will give you the ID, the rendered control will have in the HTML source. There is one thing to remember:

The ClientID is valid only, if the control has been added to the Controls of the Page!

ID before adding the controlID after adding the control
FilterButtonctl00_m_Webpart1_FilterButton

So if you need the ClientID e.g. to pass it to a JavaScript to be able to find the control, make sure you grab the ClientID after the control has been added to the Page.

Using SharePoint Controls

Back from vacation. 1 week with an offline version of feeds is hard. So I read the postings I got closely 🙂 One post I do want to bring your attention to, is about SharePoint Controls.

My post about using the SharePoint Controls shows how to use the controls you see in forms (TextField, NumberField, LookupField…).

There are plenty of SharePoint controls, which you can use. Robin Meure has written a post “re-using SharePoint controls”. The controls in his post are:

WebApplicationSelectorimage
SiteAdministrationSelectorimage
SchedulePickerimage
SPDatePickerControlimage
ButtonSectionimage
InputFormSection, InputFormControlimage
InputFormTextBoximage
InputFormRequiredFieldValidatorimage
InputFormRangeValidatorimage
ToolBar, ToolBarButtonimage

Go to his post to see the code on how to use these controls.

Update February 2010:

If you want to learn more about InputFormSection.ascx and InputFormControl.ascx Controls, you have to take a look at the post

InputFormSection.ascx and InputFormControl.ascx Controls over at Karine Bosch’s Blog.

How to use the SharePoint Web Controls – Update

My post How to use the SharePoint Web Controls has been updated.

It now shows how to use a generic control for each SPField, instead of picking the corresponding SharePoint Web Control.

   1:  BaseFieldControl webControl = field.FieldRenderingControl; 
   2:  webControl.ListId = list.ID; 
   3:  webControl.ItemId = item.ID; 
   4:  webControl.FieldName = field.Title;
   5:  webControl.ID = GetControlID(field);
   6:  webControl.ControlMode = mode;

Thanks for all the great comments and ideas!

SharePoint Web Controls to access remote content

In my post How to use the SharePoint Web Controls I talked about using the SharePoint Web Controls to show and edit data in SharePoint lists.

Today I want to post a sample how to work on a list, which is in another web. The remote list will be the "User Information List" which exists on every rootWeb.

   1:  // connect to the rootweb, to read the users list
   2:  var rootWeb = SPContext.Current.Site.RootWeb;
   3:  {
   4:      // get the current user and corresponding item in the user information list
   5:      SPUser user = SPContext.Current.Web.CurrentUser;
   6:      SPList list = rootWeb.Lists["User Information List"];
   7:      SPListItem userItem = list.GetItemById(user.ID);
   8:   
   9:      // set the context, so the controls will work
  10:      SPContext context = SPContext.GetContext(
  11:          HttpContext.Current, userItem.ID, list.ID, rootWeb);
  12:   
  13:      // Username
  14:      Controls.Add(new Label { Text = "Username:" });
  15:      var username = new TextField
  16:      {
  17:          ID = "Username",
  18:          FieldName = "Title",
  19:          ItemId = userItem.ID,
  20:          ListId = list.ID,
  21:          ControlMode = SPControlMode.Edit,
  22:          RenderContext = context,
  23:          ItemContext = context
  24:      };
  25:      Controls.Add(username);
  26:   
  27:      // about me
  28:      Controls.Add(new Label { Text = "About me:" });
  29:      var aboutMe = new RichTextField
  30:      {
  31:          ID = "AboutMe",
  32:          FieldName = "Notes",
  33:          ItemId = userItem.ID,
  34:          ListId = list.ID,
  35:          ControlMode = SPControlMode.Edit,
  36:          RenderContext = context,
  37:          ItemContext = context
  38:      };
  39:      Controls.Add(aboutMe);
  40:  }

The key point is to create a context, which is different from the current. This new context will be used by the SharePoint Web Controls to render data from the User Information List. The output would be something like this:

If you do not set the context for the controls and try to access data from another context (which you try if you specify the list from another web), you will get an InvalidOperationException.

Operation is not valid due to the current state of the object.

Technorati Tags: ,

How to use the SharePoint Web Controls

SharePoint brings its own controls, which can be used to display list items. In this article I want to show you how to use them in a Webpart. It took me a while to figure this out, because the documentation is kind of incomplete L

OK. Lets start. First lets find out which SharePoint Web Control belongs to which data type in SharePoint.

 

 

 

 

 

SharePoint Web Control

SharePoint data type

SharePoint Web Control

Single line of text

TextField

Multiple lines of text

 

PlainText

NoteField

Rich Text

RichTextField

Enhanced Rich Text

RichTextField

Choice

 

Dropdown

DropDownChoiceField

Radio Button

RadioButtonChoiceField

Number

NumberField

Currency

CurrencyField

Date and Time

DateTimeField

Lookup

 

Single Item

LookupField

Multiple Items

MultipleLookupField

Yes/No

BooleanField

Person or Group

UserField

Hyperlink or Picture

UrlField

Calculated

UrlField

Business data

 

How do we find which control belongs to the data type? We can simply look up this information on each field:

string siteUrl = "http://sharepoint";
string webUrl = "spscontrols";

using (SPSite site = new SPSite(siteUrl))

{

using (SPWeb web = site.AllWebs[webUrl])

{

SPList list = web.Lists["ControlTest"];

foreach (SPField field in list.Fields)

{

Console.WriteLine(field.Title + " – " + field.FieldRenderingControl);

}

}
}

SPControlMode

You can the controls in different Control Modes:

  • SPControlMode.Edit behaves like in an editform page of a list
  • SPControlMode.Display shows the data without the ability to change the values

Use the Controls

So how do we use these controls? The answer to this question is simple: Just use them like "normal" System.Web Controls.

RichTextField rtf = new RichTextField();
rtf.ID = "MultilineRichText";
rtf.ListId = list.ID;
rtf.ItemId = item.ID;
rtf.FieldName = "MultilineRichText";
rtf.ControlMode = SPControlMode.Edit;
this.Controls.Add(rtf);

In this case the RichTextField shows the content from the "MultilineRichText" field from our list, and our listitem in the Editmode. ID and FieldName are the Displayname from our field. You have to set the List, Item and FieldName for the Control, because usually the SharePoint Controls will use the SPContext content (remember: the controls are used in the editform, newform.. pages of every SharePoint List).

With some lines of code, you can display all fields e.g. from the DefaultView of a SharePoint List:

Table table = new Table();
TableRow row;
TableCell cell;
for (int i = 0; i < list.DefaultView.ViewFields.Count; i++)
{

string fieldName = list.DefaultView.ViewFields[i];
SPField field = list.Fields.GetField(fieldName);

row = new TableRow();
cell = new TableCell();
cell.Text = field.Title;
row.Cells.Add(cell);

cell = new TableCell();

// Add a control from RH.SharePoint.SharePointWebControls
Control cntrl = SharePointWebControls.GetSharePointControls(field, list, item, SPControlMode.Display);
// if the control is null (because it can not be rendered with a SharePoint Control) return
if (cntrl == null) continue;

cell.Controls.Add(cntrl);
row.Cells.Add(cell);

cell = new TableCell();
cell.Controls.Add(SharePointWebControls.GetSharePointControls(field, list, item, SPControlMode.Edit));
row.Controls.Add(cell);
table.Rows.Add(row);

}

this.Controls.Add(table);

Use a generic control

Instead of finding a specific control for each SPField, you can use the BaseFieldControl. The advantage is, that it doesn’t matter which field you want to render. The right control will be used.

 
I have updated my class to use the generic instead of finding the matching Webcontrol. This approach makes it easier to use MOSS controls. You don’t have to distinct between WSS and MOSS controls any more.

You can Download the RH.SharePoint.SharePointWebControls class here.

Update:

I updated my SharePointWebControls.

Update 21. Apr 2008:

I updated my SharePointWebControls. This version includes a seperate file, which handels publishing controls from the Microsoft Office SharePoint Server 2007.

Update 19. Jan 2009:

SharePoint Web Controls to access remote content

Update 22. Feb 2009:

The class not uses a generic control instead of a control for each field type.