« The AJAX Effect | Main | New Zend Framework with JSON Support »

Explore Amazon Web Services with AJAX - Price Filter - Day 4

Day 4 to Explore Amazon Web Services with AJAX, I tryed today to introduce something from the Yahoo! UI which is the Slider widget. The idea is to add the slider component so you can filter search result based on price, for example I start searching for "AJAX", then set my budget to $20 or $30. Playing with the slider widget is fun and very easy to use, but we'll see later the problems with such solution.

http://ajax.phpmagazine.net/upload/2006/03/ajax-price-filter-thumb.png

Looking at the PHP script, we are still using ItemSearch remote method, but this time by setting Keywords and MaximumPrice. I have kept in this demo SearchIndex fixed for Books , but you can make it dynamic too. In our slider prices will be in dollar, so in the PHP script I just multiplied the price by 100 before making request. The other part of the script are the same as the previous demos :


<?php

/**
* AWS 4.0 with AJAX demos using nusoap and prototype
* Demo 4 - Price filter
*
* Author Hatem Ben Yacoub <hatem@php.net>
* http://ajax.phpmagazine.net/
*/

// include nusoap classes

require_once("lib/nusoap.php");
require_once(
"lib/class.wsdlcache.php");

//------------------------------------------------//
//
//    Enter your AWS subscription key here
//
//------------------------------------------------//

$SubscriptionId = '';

//------------------------------------------------//

$AmazonUS = 'http://webservices.amazon.com/AWSECommerceService/AWSECommerceService.wsdl';

function
GetPriceSearchParams($Keywords,$Price) {
    global
$SubscriptionId;

    
$Price = $Price*100;
    
    
$request = array(
        
"Keywords" => $Keywords,//"AJAX",
        
"MaximumPrice" => $Price,
        
"SearchIndex" => "Books",
        
"ResponseGroup" => "Medium"
    
);

    
$itemSearch = array(
        
'SubscriptionId' => $SubscriptionId,
        
'AssociateTag' => 'phpmagazine-20',
        
'Request' => $request
    
);

    return
$itemSearch;
}


// Setting the WSDL
$wsdlurl = $AmazonUS;

// Try getting data from cache
$cache = new wsdlcache('cache', 120);
$wsdl = $cache->get($wsdlurl);
if (
is_null($wsdl)) {
    
$wsdl = new wsdl($wsdlurl);
    
$cache->put($wsdl);
} else {
    
$wsdl->debug_str = '';
    
$wsdl->debug('Retrieved from cache');
}

$client = new soapclient($wsdl,true);
$client->soap_defencoding = 'UTF-8';

$result = $client->call('ItemSearch', array('body' => GetPriceSearchParams($_GET['Keywords'],$_GET['Price'])));

if (
is_Array($result['Items']['Item'])) {    

    
$display = '';
    foreach(
$result['Items']['Item'] as $item) {
        
        
$author = (is_array($item['ItemAttributes']['Author']))?@implode(', ',$item['ItemAttributes']['Author']):$item['ItemAttributes']['Author'];
        
        
$display .= "<div class=item>
        <h2><a href=\""
.$item['DetailPageURL']."\">".$item['ItemAttributes']['Title']."</a></h2>
        <a href=\""
.$item['DetailPageURL']."\"><img src=\"".$item['SmallImage']['URL']."\" width=\"".$item['SmallImage']['Width']['!']."\" height=\"".$item['SmallImage']['Height']['!']."\" align=\"right\" border=0></a>
        <ul>
            <li><strong>ISBN :</strong> "
.$item['ItemAttributes']['ISBN']."  </li>
            <li><strong>Author(s) :</strong> "
.$author."</li>
            <li><strong>Publisher :</strong> "
.$item['ItemAttributes']['Publisher']."</li>
            <li><strong>Price: </strong> <font color=red style='text-decoration: line-through;'>"
.$item['ItemAttributes']['ListPrice']['FormattedPrice']."</stroke></font> <font size=+2>".$item['OfferSummary']['LowestNewPrice']['FormattedPrice']."</font>
            <a href=\"#\" onclick=\"compareprice('"
.$item['ASIN']."')\"><strong>Compare Prices </strong></a> <img alt=\"Spinner\" id=\"price_spinner_".$item['ASIN']."\" src=\"spinner.gif\" style=\"display:none;\" /></li>
        </ul>
        <div id=\""
.$item['ASIN']."\"></div>
        </div><br/>\n"
;

    }
    
} else {

    
$display = "<div class=item><font color=red>No result available for <strong>".$_GET['Keywords']."</strong></font></div>";
    
}

echo
$display;
exit;



?>


In the javascript I have used the Horizental slider demo available in the Yahoo! UI library, I just change it to make it slide from 0 to 200 and onchange make an AJAX request to refresh list with the new price. I have set the limit at $200, because I'm lazy to make it dynamic, but it's possible to make a remote call to AWS and sort results by price to get the maximum value.

This have been said, I found myself including all the Yahoo! UI libraries available in the demo code : 9 files and 54KB in total, in addition to prototype and script.aculo.us. And this is what Rasmus was talking about recently about using a code that you don't know, except that he work with Yahoo! and have more time to see what is it about.


[...]

    function livesearch(){
        var valueNow = slider1.getValue();
        if (valueNow>0 && valueNow<200){
            return PriceSearch($F('Keywords'),valueNow);
        }
          var url = 'demo1.php';
        var pars = 'Keywords='+escape($F('Keywords'));
        var target = 'result';
        
        var myAjax = new Ajax.Updater(
            target,
            url,
            {
                method: 'get',
                parameters: pars,
                onComplete:function(request){Element.hide('search_spinner')},
                onLoading:function(request){Element.show('search_spinner')},
                onFailure: reportError
            });
    }
    
    function PriceSearch(Keywords,Price){
          var url = 'demo4.php';
        var pars = 'Keywords='+escape(Keywords)+'&Price='+Price+'&operation=PriceSearch';
        var target = 'result';
        
        var myAjax = new Ajax.Updater(
            target,
            url,
            {
                method: 'get',
                parameters: pars,
                onComplete:function(request){Element.hide('search_spinner')},
                onLoading:function(request){Element.show('search_spinner')},
                onFailure: reportError
            });
    }
    
[...]
    
<script type="text/javascript" src="js/YAHOO.js" ></script>
<script type="text/javascript" src="js/log.js" ></script>
<script type="text/javascript" src="js/color.js" ></script>
<script type="text/javascript" src="js/key.js" ></script>
<script type="text/javascript" src="js/event.js" ></script>
<script type="text/javascript" src="js/dom.js" ></script>
<script type="text/javascript" src="js/animation.js" ></script>
<script type="text/javascript" src="js/dragdrop.js" ></script>
<script type="text/javascript" src="js/slider.js" ></script>
<script type="text/javascript">

    window.onload = standardSliderInit;

    var slider1;
    
    function standardSliderInit() {

        slider1 = YAHOO.widget.Slider.getHorizSlider("horizBGDiv", "horizHandleDiv", 0, 200, 1);

        slider1.onChange = function(offsetFromStart) {
            document.getElementById("horizVal").value = offsetFromStart;
            if (offsetFromStart<200 && offsetFromStart>0) {
                var Keywords = document.getElementById("Keywords").value;
                PriceSearch(Keywords,offsetFromStart);
            }
        }
    }
    
[...]

The Slider worked fine except in the limit 200, sometimes its blocked in the end and start flooding the server, so I just canceled request for $200. I guess not a lot will be interested to buy a book for $200. Otherwise the slider is simple to use, a little difficult to personalize, and as I have said lot of code that I don't know if I really need it or no.

Conclusion

This is another usage of AJAX with AWS, this time I tryed to use the Yahoo! UI library and the slider widget. If there is another Javascript slider more easy to use I'll prefer it so much, rather than including all the Yahoo! UI library, and even that it gives a working result as expected. The AJAX Amazon demo online is updated, and you can download source code of this demo from here

Bookmark this article at these sites
Comments
1

Great Script!
But I have one question:

Can I use your script on my own homepage without any payment?

I can't believe this, because in relation to other aws scripts, which cost huge amount, your script is really great!

If is right that your script are free, I will put a link to your homepage and my next order starts with your amazon id.

i'm sorry for my bad english, i'm still in learning ;)

2

Alex the script is totally free, you can download, personalize, and use it the way you want.

3

Hi, I am getting the following errors, how can I solve it? Looks like the problem is in the php.ini settings.

Warning: fopen(cache/wsdlcache-f5456923626cd8004b16fcd76cb4df24.lock) [function.fopen]: failed to open stream: No such file or directory in /user/ajaxamazon4/lib/class.wsdlcache.php on line 129

Warning: flock() expects parameter 1 to be resource, boolean given in /user/bookswap/ajaxamazon4/lib/class.wsdlcache.php on line 131

Warning: SoapClient::SoapClient() expects parameter 2 to be array, boolean given in /user/bookswap/ajaxamazon4/demo1.php on line 60

Fatal error: Uncaught SoapFault exception: [Client] SoapClient::SoapClient() [function.SoapClient-SoapClient]: Invalid parameters in /user/bookswap/ajaxamazon4/demo1.php:60 Stack trace: #0 /user/bookswap/ajaxamazon4/demo1.php(60): SoapClient->SoapClient(Object(wsdl), true) #1 {main} thrown in /user/bookswap/ajaxamazon4/demo1.php on line 60

4

Be sure that cache/ folder exist and it have write permission. Chmod 0755 could be fine, but if it doesn't try 0777.

5

We have the same kind of issue. So far, the only errors we see (2) are:

Warning: fopen(cache/wsdlcache-f5456923626cd8004b16fcd76cb4df24.lock) [function.fopen]: failed to open stream: No such file or directory in (server account)/public_html/ajaxamazon1/lib/class.wsdlcache.php on line 119

Warning: flock(): supplied argument is not a valid stream resource in (server account)/public_html/ajaxamazon1/lib/class.wsdlcache.php on line 121

Evidently, the script is looking for some kind of permission setting or possibly a different pathway value. Just guessing.

Anyone know what to do about these? We've looked for some way to set values for the paths to the cache file, but there isn't anything obvious. Changed some permissions, but didn't help.

Clues anyone?

Thanks.

6

Tom just create the cache folder under ajaxamazon1/, there is nothing else to do.

7

How can you compare the price with other merchants ?

Post a comment





(Email will remain hidden)





Please enter the security code you see here




Related entries
Email to a friend
Email this article to:


Your email address:


Message (optional):