Archive for the 'Sharepoint' Category

20
Jul
09

#30 Sharepoint: Accessing a Site Collection\SPWeb within a Workflow and updating a list

Below I am grabbing data off a Workflow with a browser enabled Infopath Form and loading a separate list.


public Microsoft.SharePoint.Workflow.SPWorkflowActivationProperties workflowProperties = new Microsoft.SharePoint.Workflow.SPWorkflowActivationProperties(); 

  private void onWorkflowActivated1_Invoked(object sender, ExternalDataEventArgs e)
        {

              ...
                //Save the identifier for the workflow
                workflowId = workflowProperties.WorkflowId;

                // InitiationData comes from the initialization form
                XmlDocument document = new XmlDocument();
                document.LoadXml(workflowProperties.InitiationData);

                // Get Data Off Of Init Form
                XmlNamespaceManager ns = new XmlNamespaceManager(document.NameTable);
                ns.AddNamespace("my", "http://schemas.microsoft.com/office/infopath/2003/myXSD/2006-12-05T20:04:17");
                managerUsername = document.SelectSingleNode("/my:flowFields/my:managerUsername", ns).InnerText;
                managerFullname = document.SelectSingleNode("/my:flowFields/my:managerFullname", ns).InnerText;
                reviewType = document.SelectSingleNode("/my:flowFields/my:reviewType", ns).InnerText;
                reviewComments = document.SelectSingleNode("/my:flowFields/my:reviewComments", ns).InnerText; 

                using (SPSite siteCollection = workflowProperties.Site)
                {
                    using (SPWeb web = siteCollection.OpenWeb())
                    {
                        SPList EmployeeReviewList = (SPList)web.Lists["EmployeeReview"];                     // Specific List
                        SPListItem EmployeeReviewItem = OptimizedAddItem(EmployeeReviewList);       // Add New Item to List
                        EmployeeReviewItem["Review Name"] = reviewType;                                            // Update elements of new item
                        EmployeeReviewItem.Update();
                    }
                }  

  ... }

       //cf.  http://blog.robgarrett.com/2009/02/25/efficient-way-to-add-a-new-item-to-a-sharepoint-list
        public  SPListItem OptimizedAddItem(SPList list)
        {
            const string EmptyQuery = "0";
            SPQuery q = new SPQuery { Query = EmptyQuery };
            return list.GetItems(q).Add();
        }

Credit due for OptimizedAddItem(): http://blog.robgarrett.com/2009/02/25/efficient-way-to-add-a-new-item-to-a-sharepoint-list/

03
Jun
09

#27 Simple Ajax WebPart Setup

This post is liberally linked into other very good resources – I only offer it as a help or path through some of the options. The ‘lazy’ web.config reconfigure via Visual Studio framework switch is very effective. I did it manually on a test system and had a lot of control reference problems. I will be trying it again to better understand what I missed though this time with a web.config to run a diff against.

Install Net Framework 3.5 SP1

Web.Config Setup

  1. Backup site web.config
  2. Create a 2.0 web app in VS
  3. Copy in web.config
  4. Change target framework to 3.5 and save web.config over production.
  5. Reference: http://weblogs.asp.net/jan/archive/2008/10/10/enabling-net-3-5-in-sharepoint-2007-sites-the-lazy-way.aspx

Add safe control in <Sharepoint><SafeControls> make sure it is 3.5.0.0 (if 3.5 SP1 installed)

  1. Reference: http://sharepoint.microsoft.com/blogs/mike/Lists/Posts/Post.aspx?ID=3  (see Point 6 )
  2. Reference: http://www.codeproject.com/KB/sharepoint/MossAjaxWebPart.aspx?display=PrintAll&fid=417786&df=90&mpp=25&noise=3&sort=Position&view=Quick&select=2156594

Default.Master

  1. Add SPScriptManager to (default) master page via SPD (Sharepoint Designer)  – here is where to place it.

 <form runat=”server”>

<WebPartPages:SPWebPartManager runat=”Server” />

<asp:ScriptManager runat=”server” ID=”ScriptManager1″>

</asp:ScriptManager>

<TABLE class=”ms-main” CELLPADDING=0 CELLSPACING=0 BORDER=0

WIDTH=”100%” HEIGHT=”100%”>

SPD designer gives a IE 6 warning ?? ignore it

Ajax Web Part

  1. Deploy a simple Ajax Web Part
  2. Reference: http://jamestsai.net/Blog/post/How-To-Create-AJAX-enabled-SharePoint-Web-Part-with-UpdatePanel-and-UpdateProgress-in-10-minutes.aspx
02
Jun
09

#26 Remove Offending WebPart causing a sever error

Occasionally I have ‘friends’ that hammer a page and have a hard time getting back to Kansas.   Recently, I (ahem) my friend added a Ajax WP forgetting to add the ScriptManager to the master page which causes a parse error and you cannot get back into the page via SPD or other means (easily).   You often get a SPD view error jamming you up :

soap:ServerServer was unable to process request. —> A Web Part or Web Form Control on this Web Part Page cannot be displayed or imported because it is not registered as safe on this site. You may not be able to open this page in an HTML editor that is compatible with Microsoft Windows SharePoint Services, such as Microsoft Office SharePoint Designer. To fix this page, contact the site administrator to have the Web Part or Web Form Control configured as safe. You can also remove the Web Part or Web Form Control from the page by using the Web Parts Maintenance Page. If you have the necessary permissions, you can use this page to disable Web Parts temporarily or remove personal settings. For more information, contact your site administrator.

There is a ‘trick’ to view web parts on a page and delete the offender. Go to the Brown Screen of Death page and add ?contents=1 at the end of the URL.  The browser will display (depending on permissions) a maintence view and the Web Parts that are the page – where you can delete the offender.

Credit due: http://www.blogcoward.com/archive/2009/03/29/Sharepoint-Designer-2007-A-Web-Part-or-Web-Form-Control.aspx

29
May
09

#25 Birthdays & Service Anniversaries

Birthdays & Years of Service

Birthdays & Years of Service

Variation on a theme – here we display weekly birthdays & service anniversaries.

Stored Procedure:


Procedure SP_Weekly
as
Select EM.Employee as EmpNum
, EmployeePhoto
, isNull(EM.PreferredName,EM.FirstName) + ' ' + RTRIM( EM.LastName) as EmployeeName
, RTRIM(datepart(month,custEmp_BirthDate)) + '/' +  RTRIM(datepart(day,custEmp_BirthDate)) as DateField
, 'Birthday'  as Notes
From EmployeeCustomTabFields ECTF
Join EM on (EM.Employee = ECTF.Employee)
Where
datepart(week,custEmp_BirthDate) = datepart(week,getdate())
And Status = 'A'
Union All
Select EM.Employee as EmpNum
, EmployeePhoto
, isNull(EM.PreferredName,EM.FirstName) + ' ' + RTRIM( EM.LastName) as EmployeeName
, RTRIM(datepart(month,HireDate)) + '/' +  RTRIM(datepart(day,HireDate))
  + '/' +  RTRIM(datepart(year,HireDate)) as DateField
, Cast(DateDiff(year, HireDate, getdate()) as varchar(12)) + RTRIM(' Years of Service' )  as Notes
From EmployeeCustomTabFields ECTF
Join EM on (EM.Employee = ECTF.Employee)
Where
datepart(week,HireDate) = datepart(week,getdate())
And Status = 'A'
Order By 4
28
May
09

#24 Small Employee Directory SP Web Part

Employee Directory for Sharepoint Column

Employee Directory for Sharepoint Column

This web part exposes props for an advance search URL, results table width and max record count. The results are displayed via bind to an ASP.Net Repeater.

properties exposed in Sharepoint

properties exposed in Sharepoint

Credit Due for dynamic template code

BWEmpDirSmall.cs

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
//add
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Data.SqlClient;
using System.Data.Common;
using System.Web.Configuration;
using System.Data.SqlTypes;
using System.Xml.Serialization;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint;
using System.IO;

namespace BWEmpDirSmall
{
    [Guid("60c0ce25-603a-4c24-8d99-8b6046f013fe")]
    public class BWEmployeeSearch2 : Microsoft.SharePoint.WebPartPages.WebPart
    {
        private bool _error = false;

        private Label lblMessage;
        private TextBox txtSearch;
        private Button btnSearch;
        private Button btnClear;
        private Repeater rptList;
        private HyperLink hlAdvSearch;

        [Personalizable(PersonalizationScope.Shared)]
        [WebBrowsable(true)]
        [System.ComponentModel.Category("My Property Group")]
        [WebDisplayName("Advance Search Page")]
        [WebDescription("URL to Advance Search")]
        public string AdvSearchURL { get; set; }

        [Personalizable(PersonalizationScope.Shared)]
        [WebBrowsable(true)]
        [System.ComponentModel.Category("My Property Group")]
        [WebDisplayName("Table Width")]
        [WebDescription("Filter &amp; Results Table Width")]
        public string TableWidth { get; set; }

        [Personalizable(PersonalizationScope.Shared)]
        [WebBrowsable(true)]
        [System.ComponentModel.Category("My Property Group")]
        [WebDisplayName("Max Count")]
        [WebDescription("Maximum Rows Returned")]
        public string MaxCount { get; set; }
        public BWEmployeeSearch2()
        {
            this.ExportMode = WebPartExportMode.All;
            this.AdvSearchURL = @"<a href='http://portal'>******</a>";
            this.TableWidth = "220px";
            this.MaxCount = "25";
        }

        /// <summary>
        /// Sets Display
        /// </summary>
        /// <param name="writer"></param>
        protected override void RenderContents(HtmlTextWriter writer)
        {
            writer.Write("<table width='" + TableWidth + "' border='0' >");

            spanRow(writer, "left", "2");
            //writer.Write("<b>Search: </b>");

            txtSearch.RenderControl(writer);
            writer.Write("&nbsp;");
            btnSearch.RenderControl(writer);
            writer.Write("&nbsp;");
            btnClear.RenderControl(writer);
            rowEnd(writer);

            spanRow(writer, "left", "2");
            hlAdvSearch.RenderControl(writer);
            rowEnd(writer);

            spanRow(writer, "left", "2");
            lblMessage.RenderControl(writer);
            rowEnd(writer);

            spanRow(writer, "left", "2");
            rptList.RenderControl(writer);
            rowEnd(writer);

            writer.Write("</table>");
        }

        protected void rowStart(HtmlTextWriter writer, string sAlign) { writer.Write("<tr><td align=" + sAlign + ">"); }
        protected void cellEnd(HtmlTextWriter writer) { writer.Write("</td>"); }
        protected void cellEndStart(HtmlTextWriter writer, string sAlign) { writer.Write("</td><td align=" + sAlign + ">"); }
        protected void rowEnd(HtmlTextWriter writer) { writer.Write("</td></tr>"); }
        protected void spanRow(HtmlTextWriter writer, string sAlign, string colspan)
        {
            writer.Write("<tr><td align=" + sAlign + " colspan=" + colspan + " >");
        }

        /// <summary>
        /// Create all your controls here for rendering.
        /// Try to avoid using the RenderWebPart() method.
        /// </summary>
        protected override void CreateChildControls()
        {
            if (!_error)
            {
                try
                {

                    base.CreateChildControls();

                     lblMessage = new Label();
                    btnSearch = new Button();
                    btnClear = new Button();
                    txtSearch = new TextBox();
                    hlAdvSearch = new HyperLink();

                    this.lblMessage.Width = new Unit("200px");

                    this.btnSearch.Text = "Search";
                    this.btnSearch.Click += new EventHandler(btnSubmit_Click);
                    this.btnClear.Text = "Clear";
                    this.btnClear.Click += new EventHandler(btnClear_Click);

                    this.rptList = new Repeater();
                    this.rptList.ItemTemplate = new MyTemplate(MaxCount);

                    this.hlAdvSearch.Text = "Advance Search";
                    this.hlAdvSearch.NavigateUrl = AdvSearchURL;

                    this.Controls.Add(lblMessage);
                    this.Controls.Add(txtSearch);
                    this.Controls.Add(rptList);
                    this.Controls.Add(btnSearch);
                    this.Controls.Add(btnClear);
                    this.Controls.Add(hlAdvSearch);

                    this.lblMessage.Width = new Unit("180px");
                    this.btnSearch.Width = new Unit("60px");
                    this.btnClear.Width = new Unit("60px");
                    this.txtSearch.Width = new Unit("150px");

                }
                catch (Exception ex)
                {
                    HandleException(ex);
                }
            }
        }

        /// <summary>
        /// Ensures that the CreateChildControls() is called before events.
        /// Use CreateChildControls() to create your controls.
        /// </summary>
        /// <param name="e"></param>
        protected override void OnLoad(EventArgs e)
        {
            if (!_error)
            {
                try
                {
                    base.OnLoad(e);
                    this.EnsureChildControls();

                    // Your code here...
                }
                catch (Exception ex)
                {
                    HandleException(ex);
                }
            }
        }

        /// <summary>
        /// Clear all child controls and add an error message for display.
        /// </summary>
        /// <param name="ex"></param>
        private void HandleException(Exception ex)
        {
            this._error = true;
            this.Controls.Clear();
            this.Controls.Add(new LiteralControl(ex.Message));
        }

        protected void btnSubmit_Click(object sender, EventArgs e)
        {

            this.rptList.ItemTemplate = new MyTemplate(MaxCount);

            if (Utilities.hasData(txtSearch))
                bindRepeater();
            else
            {
                lblMessage.Text = "No Search Criteria Entered";
                //this.rptList.DataSource = new string[] { }; //clear
                //this.rptList.DataBind();
            }

        }
        protected void btnClear_Click(object sender, EventArgs e)
        {
            txtSearch.Text = string.Empty;
            this.rptList.DataSource = new string[] { }; //clear
            this.rptList.DataBind();
            lblMessage.Text = "";
        }
        private void bindRepeater()
        {
            DataSet ds = Employee.searchEmployees(txtSearch.Text.Trim());
            this.rptList.DataSource = ds;
            this.rptList.DataBind();
            int iRecCount = 0;
            Int32.TryParse(ds.Tables[0].Rows.Count.ToString(),out iRecCount);
            if (iRecCount < (Int32.Parse(MaxCount)))
                this.lblMessage.Text = iRecCount.ToString() + " record(s) found";
            else
                this.lblMessage.Text = iRecCount.ToString() + " Recs Exceeded " + MaxCount + " Max";
        }

    }
}

MyTemplate.cs

using System;
using System.Collections;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace BWEmpDirSmall
{
    public class MyTemplate : ITemplate
    {

            static int itemcount = 0;
            static int MAXCOUNT = 25;
            ListItemType templateType;

            public MyTemplate()
            {
                templateType = ListItemType.Item;
                itemcount = 0;
            }

            public MyTemplate(string s)
            {
                templateType = ListItemType.Item;
                MAXCOUNT = 25;
                Int32.TryParse(s, out MAXCOUNT);
                itemcount = 0;
            }

            public MyTemplate(ListItemType type)
            {
                templateType = type;
                itemcount = 0;
            }

            public void InstantiateIn(System.Web.UI.Control container)
            {
                Literal lc = new Literal();
                //switch (templateType)
                //{
                //    case ListItemType.Header:
                //        lc.Text = "<TABLE border=1><TR><TH>Items</TH></TR>";
                //        break;
                //    case ListItemType.Item:
                //        //lc.Text = "<TR><TD>Item number: " + itemcount.ToString() +
                //        //   "</TD></TR>";
                //          lc.Text = DataBinder.Eval(Container.DataItem, "FirstName");
                //        break;
                //    case ListItemType.AlternatingItem:
                //        lc.Text = "<TR><TD bgcolor=lightblue>Item number: " +
                //           itemcount.ToString() + "</TD></TR>";
                //        break;
                //    case ListItemType.Footer:
                //        lc.Text = "</TABLE>";
                //        break;
                //}
                if (itemcount <= MAXCOUNT)
                {
                    lc.DataBinding += new EventHandler(TemplateControl_DataBinding);
                    container.Controls.Add(lc);
                }
                itemcount++;

            }

            private void TemplateControl_DataBinding(object sender, System.EventArgs e)
            {
                Literal lc;
                lc = (Literal)sender;
                RepeaterItem container = (RepeaterItem)lc.NamingContainer;
                lc.Text += "&amp;raquo; <font color='#99000'><b> ";
                lc.Text += DataBinder.Eval(container.DataItem, "FirstName");
                lc.Text += " &nbsp;" + DataBinder.Eval(container.DataItem, "LastName");
                lc.Text += "</b></font> ";
                if (Utilities.hasData(DataBinder.Eval(container.DataItem, "WorkPhoneExt").ToString()))
                    lc.Text += "<b> x/" + DataBinder.Eval(container.DataItem, "WorkPhoneExt") + "</b>";
                lc.Text += "<br />";
                if (Utilities.hasData(DataBinder.Eval(container.DataItem, "WorkPhone").ToString()))
                    lc.Text += "&nbsp;<i>" + DataBinder.Eval(container.DataItem, "WorkPhone") + "</i>&nbsp;";
                if (Utilities.hasData(DataBinder.Eval(container.DataItem, "MobilePhone").ToString()))
                    lc.Text += "<i> Cell: " + DataBinder.Eval(container.DataItem, "MobilePhone") + "</i> ";
                lc.Text += "<br /> ";
            }
    }

}

Employee cs searchEmployees method:

static public DataSet searchEmployees(string sTarget)
    {

        SqlCommand cmd = null;
        SqlDataAdapter da = null;
        DataSet ds = new DataSet("Employees");
        using (SqlConnection conn = Utilities.getConnR())
        {

            try
            {
                cmd = new SqlCommand("searchEmployees", conn);
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.Parameters.Add(new SqlParameter("@Target", SqlDbType.Text));
                cmd.Parameters["@Target"].Value = sTarget.Trim();

                conn.Open();
                da = new SqlDataAdapter(cmd);
                da.Fill(ds);

            }
            catch (Exception err)
            {
                throw new ApplicationException(err.Message.ToString());

                //err.Message.ToString();
            }
            finally
            {
                if (cmd != null) { cmd.Dispose(); }
                if (da != null) { da.Dispose(); }
            }
        }
        return ds;

    }

Stored Procedure:

Procedure [dbo].[searchEmployees]
(
  @Target  nvarchar(50)
)
as
  Select
   EM.Employee as EmpNum
 , RTRIM(EM.Employee) + '-' +  SUBSTRING(EM.FirstName,1,1)
  +  RTRIM(Case When(DATALENGTH(EM.MiddleName) = 0) Then '' Else  SUBSTRING(EM.MiddleName,1,1) End )
     +  SUBSTRING(EM.LastName,1,1)  as Employee
 , isNull(EM.PreferredName,EM.FirstName)    as FirstName
 , (RTRIM(EM.LastName) + ' ' + isNull(Suffix,''))  as LastName
 , EM.MiddleName
 , EM.Org         as PrimaryDept
 , EM.Region
 , EM.WorkPhone
 , EM.WorkPhoneExt
 , EM.MobilePhone
 , ECTF.Cust5ULPhysical      as Office
 , ECTF.custSecondaryDepartment     as SecondaryDept
  From
    EM
  Join EmployeeCustomTabFields ECTF on ( ECTF.Employee = EM.Employee )
  Where
 EM.Status = 'A'
 And (  EM.FirstName  like  Case When (@Target is null) Then '%' Else RTRIM(@Target) + '%' End
     OR EM.PreferredName   like  Case When (@Target is null) Then '%' Else RTRIM(@Target) + '%' End
     OR EM.LastName   like  Case When (@Target is null) Then '%' Else RTRIM(@Target) + '%' End
   OR    SUBSTRING(EM.FirstName,1,1)  +  RTRIM(Case When(DATALENGTH(EM.MiddleName) = 0) Then '' Else  SUBSTRING(EM.MiddleName,1,1) End )  +  SUBSTRING(EM.LastName,1,1)  like Case When (@Target is null) Then '%' Else  @Target  End
     OR EM.WorkPhone like '%' + isNull(@Target,'%') + '%'
   OR EM.WorkPhoneExt like '%' + isNull(@Target,'%') + '%'
   OR EM.MobilePhone like '%' + isNull(@Target,'%') + '%'
   OR  ECTF.Cust5ULPhysical = isNull(@Target, ECTF.Cust5ULPhysical)
   OR  EM.Employee like  isNull(@Target,'%') + '%'   )
12
May
09

#23 Installing Business Data Catalog Definition Editor – error 2869

When installing the Business Data Catalog Definition Editor which allows (makes it easy for) you to connect your data sources to the Sharepoint Business Data Catalog you can get this odd error. I was loading in Windows Server 2003 & all the posts I saw were for issues with Vista.  Hope this helps those non-Vista users suffering this issue.

My Log entry:

Event Type:    Error Event Source:    MsiInstaller Event Category:    None Event ID:    10005 Date:        Time:          PM User:        CSISERVER Description: Product: Microsoft ®  Application Definition Designer — The installer has encountered an unexpected error installing this package. This may indicate a problem with this package. The error code is 2869.

For those that install packages a lot this may be obvious – use the setup.exe directly instead of the msi package. It will install SQL 2005 Express with the app (there are some unhappy posts on that around) but the Definition Editor installs.

If looking for the SDK here are the links:

http://blogs.msdn.com/sharepoint/archive/2007/08/22/announcing-the-microsoft-business-data-catalog-definition-editor-for-microsoft-office-sharepoint-server-2007.aspx
http://www.microsoft.com/downloads/details.aspx?familyid=6d94e307-67d9-41ac-b2d6-0074d6286fa9&displaylang=en



27
Feb
09

#22 Some Sharepoint links regarding CAML, F# & LINQ

Navigating the vast object model in SP/MOSS can be daunting -  Here are some references regarding some good unifying work:

LINQ to CAML project

Linq SPListCollection

John Lao’s Exploring SP using F# Excellent blog covering F# and SP

Free F# eBook Free is free though you have to navigate & signup for access to get the pdf

Creating a test VPC for Sharepoint/MOSS

28
Jan
09

#21 Employee Directory Sharepoint Webpart Pt 2 – Class Files

There are Data Access Layer classes for each collection Employee, Office & Department which can use ADO or the Enterprise library to call stored procedures to access data.wpempdir

EmpDir.cs

Credit Due: for GridView Paging code - Powlo’s site (Paul Robinson’s SP Site)


using System;
using System.Collections.Generic;
using System.Text;
//add
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Data.SqlClient;
using System.Data.Common;
using System.Web.Configuration;
using System.Data.SqlTypes;
using System.Xml.Serialization;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint;
using System.IO;
[assembly: System.Security.AllowPartiallyTrustedCallers]

namespace EmpDir

{

public class EmpDir: WebPart

{

private Label       lblMessage;
private TextBox     txtSearchFN;
private TextBox     txtSearchLN;
private TextBox     txtSearchPhone;
private TextBox     txtSearchEmployee;
private TextBox     txtSearchInitials;
private Button      btnSearch;
private Button      btnClear;
private SPGridView  oGrid;
private DataSet     oDataset;
private DataView    oView;
private DropDownList ddDepartment;
private DropDownList ddOffice;

protected override void Render(HtmlTextWriter writer)
{
base.Render(writer);
}

protected override void RenderContents(HtmlTextWriter writer)
{

writer.Write("<table border='0'  width='600px'>");
writer.Write("<tr><td align='right' nowrap='nowrap'>Intials:</td>");
writer.Write("<td align='left' >");
txtSearchInitials.RenderControl(writer);
writer.Write("</td><td align='right'  nowrap='nowrap'>Emp#:</td>");
writer.Write("<td align='left' >");
txtSearchEmployee.RenderControl(writer);
writer.Write("</td><td></td></tr>");
writer.Write("<tr><td align='right' nowrap='nowrap'>First Name:</td>");
writer.Write("<td align='left' >");
txtSearchFN.RenderControl(writer);
writer.Write("</td><td align='right'  nowrap='nowrap'>Last Name:</td>");
writer.Write("<td align='left' >");
txtSearchLN.RenderControl(writer);
writer.Write("</td><td></td></tr>");

writer.Write("<tr><td align='right' nowrap='nowrap'>Phone:</td>");
writer.Write("<td align='left' >");
txtSearchPhone.RenderControl(writer);
writer.Write("</td><td align='right'  nowrap='nowrap'>Department:</td>");
writer.Write("<td align='left' >");
ddDepartment.RenderControl(writer);
writer.Write("</td><td></td></tr>");

writer.Write("<tr><td align='right' nowrap='nowrap'>Office:</td>");
writer.Write("<td align='left' >");
ddOffice.RenderControl(writer);
writer.Write("</td><td align='right'  nowrap='nowrap'></td>");
writer.Write("<td align='left' >");
//ddDepartment.RenderControl(writer);
writer.Write("</td><td></td></tr>");

// BUTTONS
writer.Write("<tr><td colspan='3'>");
btnSearch.RenderControl(writer);
writer.Write("&amp;nbsp;&amp;nbsp;");
btnClear.RenderControl(writer);
writer.Write("</table>");

// GRID
writer.Write("<table border='0'>");
writer.Write("</td></tr>");
writer.Write("<tr><td colspan='3'>");
oGrid.RenderControl(writer);
writer.Write("</td><td></td></tr>");
writer.Write("</table>");

}

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

lblMessage          = new Label();
btnSearch           = new Button();
btnClear            = new Button();
txtSearchFN         = new TextBox();
txtSearchLN         = new TextBox();
txtSearchPhone      = new TextBox();
txtSearchEmployee   = new TextBox();
txtSearchInitials   = new TextBox();
ddDepartment        = new DropDownList();
ddOffice            = new DropDownList();

Department.loadDepartmentDropdown(this.ddDepartment, "--- All Departments --");
Office.loadOfficeDropdown(this.ddOffice, "--- All Offices ---");

this.lblMessage.Width = new Unit("800px");
this.btnSearch.Text = "Search";
this.btnSearch.Click += new EventHandler(btnSubmit_Click);
this.btnClear.Text = "Clear";
this.btnClear.Click += new EventHandler(btnClear_Click);

this.oDataset = new DataSet();
this.oView = new DataView();
this.oGrid = new SPGridView();
this.oGrid.DataSource = oView;
this.oGrid.AutoGenerateColumns = false;
this.oGrid.AllowSorting = true;

this.oGrid.Sorting += new GridViewSortEventHandler(oGrid_Sorting);

this.oGrid.AllowPaging = true;
oGrid.Columns.Add(Utilities.buildColumn("Employee", "Emp #"));

// Add Cols using a utility method
oGrid.Columns.Add(Utilities.buildColumn("FirstName", "First Name"));
oGrid.Columns.Add(Utilities.buildColumn("LastName", "Last Name"));
oGrid.Columns.Add(Utilities.buildColumn("WorkPhone", "Direct"));
oGrid.Columns.Add(Utilities.buildColumn("WorkPhoneExt", "Ext"));
oGrid.Columns.Add(Utilities.buildColumn("MobilePhone", "Cell"));
oGrid.Columns.Add(Utilities.buildColumn("Office", "Office"));
oGrid.Columns.Add(Utilities.buildColumn("PrimaryDept", "Primary Dept"));
oGrid.Columns.Add(Utilities.buildColumn("SecondaryDept", "Secondary Dept"));

this.Controls.Add(lblMessage);
this.Controls.Add(ddDepartment);
this.Controls.Add(ddOffice);
this.Controls.Add(txtSearchFN);
this.Controls.Add(txtSearchLN);
this.Controls.Add(txtSearchEmployee);
this.Controls.Add(txtSearchInitials);
this.Controls.Add(txtSearchPhone);
this.Controls.Add(btnSearch);
this.Controls.Add(btnClear);
this.Controls.Add(oGrid);

this.oGrid.PageSize = 10;
this.oGrid.AllowPaging = true;

this.oGrid.PageIndexChanging += new GridViewPageEventHandler(oGrid_PageIndexChanging);

this.oGrid.PagerTemplate = null;  // Must be called after Controls.Add(oGrid)

this.lblMessage.Width = new Unit("400px");
this.ddDepartment.Width = new Unit("180px");
this.ddOffice.Width = new Unit("180px");
this.btnSearch.Width = new Unit("80px");
this.btnClear.Width = new Unit("80px");
this.txtSearchFN.Width = new Unit("180px");
this.txtSearchLN.Width = new Unit("180px");
this.txtSearchEmployee.Width = new Unit("180px");
this.txtSearchInitials.Width = new Unit("180px");
this.txtSearchPhone.Width = new Unit("180px");

this.oGrid.Width = new Unit("800px");

}

void oGrid_PageIndexChanging(object sender, GridViewPageEventArgs e)
{

oGrid.PageIndex = e.NewPageIndex;
//oGrid.DataBind();
bindGrid(String.Empty);

}
protected void btnSubmit_Click(object sender, EventArgs e)
{
bindGrid(String.Empty);
}
protected void btnClear_Click(object sender, EventArgs e)
{
txtSearchFN.Text        = string.Empty;
txtSearchLN.Text        = string.Empty;
txtSearchEmployee.Text  = string.Empty;
txtSearchPhone.Text     = string.Empty;
txtSearchInitials.Text  = string.Empty;
ddDepartment.SelectedIndex = 0;
ddOffice.SelectedIndex = 0;
Utilities.BindGridView(oGrid,true);
}

private void bindGrid(string sort)
{

string sFN = txtSearchFN.Text.Trim().Replace(" ", "%");
string sLN = txtSearchLN.Text.Trim().Replace(" ", "%");
string sEM = txtSearchEmployee.Text.Trim().Replace(" ", "%");
string sPH = txtSearchPhone.Text.Trim().Replace(" ", "%");
string sIN = txtSearchInitials.Text.Trim().Replace(" ", "%");
string sDept = string.Empty;

if (ddDepartment.SelectedIndex > 0)
sDept = "%" + ddDepartment.SelectedValue.ToString() + "%";

string sOffice = string.Empty;
if (ddOffice.SelectedIndex > 0)
sOffice = ddOffice.SelectedValue.ToString();

oDataset = Employee.searchEmployees(sFN, sLN, sIN, sPH, sOffice, sDept, sEM);
oView = new DataView(oDataset.Tables[0]);
oGrid.DataSource = oView;

if (Utilities.hasData(sort))
oView.Sort = sort;

//oGrid.DataBind();
Utilities.BindGridView(oGrid, oView, true);

}

void oGrid_Sorting(object sender, GridViewSortEventArgs e)
{

string lastExpression = "";

if (ViewState["SortExpression"] != null)
lastExpression = ViewState["SortExpression"].ToString();

string lastDirection = "asc";

if (ViewState["SortDirection"] != null)
lastDirection = ViewState["SortDirection"].ToString();

string newDirection = "asc";

if (e.SortExpression == lastExpression)
newDirection = (lastDirection == "asc") ? "desc" : "asc";

ViewState["SortExpression"] = e.SortExpression;
ViewState["SortDirection"] = newDirection;

string sSort = e.SortExpression + " " + newDirection;
bindGrid(sSort);

}

}

}

// Utilities.cs

using System;
using System.Collections.Generic;
using System.Text;
//add
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Data.SqlClient;
using System.Data.Common;
using System.Web.Configuration;
using System.Data.SqlTypes;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint;
using System.IO;

namespace BWEmpDir
{
class Utilities
{

static private string _connR  = WebConfigurationManager.ConnectionStrings["IntranetUserR"].ConnectionString;
static private string _connRW = WebConfigurationManager.ConnectionStrings["IntranetUserRW"].ConnectionString;

static public SqlConnection getConnR()
{
return (new SqlConnection(_connR));
}
static public SqlConnection getConnRW()
{
return (new SqlConnection(_connRW));
}

static public bool hasData(string f)
{
bool bReturn = false;

if (f != null &amp;&amp; f.Trim().Length > 0)
bReturn = true;

return bReturn;
}

static public bool hasData(TextBox f)
{
bool bReturn = false;

if (f != null &amp;&amp; f.Text.Trim().Length > 0)
bReturn = true;

return bReturn;
}

static public bool hasNoData(string f)
{
bool bReturn = false;

if (f == null || f.Trim().Length == 0)
bReturn = true;

return bReturn;
}

static public bool hasNoData(TextBox f)
{
bool bReturn = false;

if (f == null || f.Text.Trim().Length == 0)
bReturn = true;

return bReturn;
}

static public void BindGridView(SPGridView gv, bool bRebind)
{
gv.DataSource = new string[] { }; //clear
if (bRebind)
gv.DataBind();
}

static public void BindGridView(SPGridView gv, DataSet ds, bool bRebind)
{
gv.DataSource = new string[] { }; //clear
gv.DataSource = ds;
if (bRebind)
gv.DataBind();
}
static public void BindGridView(SPGridView gv, DataView ds, bool bRebind)
{
gv.DataSource = new string[] { }; //clear
gv.DataSource = ds;
if (bRebind)
gv.DataBind();
}

static public BoundField buildColumn(string sData, string sHeader, string SortExp)
{
BoundField col = new BoundField();
col.DataField = sData;
col.HeaderText = sHeader;
col.SortExpression = SortExp;
return (col);
}

static public BoundField buildColumn(string sData, string sHeader)
{
return(buildColumn(sData, sHeader, sData));
}

}

}

26
Jan
09

#20 Some helpful links for tracking down & fixing SP errors

Event Viewer 10016 error (application log)

“The application-specific permission settings do not grant Local Activation permission…”

http://www.cleverworkarounds.com/2007/10/25/dcom-fun-with-sharepoint/


The blasted ‘An unexpected error has occurred’ error page with nothing in any log that you can find.

http://blog.thekid.me.uk/archive/2007/02/15/a-solution-to-quot-an-unexpected-error-has-occurred-quot-in-wss-v3.aspx


CAS errors on SqlClient (System.Data.SqlClient.SqlClientPermission). Use your c:\inetpub\wwwroot\wss\VirtualDirectories\<port number>\web.config to locate your active Security Policy config file rather than the following post’s suggestion.

http://www.mysharepointblog.com/2007/03/default.aspx

14
Jan
09

#19 Employee Directory Sharepoint Webpart Pt 1 – Stored Procedure

Starting with a new proc to select data of off the EM, Employee Custom Tab Fields and a union with a Auxilary data table to add in such things as printers, conference rooms, local police,  fire etc. I will build on this stored procedure defining a datagrid with filter controls in a Sharepoint webpart.

Virtualized Dev Environment: SQL 2005, Windows 2003 server, Visual Studio 2008, Sharepoint Extensions

This proc allows wildcard searches on fields and does not filter if a null is passed.  The union to the auxiliary table poses some challenges so I created a UDF dbo.IgnoreNullParm to return ‘1′ or ‘0′ to effectively turn off the union ‘leg’ when we are passed a filter parm that does not exist for that table (i.e. Initials).

Proc Def:

Create Procedure [dbo].[searchEmployees]
(
@FirstName        nvarchar(50)
,@LastName        nvarchar(50)
,@Initials              nvarchar(03)
,@Phone               nvarchar(20)
,@Office                nvarchar(50)
,@Dept                  nvarchar(50)
,@EmpNum        nvarchar(04)
)
as
Select
EM.Employee
, isNull(EM.PreferredName,EM.FirstName) 		as FirstName
, (RTRIM(EM.LastName) + ' ' + isNull(Suffix,'')) 	as LastName
, EM.MiddleName
, EM.Org                                                    as PrimaryDept
, EM.Region
, EM.WorkPhone
, EM.WorkPhoneExt
, EM.MobilePhone
, ECTF.Cust5ULPhysical                                as Office
, ECTF.custSecondaryDepartment                as SecondaryDept
From
EM
Join EmployeeCustomTabFields ECTF on ( ECTF.Employee = EM.Employee )
Where
EM.Status = 'A'
And    (         EM.FirstName     like  Case When (@FirstName is null)    Then '%' Else RTRIM(@FirstName)    + '%' End
OR    EM.PreferredName      like  Case When (@FirstName is null)    Then '%' Else RTRIM(@FirstName)    + '%' End
)
And    EM.LastName         like  Case When (@LastName is null) Then '%' Else RTRIM(@LastName)    + '%' End
And    SUBSTRING(EM.FirstName,1,1)
+  RTRIM(Case When(DATALENGTH(EM.MiddleName) = 0) Then '' Else  SUBSTRING(EM.MiddleName,1,1) End )
+  SUBSTRING(EM.LastName,1,1)  LIKE Case When (@Initials is null) Then '%' Else  @Initials  End
And    (        EM.WorkPhone    like '%' + isNull(@Phone,'%') + '%'
OR    EM.WorkPhoneExt like '%' + isNull(@Phone,'%') + '%'
OR    EM.MobilePhone    like '%' + isNull(@Phone,'%') + '%' )
And ECTF.Cust5ULPhysical = isNull(@Office, ECTF.Cust5ULPhysical)
And ( EM.Org like '%' + isNull(@Dept,'%') + '%'
OR ECTF.custSecondaryDepartment like '%' + isNull(@Dept,'%') + '%'  )
And EM.Employee like  isNull(@EmpNum,'%') + '%'
 UNION ALL
Select  EmpNum                     as Employee
, FirstName
, LastName
, ''                            as MiddleName
, ''                            as PrimaryDept
, ''                            as Region
, Phone                        as WorkPhone
, PhoneExt                        as WorkPhoneExt
, ''                             as MobilePhone
, ECTF_Cust5ULPhysical            as Office
, ''                            as SecondaryDept
From OfficeAux OA
Where
OA.FirstName        like  Case When (@FirstName is null) Then '%' Else RTRIM(@FirstName)    + '%' End
And    OA.LastName         like  Case When (@LastName is null)     Then '%' Else RTRIM(@LastName)        + '%' End
And '1'    = dbo.IgnoreNullParm(@Initials)        <em> -- if parm is null ignore it otherwise this effectively 'turns off union' if parm is not null</em>
And '1'    = dbo.IgnoreNullParm(@Dept)           <em>-- if parm is null ignore it otherwise this effectively 'turns off union' if parm is not null</em>
And    (        OA.Phone        like '%' + isNull(@Phone,'%')  + '%'
OR    OA.PhoneExt    like '%' + isNull(@Phone,'%')  + '%')
And ECTF_Cust5ULPhysical = isNull(@Office, ECTF_Cust5ULPhysical)
And EmpNum  like  isNull(@EmpNum,'%') + '%'


UDF


Create function [dbo].[IgnoreNullParm]
(
@Field  nvarchar(50)
)
Returns bit
-- Sends back True '1' if Parm is null
-- Setup in where clause as Where '1' = IgnoreNullParm(@parm)
-- Allows you to effectively turn off a union 'leg' if a parm is not null and ignore it if not null
as

Begin

Declare @bReturn as  bit

Select  @bReturn = Case When (@Field is null) Then '1' Else '0' End

Return @bReturn

End

Auxilary Table:


CREATE TABLE [dbo].[OfficeAux](
[ID] [uniqueidentifier] NOT NULL,
[ECTF_Cust5ULPhysical] [varchar](20) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[XName] [nvarchar](255) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[EmpNum] [char](3) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[FirstName] [nvarchar](255) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[LastName] [nvarchar](255) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[PhoneExt] [nvarchar](10) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[Phone] [nvarchar](50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[MobilePhone] [nvarchar](50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[isActive] [bit] NULL,
[lastUpdated] [datetime] NULL,
[lastUpdater] [nvarchar](50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
) ON [PRIMARY]
End