Friday, November 9, 2012

Cascading dropdown lists in SharePoint 2010


Today I am going to explain you how to create a list with filtered lookup columns, based on information in previous columns. Check out SharePoint Cascaded Lookup from SharePointBoost.
Image from SharePointBoost
The software looks great. I haven’t tried it, but it does offer some great extra functionality.
Unfortunately, this piece of software is very expensive for small companies that only need this for a single form on SharePoint.
So I am going to show you how to create such a list without the need of buying this piece of software. I covered it into a lot of steps, but no programming is needed. The only things you need, are a SharePoint 2010 environment, InfoPath 2010 and this tutorial :D !
For this small tutorial, I will create a simple room-reservation list for a company existing out of multiple physical buildings. I will not explain about how to create a reservation system, I only use it as a example to show you how to filter data based on a previous selected item.
The result of this tutorial will be a form where you can select a physical location. After you made your selection, only those rooms for that building will be shown.
Again, i covered this into a lot of steps. But after you have done this a couple of times, you do not need expensive software and you can create filtered lookup forms yourself!

  1. Create a Custom list called ‘buildings’.
    A Custom list is created with no extra columns except for ‘title’. We leave it like that.
  2. Add buildings to the list: ‘Building A’, ‘Building B’ and ‘Building C’.
  3. Create another Custom list called ‘rooms’.
  4. Go to the list settings of ‘rooms’ and click on ‘create column’. Create a Lookup column called ‘Building’.
    Require that the column contains information.
    Get information from: ‘Buildings’,  in this column: ‘Title’
  5. Add some rooms to this list. I created multiple rooms at each location.
You have now created the needed lists and filled it with data, but we still need to create the room reservation form.
  1. Again, create a new Custom list called ‘reservations’.
  2. Click on ‘Create column’ and create a Lookup column called ‘Building’. Get information from: ‘buildings’,  in this column: ‘Title’
  3. Repeat step 2, but this time create a Lookup column called ‘Room’. Get information from: ‘rooms’,  in this column: ‘Title’
  4. Use Internet Explorer: Open the list settings for ‘reservations’ and click on ‘Form settings’.
    You will see a label with the text ‘Customize the current form using Microsoft InfoPath’. Click OK.
  5. The Reservations form will now be opened in InfoPath 2010.
  6. Right click on the Building field, and select properties.
    Select ‘Get choices from an external data source’ and click ‘Add…’.
    Create a connection with the following settings:
    - New connection, receive data
    - Receive data from: SharePoint library or list
    - select ‘buildings’ library
    - select the ‘id’ and ‘title’ column
    - do not check the box for making a copy of the data
    - check the box that asks for automatically retrieving data when the form is opened. Save the external data source as ‘buildings1′.
  7. At value, choose ‘ID’ and at display name, choose ‘Title’
  8. Right click on the Room field, and select properties.
    Select ‘Get choices from an external data source’ and click ‘Add…’.
    Create a connection with the following settings:
    - New connection, receive data
    - Receive data from: SharePoint library or list
    - select ‘rooms’ library
    - select the ‘id’, ‘title’ and ‘building’ column
    - do not check the box for making a copy of the data
    - do not check the box that asks for automatically retrieving data when the form is opened. Save the external data source as ‘rooms1′.
  9. At value choose ‘id’, choose ‘Title’ for  the display name.
You are not done yet, but almost there! A little break here, to tell you what you have done in the last few steps. You created 2 data connections, retrieving data from the SharePoint lists ‘buildings’ and ‘rooms’. The data connection for buildings will load its data into the buildings form when the form is being opened. The other one won’t. Check it out, press ctrl+shift+Q for a fast publish and add a new item to the registration list. If all went well you will see something like this:

The Room listbox should not yet contain any data.
Now we are going to execute the final steps. In these steps you will create a filter. This filter will show only rooms for the building you selected in the field above.
  1. Click on the xPath button at the properties dialog of Room next to ‘Entries’.
    Click on the ‘Filter data’ button.
  2. Click on ‘Add’.
    In the first column, choose ‘select a field or group’. A window pops up, choose advanced view.
    - Select the ‘main’ datasource, click on ‘dataFields’ and select ‘Building’.In the second column, choose ‘equals’.In the third column, choose ‘select a field or group’. Agan a window pops up, choose advanced view.
    - Select the ‘rooms’ datasource, click on ‘dataFields’ and select ‘Building’.
    Click OK
  3. The filter will now look like ‘Building equals Building’. Now close all property dialogs.
  4. Select the building column and click on ‘Add Rule’. Select the query action when the field is changed.

    Now choose the data connection ‘rooms1′ and click OK.
  5. Again, click Building and make a new rule: When the field is being changed, set a value for a field.

    Choose field ‘Room’ and leave value empty.
Finally! We are done. Fast publish the form to SharePoint again by pressing ctrl+shift+Q.
Now if you carefully executed all steps above, you will see a form like this:

Notice that only rooms will be shown that are located in that specific building.

Connecting two webparts in SharePoint



This tutorial describes the step to access data by connecting two different Web Parts in a SharePoint Site. In order to do so, three things should be kept in mind:
  • Provider Web Part (that provides the data)
  • Connection Interface (that provides the connection between two Web Parts)
  • Consumer Web Part ( that accepts the data)
But before we go further, one should be aware of how to create and deploy a web part.

Following are the steps :

Creating a Connection Interface
In this step, we create an interface say ‘CommunicationInterface’.  
In this interface, we define a property ‘ parameter1’ for  providing data.  The no. of properties depends on the no. of parameter to be passed.



//Code Part

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;


namespace CommunicationInterface
{
    public interface ICommunicationInterface
    {
        string parameter1 { get; }

    }
}

Once this interface is created, compile it and add its DLL to the Global Assembly Cache (C:\Windows\Assembly) in your  system.





Creating a Provider Web Part
The second step is to create a Provider Web Part to pass the data to the interface.
Create a web part and name it say ‘WP_Provider’.  Add reference of the earlier created ‘CommunicationInterface’ DLL. 
Once the reference is added,  implement the ‘ICommunicationInterface’ to ‘WP_Provider’ class.
Then the connection provider property is added and the reference to the communication Interface is returned.
Implement the property defined in the interface.

//Code Part
using System;
using System.Runtime.InteropServices;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Serialization;

using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.WebPartPages;
using CommunicationInterface;

namespace WP_Provider
{
   
   public class 
   WP_Provider: Microsoft.SharePoint.WebPartPages.WebPart,ICommunicationInterface
    
   {
        Label nm;
        TextBox tbname;
        Button btn=new Button();
       
        RadioButtonList rb = new RadioButtonList();

       
      // Provides connection provider property for the parameters
      [ConnectionProvider("Parameter1 Provider",
                    "Parameter1 Provider")]
        public ICommunicationInterface ConnectionInterface()
        {
         // this returns a reference to the communication interface
            return this;
        }

        protected string _parameter1 = "";


        // Property defined in Interface is implemented
        public string parameter1
        {
            get { return _parameter1; }
        }
       
       
        public WP_Provider()
        {
       
        }

        protected override void CreateChildControls()
        {
            base.CreateChildControls();



            //Accessing a particular list items

            SPSite mysitecol = SPContext.Current.Site;
            SPWeb mysite = SPContext.Current.Web;
            SPList mylist = mysite.Lists["UpdateList"];
            SPListItemCollection itemcol = mylist.Items;
           
            foreach (SPListItem itm in itemcol)
            {
                string nm = itm["Company_Id"].ToString();
                rb.Items.Add(nm);

            }

            btn.Text = "Send";
            this.Controls.Add(rb);
            this.Controls.Add(btn);
            btn.Click += new EventHandler(btn_Click);
        }

   public  void btn_Click(object sender, EventArgs e)
        {
            // set connection provider property with required textbox info.
           // this._parameter1 = tbname.Text;
            this._parameter1 = rb.SelectedItem.Text;
        }

    }
}

After completing the code, compile and add the DLL in the Global Assembly Cache (C:\Windows\Assembly).
Create the corresponding ‘dwp’ file and add the SafeControl in the web.config of SharePoint Site.



Creating a Consumer Web Part
The third step is to create a Consumer  Web Part to pass the data to the interface.
Create a web part and name it say ‘WP_Consumer’.  Add reference of the earlier created ‘CommunicationInterface’ DLL. 
Then the connection Consumer property is added and the reference to the communication Interface is retrieved.
From this reference, the parameter that is passed from Provider Web Part is obtained.

//Code
using System;
using System.Runtime.InteropServices;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Serialization;

using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.WebPartPages;
using CommunicationInterface;

namespace WP_Consumer
{
   
    public class WP_Consumer : Microsoft.SharePoint.WebPartPages.WebPart
    {
       //Label lblTitle;
       Label lblname=new Label();
      

    ///// the string info consumer from custom reciever   //
    ICommunicationInterface connectionInterface = null;

    // The consumer webpart  must define a method that
    // would accept the interface as an parameter
    // and must be decorated with ConnectionConsumer attribute     
    [ConnectionConsumer("Parameter1 Consumer",
                        "Parameter1 Consumer")]
    public void GetConnectionInterface(ICommunicationInterface
                                       _connectionInterface)
    {
        connectionInterface = _connectionInterface;
    }
    ///////////////////////////////////////////////////////// 

    public WP_Consumer()
    {
       
    }

        protected override void CreateChildControls()
        {
            base.CreateChildControls();
            
            this.Controls.Add(lblname);
           
        }


        protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);

            if (connectionInterface != null)
            {
                lblname.Text = connectionInterface.parameter1 +
                " is recieved!";
               

             }
            else
            {
                lblname.Text = "nothing is recieved!";
            }
           
        }

     
          
     }

       

  }
}

After completing the code, compile and add the DLL in the Global Assembly Cache. (C:\Windows\Assembly)
Create the corresponding ‘dwp’ file and add the SafeControl in the web.config of SharePoint Site.

Render methods in web parts in SharePoint

Today's blog post cover methods of rendering web parts. There are some methods which you can use to render content of a web part. The first method - override RenderContens  method. This method take HtmlTextWriter as argument. So, you can use it to write to the output any information. This code block illustrate how to do it:
protected override void RenderContents(HtmlTextWriter writer)
{
      writer.Write("Hello world");
}
This method simply put text "Hello world" to the output stream of the web part.
Another way to render web part content - override CreateChildControls:
protected override void CreateChildControls()
{
      var lblHello = new Label {Text = "Hello world"};
      Controls.Add(lblHello);
}
We'll get the same result as a previous one, but using CreateChildControls method. You can use the first method in a very simple scenarios, when there is no need to render complex layout with many controls. The second method fit situation when you must have several controls, but with rather simple logic.
But what if we have several controls, but we want insert this controls in a table or a div html tag? The third method help us - we can use both of RenderContents and CreateChildControls overloads. Standard implementation of RenderContents looks like this:
protected override void RenderContents(HtmlTextWriter writer)
{
    foreach(Control control in Controls)
    {
        control.RenderControl(writer);
    }
}
We can call control.RenderControl method in the required sequence and enclosed controls with addition html tags if required. Here is an example:
[ToolboxItemAttribute(false)]
public class HelloWorldWebPart3 : WebPart
{
    protected TextBox _txtName
    protected Button _btnSave;
 
    protected override void CreateChildControls()
    {
        _txtName = new TextBox();
        _btnSave = new Button {Text = "Save"};
        _btnSave.Click += btnSaveClick;
        Controls.Add(_btnSave);
        Controls.Add(_txtName);
    }
 
    private void btnSaveClick(object sender, EventArgs e)
    {
        //some code here
    }
 
    protected override void RenderContents(HtmlTextWriter writer)
    {
        writer.RenderBeginTag(HtmlTextWriterTag.Div);
        writer.Write("Please, enter your name:");
        _txtName.RenderControl(writer);
        writer.RenderBeginTag(HtmlTextWriterTag.Br);
            writer.RenderEndTag();
        _btnSave.RenderControl(writer);
        writer.RenderEndTag();
    }
}

SharePoint - Cannot convert a primitive value to the expected type 'Edm.Double'. See the inner exception for more details If y...

Ad