Google
You could also try tk Social Bookmarking Search or tk Video Search!

Saturday, February 11, 2006

A real transformer in action

Comments



Remember Transformers? No? Maybe this real-life transformer morphing from a vehicle to a walking robot will help jog your memory.

Categories:
Cool Tech Videos

 

Friday, February 10, 2006

MacGyver in an ad

Comments

Here's an ad starring MacGyver in a typical scenario. Relive the good old days!

Categories:
Videos

 

Monday, February 06, 2006

PC in a (whiskey) bottle

Comments

What do you do with your empty whiskey bottles? Grow plants? Stuff them with sand? How about building a PC?

Categories:
Cool Tech

 

Sunday, February 05, 2006

Howto: AJAX for Blogger peek-a-boo content

23 comments

Introduction: As part of my recent design changes earlier, I added AJAX functionality to this blog. More on this here. This is a howto on replicating this on your own blog @ Blogger. I'm assuming you have some knowledge of html, blogger template code and javascript. You may want to read up on AHAH here. I've split up the code into 3 parts.

Ok, I'm starting off with the last part of my code first, since it is easier to explain how everything works that way. First look at the template code below. Hopefully you understand what's happening here because it's basic html and blogger template codes.


<MainOrArchivePage>

<small onclick="javascript:toggler('<$BlogItemPermalinkUrl$>', this, '<$BlogItemNumber$>post')" style="cursor:hand;">Click to view</small>

</MainOrArchivePage>

<div class="post-body" <MainOrArchivePage>id="<$BlogItemNumber$>post" style="display:none;"</MainOrArchivePage>>

<ItemPage><$BlogItemBody$></ItemPage></div>


So everything starts when a user clicks on "Click to view". As you can see it calls the toggler function and from there, somehow the div class="post-body", which is the entire post appears. (The way it works for comments and backlinks are similar so I don't think an explanation is required.)

The below you see is the last part of my code, which is the toggler function. Notice that it accepts 3 variables - serverPage, linkobj and objID. Where do these variables come from? Look at "Click to view" again. Do you see '<$BlogItemPermalinkUrl$>', this, '<$BlogItemNumber$>post'? Yup those 3 are the 3 variables. The first variable, serverPage, contains '<$BlogItemPermalinkUrl$>', the post permalink url, also where you are gonna parse content from. The 2nd variable, linkobj, holds the link object itself. This is so that you can change "Click to view" to "Click to hide". The 3rd variable, objID, contains the post id, so that the script knows which post to show or hide.

Now you know how what these variables are. Let me briefly explain what the code is doing. First, it gets the element that is stored in objID and stores it in obj for later use. If objID (the post) is already shown, hide it. Then depending on whether objID contains post, blinks(backlinks) or comments, different actions will be taken. For comments, if there is no comment, the comment page will popup instead of trying to display 0 comments.

The next part does exactly the opposite. If objID is hidden, show it. The important part here is ahah(serverPage, obj, objID); that you see appearing 3 times, each for post, comments and blinks(backlinks). That is the AJAX function that requests the page from the server, which you will see later. It sends the 3 variables for processing.



function toggler(serverPage, linkobj, objID) {
var obj = getElement(objID);
if (isShown(objID)) {
obj.style.display = "none";
obj.innerHTML = "";
if (objID.indexOf("post") != -1) { linkobj.innerHTML = "Click to view"; }
else if (objID.indexOf("blinks") != -1) { linkobj.innerHTML = "Show Backlinks"; }
else if (objID.indexOf("comments") != -1) {
if (linkobj.innerHTML == "0 comments") {
window.open("http://www.blogger.com/comment.g?blogID=19630625&postID=" + objID.substring(0, objID.indexOf("comments")));
}
}
}
else {
if (objID.indexOf("post") != -1) {
obj.style.display = "block";
linkobj.innerHTML = "Click to hide";
ahah(serverPage, obj, objID);
}
else if (objID.indexOf("blinks") != -1) {
obj.style.display = "block";
linkobj.innerHTML = "Hide Backlinks";
ahah(serverPage, obj, objID);
}
else if (objID.indexOf("comments") != -1) {
if (linkobj.innerHTML == "0 comments") {
window.open("http://www.blogger.com/comment.g?blogID=19630625&postID=" + objID.substring(0, objID.indexOf("comments")));
}
else {
obj.style.display = "block";
ahah(serverPage, obj, objID);
}
}
}
}

function getElement(id) { return document.getElementById(id); }

function isShown(id) { return getElement(id).style.display != "none"; }

//-->
</script>
</MainOrArchivePage>


The code you see below is the main part of AJAX, which happens to be the first part of my code. It is where the magic gets done. Basically, when a user does something, the browser will request for some info from the server and update only the necessary elements. You'll see that it accepts 3 variables and these 3 variables came from the part above. What can be safely changed here is obj.innerHTML = 'Hang on...';. This is just a message telling the user to wait for changes. Next, notice this part ahahDone(obj, objID);. It sends 2 variables to the ahahDone function for processing.

The ahahDone function is just checking to see if everything is ok. If it is, well we're happy and it can send a variable to either getPost, getComments or getBlinks function, depending on what objID contains. These functions strip out the parts we want and throw the rest away. What you can change here is { obj.innerHTML="Status:\n" + xmlhttp.statusText; }. This is sort of like an error message informing the user when AJAX fails (here I left it as the status message returned instead).

<MainOrArchivePage>
<script type="text/javascript">
<!--
function ahah(serverPage, obj, objID) {
obj.innerHTML = 'Hang on...';
if (window.XMLHttpRequest) { xmlhttp = new XMLHttpRequest(); }
else if (window.ActiveXObject) { xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); }
if (xmlhttp) {
xmlhttp.onreadystatechange = function() { ahahDone(obj, objID); };
xmlhttp.open("GET", serverPage, true);
if (window.XMLHttpRequest) { xmlhttp.send(null); }
else if (window.ActiveXObject) { xmlhttp.send(); }
}
}

function ahahDone(obj, objID) {
if (xmlhttp.readyState == 4) {
if (xmlhttp.status == 200 req.status == 304) {
if (objID.indexOf("post") != -1) { getPost(obj); }
else if (objID.indexOf("blinks") != -1) { getBlinks(obj); }
else if (objID.indexOf("comments") != -1) { getComments(obj); }
}
else { obj.innerHTML="Status:\n" + xmlhttp.statusText; }
}
}



The code below is the 2nd part of my code. It appears last as it is the easiest to explain. Each function accepts a variable sent from ahahDone. This variable happens to contain a reference to the element where you want the content to appear. Next, resText = xmlhttp.responseText;, where resText contains the entire page retrieved from the server. Obviously, you only want to insert certain parts of the page inside, so you'll need to search for the things you want. The rest of the lines just do some careful searching (all those indexOf lines) and the very last line of each function does a substring to cut out the relevant parts out and stick it into the html of the post element (obj).



function getPost(obj) {
resText = xmlhttp.responseText;
start = resText.indexOf("<!-- Begin .post -->");
start1 = resText.indexOf('<h3 class="post-title">', start);
start2 = resText.indexOf('</h3>', start1) + 5;
end = resText.indexOf('<p class="post-footer">', start2);
obj.innerHTML = resText.substring(start2, end);
}

function getBlinks(obj) {
resText = xmlhttp.responseText;
start = resText.indexOf("<!-- Begin #comments -->");
start1 = resText.indexOf('<a name="links">', start);
end = resText.indexOf('<p class="comment-timestamp">', start1);
obj.innerHTML = resText.substring(start1, end);
}

function getComments(obj) {
resText = xmlhttp.responseText;
start = resText.indexOf("<!-- Begin #comments -->");
end = resText.indexOf('<a name="links">', start);
obj.innerHTML = resText.substring(start, end);
}


And that sums it up. With some luck, you should be able to do the same. Comments on this are welcome.

Edit: I added a line of code in the toggler function to fix a bug. That line is (obj.innerHTML = "";).

 
Google
You could also try tk Social Bookmarking Search or tk Video Search!