Not Everything’s Fine With Yahoo Panama
There are a couple bits of interesting YPN/Yahoo related news recently. The first is that Yahoo’s new product, MyBlogLog, happens to do Adsense tracking. This means that if you use MyBlogLog, Yahoo could be learning proprietary information about your Adsense to use to improve their competing YPN product:
Coincidentally, MyBlogLog (Yahoo) is also tracking information on Google AdSense — how many clicks Google AdSense ads are receiving (on webpages that have both MyBlogLog and AdSense installed), the ad unit size, and what webpage those clicks occurred. Yahoo doesn’t know the CPC for each of Google’s ads, but they do know the click-through rate (CTR) — and can specifically target high CTR publishers first, with their YPN offering.
Then in the “we made a huge bug” department, Yahoo charged their $1000 bill 50 times to a guy’s credit card, which would definitely suck for him:
Yahoo! experienced a technical issue that caused the credit cards of a few advertisers to be charged incorrectly on Wednesday, February 14. Some credit cards were authorized for one or more charges in error.
We caught this early and were able to halt the process before the charges were actually completed. We’re very sorry for any issues this might have caused you and we’re doing everything possible to completely resolve the situation as quickly as possible, and to ensure that it doesn’t happen again.
So, the transition to their new Advertising platform Panama is probably not going as smoothly as they’d like, with much internal patching and scurrying, but over the next few months these kind of events will probably fade away. Bugs are to be expected with change, as are accusations of “under the table” business practices.
Yahoo’s PIPE api
In a much better naming than Technorati’s immature WTF (Where’s the fire), Yahoo today released a labs product called Yahoo Pipes. The name comes from linux file handle terminology:
Pipes is a hosted service that lets you remix feeds and create new data mashups in a visual programming environment. The name of the service pays tribute to Unix pipes, which let programmers do astonishingly clever things by making it easy to chain simple utilities together on the command line.
The idea is quite simple. Yahoo Pipes lets users take everyday RSS feeds and mash them together with Yahoo APIs, other feeds, and programmatic building blocks in an easy to use graphical environment. Unfortunately, the execution is terrible and buggy. Take, for example, this yahoo pipe I created to scan the NYT feed for locations / keywords and insert flickr images as appropriate:

The first thing you might notice is that it doesn’t really do what it’s supposed to. Well, we’ll come to that in a minute. You’ll also notice a lot of & going around–every time I hit save it re-encoded the original ampersand. How irritating. Worse is how their pipes are so watered down they can’t do anything:

All I wanted to do was take some content, for each item do content analysis and geo analysis, and use those outputs as the input to a flickr search, then append the photo to the text snippet. Well, first you can’t fork a data stream into two bits and recombine them later. So scratch two kinds of analysis. Second, the outputs of content/geo analysis can’t be used to populate the inputs of the flickr data source–an obvious problem. And third, the annotation feature useless doesn’t annotate, it just replaces chunks messily.
Yahoo, your pipes are indeed clogged.
Ajax Edit In Place with Yahoo UI API
You’ve probably seen the article at at 24 ways about Ajax in-place editing, but honestly the javascript they code up there seems quite hacky and un-standards-compliant. Instead, we’re going to use the Yahoo UI Library (YUI, YUI-EXT), a modern cross-browser javascript toolkit, to accomplish the same results with less hassle, and more power.
The effect we want is like Flickr’s edit in place descriptions:

Part 1: The YUI javascript example:
In javascript, here’s the code. First you need some includes:
<script type="text/javascript" src=js/yahoo.js"></script> <script type="text/javascript" src=js/connection.js"></script> <script type="text/javascript" src=js/event.js"></script> <script type="text/javascript" src=js/utilities.js"></script> <script type="text/javascript" src=js/dom.js"></script> <script type="text/javascript" src=js/yui-ext.js"></script>
Don’t forget to add this handy shortcut–we’ll use it later:
<script type="text/javascript"> var $ = YAHOO.util.Dom.get </script>
Then we need a function to show something as editable:
function showAsEditable(e){
YAHOO.util.Event.preventDefault(e);
YAHOO.util.Event.stopPropagation(e);
if(this.oldBG == undefined) {
var pos = this;
while(pos && pos.style.backgroundColor == '') {
pos = pos.parentNode;
}
this.oldBG = pos.style.backgroundColor;
}
var anim = new YAHOO.util.ColorAnim (
this,
{backgroundColor:{to:'#ffffd3'}},
.5,
YAHOO.util.Easing.easeOut
);
anim.animate();
}
This function finds the closest defined background color, if not already defined, and saves it. Then it animates to a nice yellow overlay color. Now we need its reverse:
function showAsNotEditable(e){
YAHOO.util.Event.preventDefault(e);
YAHOO.util.Event.stopPropagation(e);
var anim = new YAHOO.util.ColorAnim (
this,
{backgroundColor:{to:this.oldBG}},
.5,
YAHOO.util.Easing.easeOut
);
anim.animate();
}
This function is even simpler–it just restores the saved background color. Now that we can turn their “editable effect” on and off, we need something to actually do the work:
function editHandler(e){
YAHOO.util.Event.preventDefault(e);
YAHOO.util.Event.stopPropagation(e);
var target = (e.srcElement) ? e.srcElement : e.target;
var form = '<div id="' + target.id + '_editor">';
form = form + '<textarea id="' + target.id +
'_edit" name="' + target.id +
'" rows="4" cols="60">' +
target.innerHTML + '</textarea>';
form = form + '<br/><input id="' + target.id +
'_save" type="button" ' +
'value="SAVE" /> OR <input id="' +
target.id + '_cancel" type="button" ' +
value="CANCEL" /></div>';
form = form + '</div>';
YAHOO.ext.DomHelper.insertHtml('afterEnd', target, form);
YAHOO.util.Event.addListener(target.id + '_save', 'click', function(){
YAHOO.util.Connect.asyncRequest('POST', 'ajax.php',
{
success: function(o){
target.innerHTML = $(target.id + '_edit').value;
$(target.id + '_editor').parentNode.
removeChild($(target.id + '_editor'));
target.style.display = 'block';
},
failure: function(o){
$(target.id + '_editor').value =
'Sorry, the update failed...';
},
scope: this
},
'action=updatepost&target=' + target.id + '&value='
+ escape($(target.id + '_edit').value)
);
});
YAHOO.util.Event.addListener(target.id + '_cancel', 'click', function()
{
$(target.id + '_editor').parentNode.
removeChild($(target.id + '_editor'));
target.style.display = 'block';
});
target.style.display = 'none';
}
Now that that’s out of the way, you just need to add these handlers to mouseover, mouseout, and click events of “editable” items:
var elements = YAHOO.util.Dom.getElementsByClassName('editable');
YAHOO.util.Event.addListener(elements, 'click', editHandler);
YAHOO.util.Event.addListener(elements, 'mouseover', showAsEditable);
YAHOO.util.Event.addListener(elements, 'mouseout', showAsNotEditable);
YAHOO.ext.EventManager.onDocumentReady(Init.init, Init, true);
Part 2: the HTML code
Here’s an example of some html code that automatically makes itself editable:
<div class="itemcontent"> <p id="description-' . $row['id'] . '" class="editable">' . htmlentities($row['description']) . '</p> </div>
Part 3: the AJAX
Since we encode the field name and identifier in the id attribute of the editable element, processing the ajax request is easy:
$value = urldecode($_POST['value']);
$bits = preg_split('[-]', $_POST['target'], -1);
$field = $bits[0];
$id = $bits[1];
switch($field) {
case 'title':
$object->UpdatePostTitle($id, $value);
break;
case 'description':
$object->UpdatePostDescription($id, $value);
break;
}
Conclusion
Using YUI you can add a robust, cross-platform edit-in-place solution that’s as easy as giving your html elements id attributes in the form “$field-$id” and the classname “editable.” The rest is magic. For a live demo, see my edit in place demo.