So after releasing an updated version of my CFYahoo project at lunch, I thought I'd whip up a super quick demo that made use of it. While researching some of the API changes last night, I came across YahooBattle!. With a name like that, how could I not click? The idea is simple - provide two search terms and it tells you which term has the most results. I decided to quickly whip up an example that would allow you to compare multiple keywords.

I began with just a form:

<form> <input type="button" id="reportBtn" value="Display Report"><br/> Keywords:<br/> <div id="keywordgutter"> <input type="text" name="keyword"><br/> <input type="text" name="keyword"><br/> </div> <input type="button" id="addBtn" value="+" title="Add Keyword"> </form>

I've got 2 keyword fields, a "add" button at the bottom, and I put my Display Report button top. Now for the jQuery:

$(document).ready(function() {

//add a new keyword when you hit + $("#addBtn").click(function() { var s = '<span><input type="text" name="keyword"><input type="button" value="-" name="remove" title="Remove Keyword"><br></span>' $("#keywordgutter").append(s) })

//support removing new keywords only $("input[name='remove']").live("click",function() { $(this).parent().remove() })

//display report $("#reportBtn").click(function() { var keywords = [] $("input[name='keyword']").each(function() { var value = $.trim($(this).val()) if(value != '') keywords[keywords.length] = $(this).val() }) if(keywords.length > 0) { $("#report").html("<i>Checking your keywords - please stand by...</i>") $("#report").load('report.cfm',{keywords:keywords}) } }) })

There are 3 main functions here. The first adds support for adding keyword fields. I do this with a simple bit of HTML that gets appended to my form. Notice the span around the field. That will come back later.

The second function handles removing data. Now because I'm adding stuff on the fly, I have to use the jQuery live function. This is a way to handle items that don't exist in the DOM at the time of script execution. Since the new keyword fields are being added dynamically, I can use the live method to kind of 'monitor' them as they get added. Now to actually remove the keyword, I just have to bind to the button I added, and then just grab the parent. Remember how I wrapped the keyword field and the minus button with a span? That's the parent. So I can just do .parent().remove(). God I hate jQuery for being so simple.

The next function handles loading the report. I gather up all the form fields using the name keyword. For each, I do a quick trim and then add it to an array. If we actually have values, I pass them all to ColdFusion to handle generating the report.

So the actual ColdFusion code is almost as simple.

<cfparam name="form.keywords" default="">

<cfif form.keywords is ""> <p> No keywords were sent to the report. </p> <cfabort> </cfif>

<cfset searchAPI = createObject("component", "")>

<cfset scores = {}> <cfset total = 0>

<cfloop index="word" list="#form.keywords#"> <cfinvoke component="#searchAPI#" method="search" returnVariable="result"> <cfinvokeargument name="query" value="#word#"> <!--- we ask just for one because all we care about is the total ---> <cfinvokeargument name="results" value="1"> </cfinvoke> <cfset scores[word] = result.totalavailable> <cfset total+=result.totalavailable> </cfloop>

<style> h2 { font-family:Arial; } </style>

<h2>Number of Yahoo Results per Keyword</h2> <cfchart format="flash" chartheight="400" chartwidth="400"> <cfchartseries type="pie"> <cfloop item="word" collection="#scores#"> <cfchartdata item="#word#" value="#scores[word]#"> </cfloop> </cfchartseries> </cfchart>

As you can see, I loop over the keywords and for each I ran a query against Yahoo. All I need are the totals so I tell the API to return only one result. I don't actually even care what it is - I just grab the total.

Lastly, I take the data and simply pass it over to a pie chart.

Have you ever wondered how "megamouth shark", "cylon", and "mustache trimmer" would compare? Now you know:

You can test this yourself here: