Thursday, August 2, 2012

Get selected Lookup field value in SharePoint 2010

SPFieldLookup myField = myItem[i].Fields["LookupFieldName"] as SPFieldLookup;

SPFieldLookupValue myLookupValue = myField.GetFieldValue(myItem[i]["LookupFieldName"].ToString()) as SPFieldLookupValue;

string LookupFieldValue = myLookupValue.LookupValue;

Monday, July 16, 2012

Remove unwanted item in SharePoint 2010 Navigation Up Menu

I created several web part pages and put them to the site's document library("SitePages"):

http://mysite.com/worksite/SitePages/workpage1.aspx
http://mysite.com/worksite/SitePages/workpage2.aspx
...

Then I configured navigation to the pages.
When I navigate to any one of the pages, click the Navigate Up button, I can see the following hierarchy menu:

Home -> worksite -> SitePages -> workpage?.aspx

The "SitePages" is the name of a document library, I don't want it to show to the client, I need to remove this item from the hierarchy menu. I have done this as following.

Getting the HTML code by "View source", search string "SitePages" (the document library name), we will find following code snippet:

<ul class="s4-breadcrumb">
        <li class="s4-breadcrumbRootNode"><span class="s4-breadcrumb-arrowcont"><span style="height: 16px;
            width: 16px; position: relative; display: inline-block; overflow: hidden;" class="s4-clust s4-breadcrumb">
            <img src="/_layouts/images/fgimg.png" alt="" style="border-width: 0px; position: absolute;
                left: -0px !important; top: -353px !important;" />
        </span></span><a class="s4-breadcrumbRootNode" href="/">Home</a><ul class="s4-breadcrumbRootNode">
            <li class="s4-breadcrumbNode"><span class="s4-breadcrumb-arrowcont"><span style="height: 16px;
                width: 16px; position: relative; display: inline-block; overflow: hidden;" class="s4-clust s4-breadcrumb">
                <img src="/_layouts/images/fgimg.png" alt="" style="border-width: 0px; position: absolute;
                    left: -0px !important; top: -353px !important;" />
            </span></span><a class="s4-breadcrumbNode" href="/worksite">worksite</a><ul
                class="s4-breadcrumbNode">
                <li class="s4-breadcrumbNode"><span class="s4-breadcrumb-arrowcont"><span style="height: 16px;
                    width: 16px; position: relative; display: inline-block; overflow: hidden;" class="s4-clust s4-breadcrumb">
                    <img src="/_layouts/images/fgimg.png" alt="" style="border-width: 0px; position: absolute;
                        left: -0px !important; top: -353px !important;" />
                </span></span><a class="s4-breadcrumbNode" href="http://mysite.com/worksite/_layouts/listform.aspx?ListId=%7B8CF0AC51%2D1703%2D4126%2DAE21%2DB60CF69F6EBE%7D&amp;PageType=0">
                    SitePages</a><ul class="s4-breadcrumbNode">
                        <li class="s4-breadcrumbCurrentNode"><span class="s4-breadcrumb-arrowcont"><span
                            style="height: 16px; width: 16px; position: relative; display: inline-block;
                            overflow: hidden;" class="s4-clust s4-breadcrumb">
                            <img src="/_layouts/images/fgimg.png" alt="" style="border-width: 0px; position: absolute;
                                left: -0px !important; top: -353px !important;" />
                        </span></span><span class="s4-breadcrumbCurrentNode">workpage?</span></li></ul>
                </li>
            </ul>
            </li>
        </ul>
        </li>
    </ul>

We can see "SitePages" is at the third level of the hierarchy menu.
What we need to do is: first, get the current level DOM("SitePages") node, second, get the upper level and forth level DOM node, and then replace the third level node with forth level node.
Following is the javascript code:

<script type="text/javascript" language="javascript">
  var x = document.getElementsByTagName("a")
  var i=0;
  for (i=0;i<x.length;i++)
  {
    if (x[i].className=="s4-breadcrumbNode")
    {
     if (x[i].innerHTML=="SitePages")
     {
         var parent1=x[i].parentNode.parentNode;

         var parent2=parent1.parentNode;

         var child1=parent1.lastChild;

         var child2=child1.lastChild;

         parent2.replaceChild(child2,parent1);

      }
    }
  }
</script>

Put the javascript to a Notepad file and upload it to the site's document library, then add a Content Editor web part to the web part page, in Edit Web Part, enter the Content Link with the uploaded javascript file url, then the "SitePages" item is removed from the Navigation Up hierarchy menu.

Thursday, July 5, 2012

Get Created By user information from list item

SPUser ItemCreatedby =
new SPFieldUserValue(SPContext.Current.Web, myItems[i]["Author"].ToString()).User;

Tuesday, May 1, 2012

Error: "The sandboxed code execution request was refused because the Sandboxed Code Host Service was too busy to handle the request"

I created a Sandboxed Solution on SharePoint 2010 including one web part and three event receivers registered to one list's ItemAdded, ItemDeleting and ItemUpdated. The web part has a delete button used to delete the list's items.

I deployed the sandboxed solution package to the site collection, when I click delete button on the web part, the error message: "The sandboxed code execution request was refused because the Sandboxed Code Host Service was too busy to handle the request"

I googled this message, most of the articles suggest to check if the Microsoft SharePoint Foundation Sandboxed Code Service is running on Central Admnistration and other settings on the system, the approaches didn't work for me.

I put one web part and three event receivers to seperate features, I found if I deactivate the ItemDeleting event receiver feature, the web part works well without any problem. Obviously the web part deleting fires the ItemDeleting event receiver.

So I need to disable the ItemDeleting event firing from the web part deleting code. I created one column on the list as a flag, it is set in the web part code. if this flag is found in the ItemDeleting event, just ignore the event.

I deployed and tested the project on my dev machine, the error message is gone, it's working well. When I deployed it to another SharePoint server, the same error message was back.

Then I google the following solution

//Code in delete button of the web part.
using (new DisabledItemEventsScope())
{
 //Code to delete the items.
}

public class DisabledItemEventsScope : SPItemEventReceiver, IDisposable
{
        private bool eventFiringEnabledStatus;
        public DisabledItemEventsScope()
        {
            eventFiringEnabledStatus = base.EventFiringEnabled;
            base.EventFiringEnabled = false;
        }
        #region IDisposable Members
        public void Dispose()
        {
            base.EventFiringEnabled = eventFiringEnabledStatus;
        }
        #endregion
}

I applied this code to my project and deployed the project, the error message is gone and everything is working well.

Monday, April 23, 2012

SharePoint Codeless Solution for Parent/Child Database Tables Data Enty

Platform and Tools: SharePoint Server 2010, InfoPath 2010, SharePoint Designer 2010.

The client wanted to insert data into two tables with SharePoint. for example: Products and Orders, One table has a foreign key relationship to the other table's primary key.

1. Create two database tables on a backend SQL Server database,  create an Auto Increment column on Products table as primary key.

2. By using Business Connectivity Services(BCS), Create two External Content Types based on a back end database tables in SharePoint Designer 2010.

3. Create two External Lists based on the External Content Types in SharePoint Designer.

4. Design Form in InforPath:  Select the created External List, start from here, see picture:


For Products: File -> Info -> Form Options -> Property Promotion, add the primary key field in datafields to the bottom list. see picture:


put a submit button, add two rules: 1. Submit data to main data connection. 2. send data to web part.
For Orders: Add a field named "ProductID",then File -> Info -> Form Options -> Property Promotion, add the foreign key field in datafields and the newly added field "ProductID" to the bottom list. put a submit button, add 4 rules: 1. Submit data to main data connection, 2. set a field's value: EIR="", this is very important, Later on when user enter data by InfoPath Form web part, after submit, it will step to next record for enter automatically. Otherwise it will stay on same record. 3. set a field's value: ProductID=foreign key field name, 4. send data to web part. Of course, we want to see the data entered once we submit it. New a blank form, add a new data connection to Orders External list. we have already created, drag and drop the data fields to the form as a repeating table, add a new field "ProductID" under Main data connection data fields, add two rule on this field's this field changes event: 1. Set a field's value, select the foreign key field from queryfields, set the value as field "ProductID" value. 2. Query using a data connection: Orders.
We can create one more InfoPath form to display and filter Products data entered in the same way above.
Publish above forms to the Document Librarys on the site you want.

5. On SharePoint site, add InforPath Webpart to webpart page. See picture:


Create a webpart page, add three or four InfoPath Form Web Parts on the same page from top to bottom by selecting the right library from the tool pane: Products new item form, Orders new item form, Orders display form, or Products display form. Then create web part data connections, Orders new item should get data from Products new item web part, connect Products primary key field to Orders foreign key field. Orders display form connect ProductID field to Orders foreign key field.
There is a trick here. We have already created Products and Orders External Lists, it is supposed to use Products new item web part connection to Orders External List web part to filter data, but the reality is that Orders External List web part is always empty,I have not found the reason or explanation so far. That's why we use InfoPath form repeating table to display the filtered data.