Modify the DNN Search Button

Recently, I have a chance to work with DNN skin and containers using PhotoShop files from a designer. So far so good. However, with the latest skin, an image must be used instead of text for the DNN search button (<dnn:SEARCH> control).
First, create a copy of the search user control located under admin/skins and name it "CustomSearch.ascx". Then modify the source code to set custom css classes for the controls inside. The modified code looks something like this:
<%@ Control language="vb" CodeFile="Search.ascx.vb" AutoEventWireup="false" Explicit="True" Inherits="DotNetNuke.UI.Skins.Controls.Search" %>
<asp:RadioButton ID="optWeb" runat="server" CssClass="SkinObject" GroupName="Search" Text="Web" />
<asp:RadioButton ID="optSite" runat="server" CssClass="SkinObject" GroupName="Search" Text="Site" />
<asp:TextBox id="txtSearch" runat="server" CssClass="SearchTextbox" enableviewstate="False" MaxLength="255"></asp:TextBox>
<asp:LinkButton ID="cmdSearch" Runat="server" CausesValidation="False" CssClass="SearchButton"></asp:LinkButton>
Note that we could have modified the existing Search.ascx but that might affect the whole site since some skins might make use of this default search e.g. the default blue skin.
Notice that it uses a link button as a search button. This will be converted into an <a> HTML tag and thus cannot set an image for it. We need to set it in CSS 9not shown here).
Also notice that the code file is still "Search.ascx.vb". Therefore, I did not change any control's ID just for simplicity and compatibility with the code file. I also assigned "SearchTextbox" and "SearchButton" CSS classes for <asp:Textbox id="txtSearch"> and <asp:LinkButton id="cmdSearch"> accordingly. These CSS classes have been defined in my skin.css under my skin folder. The image for the button has also been set here as a background image.
Now place the CustomSearch.ascx back to admin/skins folder and use <dnn:CUSTOMSEARCH> instead of <dnn:SEARCH> in my skin ascx file. This ALMOST gave me the result I expected. The textbox and image button shows properly BUT there is a text "search" appearing on the search button.
After some investigations in the Search.ascx.vb file, I found that the search text is extracted from a resource file.
In the "Private Members" region, a file name is set as a constant here.
Const MyFileName As String = "Search.ascx"
Under the "Event Handlers" region, a string value has been extracted from a resource file and set as the search text.
Submit = Services.Localization.Localization.GetString("Search", Services.Localization.Localization.GetResourceFile(Me, MyFileName))
.
.
.
cmdSearch.Text = Submit
Now look for "Search.ascx.resx" file under App_LocalResources folder. This file is the resource file that the code calls. Look near the bottom of the file and we see...
<data name="Search.Text"> <value>Search</value> </data>
Bingo! The text that we DON'T want is here. We could just remove the string value but, again, it might affect other skins. So I decided to create another name-value pair and set no value to it.
<data name="SearchNoText.Text"> <value></value> </data>
We could have created another resource file but I don't think it's necessary since adding another name-value pair should work just fine. We will discuss more on this issue in a moment.
Go back to the Search.ascx.vb file and change the line where it gets the string resource to the following:
Submit = Services.Localization.Localization.GetString("SearchNoText", Services.Localization.Localization.GetResourceFile(Me, MyFileName))
.
.
.
cmdSearch.Text = Submit
Save the file as CustomSearch.ascx.vb. Now we have got the code file we want which calls a string value we are looking for (which is a blank). What to do next is to tell the skin to use this code file instead.
<%@ Control language="vb" CodeFile="CustomSearch.ascx.vb" AutoEventWireup="false" Explicit="True" Inherits="DotNetNuke.UI.Skins.Controls.Search" %>
<asp:RadioButton ID="optWeb" runat="server" CssClass="SkinObject" GroupName="Search" Text="Web" />
<asp:RadioButton ID="optSite" runat="server" CssClass="SkinObject" GroupName="Search" Text="Site" />
<asp:TextBox id="txtSearch" runat="server" CssClass="searchtextbox" enableviewstate="False" MaxLength="255"></asp:TextBox>
<asp:LinkButton ID="cmdSearch" Runat="server" CausesValidation="False" CssClass="searchbutton"></asp:LinkButton>
Now put this skin in use and the search text will no longer be there :)
In conclusion, here is how it gets to the resource string:
CustomSearch.ascx (skin) --> CustomSearch.ascx.vb (code file) --> Search.ascx.resx.
We could have created a another resource file as mentioned earlier. For example, we could create a copy of Search.ascx.resx and name it "CustomSearch.ascx.resx". In this file, we can just remove the value for the data name "Search.Text". The rest remains unchanged. Then in the code file, change the MyFileName constant to "CustomSearch.ascx". This way, the code file will access CustomSearch.ascx.resx to look for the resource string. But, again, there is no need to do that much. Just add another name-value pair and we are ready to go :)
I hope this could give you an idea on how to modify the search module to look the way you want :)
Further Study:
It might be possible to use an image button for the search button and set the id to be the same (cmdSearch). This could also be used to customize the search behavior of the search module. By the way, I am a C# developer, not VB.NET. So, later I will try to create some with C# :)