SharePoint Survey List Webpart

Hi SharePoint Developers,

This is my first blog post and I am very excited about sharing my experience with you.

So let’s just dive into it.

I wanted to present to you a solution that I think was interesting; I had an issue in a project that we had a SharePoint site that contained several SharePoint out of the box survey lists. As you know in SharePoint Surveys are actually SP lists with every survey responses recorded as list items. so what we wanted is to have one page that can display all surveys in this site and would allow the logged in user to see only the surveys he/she did not respond to before. I searched over the internet and found there is nothing that does this. I found commercial components that perform something like that but using custom surveys and not the SP out of the box ones. So I started VS and developed a new web part that performs this function.

So this should be simple right? :) Well the task had some glitches later as you will see. I created a new feature as usual called it "SurveyList", added an element pointing to a .webpart file with the following:

<?xml version="1.0" encoding="utf-8"?>

<webParts>

  <webPart xmlns="https://schemas.microsoft.com/WebPart/v3">

    <metaData>

      <type name="MCS.Blog.SurveyList, MCS.Blog, Version=1.0.0.0, Culture=neutral, PublicKeyToken=***********" />

      <importErrorMessage>Cannot import SurveyDisplay Web Part.</importErrorMessage>

    </metaData>

    <data>

      <properties>

        <property name="Title" type="string">SurveyList Web Part</property>

        <property name="Description" type="string">SurveyList Description</property>

      </properties>

    </data>

  </webPart>

</webParts>

Then I created a new class called “SurveyList” for the webpart itself and another called “SurveyListTool” for the webpart properties. In the SurveyList class I overridden the “CreateChildControls” method as below:

        protected override void CreateChildControls()

        {

            try

            {

                this.findSurvey();

                this.htMainContainer = this.CreateMainTable();

                if (this.htMainContainer != null)

                    this.Controls.Add(this.htMainContainer);

            }

            catch (Exception exception)

            {

                throw exception;

            }

        }

There are two main functions here “findSurvey” and “CreateMainTable”. The “findSurvey” function would simply crawl all survey lists on the currently opened SP site (or SPWeb if you are talking development) and then adds them to an array to be rendered later by the function “CreateMainTable”.

The function to get the full list of survey lists is fairly simple.

        private void findSurvey()

        {

            try

            {

                using (SPSite site = new SPSite(SPContext.Current.Web.Url))

                {

                    using (SPWeb web = site.OpenWeb())

                    {

                        SPListCollection lists = web.Lists;

           int num = 0;

                        this.SurveyCount = 0;

                        foreach (SPList list in lists)

                        {

                            string str = list.BaseTemplate.ToString();

                            SPContentTypeCollection types = list.ContentTypes;

                            if (str.Contains("Survey"))

                            {

                                this.SurveyNames[num++] = Convert.ToString(list);

         this.SurveyCount++;

                            }

                        }

                    }

                }

            }

            catch (Exception exception)

            {

                throw exception;

            }

  }

Now the function to display the surveys is the tricky one. I tried first to use the standard ListViewWebPart and create one per survey list to show them as if you are adding the survey list to your page using the add webpart functionality. Now this worked fine but the problem is that I was not able to configure the list view web part view as the default addition does. I found that for the survey list you have by default three views created “Overview”, “Graphical display”, and “All responses”. So I thought the list view web part uses the default view which is the “Overview” view. So I created the list view web part as below:

                                lvw = new ListViewWebPart();

                                lvw.ListName = list.ID.ToString("B").ToUpperInvariant();

                                lvw.TitleUrl = list.DefaultViewUrl;

                             lvw.WebId = list.ParentWeb.ID;

                                lvw.Title = list.Title;

                                lvw.ViewGuid = list.DefaultView.ID.ToString("B").ToUpper();

                                lvw.ChromeState = System.Web.UI.WebControls.WebParts.PartChromeState.Normal;

                                lvw.ChromeType = System.Web.UI.WebControls.WebParts.PartChromeType.Default;

Now for my surprise this showed up a view that is the view you get when you click on the survey title of the survey as shown in the image below.

But the default view for the list view web part is different it has the link to participate in this survey which this overview does not have as you see in the image below.

So I investigated that and for my surprise when adding a survey list view web part on any page this survey list gets a new view created for it, which is called “Summery” view. I tried to create this view by myself but I ran out of time (If someone knows this it would be great). So what I did instead is that I created an extra link and added that after the web part.

                                lnk = new HyperLink();

                                lnk.Text = "Responde to this survey";

                                lnk.CssClass = "ms-addnew";

                                lnk.NavigateUrl = list.Forms[PAGETYPE.PAGE_NEWFORM].ServerRelativeUrl + "?Source=" + HttpContext.Current.Request.Url;

I even tried to work with changing the toolbar type for this list view webpart from standard (default) to freeform and add the toolbar CAML but this failed to work as sometimes the toolbar node does not even have the type node and when I created that and set the value to freeform it did not give any effect at all.

So now the source code for the display of the surveys list is as below.

                ListViewWebPart lvw = null;

                HyperLink lnk = null;

                using (SPSite site = new SPSite(SPContext.Current.Web.Url))

                {

                    using (SPWeb web = site.OpenWeb())

                    {

    for (int i = 0; i < this.SurveyCount; i++)

                        {

                            SPList list = web.Lists[this.SurveyNames[i].ToString()];

                            SPQuery query = new SPQuery();

                       query.Query = "<Where><Contains><FieldRef Name='Author' /><Value Type='User'>" + web.CurrentUser.Name + "</Value></Contains></Where>";

                            if (list.GetItems(query).Count == 0)

                            {

                     if (!flag)

                                {

                                    flag = true;

                                }

                                lvw = new ListViewWebPart();

                                lvw.ListName = list.ID.ToString("B").ToUpperInvariant();

                                lvw.TitleUrl = list.DefaultViewUrl;

                                lvw.WebId = list.ParentWeb.ID;

                                lvw.Title = list.Title;

                                lvw.ViewGuid = list.DefaultView.ID.ToString("B").ToUpper();

                                lvw.ChromeState = System.Web.UI.WebControls.WebParts.PartChromeState.Normal;

                                lvw.ChromeType = System.Web.UI.WebControls.WebParts.PartChromeType.Default;

      lnk = new HyperLink();

                                lnk.Text = "Responde to this survey";

                                lnk.CssClass = "ms-addnew";

                                lnk.NavigateUrl = list.Forms[PAGETYPE.PAGE_NEWFORM].ServerRelativeUrl + "?Source=" + HttpContext.Current.Request.Url;

                                this.Controls.Add(lvw);

                                this.Controls.Add(lnk);

                            }

                        }

                    }

                }

Thank you for your time and hope that gave you some help.