Elliott C. Back: In Aere Aedificare

My Girlfriend is Amazing

Posted in WTF, Wendy by Elliott Back on April 18th, 2007.

Quote: “Go play counterstrike while I make you dinner dear.” OMG!

I am “very evil”

Posted in Memes, Wendy by Elliott Back on April 10th, 2007.

I feel like it might be a good idea to inform Wendy of the results of this rather silly quiz:


You Are 64% Evil


You are very evil. And you’re too evil to care.
Those who love you probably also fear you. A lot.

Nooo, it’s not true!! Muahahahaha…

X-ray Kiss Photo

Posted in Health, Photo, Wendy by Elliott Back on March 1st, 2007.

kissy-kissy.jpg

This is too cute, this x-ray photo of a kiss.

Egyptian Cat Photo

Posted in Photo, Wendy by Elliott Back on February 28th, 2007.

Egyptian Cat Entrances Photog

This is a brilliant meta-photo of me that Wendy took in the British Museum!

Ajax Edit In Place with Yahoo UI API

Posted in Computers & Technology, Web 2.0, Interface, AJAX, Yahoo, Wendy by Elliott Back on February 9th, 2007.

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:

edit-in-place.jpg

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.

« Previous PageNext Page »