In this tutorial, you will create a JavaScript application that searches the eBay site for items matching an advanced Shopping API query. The sample application displays the results as a list of links to the item listings on the eBay site. The application uses the eBay Shopping API, which enables developers to interact with the eBay API servers using a simple URL over HTTP.
Think of this tutorial as "Hello World" for eBay's Shopping Web Service. It shows you how easy it is to interact with the Shopping Web Service. When you complete the tutorial, you will have an application that looks like this when it runs:
The example above is actually made up of three search widgets - one to find items in the $0-$50 range, one to find items in the $50 - $200 range, and one to find items in the $201 - $500 range. This tutorial will explain how to create the first widget and then how to modify it to create the widgets with the other sets of results.
Before we begin our step-by-step procedure, let's go over the basics of using the JavaScript SDK. With this SDK, you can design using pre-created javascript classes that correspond to the calls in the eBay Shopping Web Service.
If you look in the /src folder in your JavaScript SDK, you will see these call-specific .js files.
Since each of the Shopping Web Service calls is available as a .js file, you can easily create an application that
incorporates any of these calls, without writing them from scratch. Each call-specific .js file instantiates the
types used by that call.
Within the src/com/ebay/shoppingservice directory, you will see all of the type files used by the
eBay Shopping Web Service (in the form of .js files). You can either store all of the shoppingservice
directory files locally and link to them locally, or link to the Shopping Web Service within your .html file from a
remote location.
Please refer to the JavaScript SDK User Guide for general information about how to use the JavaScript SDK.
After running this tutorial, if you start creating your own search widgets or applications that bring traffic to the eBay web site, you can earn money through the eBay Affiliate Program. For notes about the tutorial and the eBay Affiliate Program, see Notes and Next Steps.
There are seven main steps for this tutorial:
Step 1: Create and setup the .html information
Step 2: Create the JavaScript appliction files
Step 3: Set up the Shopping Web Service calls
Step 4: Add the returned data to an array
Step 5: Add code to display the results
This tutorial was designed to explain the FindItemsAdvanced sample files, located within the /samples directory of your JavaScript SDK, and to help you create your own applications based on these samples. Some of the steps may include a sub-set of the code that is actually in the sample, in order to keep the tutorial concise. Please compare the tutorial to the samples as you proceed.
There are some basic requirements for performing this tutorial:
Use a text editor to create an .html file and then add tags within your .html file that point to the JavaScript files that will be used by your application. We are referring to this file as, "FindItemsAdvancedSample.html" in this tutorial. Note that you can alternately add this information to an existing .html file. Start by creating the DOCTYPE and header information for the file. In the header information, you need to include the URL of the eBay Shopping Web Service. The Shopping.js file includes shopping service interfaces and bootstrap code for the JavaScript object-oriented extension and namespace mechanism. Therefore, it should be loaded first:
<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'> <html xmlns='http://www.w3.org/1999/xhtml'> <head> <title>FindItemsAdvancedSample</title> <script TYPE='text/javascript' SRC='http://w-1.ebay.com/js/2.0/min/Shopping.js'></script> </head>
Within the body tags, include your main .js application file along with any supporting files you plan to use. In the JavaScript SDK, we have part of the UI separated into a different JavaScript file called, 'ItemListUI.js'.
<body> <script TYPE='text/javascript' SRC='ItemListUI.js'></script> <script TYPE="text/javascript" SRC="FindItemsAdvancedSample.js"></script>
Finally, you have to include a statement that designates which classes and calls to use, and where they are located. In this example, we are specifying the goSearch method of the findItemsAdvanced Shopping API call, which is located within the FindItemsAdvanced.js file on the eBay developer web server at:http://w-1.ebay.com/js/2.0/min/
<script TYPE='text/javascript'>
com.ebay.widgets.needs({
baseUrl: 'http://w-1.ebay.com/js/2.0/min/',
files: ['FindItemsAdvanced.js'],
resources: com.ebay.shoppingservice.Shopping.findItemsAdvanced,
callback: function() {
image = 'http://w-1.ebay.com/images/stockimage1.jpg';
FindItemsAdvancedSample.goSearch({g_queryKeyword:"iPod"});
}
});
</script>
<div id="itemContent"></div>
</body>
</html>
Create a JavaScript file that will contain your JavaScript calls, parse the results of those calls, and pass the retreived information to a UI display function. We are referring to this file as, "FindItemsAdvancedSample.js" in this tutorial.
In our sample, all of the steps previous to Step 6 are part of the constructor for the FindItemsAdvancedSample function. In other words, you will call this function in the main application to set your configuration variables. We set up our sample this way so that you will set all of the variables (this.variable) and definition code (methods of the FindItemsAdvancedSample class) before you create the main application. This function will need to store: an array of items returned for each price range (items); an array of item numbers associated with the items returned (itemcount), and the keywords entered.
Let's begin by setting up the properties for the FindItemsAdvancedSample class:
function FindItemsAdvancedSample(config)
{
/**
* storing items for each price range
* @type Array
*/
this.items = new Array(3);
/**
* storing items number for each price range
* @type Array
*/
this.itemcount = new Array(3);
/**
* keyword for query
* @type String
*/
this.queryKeyWords= null;
In addition, this class will store the config parameters such as appId, affiliate tracking information (optional) and siteId in order to run the findItemsAdvanced Shopping API call. The config object is passed in as parameter of the constructor. Add your own appId and other information to the FindItemsAdvancedSample.js file and then you will be able to run the search query by opening the FindItemsAdvancedSample.html file in a browser, as discussed in more details in Step 6.) The errorCount will store the number of errors that occur when connecting or making calls to the eBay Shopping Web Service.
/**
* config object includes appId, affiliate tracking information, etc
* @type Object
*/
this.config = config;
/**
* number of errors
* @type int
*/
this.errorCount = 0;
We also need to set up variables for error handling. The error handling function will be called when a request to the Shopping Web Service fails.
/**
* function for error handling
* @param {ErrorType} error
*/
this.onSomeItemsReturnedFailed = function(error) {
var userDiv = document.getElementById("itemContent");
if(this.errorCount == 0) {
var search = "<div><input id='query' type='text' size='22' maxlength='30'>";
search += "<input onclick='FindItemsAdvancedSample.goSearch();'; type='image' src='http://w-1.ebay.com/images/go.gif'>";
search += "<br></div>";
userDiv.innerHTML = search;
}
var errorHTML = "<div>" + error[0].longMessage + " please try again!</div>";
userDiv.innerHTML = errorHTML + userDiv.innerHTML;
this.errorCount ++;
};
And the constructor includes a variable to keep track of the number of items returned for each price range. The class also sets up the success handling function which will be called when a request to the Shopping Web Service is successful (data is returned). At the end of this function, we call the dispalyItems function.
/**
* callback function for processing returned items
* @param {int} index
*/
this.onSomeItemsReturned = function (index) {
return function (data) {
this.items[index] = this.convertData4ItemListUI(data);
this.itemcount[index] = data.totalItems;
//waiting until items for all 3 price rangs are received.
for (var i = 0; i < 3; i++) {
if (this.items[i] == null) {
return;
}
}
this.displayItems();
};
}
In this step, we will set up a function to get the FindItemsAdvanced request object. This function takes pmax (the upper limit of the price) and pmin (the lower limit of the price) as parameters within the function. we also need to specify item sort code, item type, query keywords, and how many items we want to retrieve. This function returns a FindItemsAdvancedRequestType object.
/**
* getting FindItemsAdvanced requests
* @param {int} pmax, the upper limit of the price
* @param {int} pmin, the lower limit of the price
* @return {FindItemsAdvancedRequestType}
*/
this.getFiaRequest = function (pmax, pmin){
var fiaRequest = new com.ebay.shoppingservice.FindItemsAdvancedRequestType({
priceMax: {currencyID: com.ebay.shoppingservice.CurrencyCodeType.USD, Value: pmax},
priceMin: {currencyID: com.ebay.shoppingservice.CurrencyCodeType.USD, Value: pmin},
itemSort: com.ebay.shoppingservice.SimpleItemSortCodeType.BestMatch,
QueryKeywords: this.queryKeywords,
itemType: com.ebay.shoppingservice.ItemTypeCodeType.FixedPricedItem,
maxEntries: 10
});
return fiaRequest;
};
Before we can connect to the web service, we need to create an instance of the Shopping class (with config parameters so we can access the eBay Shopping Web Service);
var service = new com.ebay.shoppingservice.Shopping(this.config);
Then we get a FindItemsAdvanced request object by calling the getFiaRequest function created above. request1 is for price range $0 - $50.
var request1 = this.getFiaRequest(0,50);
And we construct a ShoppingCallback object, in the parameter, we specify that if the call is successful, then onSomeItemsReturned function should be called, if the call is failed, then onSomeItemsReturnedFailed function should be called. callback1 is also for price range $0 - $50.
var callback1 = new com.ebay.shoppingservice.ShoppingCallback({object: this,
success:this.onSomeItemsReturned(0), failure:this.onSomeItemsReturnedFailed});
Lastly, we call the findItemsAdvanced method of the service object with request1 and callback1 as parameters. The service object will connect to the eBay Shopping Web Service and will callback onSomeItemsReturened or onSomeItemsReturnedFailed, depending on whether the call was successful or whether it failed.
var url = service.findItemsAdvanced(request1,callback1);
Now, let's put all of these sections together into a findItems function. Since we need items in three price ranges, we will repeat the code we created (in the sections above) three times in this function. findItems is the public interface of the FindItemsAdvancedSample class.
/**
* call findItemsAdvanced shopping api 3 times for each price range
* @param {String} queryKeywords
*/
this.findItems = function(queryKeywords) {
this.queryKeywords = queryKeywords;
var service = new com.ebay.shoppingservice.Shopping(this.config);
var request1 = this.getFiaRequest(0,50);
var callback1 = new com.ebay.shoppingservice.ShoppingCallback({object: this, success:this.onSomeItemsReturned(0), failure:this.onSomeItemsReturnedFailed});
var url = service.findItemsAdvanced(request1,callback1);
var request2 = this.getFiaRequest(51,200);
var callback2 = new com.ebay.shoppingservice.ShoppingCallback({object: this, success:this.onSomeItemsReturned(1), failure:this.onSomeItemsReturnedFailed});
url = service.findItemsAdvanced(request2,callback2);
var request3 = this.getFiaRequest(201,500);
var callback3 = new com.ebay.shoppingservice.ShoppingCallback({object: this, success:this.onSomeItemsReturned(2), failure:this.onSomeItemsReturnedFailed});
url = service.findItemsAdvanced(request3,callback3);
};
In this step, we will create a converData4ItemListUI function that saves any data returned (that is not null) to an array. We also filter out data that does not satisfy our requirements. The returned items array will be displayed in the ItemListUI component.
/**
* convert returned items into format suitable for display in UI
* @param {FindItemsAdvancedResponseType} data
* @return {Array}, converted items
*/
this.convertData4ItemListUI = function(data) {
if (data.searchResult !== null) {
var itemArray = data.searchResult[0].itemArray;
}
var items = [];
if (itemArray) {
var count = itemArray.item.length ;
var i = 0;
while (items.length < 3 && i < count) {
if (!itemArray.item[i].buyItNowAvailable
&& itemArray.item[i].listingType.value == com.ebay.shoppingservice.ListingTypeCodeType.Chinese.value) {
continue;
}
var item = itemArray.item[i];
items.push(item);
i++;
}
}
return items;
};
Your display code needs to take the data returned by the FindItemsAdvanced call and send it to the UI calls. We will discuss briefly how these UI calls relate to the finished product that you see. The JavaScript SDK contains some of these UI files as examples, but the JavaScript SDK is actually the libraries and methods we provide - we assume that you will use JavaScript to implement your own UI designs.
Still working within the FindItemsAdvancedSample class, we create a displayItems function that sets the layout and style for the UI structure that we want to see in the end result. Within this function, we instantiate an ItemListUI object and call the display method of that object.
/**
* construct HTML and display items.
*/
this.displayItems = function() {
var priceRanges = ["$0-$50","$51-$200","$201-$500"];
var userDiv = document.getElementById("itemContent");
var newLine = "\n";
var src = "<div id='products' style='float: left;width: 600px; padding: 10px 0;font-family: Arial, sans-serif; font-size: small; border: 2px solid #D9E0E6; background: #e0e040'>" + newLine;
src = src + "<table width='100%' cellspacing='0' cellpadding='0' border='0'>" + newLine;
src = src + "<tr><td colspan='2' style='font-size: 150%; padding: 4px; font-weight:bold;'>Search Results for \"" + this.queryKeywords + "\"<br></td></tr>" + newLine;
for (var i= 0; i< 3; i++) {
src = src + "<tr><td colspan='2' style='font-size: 150%; padding: 4px;'>" + priceRanges[i] + " (" + this.itemcount[i] + " items found):</td></tr>" + newLine;
src = src + "<tr><td colspan='2'>" + newLine;
src = src + (new ItemListUI(this.items[i], false).display());
src = src + "</td></tr>" + newLine;
//src = src + "<tr><td colspan='2'><br></td></tr>" + newLine;
}
src = src + "<tr><td colspan='2'>" + newLine;
src = src + "<table width='100%' cellspacing='0' cellpadding='0' border='0'>" + newLine;
src = src + "<tr><td style='padding: 0 4px 0 0;' bgcolor='#e0e040' align='right' valign='bottom'>" + newLine;
src = src + "<input id='query' type='text' size='22' maxlength='30'><input onclick='FindItemsAdvancedSample.goSearch();'; type='image' src='http://w-1.ebay.com/images/go.gif'>" + newLine;
src = src + "</td>" + newLine;
src = src + "</table>" + newLine;
src = src + "</td>" + newLine;
src = src + "</tr>" + newLine;
src = src + "</table>" + newLine;
src = src + "</div>" + newLine;
userDiv.innerHTML = src;
};
The next four sections are from the ItemListUI.js file. As mentioned previously, this is one of two UI files that have been included in the JavaScript SDK so that you can run your samples successfully (after you enter your appID in the config information). This section will give you a brief tour of what's going on within the ListUI.js file. This section has it's own constructor where you create local variables to store item listing data. The code snippet below shows the properties section of the ItemListUI component.
/**
* @class ItemListUI UI component to display items
* @constructor
* @param {Array} items array of com.ebay.shoppingservice.SimpleItemType
* @param {Boolean} if show bid column
*/
function ItemListUI(items, showBid)
{
/**
* items
* @type Array
*/
this.items = items;
/**
* if show bid column
* @type Boolean
*/
this.showBid = showBid;
/**
* new line char
* @type String
*/
this.newLine = "\n";
/**
* colums width
* @type Array
*/
this.width = null;
/**
* colums titles
* @type Array
*/
this.titles = null;
if (showBid) {
this.titles = ["","Item Title","Condition", "Bids", "Price", "Shipping", "Time left"];
this.width = [10, 45, 5, 5, 10, 10, 15];
} else {
this.titles = ["","Item Title","Condition", "Price", "Shipping", "Time Left"];
this.width = [10,50,5,10,10,15];
}
This section uses the local variables from the section above to set up the item data for the UI. The code snippet below shows the display method of the ItemListUI component.
/**
* constructing HTML
* @return {String} constructed HTML
*/
this.display = function() {
var str = "<table style='padding: 3px 3px 3px 3px; background: #efefff;' width='100%' cellspacing='0' cellpadding='1' >" + this.newLine;
if (this.titles) {
str = str + "<tr style='background: #ccc; font-family: Calibri; font-weight:bold;'> " + this.newLine;
if ( com.ebay.widgets.typeOf(this.titles) == 'array') {
for (var i = 0; i< this.titles.length; ++i ) {
str = str + "<td width='" +this.width[i] + "%' >" + this.titles[i] + "</td>" + this.newLine;
}
} else {
str = str + "<td>" + this.titles + "</td>" + this.newLine;
}
str = str + "</tr>" + this.newLine;
}
if (this.items) {
if ( com.ebay.widgets.typeOf(this.items) == 'array') {
for (i = 0; i< this.items.length; ++i ) {
str = str + "<tr height='65' onmouseover='changeColor(this)' onmouseout='returnColor(this)'> " + this.newLine;
var item = this.items[i];
if (this.items[i].galleryURL) {
str = str + "<td><img style='margin: 0 6px 0 6px' height='50' width='50' src='" + this.items[i].galleryURL + "' " + "</td>" + this.newLine;
} else {
str = str + "<td><img style='margin: 0 6px 0 6px' height='50' width='50' src='" + image + "' " + "</td>" + this.newLine;
}
str = str + "<td><a href='" + this.items[i].viewItemURLForNaturalSearch + "'>"
+ this.items[i].title + "</a>" + "</td>" + this.newLine; // title
if (this.items[i].halfItemCondition) {
str = str + "<td>" + this.items[i].halfItemCondition.value + "</td>" + this.newLine; // condition
} else {
str = str + "<td>" + "</td>" + this.newLine;;
}
if (this.showBid) {
if (this.items[i].bidCount) {
str = str + "<td>" + this.items[i].bidCount + "</td>" + this.newLine;
} else {
str = str + "<td>" + "-" + "</td>" + this.newLine;
}
}
str = str + "<td style='font-weight:bold;'>" + "$" + this.items[i].convertedCurrentPrice.value.toFixed(2) + "</td>" + this.newLine;
if (this.items[i].shippingCostSummary.shippingServiceCost) {
str = str + "<td style='font-weight:bold;'>" + "$" + this.items[i].shippingCostSummary.shippingServiceCost.value.toFixed(2) + "</td>" + this.newLine;
} else {
str = str + "<td style='font-weight:bold;'>" + "Not Specified" + "</td>" + this.newLine;
}
str = str + "<td style='font-weight:bold; color:red;' >" + this.items[i].timeLeft + "</td>" + this.newLine;
str = str + "</tr>" + this.newLine;
str = str + "<tr><td colspan='" + this.titles.length + "' style='border-bottom: 2px solid #FFFFFF;'></td></tr>" + this.newLine;
}
}
}
str = str + "</table> " + this.newLine;
return str;
};
}
The two functions below are used internally by the display function to change the background color of the display when the mouse moves over it.
function changeColor(e) {
e.style.background = "#e0e040";
};
function returnColor(e) {
e.style.background = "#efefff";
}
Now we are ready to create the main function for our JavaScript program. First we will create a search function (called goSearch) for the FindItemsAdvancedSample class. This will be a static function which can be called from FindItemsAdvancedSample directly. The goSearch function can accept one of three types of keyword parameters. First, we check whether the query keyword has been passed in from an input box or as a query string. If not, we set the default query keyword to 'iPod'.
/**
* main static entry function for search
* @param {Object} params
*/
FindItemsAdvancedSample.goSearch = function(params) {
queryKeyword = null;
var query = document.getElementById('query');
if (query) {
queryKeyword = query.value;
}
if (queryKeyword === null && params) {
queryKeyword = params.g_queryKeyword;
}
if (queryKeyword === null) {
queryKeyword = "iPod";
}
Then you need to add your application ID and site ID (mandatory input), plus any other information that you want to include in your search (optional input).
If you don't already have an eBay Application ID, you can get one here.
var props = {};
/*
* Place your appId here
* props["appId"] = ;
* Place your affiliate information
* props["trackingId"] = ;
* props["trackingPartnerCode"] = ;
* props["affiliateUserId"] = ;
* Place site id, default is 0 if you don't set
* props["siteId"] = ;
*/
Create a new instance of the JavaScript SDK ShoppingConfig class that takes the IDs you just added as input. Save the results to the config variable.
var config = new com.ebay.shoppingservice.ShoppingConfig(props);
Create a new instance of the FindItemsAdvancedSample class that takes the config object as an input parameter, and calls the findItems function with the queryKeyword input upon creation.
new FindItemsAdvancedSample(config).findItems(queryKeyword);
};
Now let's look at the FindItemsAdvancedSample.html file again. You should be able to see that the main application we just created (and added parameters to) gets called after connecting to the eBay Shopping Web Service and pulling in the UI inforamtion:
<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'>
<html xmlns='http://www.w3.org/1999/xhtml'>
<head>
<title>FindItemsAdvancedSample</title>
<script TYPE='text/javascript' SRC='http://w-1.ebay.com/js/2.0/min/Shopping.js'></script>
</head>
<body>
<script TYPE='text/javascript' SRC='ItemListUI.js'></script>
<script TYPE="text/javascript" SRC="FindItemsAdvancedSample.js"></script>
<script TYPE='text/javascript'>
com.ebay.widgets.needs({
baseUrl: 'http://w-1.ebay.com/js/2.0/min/',
files: ['FindItemsAdvanced.js'],
resources: com.ebay.shoppingservice.Shopping.findItemsAdvanced,
callback: function() {
image = 'http://w-1.ebay.com/images/stockimage1.jpg';
FindItemsAdvancedSample.goSearch({g_queryKeyword:"iPod"});
}
});
</script>
<div id="itemContent"></div>
</body>
</html>
Before running the application, remember to replace the appid placeholder in FindItemsAdvancedSample.js with your own application ID. In order to do this, you need to either uncomment the appID piece of the var props section of the sample (shown in Step 6), or add a line below that section such as:
props["appId"] = "myebayappid";
To run the application, open the FindItemsAdvancedSample.html file in a browser window. This will activate the .js scripts that you
have tagged within the .html and cause the application to search the eBay Shopping Web Service and display the result. Note that
the default keyword for these samples is set to "ipod" in the FindItemsAdvancedSample.html file, but you can add a different keyword
within the file or type a new keyword into the field in the lower right corner and click the Go button once the interface
is live. This will allow you to search for other eBay items from your browser, using the same search widget.
Congratulations! You now have a working application that uses eBay Shopping Web Services.
This section contains observations about the tutorial and offers some alternate ways to achieve similar or better results. We've also provided some suggestions about where you can go from here.
Now that you've completed the Tutorial for the FindItemsAdvanced call, you may want to proceed to a more complex tutorial. The GetUserProfile tutorial uses both the FindItemsAvanced call and the GetUserProfile call to create an application that returns both item data and user data.
The eBay Affiliate Program allows you to earn money by driving traffic to the eBay site using applications or widgets you create and post on your own web page. You can think of this as a way to enhance your existing business or create a new enterprise. With just a little effort, you can earn a lot of money.
Now that you have a working search application, you can earn money with the eBay Affiliate Program! Join the affiliate program now!
Once you have joined the eBay Affiliate Program, sign up for the Affiliate API Tier of the eBay Developers Program, then check the Knowledge Base to see how to generate View Item links with Affiliate Tracking from the REST API.
As noted at the beginning of the tutorial, we tried to keep things simple. The eBay community codebase contains many excellent samples that are more complex and many give you good ideas for ways to design your applications.
The sample provided with this tutorial was built and tested on a Windows 2003 Server platform using JS for Win32 and Microsoft IIS 5.0.
For the tutorial, we took a minimalist approach to input parameters. The FindItemsAdvanced call is very powerful. It supports numerous input parameters. Visit the JavaScript Developer Center for links to documentation and additional information.
The JSON form of the call made by this application looks like the following:
http://open.api.ebay.com/shopping?callname=FindItemsAdvanced&responseencoding=JSON&appid=YourAppIDHere&siteid=0&version=539&QueryKeywords=ipod%20original&MaxEntries=3
If you replace <YourAppId> and <YourUserId> with your
App ID and eBay user ID, you can paste this URL into your browser to receive the JSON response
for the GetUserProfile call.
If you're interested in learning more about building applications using JavaScript with the eBay Shopping Web Service, see Getting Started with Search: Specifying JSON Results in a Shopping API GET Request.
Here's a list of resources for the topics and technologies discussed in this tutorial:
In order to leave a comment in this section, you must view this Tutorial via the eBay web site: online version.
© 2007-2008 eBay Inc. All rights reserved.
eBay and the
eBay logo are registered trademarks of eBay Inc.
All other brands are the
property of their respective owners.