Search widget appearance
Hey all,
Another styling question from me...One day I will actually learn what I am doing.
Can someone tell me how to skin/style the new search toy that came with latest release. When I place it on my page it has a fairly boring looking button and the control has wrapped itself in a white border (black website).
Any help...as always is appreciated.
Cheers!
Hi James ,
Currently the template is not exposed and you can edit it only if you map it. Below is the template of the SearchBox control.
<%@ Control Language="C#" %>
<%@ Register Assembly="Telerik.Sitefinity" Namespace="Telerik.Sitefinity.Web.UI" TagPrefix="sf" %>
<
sf:ResourceLinksid
=
"resourcesLinks"
runat
=
"server"
>
<
sf:ResourceFileJavaScriptLibrary
=
"JQuery"
/>
<
sf:EmbeddedResourcePropertySetterName
=
"Telerik.Sitefinity.Resources.Themes.Default.Images.Loadings.sfLoadingData.gif"
Static
=
"true"
ControlID
=
"loadingImage"
ControlPropertyName
=
"ImageUrl"
/>
</
sf:ResourceLinks
>
<
fieldsetclass
=
"sfSearchBoxSet"
>
<
asp:LabelID
=
"lblSearchBox"
runat
=
"server"
CssClass
=
"sfSearchLbl"
Text="<%$ Resources:Labels, Search %>" AssociatedControlID="searchBox" />
<
asp:TextBoxID
=
"searchBox"
runat
=
"server"
CssClass
=
"sfTxt"
/>
<
asp:LinkButtonID
=
"searchButton"
runat
=
"server"
CssClass
=
"sfLinkBtn"
OnClientClick
=
"return false;"
>
<
strongclass
=
"sfLinkBtnIn"
>
<
asp:LiteralID
=
"searchLiteral"
runat
=
"server"
Text='<%$ Resources:Labels, SearchLabel %>'></
asp:Literal
>
</
strong
>
</
asp:LinkButton
>
</
fieldset
>
<
div id
=
"searchProgressPanel"
runat
=
"server"
style
=
"display:none;"
class
=
"sfSearchLoading"
>
<
sf:SfImageID
=
"loadingImage"
runat
=
"server"
AlternateText="<%$Resources:Labels, Searching %>" />
</
div
>
<
scripttype
=
"text/javascript"
>
$('#<%= searchBox.ClientID %>').focus(function()
$("#<%= lblSearchBox.ClientID %>").css("text-indent","-99999px");
);
$('#<%= searchBox.ClientID %>').blur(function()
if ($(this).val() === '')
$("#<%= lblSearchBox.ClientID %>").css("text-indent","0");
else
$("#<%= lblSearchBox.ClientID %>").css("text-indent","-99999px");
);
$('#<%= lblSearchBox.ClientID %>').click(function()
var id, field;
id = $(this).attr("for");
if (id && (field = $("#"+id)))
field.focus();
);
$('#<%= searchBox.ClientID %>').blur();
//hideFormLabel($('#<%= searchBox.ClientID %>'),false);
</
script
>
Hi Ivan,
I have the template all set up, pretty straight forward except a few name changes of the controls within the template but now I want to change the button to an image button and I'm getting the following:
A required control was not found in the template for "~/App_Data/CustomControlTemplates/SearchBox.ascx". The control must be assignable form type "System.Web.UI.WebControls.Button" and must have ID "searchButton".
Does the button control have to be a System.Web.UI.WebControls.Button? If so will this be changed in a future release?
Thanks,
Steve
Hi James,
The control is required and the actual type is LinkButton.
Best wishes,
Ivan Dimitrov
the Telerik team
Hi Ivan,
It's Steve and the actual control it wants is a button. If it was a link button there would not be a problem.
Is this going to be changed to a LinkButton in the future?
Thanks,
Steve
image attached.
Hi Steve,
I was looking into the backend search. The type is "Button" and we will not change it for now. The control is set as required and the only way to replace it is overriding the SearchButton property and replacing the type.
Then inside GetScriptDescriptors() you should pass the control ID to the client
descriptor.AddElementProperty("searchButton", this.SearchButtonCustom.ClientID);
Greetings,
Ivan Dimitrov
the Telerik team
Hi Ivan,
That's kind of restrictive isn't it? Do you have some code samples?
Thanks,
Steve
Hi ,
You can add css rules in your theme for the classes used by SearchBox control. You can see the css classes from the template I sent you.
Here is a sample code o a custom control that shows how to replace the default Button with LinkButton
using
System;
using
System.Collections.Generic;
using
System.Linq;
using
System.Text;
using
Telerik.Sitefinity.Services.Search.Web.UI.Public;
using
System.Web.UI.WebControls;
using
System.Web.UI;
namespace
Telerik.Sitefinity.Samples
public
class
SearchBoxCustom : SearchBox
protected
override
string
LayoutTemplateName
get
return
SearchBoxCustom.layoutTemplateName;
protected
override
Button SearchButton
get
return
this
.Container.GetControl<Button>(
"searchButton"
,
false
);
protected
virtual
LinkButton SearchButtonCustom
get
return
this
.Container.GetControl<LinkButton>(
"searchButtonCustom"
,
false
);
public
override
IEnumerable<System.Web.UI.ScriptDescriptor> GetScriptDescriptors()
var descriptor =
new
ScriptControlDescriptor(
typeof
(SearchBoxCustom).FullName,
this
.ClientID);
descriptor.AddElementProperty(
"searchButtonCustom"
,
this
.SearchButtonCustom.ClientID);
return
new
[] descriptor ;
private
const
string
layoutTemplateName =
"Telerik.Sitefinity.Samples.Resources.SearchBox.ascx"
;
public enum WordsMode
AllWords = 0,
AnyWord = 1
Type.registerNamespace(
"Telerik.Sitefinity.Samples"
);
Telerik.Sitefinity.Samples.SearchBoxCustom =
function
(element)
Telerik.Sitefinity.Samples.SearchBoxCustom.initializeBase(
this
, [element]);
this
._searchTextBox =
null
;
this
._searchButtonCustom =
null
;
this
._wordsMode =
null
;
this
._resultsUrl =
null
;
this
._indexCatalogue =
null
;
this
._keyPressDelegate =
null
;
this
._clickDelegate =
null
;
Telerik.Sitefinity.Samples.SearchBoxCustom.prototype =
initialize:
function
()
Telerik.Sitefinity.Samples.SearchBoxCustom.callBaseMethod(
this
,
"initialize"
);
if
(
this
._searchTextBox)
this
._keyPressDelegate = Function.createDelegate(
this
,
this
._keyPressHandler);
$addHandler(
this
._searchTextBox,
"keypress"
,
this
._keyPressDelegate);
if
(
this
._searchButton)
this
._clickDelegate = Function.createDelegate(
this
,
this
._clickHandler);
$addHandler(
this
._searchButton,
"click"
,
this
._clickDelegate);
,
dispose:
function
()
if
(
this
._searchTextBox &&
this
._keyPressDelegate)
if
(
this
._searchTextBox)
$removeHandler(
this
._searchTextBox,
"keypress"
,
this
._keyPressDelegate);
delete
this
._keyPressDelegate;
if
(
this
._searchButton &&
this
._clickDelegate)
if
(
this
._searchButton)
$removeHandler(
this
._searchButton,
"click"
,
this
._clickDelegate);
delete
this
._clickDelegate;
Telerik.Sitefinity.Samples.SearchBoxCustom.callBaseMethod(
this
,
"dispose"
);
,
/* -------------------- Public methods ---------------- */
navigateToResults:
function
(e)
if
(!e)
var
e = window.event;
if
(e.stopPropagation)
e.stopPropagation();
else
e.cancelBubble =
true
;
if
(e.preventDefault)
e.preventDefault();
else
e.returnValue =
false
;
if
(
this
._searchTextBox.value &&
this
._indexCatalogue)
window.location =
this
.getLocation();
,
getLocation:
function
()
var
query =
this
._searchTextBox.value;
var
separator = (
this
._resultsUrl.indexOf(
"?"
) == -1) ?
"?"
:
"&"
;
var
indexCatalogue = String.format(
"0indexCatalogue=1"
, separator, Url.encode(
this
._indexCatalogue));
var
searchQuery = String.format(
"&searchQuery=0"
, Url.encode(query));
var
wordsMode = String.format(
"&wordsMode=0"
,
this
._wordsMode);
var
url =
this
._resultsUrl + indexCatalogue + searchQuery + wordsMode;
return
url;
,
/* -------------------- Event handlers ---------------- */
_keyPressHandler:
function
(e)
if
(!e)
var
e = window.event;
var
keyCode =
null
;
if
(e.keyCode)
keyCode = e.keyCode;
else
keyCode = e.charCode;
if
(keyCode == 13)
this
.navigateToResults(e);
,
_clickHandler:
function
(e)
this
.navigateToResults(e);
,
/* -------------------- properties ---------------- */
get_searchTextBox:
function
()
return
this
._searchTextBox;
,
set_searchTextBox:
function
(value)
this
._searchTextBox = value;
,
get_searchButton:
function
()
return
this
._searchButton;
,
set_searchButton:
function
(value)
this
._searchButton = value;
,
get_wordsMode:
function
()
return
this
._wordsMode;
,
set_wordsMode:
function
(value)
this
._wordsMode = value;
,
get_resultsUrl:
function
()
return
this
._resultsUrl;
,
set_resultsUrl:
function
(value)
this
._resultsUrl = value;
,
get_indexCatalogue:
function
()
return
this
._indexCatalogue;
,
set_indexCatalogue:
function
(value)
this
._indexCatalogue = value;
;
Telerik.Sitefinity.Samples.SearchBoxCustom.registerClass(
"Telerik.Sitefinity.Samples.SearchBoxCustom"
, Sys.UI.Control);
Telerik.Sitefinity.Samples.SearchBoxCustom.Public.WordsMode =
function
()
/// <summary>
/// Represents the different client side words modes
/// </summary>
;
Telerik.Sitefinity.Samples.SearchBoxCustom.WordsMode.prototype =
AllWords: 0,
AnyWord: 1
;
Telerik.Sitefinity.Samples.SearchBoxCustom.WordsMode.registerEnum(
"Telerik.Sitefinity.Web.UI.Fields.FieldDisplayMode"
);
Hi Ivan,
Thank you very much for the effort you put in on this one, it's very much appreciated.
Steve
Hi All,
I am not sure if this will have changed in the RTM version, but anyone who gets caught out by this, you need to restart the Application before the ViewMap takes effect.
Hope that helps someone...
Sorry, not sure what all this means :-), is there a simple solution (in the css) for making the button an image rather then the standard submit button? There isn't an 'advanced' section to this widget which most others do to be able to theme them, is that right, or am I missing it? Thanks...
Hi Richard,
You can add styles to your themes .css files like the following:
.sfsearchBox
padding
:
0px
0px
0px
0px
;
margin
:
0px
0px
0px
0px
;
width
:
253px
;
height
:
43px
;
background-color
:
#d4d3d3
;
position
:
relative
;
border
:
0px
solid
#FFFFFF
;
.sfsearchBox .sfsearchTxt
border
:
0px
solid
#FFFFFF
;
padding
:
3px
5px
0px
5px
;
margin
:
0px
0px
0px
0px
;
height
:
21px
;
width
:
143px
;
position
:
absolute
;
top
:
10px
;
left
:
9px
;
.sfsearchBox .sfsearchSubmit
font-size
:
0px
;
color
:
#FFFFFF
;
height
:
24px
;
width
:
84px
;
background
: Transparent
url
(
'images/searchButton.gif'
)
no-repeat
;
border
:
0px
solid
#FFFFFF
;
padding
:
0px
0px
0px
0px
;
margin
:
0px
0px
0px
0px
;
position
:
absolute
;
top
:
10px
;
left
:
162px
;
Thanks Steve...
Is there any way to pre-populate the search box field with text via the CSS or similar? Thanks,
Cheers
Richard
Hi Richard Cross,
I think it is not a good idea to use CSS to populate text. The approach to pre-populate the search box will depend on what the text will be.
Kind regards,
Katia
the Telerik team
Hi Katia
Probably a question too far and not really a Sitefinity thing, but how do people get the word 'search' to show in the search box, is it using a background image with the word search in that when clicked gets taken over by the box entry field? Might be a good option for Sitefinity to offer on the search facilities?
Thanks in advance...
Cheers
Richard
Hi Richard,
The approach we take is to use javascript.
http://mucur.name/system/jquery_example/
Since jQuery is already embedded in Sitefinity 4 this is pretty easy to just implement the plugin.
www.sitefinity.com/.../controls-utility-controls-resourcelinks-control.html
<
sitefinity:ResourceLinks
ID
=
"resourcesLinks"
runat
=
"server"
>
<
sitefinity:ResourceFile
JavaScriptLibrary
=
"JQuery"
></
sitefinity:ResourceFile
>
</
sitefinity:ResourceLinks
>
I was following your code, but when I tried to tested, the Submit doesn't work. Any Idea?
Hi Sean,
Have you set the ID of the index pipe? Since you have the entire code which is exposed in the other posts, you can subscribe for the click event of the button and see whether it is fired and what is going on after the request.
Best wishes,
Ivan Dimitrov
the Telerik team
@Richard
"InnerSearchBoxText" is the property you want...it'll put the placeholder text inside the box until it's clicked on, then it disappears.
<
sitefinity:SearchBox
ID
=
"searchBox"
runat
=
"server"
BinderBoxLabelText
=
""
InnerSearchBoxText
=
"Search..."
/>
A bit confusing
Which way to follow to style the search box.
This thread here or http://www.sitefinity.com/devnet/forums/sitefinity-4-x/general-discussions/style-the-search-box.aspx
Markus
I'm with Marcus, this is ludicrously complicated for something so very simple. All I want to do is replace the search Button with an Image!!
There are four threads on this forum explaining four different ways to approach this, but I cannot get any of them to work.
By creating a WebUserControl in the following location, with the following files:
~/UserControls/GTC_Search_Box.ascx
~/UserControls/GTC_Search_Box.ascx.cs
~/UserControls/GTC_Search_Box.ascx.designer.cs
and edit ONLY GTC_Search_Box.ascx to read:
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="GTC_Search_Box.ascx.cs" Inherits="SitefinityWebApp.UserControls.GTC_Search_Box" %>
<%@ Register TagPrefix="sitefinity" Assembly="Telerik.Sitefinity" Namespace="Telerik.Sitefinity.Web.UI" %>
<
fieldset
id
=
"main"
class
=
"sfsearchBox"
runat
=
"server"
>
<
asp:Label
ID
=
"searchLabel"
runat
=
"server"
>Search</
asp:Label
>
<
asp:TextBox
ID
=
"searchTextBox"
runat
=
"server"
CssClass
=
"sfsearchTxt"
/>
<
asp:Button
id
=
"searchButton"
runat
=
"server"
Text="<% $Resources:SearchResources, Search %>" OnClientClick="return false;" CssClass="sfsearchSubmit" />
</
fieldset
>
Hey Paul, if that's all you need to do then you don't even need to make your own template. There should be enough CSS classes defined in the base control to allow you to do a CSS background image which is the preferred way to make an image button anyway. If you make it the asp:image button then to get hover states (etc) you need to gimp around with JavaScript hover events instead of simple CSS hover rules.
@Steve
@Paul
I ende up using CSS. But if you think about further like you would have 2 search options (news, site) then the hassle probably begins.
Programmers usually appreciate it that they have multiple ways to do something. People who do also design and stuff are often getting confused. And more then once you have only parts of the solution and you start cut and pasting stuff together which never works.
So Paul take Steves advice and try to style it.
Maybe this helps as an starting point:
/* search */
.sfsearchBox
border
:
0
!important
;
.sfsearchTxt
border
:
1px
;
border-color
: Gray;
color
:
gray
;
font-size
:
10px
;
width
:
115px
;
background-color
:
white
;
border-radius:
5px
;
height
:
15px
;
padding-left
:
5px
;
.sfsearchSubmit
background-color
:
#CCC
;
font-size
:
10px
;
border-radius:
5px
;
width
:
28px
;
margin-left
:
0
;
border
:
0
none
;
height
:
15px
;
.sfsearchSubmit:hover
background-color
:
#bcbbbb
;
Hi Steve,
LOL! Very lateral thinking - I like it! In this particular example you are quite correct - and I feel rather stupid for not thinking of it myself - full on tunnel vision. However, it doesn't really cover the more general case. Interestingly though, I have just found a post (using Google's search rather than the built in forum search) here:
http://www.sitefinity.com/devnet/forums/sitefinity-4-x/sdk/how-to-get-a-custom-search-going.aspx
It contains the files for a custom search that compiles and works correctly. Whilst it doesn't actually replace the Button, it looks like a good basis to start.
Paul
@Markus
Have done, and I can feel my blood pressure reducing as I type :)
Has anyone considered simply hiding the button and adding an image button instead? Seems to work for me.
<asp:Button id="searchButton" runat="server" Text="<%$Resources:SearchResources, Search %>" OnClientClick="return false;" Visible="False" />
<asp:ImageButton id="searchButton2" runat="server" Text="<%$Resources:SearchResources, Search %>" OnClientClick="return false;" ImageUrl="~/Path/Image.gif" Width="32" Height="32" />
Steve's CSS solution worked great. I added a new stylesheet to my theme, including the styles he provided, and customized them to match my site. Problem solved.
I have a different Problem, but with the SearchBox too. I have styled it like I wanted, but the "Search" on the searchbutton is not localized for German for example. I tried to inherit from SearchBox and write my own SearchBoxDesigner by inheriting the SearchBoxDesigner class. Made my own designer.ascx and .js but when I use my widget and want to edit it, the designer is empty (simple and advanced) debugging the javascript gives no problems with my .js.
Maybe I'm thinking to complicated. Is there a good and easy way to localize the searchbutton? Thanks!
Hello Carsten Koster,
Usually when an empty designer is shown this means that there is a problem with the javascript component, so I'm not sure what else could be the problem. Can you open a support ticket and send me your control, so I can check it out?
Best wishes,Another question. Do I really have to implement my own search widget just to be able to localize the text of the search button? Would you implement that feature for me in the next Sitefinity version? :)
Another question. Do I really have to implement my own search widget just to be able to localize the text of the search button? Would you implement that feature for me in the next Sitefinity version? :)
Hello Carsten Koster,
I'll share with the community my response to your support ticket here, as well:
We have an exposed configuration for localizing the resources and since the SearchBox is using a resource for the text that is displayed in the Button, you can localize it from Administration >> Interface Labels and Messages and there look for this resource:
Search
Used in : SearchResources , Resource key : Search
When you click on it, you will be able to specify different labels for all the frontend cultures that you currently have in your project.