16 December 2006

Native Blog Search improved!

Edit: I've updated the instructions and code since some people were complaining of it not working. I'd also like to mention that for some reason, external data calls aren't supported from the preview page, so please save your template, and try it again from your home page. If it still doesn't work, I'll be glad to help!

Update: I've made a few more changes, to make it check if it needs to paginate the results. Plus, a ironed out a few bugs.


It's been quite a long while since this hack was updated, even though it's been my most successful one! I'm sorry about that, but I guess it's better to follow the 'If it ain't broke, don't fix it' method. But I can sure as hell improve it! :P So now I present to you a slightly updated version of NSS. The original and first version can be found here! :)

This update was triggered mostly by Avatar's list of ideas for coders to tackle. If you think you have what it takes to tackle the others, check out the post here. Now, on to the hack itself. The only change at the moment is that you can now access results as an AJAX pagination type approach. Your results are preceded by the number of posts being shown, and a link to get the previous or next 10 results. I'll be soon adding a Google AJAX type search for other blogs, or Google services (as demonstrated on Hoctro's blog). I'm not adding that in this update because it'll need some major changes to the implementation, for which I need to come up with a simpler explanation than the one I have at the moment. That update to the hack itself is complete though ;)

The code

You might as well start by removing all the previous code, since all the functions have been updated. This will not confuse you later on! Start by adding this piece of code in your area of the template:

<script language='javascript'>
//<![CDATA[
var blog_name="BLOG'S NAME";
var _num=0, _para, p;

function $()
{
  for( var i = 0, node; i < arguments.length; i++ )
    if( node = document.getElementById( arguments[i] ) )
      return node;
}

/* ```````````` NATIVE SEARCH ``````````````` */
/* <license resource="http://creativecommons.org/licenses/by-nc-sa/2.5/"> */
/* Coded by Aditya Mukherjee (www.aditya-mukherjee.com) */

function d_script(para, num, paged){
_para = para;
_num = num;

var url = (p=='paged') ? "http://xoxotools.ning.com/outlineconvert.php?output=json&classes=item&url=http%3A%2F%2Fblogsearch.blogger.com%2Fblogsearch_feeds%3Fq%3D"+_para+"%2Bblogurl%3A"+blog_name+".blogspot.com%26hl%3Den%26ui%3Dblg%26ie%3Dutf-8%26num%3D10%26output%3Drss%26start%3D"+_num+"&submit=Convert&callback=json" : "http://xoxotools.ning.com/outlineconvert.php?output=json&classes=item&url=http%3A%2F%2Fblogsearch.blogger.com%2Fblogsearch_feeds%3Fq%3D"+_para+"%2Bblogurl%3A"+blog_name+".blogspot.com%26hl%3Den%26ui%3Dblg%26ie%3Dutf-8%26num%3D100%26output%3Drss&submit=Convert&callback=json";

var script = document.createElement('script');
 script.type = 'text/javascript';   
 script.src = url;   
 script.id = "app-script";
 document.getElementsByTagName("head")[0].appendChild(script);
}

function json(rss){

 function paginate(){
    if(_num>=10) {
   $('stext').innerHTML="<div class='search-paginate-links'>Displaying "+(_num+1)+" to "+(_num+10)+". <a id='prev' href='javascript:d_script(\""+_para+"\","+(_num-10)+")'>Previous 10</a> | <a id='next' href='javascript:d_script(\""+_para+"\","+(_num+10)+")'>Next 10</a></div><br />";
   }
  else {
   $('stext').innerHTML="<div class='search-paginate-links'>Displaying "+(_num+1)+" to "+(_num+10)+". <a id='next' href='javascript:d_script(\""+_para+"\","+(_num+10)+")'>Next 10</a></div><br />";
   }
}
 
 function display_search(){  
  $('stext').innerHTML='';
  $('stext').style.display="block";
  $('stextcont').style.display="block";
 }
  
 var i=0;
 var results = [];
 if (!rss.item) {
  alert('No Entries\!');
  }
 else if(typeof(rss.item[1])=='undefined') { 
  results.push(rss.item); display_search(); 
  }
 else {
  results=rss.item; display_search();
  alert(results.length);
   if(results.length>=10){
    paginate();
                p = 'page';
   }
  }
 
 for(i=0;i<10;i++){
  app=document.createElement('a');
   app.href=results[i].link;
   app.innerHTML=results[i].title;
   app.title=results[i].title; 
  dv=document.createElement('div');
   dv.innerHTML=results[i].description;
  sp=document.createElement('br');
  
if(app.innerHTML!='undefined' && dv.innerHTML!='undefined'){
  $('stext').appendChild(app);
  $('stext').appendChild(dv);
  $('stext').appendChild(sp);
  }
else
  $('stext').appendChild(document.createTextNode('No results!'));
  }
}
//]]>
</script>

Just put in the name of your blog in the variable named 'blog_name' right at the top! For example, this blog would have it as 'var blog_name="lastword";'. Update: The links positioning can now be styled by styling the class 'search-paginate-links' :) Make 'em look good! Now, the form itself:

<form action='javascript:var q=document.getElementById("query").value;q=q.replace(/\s/ig,"%252520");d_script(q, 0);'>
     <input id='query' name='as_q' onfocus='clearDefault(this)' type='text' value='Your Query'/> <input class='preview' id='searchbtn' type='submit' value=' Search '/>
<div style='text-align:center'>Powered by <a href='http://lastword.blogspot.com'>Aditya</a></div>
</form>

To display the search, put this bit wherever you want the results to show up:

<div id='stextcont' style='position:relative;display:none'><a href='javascript:$("stext").style.display="none";$("stextcont").style.display="none";void(0);'><img id='close' src='http://images.google.com/images?q=tbn:ReDgICpawihOsM:http://lubeselector.bpmadeniyaglar.com/Images/bpClose_icon.gif' style='position:absolute;top:0px;right:0px'/></a>
<div id='stext'/>

That's it, you're done! :) Simple? Good! Go ahead and give it a whirl. Any comments and/or doubts should be asked and will be answered in the comments. Don't mail me your doubts b'cuz I want everyone to benefit from them, not just you! :)


11 comments

Deepak said...

I have made a hack similar to your ABC Index, but which uses AJAX XMLHttpRequest. And this happens to be the opening hack in my tech blog. ;)
Would appreciate if you commented.

http://blogger-hacked.blogspot.com

Aditya said...

I checked and commented, but forgot to add one thing. You can reduce some of the coding by probably using a JSON(P) call, and work on the data being returned.

The current method is although not that different, but just makes you write more lines of code than needed :) Good job nonetheless!

Deepak said...

If you mean JSON with callback function by JSON(P), I thought of that.
The one disadvantage that it has is that you cannot give multiple http requests simultaneously in that case.
Although there is no current implementation in my blog needing multiple calls, who knows what I may end up doing!

One thing I can think of is reusing the Ajax.Request part for other AJAX functionalities like asynchronous loading of sidebar items.

Singpolyma said...

Where is this in your blog? Alt+Shift+S is search, but that just uses the standard BETA search page...

Aditya said...

True, and I haven't installed it in this blog. I didn't see any reason to, since the BETA native search is pretty good on it's own.

Although, if you want to see it work, you can have a look at http://hackinggrounds.blogspot.com. It's there at the bottom! :)

JAY said...

Hi Aditya,

I have tried this code but it doesn't work.
my blog address is jaywalkeroeuvre.blogspot.com

I shd write jaywalkeroeuvre in the blog name or Jay's oeuvre.

plus i use Beta but i use the same template code i used use in old blogger.

Aditya said...

I have updated the code and instructions. Please try it with the new stuff, and I'm sure it'll work for you.

Also, do not try and use it from the preview page, since it won't work from there. That's a Blogger glitch, not my code :P

And the blog_name variable should contain jaywalkeroeuvre :)

Cyber-Buff said...

sorry I could not get the second part of the code. where should I put it?

Aditya said...

By second part I'm assuming you mean the form and the container part (the two small blocks of code at the end).

The first small block is the form, which users will use to perform the search. This will go wherever you want to show the input box. It can be resized and adjusted via CSS, so it can go in your sidebar, or a floating one like mine.

The second part is where the search results will be displayed. This should practically be close to the input box, but you can put it anywhere you like. It's contents can be styled using the 'div#stext' selector :)

Cyber-Buff said...

well, i tried it with my test blog. please take a look. but it's still not working. I added an HTML widget for the form and then added another HTML widget for the results. But it's still not working...:(

Aditya said...

Ok, I've looked up the codes, and tried adding it as a widget. It looks like Blogger messes up different quote styles, and hence my inline scripts are being messed up.

I'm sorry, but you'll have to add this into your template yourself, as the widget method will not work. I will try and fix this soon.