Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

Free Nodelet Hack: AJAX-enabled Chatterbox

by bellaire (Hermit)
on Mar 13, 2009 at 20:57 UTC ( #750520=monkdiscuss: print w/replies, xml ) Need Help??

This code is still very new, but it seems to work acceptably for me in Firefox and Opera. Basically, it uses Ajax to update the contents of your chatterbox every 10 seconds. Also, postbacks using the "talk" button are sent through Ajax. It's similar in effect to the sidebar or one of the fullpage clients, except it works in-place and looks just like the vanilla CB. However, there are some caveats. Suggestions/demands for improvement are welcome:
  • The code downloads the jQuery API from Google. If you don't trust Google, I suppose you could shove the entire minified jQuery core into your free nodelet instead, I think it'd take about a quarter of your available space by itself, and this thing probably an additional 10%. Of course, I don't know how well the free nodelet templating will play with the minified jQuery core.
  • There's some jumpiness. Since it's running as an inline CB, the size (rendered height) of the CB can change out from under you. Not sure the best way to handle this yet. Also, there is a brief lag every 10 seconds while your browser messes with the DOM to update the CB.
  • It's not mature. By any stretch. I'm sure there are still bugs in this code. Use at your own risk. Your mileage may vary.
Change Log:
  • 3/13/2009
    • As requested by tye, the script now includes a timeout. By default, if you don't click "Talk" for 10 minutes, the script will stop updating. You get a 1-minute warning as this time approaches. If the script stops updating, you can always click "Talk" to refresh and resume.
    • The script now uses the hostname of the open window rather than a hardcoded 'www.perlmonks.org', so it will work whether you use that or just 'perlmonks.org'.
    • The scroll position of your window is maintained even if you have focus in the text entry box when an update occurs.
  • 3/14/2009
    • Fixed a bug where the hack would stop working if there were no messages in the CB.
  • 3/15/2009
    • Moved configuration variables to the top of the JS with comments.
    • Fixed a bug where the checkboxes to delete private messages were always checked on an update.
    • Fixed a bug where in Firefox the cursor position in the talkbox would reset to the beginning of the text field on an update.
    • Added basic fixed-height CB support, but I don't like the way it works yet so it's disabled by default.
  • 3/16/2009
    • Fixed issues with the input box by not replacing it when updating the chatterbox. This simplifies the code quite a bit, and resolves bugs related to strange things interrupting/messing with the input while you are typing a message.
  • 3/20/2009
    • Fixed a small bug related to the previous fix. Even though the talkbox wasn't being replaced, its contents were still being overwritten on each update. Removed the lines responsible. Should fix some quirkiness while typing in some browsers.
  • 3/27/2009
    • Per suggestion by Your mother, changed the presence detection to work by detecting all common events (including mouse motion) in the window. Hence the system no longer asks you to click "Talk" if you are present, all you have to do is move your mouse over the page (or trigger practically any other event) to resume a stopped CB.
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery. +min.js"></script> <script> // Configuration Options -------------------------- var refreshDelay = 10; // seconds between refreshes var inactiveDelay = 600; // inactive seconds before stop var fixedHeight = false; // force fixed height CB var CBHeight = '300px'; // fixed height to use //-------------------------------------------------- var dateObj = new Date(); var CBTimeout; var lastPresence; var CBUpdating = true; $(document).ready(function() { $("body").bind("focus resize scroll click mouseover keypress", +function(){ var nowObj = new Date(); lastPresence = nowObj.getTime(); $('#cb_timeout_warning').remove(); if (!CBUpdating) { CBUpdating = true; updatecb(); } }); CBTimeout = setTimeout("updatecb()", 1000 * refreshDelay); lastPresence = dateObj.getTime(); talkbind(); CBwrap(); }); function send_talk(message,dont_clear) { $('#cb_timeout_warning').remove(); dateObj = new Date(); lastPresence = dateObj.getTime(); clearTimeout(CBTimeout); var dataObj = { node_id: 431883, op: 'message', message: message, }; getCheckboxes(dataObj); $.ajax({ url: 'http://'+window.location.hostname+'/?', type: 'post', data: dataObj, success: function(data) { if(!dont_clear) $('`[name=message`]').val(''); updatecb(); }, error: function(x,t,e) { //opera.postError(t+e); } }); return false; } function talkbind() { $('input`[name=message_send`]').click(function() { return send_talk($('`[name=message`]').val(),false); }); } function CBwrap() { if(fixedHeight) $('#Chatterbox form').children(':not(input:not(`[type=chec +kbox`]))') .wrapAll('<div style="height:'+CBHeight+';overflow:aut +o;"></div>'); } function getCheckboxes(dataObj) { $('#Chatterbox input:checked').each(function() { if ($(this).attr('name').match(/^deletemsg_/)) dataObj`[$(this).attr('name')`] = 'yup'; }); } function updatecb() { $.ajax({ url: 'http://'+window.location.hostname+'/?', data: { node: 'chatterbox sidebar upper', }, success: function(data) { var dataObj = {}; getCheckboxes(dataObj); var extravisible = $('.cbextra:visible').get(0); $('#tempdiv').html(data); $('#Chatterbox form').children(':not(input:not(`[type= +checkbox`]))').remove(); $('#Chatterbox form').prepend($('#Free_Nodelet form'). +contents()); CBwrap(); for (name in dataObj) { $('input`[name=' + name + '`]').attr('checked', 'c +hecked'); } dateObj = new Date(); if((dateObj.getTime() - lastPresence) > ((inactiveDela +y - 60)*1000)) { if(!$('#cb_timeout_warning').get(0)) { $('#Chatterbox .nodelet_body').append( '<div id="cb_timeout_warning" style="color:r +ed">Updates will stop due to inactivity in < 1 minute.</div>' ); } } if ((dateObj.getTime() - lastPresence) > (inactiveDela +y*1000)) { $('#cb_timeout_warning').css({fontWeight : 'bold'}).text(' +Updates stopped due to inactivity.'); CBUpdating = false; } else { CBTimeout = setTimeout("updatecb()", 1000 * refres +hDelay); CBUpdating = true; } } }); } </script> <div id='tempdiv' style='display:none'> </div>

Replies are listed 'Best First'.
Re: Free Nodelet Hack: AJAX-enabled Chatterbox
by tye (Sage) on Mar 13, 2009 at 23:56 UTC

    Please include some "presence" detection such that leaving something like this "up" forever with no interaction times out and stops refreshing.

    Update: Thanks!

    - tye        

      Okay, done. If the user doesn't click "Talk" for 10 minutes, the script stops updating.

        ++ Really neat. You could instead of tying to it 10 minutes after talk tie it to page interaction. Put a listener on the body or something(?) and only refresh every x while there is page activity. Click or scroll, something. Might be the lightest server-load way to go.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: monkdiscuss [id://750520]
Approved by Tanktalus
Front-paged by grinder
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others about the Monastery: (1)
As of 2021-10-17 10:07 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    My first memorable Perl project was:







    Results (71 votes). Check out past polls.

    Notices?