Tuesday, November 10, 2009

Use SearchControl and SearchForm of Google Search Ajax API

When using the Google Search Ajax API, we may sometimes what to add functions when user initiate a search or clear the search result. the SearchForm is designed to do this. It provides .setOnSubmitCallback(object, method) and .setOnClearCallback(object, method) to let developer define method to call when user search or clear search result. But can we use the SearchControl, which provides easy-to-use and nice wrapped searcher, along with the SearchForm? The answer is yes. Here is the example code of using them together.
function OnLoad() {
var searchControl = new google.search.SearchControl();
searchControl.addSearcher(new google.search.WebSearch());
searchControl.addSearcher(new google.search.ImageSearch());

var drawOptions = new google.search.DrawOptions();
drawOptions.setDrawMode(google.search.SearchControl.DRAW_MODE_TABBED);
drawOptions.setSearchFormRoot(document.getElementById
("searchcontrol"));
searchControl.draw(document.getElementById("containerResults"), drawOptions);

var searchForm = new google.search.SearchForm(true, document
.getElementById('searchcontrol'));
searchForm.setOnSubmitCallback(searchControl, function() {
this.execute(searchForm.input.value);
});
searchForm.setOnClearCallback(searchControl, function() {
searchForm.input.value = '';
searchControl.clearAllResults();
});
searchForm.execute(QueryString);
}
google.setOnLoadCallback(OnLoad);

The HTML code is

< id="searchcontrol">
< id="containerResults">

The point to collect this two part together is drawOptions.setSearchFormRoot(document.getElementById("searchcontrol"));, which tells the SearchControl where to look for the associated SearchForm. Another thing to notice is that, in the SearchForm.SetOnCallBack, the execute() method to call should be the one of the SearchForm, like this.execute(searchForm.input.value);, not the one of the SearchControl (searchControl.execute(searchForm.input.value);), otherwise, the method set to OnClearCallBack will not be called when user clear search result.

Things to notice when testing form on Wicket

Wicket, a Java-based web application framework, provides powerful tester to test the application. The tester can simulate activities of users on the web application. The form tester is a component of the tester, which use to test form behavior on the page. However, there are something one need to notice when using the form tester.

Let's look at this example.
We test a form in the Checkout page, which looks like this

























Name
Street
Zip code
City
State





The test code is
FormTester formTester = tester.newFormTester("form");
formTester.setValue("name", "Philip");
formTester.setValue("street", "Main Street");
formTester.setValue("zipcode", "96822");
formTester.setValue("city", "Anchorage");
formTester.setValue("state-wmc:state", "Alaska");
formTester.submit();
tester.assertRenderedPage(Index.class);

But when run the test, the last assertion indicate that it still in the Checkout page. Did you find anything wrong? The problem lies in
formTester.setValue("state-wmc:state", "Alaska");

And the fix is

formTester.select("state-wmc:state", 1);


The reason is that, FormTester.setValue() method cannot be used to set the value of selection field, thus the "state-wmc:state" field is not filled, so when the form is submitted, an error of invalid value occurs. This is an usual mistake when using FormTester.

Additionally, in order to find out what goes wrong when the test fail, we can use the Tester.assertErrorMessages(String[]) to see the error message.