Thursday 19 July 2012

Mobile SearchBox

Now that you have your mobile MasterPage, you probably want to incorporate some sort of searching ability, so we are going to create a regular WebPart (that is not a visual one) and we're going to inherit from SearchBoxEx, then override the CreateChildControls() method and create our own very simple interface that's going to consist of a textbox and a button.

First add a web part to our project, again right click on your solution explorer, hover over add and select new item, or just hit ctrl+shift+a.
In the left hand pane make sure to select a sharepoint 2010 project, in the middle pane select Web Part then finally give your Web Part a descriptive name; I'm going with Mobile search. Open up the Mobile Search.cs file and this is what you should see.
If you're like me and just jumped on the SharePoint bandwagon post 2010, it may be a little different then what you're use to, for example there is not ascx file (the UI stuff); now if you listen to the old timers who make it sound as if they had it hard; don't let them phase you this stuff is actually a lot easier then some people make it out to be.

Now I could hold your hand through this and describe to you what to do and then post the code for you to look at, but it's really not all that complicated; basically:
  • you inherit from the SearchBoxEx
  • build the UI using a the base function createchildcontrols 
  • then you hide what the original webpart creates
  • move the objects around so that rather then being in a table you place it in some divs
  • then you add your own css to style it, not exactly rocket surgery.
the only part that might be a bit tricky is the fact that I have a custom search page. Anyway here you go the .cs code
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.Portal.WebControls;
 
namespace CCW.SharePoint.Mobile.WebParts.MobileSearch
{
    public class MobileSearch : SearchBoxEx
    {
        const string searchUrl = "/pages/MobileSearch.aspx";
 
        protected override void CreateChildControls()
        {
            // build the base searchBoxEx
            base.CreateChildControls();
 
            if (Controls.Count < 2)
            {
                return;
            }
 
            // hide the base
            if (Controls[1].GetType() == typeof(Table))
            {
                Table tabel = (Table)Controls[1];
                tabel.Visible = false;
            }
 
            if (m_searchKeyWordTextBox != null && m_hlink != null)
            {
                HtmlGenericControl div = new HtmlGenericControl("div");
                m_searchKeyWordTextBox.Style.Clear(); 
                m_searchKeyWordTextBox.Attributes["class"] = "SearchBox";
                m_hlink.Attributes["class"] = "SearchButton";
                m_hlink.Controls.Clear();
                m_hlink.Text = "Go";
                m_ddlScopes.Attributes["class"] = "secrete";
 
                div.Controls.Add(m_searchKeyWordTextBox);
                div.Controls.Add(m_hlink);
                div.Controls.Add(m_ddlScopes);
 
                Controls.Add(div);
            }
 
            base.SearchResultPageURL = searchUrl;
            base.UseSiteDefaults = false;
            base.ShouldTakeFocusIfEmpty = false;
            base.UseSiteDropDownMode = false;
            base.QueryPromptString = "Search for...";
 
            CssRegistration.Register("/_layouts/CCW.SharePoint.Mobile/mobileSearch.css");
        }
    }
}
and for good measure here's the css
.SearchBox
{
    font:20px sans-serif;
    margin10px 0px;
    padding:5px 10px;
 
    -webkit-border-top-left-radius15px;
    -webkit-border-bottom-left-radius15px;
    -moz-border-radius-topleft15px;
    -moz-border-radius-bottomleft15px;
    border-top-left-radius15px;
    border-bottom-left-radius15px;
}
 
a.SearchButton:linka.SearchButton:visiteda.SearchButton:hovera.SearchButton:active
{
    color:#fff;
    font-weight:bold;
    padding:11px 10px;
    text-decoration:none;
    top:-1px;
    
    background-imagelinear-gradient(bottom, #243157 35%, #3F71A6 74%);
    background-image-o-linear-gradient(bottom, #243157 35%, #3F71A6 74%);
    background-image-moz-linear-gradient(bottom, #243157 35%, #3F71A6 74%);
    background-image-webkit-linear-gradient(bottom, #243157 35%, #3F71A6 74%);
    background-image-ms-linear-gradient(bottom, #243157 35%, #3F71A6 74%);
 
    background-image-webkit-gradient(
     linear,
     left bottom,
     left top,
     color-stop(0.35, #243157),
     color-stop(0.74, #3F71A6)
    );
    
    -webkit-border-top-right-radius15px;
    -webkit-border-bottom-right-radius15px;
    -moz-border-radius-topright15px;
    -moz-border-radius-bottomright15px;
    border-top-right-radius15px;
    border-bottom-right-radius15px;
}
 
.secrete
{
    display:none;
} 
Now the fun part, since the SearchBoxEx webpart is an artifact from a previous version of SharePoint either 2003 or 2007 you have to change the .webpart file into a .dwp. If you open the .webpart file you should see something along the lines of:
<?xml version="1.0" encoding="utf-8"?>
<webParts>
  <webPart xmlns="http://schemas.microsoft.com/WebPart/v3">
    <metaData>
      <type name="CCW.SharePoint.Mobile.WebParts.MobileSearch.MobileSearch, $SharePoint.Project.AssemblyFullName$" />
      <importErrorMessage>$Resources:core,ImportErrorMessage;</importErrorMessage>
    </metaData>
    <data>
      <properties>
        <property name="Title" type="string">MobileSearch</property>
        <property name="Description" type="string">My WebPart</property>
      </properties>
    </data>
  </webPart>
</webParts> 
Replace it with the following:
<?xml version="1.0" encoding="utf-8" ?>
 
<WebPart xmlns="http://schemas.microsoft.com/WebPart/v2">
  <Assembly>$SharePoint.Project.AssemblyFullName$,Version=1.0.0.0,Culture=Neutral,PublicToken=XXXXXXXXXXXXXXXX</Assembly>
  <TypeName>CCW.SharePoint.Mobile.WebParts.MobileSearch.MobileSearch</TypeName>
  <Title>CustomSearchBox</Title>
  <Description>Mobile SearchBox</Description>
</WebPart> 
Note that the public token is a bunch of x's, click to get your public key.
with your webpart file transformed into a dwp, change the Property deployment Type to ElementFile from None


finally open up the elements file and make sure you change the webpart extension to .dwp

<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/" >
  <Module Name="MobileSearch" List="113" Url="_catalogs/wp">
    <File Path="MobileSearch\MobileSearch.dwp" Url="MobileSearch.dwp" Type="GhostableInLibrary">
      <Property Name="Group" Value="Custom" />
    </File>
  </Module>
</Elements>
with all that done deploy your webpart and add it to a page.