On August 15, 2009 Amazon changed the way it accepts API requests. API requests must now be signed using a painful and error prone 10-step process outlined at the Amazon Developer Guide website. There are a few examples for PHP floating around the web right now but I had to try them all and do a little tweaking myself to get this to work. The code below is based on this blog post over at Every Good Path.
I'm not going to explain this line by line but I will say that the following request is designed to search for books by ISBN number and return the book image, author, Amazon link, etc. Have fun!
$request = 'Service=AWSECommerceService&'.
'AWSAccessKeyId='.AMAZON_ACCESS_KEY_ID.'&'.
'Operation=ItemSearch&'.
'Keywords='.$itemISBN.'&'.
'SearchIndex=Books&'.
'ResponseGroup=Images,ItemAttributes,Small&'.
'Version=2009-01-06&'.
'Timestamp='.gmdate("Y-m-d\TH:i:s\Z");
// encode url - replace commas w/ %2C, replace colon w/ %3A
// Could use urlencode($request) here, but $request may already be partially encoded
$request = str_replace(',','%2C', $request);
$request = str_replace(':','%3A', $request);
// break request string into key/value pairs,
$reqarr = explode('&',$request);
// sort on byte value
sort($reqarr);
// tie back together w/ &'s
$string_to_sign = implode("&", $reqarr);
$string_to_sign = "GET\nwebservices.amazon.com\n/onca/xml\n".$string_to_sign;
$signature = urlencode(base64_encode(hash_hmac("sha256", $string_to_sign, AMAZON_SECRET_ACCESS_KEY, True)));
$request .= '&Signature='.$signature;
$request = 'http://webservices.amazon.com/onca/xml?'.$request;
$response = file_get_contents($request);
$amazonXML = simplexml_load_string($response);
Recently, a client was having trouble with an autocompleter implementation I had built for them. This particular application contains a call log module that
allows the client to log every contact made with a customer: phone, walk-in, email, etc. In order to speed up call log entries while on the phone, I created a customer lookup feature that includes an autocompleter on the last name field. The client begins typing in the last name field and a list of potential matches pops up. The client selects the correct customer if they exist, the customer information populates and the client can then begin entering information about this particular contact.
The contact log has reached over 2000 entries by now and there are many customers in the database with similar/same last name. This causes the autocomplete list to extend past the defined height of the container div in many instances which in turn causes scroll bars to appear. Great - everything working as it should. But...in IE 7 and 8 clicking on the scroll bars to view the hidden content causes the div and the autocomplete list to vanish! Oops! In Firefox, everything works fine.
Here's a great forum post on how to fix this problem but I'll lay it out here a little more cleanly. The application UI is built on Prototype and Scriptaculous so we're using Ajax.Autocompleter to make this happen.
We're assuming the autocomplete textbox id is nameLast and the autocomplete div id is nameLastAutocompleter. First, replace your autocompete instantiation code with something like this:
var autocompleteLastName = new Ajax.Autocompleter('nameLast', 'nameLastAutocompleter', memberLookupLastNameURL, {paramName: "autoText", minChars: 3, updateElement: this.returnAutocompleterFieldsMember});
Event.observe('nameLastAutocompleter', "mouseover", autocompleteLastName.onHover.bindAsEventListener(autocompleteLastName));
Event.observe('nameLastAutocompleter', "click", autocompleteLastName.onClick.bindAsEventListener(autocompleteLastName));
if (Prototype.Browser.IE) {
$('nameLastAutocompleter').observe('mousedown', function(e) {
autocompleteLastName.dontBlur = true;
e.stop();
});
$('nameLastAutocompleter').observe('blur', (function(e) {
setTimeout((function() {
if (! $('nameLast').focused)
this.onBlur(e);
}).bind(this), 100);
e.stop();
}).bindAsEventListener(autocompleteLastName));
$('nameLast').observe('focus', function() { $('nameLast').focused = true; });
$('nameLast').observe('blur', function() { $('nameLast').focused = false; });
} else {
$('nameLastAutocompleter').observe('mousedown', function(e) {
e.stop();
});
} Then, at the bottom of the Scriptaculous controls.js file (or any other globally included js file), add the following:
Autocompleter.Base.prototype.render = function() {
if(this.entryCount > 0) {
if (this.selected_item)
Element.removeClassName(this.getEntry(this.selected_item-1),"selected");
Element.addClassName(this.getEntry(this.index),"selected");
this.selected_item = this.index+1;
if(this.hasFocus) {
this.show();
this.active = true;
}
} else {
this.active = false;
this.hide();
}
};
Autocompleter.Base.prototype.onHover = function(event) {
var element = Event.findElement(event, 'LI');
if(element && defined(element.autocompleteIndex) && this.index != element.autocompleteIndex) {
this.index = element.autocompleteIndex;
this.render();
}
Event.stop(event);
};
Autocompleter.Base.prototype.addObservers = Prototype.emptyFunction;
if (Prototype.Browser.IE) {
Autocompleter.Base.prototype.onBlur = function(event) {
setTimeout((function(e) {
if (this.dontBlur) {
this.dontBlur = false;
return;
}
this.hasFocus = false;
this.active = false;
this.hide();
}).bind(this), 100);
};
} It's a lot of code, I know - but it did the trick for me.
I'm pleased to announce that one of our products, CreativePro Office, was featured in a post by the popular Smashing Magazine blog on Nov. 13th.
The post entitled, 15 Useful Project Management Tools, gave CPO good reviews along-side some pretty heavy-hitters including Basecamp, ActiveCollab and Trac Project.
Client tracking is integrated, making this handy for those who work with lots of different clients, and it could even serve as a simple CRM program, depending on your needs.
Integrated invoices and financial information is handy, and the finances page gives you options for viewing and creating invoices, expenses and reports.
CreativePro Office is very robust for a completely free application and is definitely worth checking out before shelling out for an expensive paid solution.
CPO received 14,000 unique visits and 560 new user registrations on the day the article was published. So I just wanted to say Thanks Smashing! We appreciate the plug.
Other UpStart Productions products have been featured in popular blogs. On Jan 23, 2008, our StuffSafe home and office online inventory application was the featured topic in a blog post by Lifehacker.
Years ago I made this little MP3 player button just to fool around with Flash and gain some experience with ActionScript. It's based loosely on the Wimpy Button but with fewer features.
To make this work, just change 1 flashvar that points to the path of your MP3 file like so...
flashvar="soundFile=(path to your MP3 file)"
The path may need to be a full path to the MP3 file even if it resides in the same directory as the SWF file. I'm not sure why but this is something I ran into when deploying this on my webserver.
Thanks and have fun.
Download the SWF and FLA files here.
This is a Flash multi-MP3 player I built a number of years ago. Tracks are added to the playlist through an XML file. Take a look at the file sounds.xml to see how to configure your playlist. Essentially you just add track title, artist name, and MP3 path to the appropriate XML nodes and you're set to go.
Configure only one flashvar to tell the player which XML file to use like this...
flashvar="soundFile=(path to XML file)"
There are a few things that should be fixed to make this player really polished. You'll see what I mean if you play with it for a bit.
Well anyway, it's free so crack open the ActionScript and have some fun making it work better. Let me know if you have any success.

Sylvie Roberta Denton was born on September 30, 2008 at 8:00 am - weighing in at 7lb 12oz. Mother and baby are both doing fine. Of course, she is an exceptionally healthy and beautiful little girl. Expect to see more pics in the near future.
I’m not ashamed to admin that I’ve fought with this problem for months. I’ve always put it on the back burner for a more convenient time, but today I just hammered away until I found a solution.
Now, to some of you (most???) this may seem trivially obvious. The scenario is this…let’s say you have a JavaScript method containing an Ext.Ajax.Request with a callback function. Furthermore, you need to pass a couple of variables to this method and have them processed in the callback function. The scenario in code looks like…
var someClass = {
someMethod: function(var1,var2) {
Ext.Ajax.request({
url: 'someURL.php',
method: 'POST',
params: {param1:'param1',param2:'param2'},
success: function(response) {
// Do something with response.responseText AND var1, var2 here.
}
});
}
}
At first glance this presents a big scoping problem since var1 and var2 are local and available only to someMethod. The answer is the ’scope’ parameter of the Ajax.request object. If we set the scope parameter to someClass.someMethod we now have access to var1 and var2 inside the success callback function.
var someClass = {
someMethod: function(var1,var2) {
Ext.Ajax.request({
url: 'someURL.php',
method: 'POST',
scope: someClass.someMethod,
params: {param1:'param1',param2:'param2'},
success: function(response) {
// We now have access to var1 and var2.
alert('Response = '+response.responseText+' var1 = '+var1+' and var2 = +var2);
}
});
}
}
Take a minute and answer this question...
“What do you do for your clients?”
You ready? If you answered something like “Build websites” you need to think harder. How you answer this question is your ‘value proposition’ and your value proposition is what differentiates you from your competitors.
The web design industry is still pretty fast and loose although some standards have emerged over the past few years. It’s a lot like woodworking. Any hack can drop a Craftsman tablesaw in their garage and call themselves a custom woodworker. Likewise, any two-bit geek can get a pirated copy of Dreamweaver and start cranking out diabolical code in minutes. So what separates you from this guy?
To compound matters, your customers often won’t know a good value proposition from no value proposition when they shop for a developer. They believe that they just need a website. So, the first guy that comes along claiming to be a web designer often gets the job, no questions asked.
Think of something you know nothing about. For me, that would be several things but I’ll settle on corporate accounting. This stuff makes my nose bleed it’s so dull and confusing. Let’s say I want to incorporate my business and I’m on the hunt for a good accountant. What are my needs and concerns? I want to avoid an IRS audit, I want to know what my cash flow is doing, I want someone who can continue to help me if my business expands and I don’t want to spend a lot of time thinking about it. A quick glance through the Yellow Pages finds…
CPA #1: 20 years experience - taxes - bookkeeping - Quickbooks - answers
CPA #2: “Taking your business beyond the numbers.” (Huh?)
\nCPA #3: Over 30 years experience - tax & accounting services (Well no kidding.)
CPA #4: Small business tax & accounting solutions - over 25 years experience.
Do you see a pattern? What in the world makes me want to call one of these folks over another? I suppose I’ll call ALL of them and pick the one with the cheapest rates.
A quick glance at local web designers reveals a similar trend. Most firms talk about WHAT they do instead of how what they do makes a business successful in the competetive, global online marketplace. Talking about what you do, the mechanics, is easy. “Our firm specializes in dynamic, database driven sites that present a professional image of your company to the world. We employ only the latest web technologies including .NET, Flash, PHP, ASP, MySQL, Oracle, etc. etc. etc…….” Here’s a secret - your customers don’t care.
“OK, Jeff. Do you have a point?” Yes, I do. Please bear with me - it’s complicated.
Imagine Les Schwab billboards showing you the process they use to change tires. Not very compelling is it? Instead, their value proposition is:
1. Location: chances are good there’s a Les Schwab tire center within 5 miles of your house.
2. Selection: they will get you any damn tire you need.
3. Peace of mind: Have a problem? Take your tires back and they’ll replace them for free, no questions asked.
Maybe you’ve had a bad experience with Les Schwab and you think I’m all washed up. Fine. Then think about the last time you had a really positive experience with a company and try to isolate what it is that made you feel so good about doing business with them. Some possibilities are…
1. You got a great product for less than you expected. The company exceeded your expectations.
2. You felt a great deal of trust when doing business with this company. They could relate to you and your needs like no one else.
3. You experienced simplicity at its finest. The company anticipated your needs, guided you toward the correct product and simplified the transaction.
This is where I begin to loose traction. Everyone’s business is a little different and probably requires a slightly different value proposition. I can say that your value proposition should be easy to remember and condensed to one (at most two) sentences. The latest version for my company is…
Notice that this is not a mission statement. You can have a mission statement if you wish but from what I’ve seen, most mission statements are fluff, hype, unattainable promises and very abstract. A value proposition goes beyond the mission statement in that it should permeate your entire business. Every thing you do – from your design, code, invoices, emails, client meetings, etc. – should in some way track back to your value proposition. In my next blog I’ll show you how I try to live out my value proposition in the day to day events of business.
If you have developed a value proposition for your company, post a comment. I would love to see what others are doing.
Thanks for reading.
Ok, I’m being a little dramatic I know. But I feel pretty strongly about this topic because I wrestled with it myself for years. A few not-so-subtle experiences ultimately formed my opinion on the matter.
I once had to hire an attorney to settle a dispute and I took keen interest in how she billed me (at $250.00 per hour). While in her office, she started a timer the moment I darkened her doorway and stopped it when my foot was past the threshold on the way out. Her invoices weren’t quite as exact - she rounded up to the nearest 1/4 hour and at $4.17 per MINUTE this adds up. No freebies here.
Sitting in my office one day it occurred to me that I was constantly swamped with work but always seemed way short on cash flow. In passing, I relayed this observation to a close friend, emphasizing that my workload was certainly the result of my obvious skill as a designer. “My clients love my work”, so my thinking went. My friend was almost too quick to point out that “Some people will love you just ’cause you’re cheap.” Ouch!
The pain of a heavy workload coupled with an inability to pay your bills is a quick receipe for throwing in the towel and flippin’ burgers for the rest of your life. So, back to our original premise - bill your clients for everything! Let’s explore this with some mind-games I used to play on myself (and my wife) back in the days of famine.
This may or may not be true but it was a bedrock assumption I held. Shoot, everyone from Les Schwab to Home Depot gives free estimates or quotes. But large companies have two things going for them that most of us don’t: numbers and systematization. They have their estimation process down to a science - it’s fast and sometimes even accurate. And they have the customer base to justify 5 looser estimates for each one that makes some money.
\nNow, what about us? Well, I was spending approximately 3-4 hours on each free quote. That’s time to drive to the clients’ place of business, interview the client for one hour and then draft the quote. One-half day of no billable hours which is fine if you’re playing golf.
It got to the point where only about 1/3 of my free quotes returned as actual projects. The successful quotes averaged around $1,800.00. At the time I was billing out at $65.00 per hour which means that I was spending $520.00 to acquire an $1,800.00 project. Not a very good prognosis for success.
Lesson Learned: Bill for quotes, estimates and other administrative tasks. Most professionals do not give away their time in any capacity and your clients should know this already. If a potential client balks at paying for an estimate, they do not value your service or time. Direct them to your nearest competitor so they can go out of business instead of you.
If I had a dollar for every time I heard this sad come on line. I’ve been approached with these offers no fewer than 10 times in the past five years. The come on generally goes something like this… “I’ve got this market smashing idea - but I don’t have any funding just yet. Do this job cheap and I PROMISE you’ll get all the work you can handle.” Or, the more seductive…”I’ve seen your work and I LIKE IT! I’ve got (insert some number here) potential clients just waiting for your design expertise. I just need to know you and I will work well together before I commit to paying a lot of money. I’m sure you understand.”
Both of these positions are insulting to any honest person - or they should be. But maybe you’re trying to build your portfolio and you need a new client. Or, you’re trying to push your skill set beyond Front Page. Or, you’re just going through a dry spell and any work is beginning to look enticing. Having, at one time or another, faced all of these scenarios I can still say with vigor, RUN don’t walk to the nearest door, fire escape, window, whatever to get away from a offers like these. Folks who propose these offers are on the prowl for the weak and hungry looking to take your dinner.
“Oh, come on man. You’re being dramatic again!” Sure, there are a very, very few scenarios where you might be advantaged by providing some cheap labor. Close and trusted business associates should be able to count on you to share some perks if they’ve stuck their neck out for you at one time or another. And legitimate “investment opportunities” do arise from time to time – but rarely.
Lesson Learned: simply commit to charging what you’re honestly worth all the time. Again, I go back to the fact that a true professional will not give away their work for free and good clients know this.
This may be true of some folks but certainly there are many people who know the costs involved when dealing with professionals and they expect to spend some money. I always felt like I would somehow impose a burden on my clients if I didn’t allow them to freely call at any time with any question that came to their mind.
Billing for communication with the client does two marvelous things: it increases your billable hours and keeps clients from wandering into your office and wasting an afternoon while they suck every last bit of hard-earned expertise right out of your head. When I knew my attorney would bill me $62.50 for every phone call, you bet I thought long and hard about what I wanted to ask and whether I needed to ask at all. Imagine you have 4 active projects - not unrealistic for a single developer. Each of those 4 clients will likely contact you an average of 6 times per week, more if their project is just starting or ready to launch. That’s an average of 24 emails or phone calls per week. Let’s say a phone call lasts an average of 15 minutes and it takes about 5 minutes to thoughtfully reply to an email. To make this east, let’s assume that your 24 points of contact throughout the week are split 50/50 between emails and phone calls. That’s a total of 4.5 hours per week spent communicating with clients. Throw in a few random emails or calls from previous clients and you can see how this quickly becomes a nighmare if you’re not billing for this service. Put yourself in the shoes of your client. Would you rather pay for a thoughtful, prompt and accurate reply or get a hasty, thoughtless, inaccurate reply for free - or no reply at all.
Lesson Learned: find a way to recoup time spent communicating with clients. You can pad your estimates by some percentage to account for this, submit a monthly, detailed invoice, wait until the project is complete and add this expense to the final payment – anything is better than letting this one go unpaid.
Man, oh man this hurts. Some of us just need to be loved so we accommodate the impossible in order to please. What we inadvertently wind up doing is dropping the ball a lot - or maybe I just speak for myself.
Now, relationships in business are extremely important and I value relationships more than anything else. Really, I do. It’s rewarding to get a fat check, but to me it’s more rewarding to hear someone say, “Good job!”. However, without the fat check we won’t be around to get the pat on the back. So a balance must be found.
Again, I go back to my experiences with other good professionals. What is it that made me like THEM? Without fail I have to say it was their competence and attitude that impressed me. How much they charged is almost a non-issue. Our customers want us to do a job and that job is to design a web presence that will make them money. If we’re nice to them, that’s a big bonus. But if we’re nice and DON’T do the job well, we shouldn’t expect our clients to be nice to us.
Lesson Learned: my client doesn’t want to invite me to their summer BBQ, like their dog or marry their daughter. They want me to work on behalf of their company to increase revenue using the web as a medium – simple as that. They demand competence over nice any day of the week.
This is a brief list that I’ve managed to beat almost to death. Look for more items down the road.
Thanks for reading.
Very good questions, thank you for asking. UpStart Productions is a one-man development shop started by me, Jeff Denton, back in Nov. 2000. At one point or another, I’ve done logo design, graphic design for print and web, Flash animation, static and dynamic websites and web applications. My company is currently in hibernation but I’ll shed more light on that later.
\nThe world is not pounding on my door for me to write a web development blog. There are plenty of great design blogs and other resources available such as Sitepoint, V7N.com and WDVL. You see, what you’re reading is the very first blog post from UpStart Productions and I want to take this in a decidedly different direction from other resource sites. I want to focus on the business of web design, not the academic, technical aspects.
I probably won’t show off any new PHP classes, teach you how to build yet another RSS reader or debate the merits of CSS vs. table based layout (a debate long settled in my opinion). However, I will discuss the ups, downs, successes, failures and pitfalls inherent in being a freelance designer of any species be it web, print, multimedia or application. And I’ll try to form some coherent thoughts about a few issues in our industry that nobody seems to be talking about. We’ll dicuss those down the road a bit.
I’m not the quintessential geek but probably close. I’ve been fiddling with computers since I got a Timex Sinclair 1000 at 13 years of age - I was hooked. The web exploded onto the scene (for me, anyway) around 1994, just when I was being forced to abandon my pursuit of an Electrical Engineering BS at Chico State University. So, I discovered programming again: a little C, C++, and this odd markup language called HTML.
I began my career by building a few simple sites for myself and one paying gig for a friend of mine the saw sharpening business. I remember earning $350.00 for that project. At the time I thought it was virtually immoral, earning so much money for doing work I actually enjoyed. At the time I was living in a small, Northern California town. It seemed that a lot of action around what is now affectionately called “the bubble” was happening in Seattle and, to a lesser extent, Portland. So, at 28 I packed up the wife and kids and moved to the Pacific Northwest where I still live - sans wife, well, THAT wife anyway but that’s a story for another time.
No one would hire me as a designer up here in ‘98. Heck, I had no degree, no formal training in design and I really didn’t know my HTML that well either - I wouldn’t have hired me. I sat through countless interviews in bizarre corporate meeting rooms with large conference tables and speaker phones. I endured the embarasment when an interviewer showed me a page of 200+ lines of HTML code and asked me to find the errors. I knew I needed to fall back and punt.
Two year and a few “out of the blue” opportunities later, UpStart Productions was uncerimoniously born.
I’ll spare you the rest of the details until later. Please stay tuned and I hope you’ll let me know when I’m right on, close, full of crap or drifting into a place no one else really wants to go.
Thanks for reading.
Signing Amazon Requests with PHP
The Sciptaculous Autocompleter Disappears in IE!
CreativePro Office Gets Smashed!
Passing Extra Data to an Ext AJAX Request Callback
What's Your Value Proposition?
Bill Your Clients for Every Last Little Nitpickin' Thing
Who is UpStart Productions and Why Do We Need Another Web Design Blog?
Coding [3]
coding php javascript mysql [0]
ExtJS [1]
Family [1]
Flash [2]
Free Stuff [2]
JavaScript [2]
News [1]
Reviews [0]
Reviews Coding [0]
Webusiness [3]
September 2009 [1]
June 2009 [1]
November 2008 [1]
October 2008 [3]
September 2008 [1]
March 2006 [3]