Skip to main content

Laborator: Open-Source Collaboration Tools for Blogger Built on Google Platforms

Laborator Introduces Blog Chat
Update 7-3-2008: The latest update of the Google Visualization API appears to have broken the application! Bummer! Anyone have any ideas about how to fix it?

The newest Laborator feature is in-blog chat. Now, your blog readers can chat within a blog post!

Try chatting now!
You can try out the chat engine below. Just invent a user name for yourself, log on with a buddy, and chat away. No buddies available? Open two browser windows to this page, invent two user names, and try it out.

Chat on Laborator
Instructions


To: From:

userid:
Who's Been Online Recently


Laborator is a set of rapidly evolving open-source collaboration tools for Blogger with two goals.
The first goal is to provide prototype collaboration tools sans hosting, (all the source code is in the source of this web page), that serve as interesting learning vehicles for Google platform tools like Google Docs and the Visualization API. The second is to call attention to bills before the U.S. Congress that affect the high tech community.

Thanks to jennifermadden.com for the 'Enter key form submission code example, and to Eric's weblog for the auto-scrolling code example. And of course to Google for providing the platforms.
Source Code:

<script type="text/javascript" src="http://www.google.com/jsapi"></script>

<script type="text/javascript">

google.load("visualization", "1");


//Code to start the app

google.setOnLoadCallback(hr5642_chat_initialize);


//Global variables

var chathtml = [];

var lastdate = 'test';

var lastmessage = 'test';

var got_messages = 0;


//Publish the list of users recently online

//So you know who might be available to chat

function hr5642_chat_initialize() {

whose_online();

}


var stQuery_chat = 'http://spreadsheets.google.com/tq?key=pvFXGB-79Kl2GEcZuVgOiQw&gid=0&pub=1';

var news_div = 0;

var otherblog_div = 1;

var thisblog_div = 2;



function whose_online() {

var query = new google.visualization.Query(stQuery_chat);

query.setQuery("select max(A), C group by C order by max(A) desc");

query.setRefreshInterval(30);

query.send(hr5642_handleWhoseOnlineProxy);

}


function hr5642_initialize_chat() {

var query = new google.visualization.Query(stQuery_chat);

stFrom = hr5642_getSrch('chat_from');

stTo = hr5642_getSrch('chat_to');

query.setQuery("select A, B, C, D where B ='" + stFrom + "' order by A desc");

query.setRefreshInterval(4);

query.send(hr5642_chat_handleNewsQueryResponseProxy);

}



function hr5642_chat_handleNewsQueryResponseProxy(response){

hr5642_chat_handleQueryResponse(response, 0);

}



function hr5642_get_messages() {

var query = new google.visualization.Query(stQuery_chat);

var stFrom = hr5642_getSrch('login_id');

var stTo = hr5642_getSrch('login_id');

query.setQuery("select A, B, C, D where B ='" + stFrom + "' or C = '" + stTo + "' order by A desc");

query.setRefreshInterval(0);

query.send(hr5642_get_messages_Proxy);

}



function hr5642_handleWhoseOnlineProxy(response){

if (response.isError()) {

alert('Error in query: ' + response.getMessage() + ' ' + response.getDetailedMessage());

return;

}

var data = response.getDataTable();

var wolhtml = [];

for (var row = 0; row < data.getNumberOfRows(); row++){

wolhtml.push(data.getFormattedValue(row, 1));

wolhtml.push(' at: ');

wolhtml.push(data.getFormattedValue(row, 0));

wolhtml.push('<br>');



}

document.getElementById('whoseonline').innerHTML = wolhtml.join('');

}





function hr5642_chat_handleQueryResponse(response, div_to_use) {

if (response.isError()) {

alert('Error in query: ' + response.getMessage() + ' ' + response.getDetailedMessage());

return;

}

var data = response.getDataTable();

var html = [];

var stListID = "";

var start_out_row = 0;

switch(div_to_use){

case 0:

stListID = 'chat';

break;

case 1:

stListID = 'otherblog';

break;

case 2:

stListID = 'thisblog';

break;

}

var row = 0;

while(row < data.getNumberOfRows()){

if(lastmessage == data.getFormattedValue(row, 0)){

start_out_row = row;

row = data.getNumberOfRows();

}

else{

row = row + 1;

}

}


for (var row = start_out_row; row >= 0; row--){

if(data.getFormattedValue(row, 2) != 'login'){

chathtml.push(data.getFormattedValue(row, 2) + " said: ");

chathtml.push(data.getFormattedValue(row, 3));

chathtml.push('<p>');

}

}

lastmessage = data.getFormattedValue(0, 0);

document.getElementById('chat').innerHTML = chathtml.join('');

var objDiv = document.getElementById('chat');

objDiv.scrollTop = objDiv.scrollHeight;

}


function hr5642_get_messages_Proxy(response){

if (response.isError()) {

alert('Error in query: ' + response.getMessage() + ' ' + response.getDetailedMessage());

return;

}

var stFrom = hr5642_getSrch('login_id');

var stTo = hr5642_getSrch('chat_to');

var data = response.getDataTable();

var wolhtml = [];

var row = 0;

var start_out_row = 0;

lastmessage = data.getFormattedValue(0,0);

while(row < data.getNumberOfRows()){

//Roll back messages to me until the last message from

//me is found

if(stFrom == data.getFormattedValue(row, 2)){

lastmessage = data.getFormattedValue(row,0);

if(row != 0){

start_out_row = row - 1;

}

else{

start_out_row = 0;

}

row = data.getNumberOfRows();

}

else{

row = row + 1;

}

}

//Roll forward publishing all messages to me

//since my last message

chathtml.push('messages received: <p>');

for (var row = start_out_row; row >= 0; row--){

if(stFrom == data.getFormattedValue(row, 1) &&

data.getFormattedValue(row, 2) != 'login'){

chathtml.push(data.getFormattedValue(row, 2) + " said: ");

chathtml.push(data.getFormattedValue(row, 3));

chathtml.push('<p>');

}

}

chathtml.push('end of messages<p>');

document.getElementById('chat').innerHTML = chathtml.join('');

got_messages = 1;

}



function hr5642_getSrch(my_value){

var stSearch = document.getElementById(my_value).value;

return stSearch;

}


function hr5642_update_from_me(){

chathtml.push(hr5642_getSrch('chat_from') + " said: ");

chathtml.push(hr5642_getSrch('entry_2'));

chathtml.push('<p>');

document.getElementById('chat').innerHTML = chathtml.join('');

var objDiv = document.getElementById('chat');

objDiv.scrollTop = objDiv.scrollHeight;

empty_st = '';

setTimeout("document.getElementById('entry_2').value = empty_st",50);

}


function log_me_in(){

document.getElementById('login').submit();

hr5642_get_messages();

document.getElementById('chat_from').value = hr5642_getSrch('login_id');

document.getElementById('entry_2').disabled = false;

setTimeout("hr5642_initialize_chat();",5000);


}


function checkEnter(e){

var characterCode;


if(e && e.which){

e = e;

characterCode = e.which;

}

else{

e = event;

characterCode = e.keyCode;

}


if(characterCode == 13){

st_on = 'online';

document.getElementById('entry_3').value = st_on;

document.getElementById('chatter').submit();

hr5642_update_from_me();

return false;

}

else{

return true;

}


}



</script>

Comments

Popular posts from this blog

Cool Math Tricks: Deriving the Divergence, (Del or Nabla) into New (Cylindrical) Coordinate Systems

The following is a pretty lengthy procedure, but converting the divergence, (nabla, del) operator between coordinate systems comes up pretty often. While there are tables for converting between common coordinate systems, there seem to be fewer explanations of the procedure for deriving the conversion, so here goes!

What do we actually want?

To convert the Cartesian nabla



to the nabla for another coordinate system, say… cylindrical coordinates.



What we’ll need:

1. The Cartesian Nabla:



2. A set of equations relating the Cartesian coordinates to cylindrical coordinates:



3. A set of equations relating the Cartesian basis vectors to the basis vectors of the new coordinate system:



How to do it:

Use the chain rule for differentiation to convert the derivatives with respect to the Cartesian variables to derivatives with respect to the cylindrical variables.

The chain rule can be used to convert a differential operator in terms of one variable into a series of differential operators in terms of othe…

The Valentine's Day Magnetic Monopole

There's an assymetry to the form of the two Maxwell's equations shown in picture 1.  While the divergence of the electric field is proportional to the electric charge density at a given point, the divergence of the magnetic field is equal to zero.  This is typically explained in the following way.  While we know that electrons, the fundamental electric charge carriers exist, evidence seems to indicate that magnetic monopoles, the particles that would carry magnetic 'charge', either don't exist, or, the energies required to create them are so high that they are exceedingly rare.  That doesn't stop us from looking for them though!

Keeping with the theme of Fairbank[1] and his academic progeny over the semester break, today's post is about the discovery of a magnetic monopole candidate event by one of the Fairbank's graduate students, Blas Cabrera[2].  Cabrera was utilizing a loop type of magnetic monopole detector.  Its operation is in concept very simpl…

The Javascript Google URL Shortener Client API

I was working with the Google API Javascript Client this week to shorten the URLs of Google static maps generated by my ham radio QSL mapper. The client interface provided by Google is very useful. It took me a while to work through some of the less clear documentation, so I thought I'd add a few notes that would have helped me here. First, you only need to authenticate your application to the url shortener application if you want to track statistics on your shortened urls. If you just want the shortened URL, you don't need to worry about this. The worst part for me was that the smaple code only showed how to get a long url from an already shortened rul. If you follow the doucmentaiotn on the insert method, (the method for getting a shortened url from a long one), there is a reference to a rather nebulous Url resource required argument. It's not at all clear how to create one of these in Javascript. The following example code shows how:
var request = gapi.clie…