Instant search seems to be all the rage lately. So I decided I would give one a go on my site.
While I found a few methods with PHP, I couldnt seem to find one with Coldfusion, so I decided it was time to turn a PHP method and show how much easier it is to do with Coldfusion
You can download the example from here. Just a warning, that on this server, the demo is pretty slow. This script isnt that efficient, but its more the fact that cheap, shared hosting = #fail. I would recommend trying it on your local system.
Kudos needs to be given to two people:
- Luiz Eduardo for his PHP version which i used a base model
- Ben Nadel for his method of turning the JSON into an array of structs.
The code is included below:
HTML FILE (instant-search.cfm):
This just includes the basic form and the inclusion, including the JS file and the all important jQuery
. You will need to change the styles in here to suit how you wish the results and content to be displayed.
<html>
<head>
<title>Instant Search</title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script type="text/javascript" src="instant.js"></script><style>
form{
margin:15px;
padding:5px;
border-bottom:1px solid #ddd;
}
form input[type=submit]{display:none;}
div#results{
padding:10px 0px 0px 15px;
text-align: left;
}
div#results div.result{
padding:10px 0px;
margin:10px 0px 10px;
}
div#results div.result a.readMore{color:green;}
div#results div.result h2{
font-size:19px;
margin:0px 0px 5px;
padding:0px;
color:#1111CC;
font-weight:normal;
}
div#results div.result h2 a{
text-decoration:none;
border-bottom:1px solid #1111cc;
}
div#results div.result p{
margin:0;
padding:0;
}
span.highlight{
background:#FCFFA3;
padding:3px;
font-weight:bold;
}
#q {
width: 60%;
height: 30px;
}
body {
text-align: center;
}
</style>
</head>
<body>
<h3>CF Instant Search</h3>
<form method="get" action="">
<input type="text" id="q" name="q" />
<input type="submit" value="Search" />
</form>
<div id="results"></div>
</body>
</html>
JAVASCRIPT (instant.js):
$(document).ready(function(){
var runningRequest = false;
var request;
$('input#q').keyup(function(e){
e.preventDefault();
var $q = $(this);
if($q.val() == ''){
$('div#results').html('');
return false;
}
//Abort opened requests to speed it up
if(runningRequest){
request.abort();
}
runningRequest=true;
// THis needs to be changed to the location of the search.cfm file
request = $.getJSON("search.cfm",{
q:$q.val()
},function(data){
showResults(data,$q.val());
runningRequest=false;
});
function showResults(data, highlight){
var resultHtml = '';
$.each(data, function(i,item){
resultHtml+='<div>';
resultHtml+='<h2><a href="#">'+item.title+'</a></h2>';
resultHtml+='<p>'+item.content.replace(highlight, '<span>'+highlight+'</span>')+'</p>';
resultHtml+='<a href="#">Read more..</a>'
resultHtml+='</div>';
});
$('div#results').html(resultHtml);
}
$('form').submit(function(e){
e.preventDefault();
});
});
});
SEARCH FILE (search.cfm):
I enabled cfoutputonly, for the simple fact so you can see the jSON results in firebug, rather than having to scroll a country mile. This is using a copy of the cfbookclub default database in MySQL, rather than in the default datastore when you install coldfusion. But i dont think you would need to change much here.
<cfsetting enablecfoutputonly="true"></cfsetting>
<cfif url.q neq ''>
<cfset theQ = lcase(q)>
<cfset application.dsn = "cfbookclub">
<cfquery datasource="#application.dsn#" name="qry" maxrows="20">
select title, BOOKDESCRIPTION as content
from books
where
lower(title) like '%#theQ#%'
or
lower(BOOKDESCRIPTION) like '%#theQ#%'
</cfquery>
<cfset rows = [] />
<!--- Loop over the query to convert it. --->
<cfloop query="qry">
<cfset row = {} />
<!--- Add each column to our struct. --->
<cfloop index="column" list="#qry.columnList#" delimiters=",">
<cfset row[ lcase(column) ] = qry[ lcase(column) ][ qry.currentRow ] />
</cfloop>
<cfset arrayAppend( rows, row ) />
</cfloop>
<!---
Now that we have converted our query to an
array of structs, we can serialize it using the
serializeJSON() method.
--->
<cfset serializedQuery = serializeJSON( rows ) />
<cfoutput>#serializedQuery#</cfoutput>
</cfif>
#1 by Ben Nadel on November 5, 2010 - 11:47 pm
The demo works really well. Nice job.
#2 by Richard on November 7, 2010 - 11:46 am
Thanks Ben
#3 by tss on January 31, 2011 - 12:53 am
Is this example applicable to be used with SearchBlox for having instant search on our websites?
#4 by Richard Brasier on January 31, 2011 - 10:47 am
I dont see why not. I have not used SearchBlox before, but as long as you can query it and return a datastructure in Coldfusion you will be able to modify the code to be able to use it.
All it does essentially for the data side is take a query structure and return JSON
#5 by jez on February 3, 2011 - 7:57 pm
Hi! Just want to ask, why is there a Submit button in the code, but there’s none on your demo?
I tried to run your code. I’m running instant-search.cfm, but it does not perform the query. maybe i’ve done it in the wrong way. is there anything i should have done first?
thanks.
#6 by Richard Brasier on February 4, 2011 - 10:43 am
Hi Jez,
The demo does have a submit button in the code, it is just set to display: none.
You shouldnt need to do anything first. Are you getting any errors when trying to do a search? Check in the response tab in Firebug, or you can go to: search.cfm?q=test (on the demo its http://www.rbrasier.com/examples/2010/Nov/cf-instant/search.cfm?q=test ) and see if there are any errors being thrown
#7 by jez on February 4, 2011 - 12:33 pm
Hi Richard!
Thanks for the response. Actually, I’m new to COldfusion, so I apologize if my questions sound a bit stupid. =)
I’ve copied and pasted your code and did some changes, like the query, its datasource and script in SQL Server.
When I run the code (instant-search.cfm), I only get the textbox and button. When I look at the Debugging Info, I don’t see the query being done. Did I miss something?
What I want to do is to see the search results as I type in the textbox, just like in Google Instant Search.
Thank you.
Jez
#8 by Richard Brasier on February 4, 2011 - 1:25 pm
No worries Jez,
Just try and retrace your steps. Try and getting it working with the data that is in there – the database that is used is installed by default with coldfusion, so you shouldnt need to do anything in order to get it working. If you like you can start afresh with the zip file (http://www.rbrasier.com/examples/2010/Nov/cf-instant/cf-instant.zip)
If you cant get it working from the zip let me know. Have a look at the search.cfm?q=test to see if any errors are thrown.
Once you have it working with this, then move on to customizing it to work with your SQLServer database.
#9 by jez on February 4, 2011 - 5:29 pm
It’s me again!
I tried your original code and I can’t make it work. I’ve created an index.cfm that includes instant-search.cfm. There’s no error when I run it, but the only thing I get is the textbox and the submit button. Nothing happens when I enter something in the textbox.
I also tried search.cfm?q=test but I get an error saying there’s an invalid CFML construct found on line 21:
What shall I do with this? Thanks again.
#10 by jez on February 4, 2011 - 5:44 pm
The line that has an error is this:
It is in line 17 in search.cfm at the code above.
Thanks.
#11 by Richard Brasier on February 7, 2011 - 10:03 am
Jez,
I’ll email you directly tonight about your issue.
Cheers
Richard
#12 by jez on February 9, 2011 - 5:57 pm
Hi! Thanks, I’ll wait for it.
Actually, I’ve done a little progress. I can now query with my table, convert it to array of structs, and serialize it. However, I can’t loop through the json structure properly and make them appear in the results div.
Example, I get this: [{"lastname":"a"}, {"lastname":"b"}]. I’ve been trying to use $.each but to no avail.
I can show you my code through the email.
Many thanks.
#13 by Gali on February 22, 2011 - 9:59 am
Hello! Brasier
How to add pagination for the search results ? Great tuts.
(PHP) jijijijijijiji
regards!
#14 by Fleta on June 30, 2011 - 12:16 am
Geez, that’s unbielaevble. Kudos and such.
#15 by Jerry on October 19, 2011 - 9:41 am
I am trying to get your demo working and everything seems to be working correctly except that the results are not returning in the results div. In line #25 instant.js, I don’t see how you get the data in the function. This object continues to be null. Any idea, what I am doing incorrectly. Thanks.
#16 by Richard on November 12, 2011 - 5:10 pm
Hi Jerry,
On line 25, to understand how the data gets thrown into this function, is to understand how jQuery works.
To understand this i would recommend having a look at this page (hopefully it will be able to explain it better than I can)
http://api.jquery.com/jQuery.getJSON/
Have firebug open when you open the page and it will make a little more sense.
Once a key is pressed, data is submitted to this javascript and the search.cfm is called.
Sorry if this isnt making more sense, but to get a better understanding of it all, i would really recommend getting know more about jQuery
#17 by Gordo on April 6, 2012 - 1:07 am
Hi, thanks for the demo. I copied the files, modified to fit my database and tested… it seems to work, the request is fired, I get a response back in firebug, but it does not display in the area…
Any thoughts?