Blog searching
A while ago I added a search box to my blog. It went off and searched google, but the results were pretty poor. So I forgot about it.
A couple of day ago, Sahil Malik theived - no - stole - no - plagiarised - no - (just kidding mate! :) had the same idea as I did and got the same thing going on his. One of the comments he received was from Steve Eichert, who pointed out that .Text actually does have a search feature, it's just well hidden.
Well, besides being annoyed that I didn't know of it earlier, this piqued my curiosity. So I went to update my side bar to search locally instead of on google.
To start with, because we don't get much control over stuff on our blog pages (without a lot of css - and otherwise - hacking, I have to put the search box in the 'News' Section.
<H3>Search my blog</H3>
<ul>
<li>
<input type="text" id="BlogSearch.ascx_Search1_tbSearch" name="BlogSearch.ascx:Search1:tbSearch" value="">
</li>
</ul>
This is all good, but it's ugly. The NAME and ID of the input box is taken straight out of a view-source of the in built search page. So next we define a CSS class for 'Custom CSS Selectors' section, and attach it to the search box.
.BlogSearch
{
border-style: solid;
border-width: 1px;
border-color: #1649B0;
width: 127px;
}
<input class="BlogSearch" type="text" id="BlogSearch.ascx_Search1_tbSearch" name="BlogSearch.ascx:Search1:tbSearch" value="">
The next trick was to get it to do a search. So I hooked the onKeyPress event to do the dirty work.
<input class="BlogSearch" type="text" id="BlogSearch.ascx_Search1_tbSearch" name="BlogSearch.ascx:Search1:tbSearch" value="" onkeypress="return freddSearch(this);">
The freddSearch() javascript function is called with every keypress. It's ok, almost all the time it does nothing, and it's not like you type there very often, right? :)
So now we have to convince ASP.net that it's been posted to from .Text's own search page.
<script type="text/javascript">
function freddSearch(oInput) {
if (event.keyCode == 13) {
var oForm = document.getElementById('Form1'); //grab the form object
oForm.action = "/weblog/fredd/search.aspx"; //reset the target
oForm.submit();
return false;
}
return true;
}
</script>
Now, legally we're not supposed to have script blocks anywhere except inside the HEAD. But no one does, so screw it :) This is added to the 'News' section too. Basically, I test the event.keycode for 13. 13 is the numerical equivalent to the enter key (well, it is on my keyboard, anyway :) If it's not a 13, then we just return true, so that we can continue typing.
If it was the enter key, the tricky stuff starts. I grab a hold of the form element, and rewrite where it's submitting to (the url of the inbuilt search page). I've already named the input box the same as what it would expect, so surely this will work? So i tried this out and -
No dice.
I had a closer look at what was going on, and saw that some validation was going on. Maybe I'd better get rid of that :)
function freddSearch(oInput) {
if (event.keyCode == 13) {
var oForm = document.getElementById('Form1'); //grab the form object
oForm.action = "/weblog/fredd/search.aspx"; //reset the target
oForm.onsubmit = null; //remove any onsubmit validation
oForm.submit();
return false;
}
return true;
}
This will work, right? Nope. It got further (the form submitted) but it didn't actually perform a search. So I hunted more. There's a few hidden elements on the page, but it's things like viewstate, and they were empty. Surely it's not...no...it needs a 'Search' button?
function freddSearch(oInput) {
if (event.keyCode == 13) {
var oForm = document.getElementById('Form1'); //grab the form object
oForm.action = "/weblog/fredd/search.aspx"; //reset the target
oForm.onsubmit = null; //remove any onsubmit validation
var newHidden = document.createElement("INPUT");//create a new input element
newHidden.name = "BlogSearch.ascx:Search1:Button1"; //name it the same as on the search page
newHidden.value = "Search"; //label it the same
newHidden.type = "hidden"; //but we'll hide it.
oForm.appendChild(newHidden); //add it as a child of the form.
oForm.submit();
return false;
}
return true;
}
You know what? It worked! I was excited. I really was. I was a master Haxx0r! But then I noticed something.
I couldn't believe my eyes. I fired up my trusty ieHTTPHeaders explorer bar to make sure. Here's my request when I ran the search through the sidebar:
POST /weblog/fredd/search.aspx HTTP/1.1
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*
Referer:
http://blogs.crankygoblin.com/blogs/geoff.appleby/Accept-Language: en-au
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)
Host: dotnetjunkies.com
Content-Length: 100
Connection: Keep-Alive
Cache-Control: no-cache
__VIEWSTATE=&BlogSearch.ascx%3ASearch1%3AtbSearch=firefox&BlogSearch.ascx%3ASearch1%3AButton1=Search
And here's the response that came back:
HTTP/1.1 302 Found
Date: Tue, 21 Dec 2004 10:17:51 GMT
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
X-AspNet-Version: 1.1.4322
Location: /weblog/fredd/search.aspx?q=firefox
Cache-Control: private
Content-Type: text/html; charset=utf-8
Content-Length: 152
The damn thing was just redirecting to a standard GET request!
So, the end result is that I have the CSS class as shwon above in my 'Custom CSS Selectors' section of my blog options, and in the 'News' section there's this:
<H3>Search my blog</H3>
<ul>
<li>
<input class="BlogSearch" type="text" name="searchBox" value="" onkeypress="return freddSearch(this);" ID="Text1">
</li>
</ul>
<script type="text/javascript">
function freddSearch(oInput) {
if (event.keyCode == 13) {
window.navigate('/weblog/fredd/search.aspx?q=' + oInput.value);
return false;
}
return true;
}
</script>
Simple huh? Now I only have to whinge about the quality of search results from .Text, instead of mucking dirt on Google :)
Listening to: live-in skin - foo fighters - (3:52)