wiki:FancyStatus
Warning: Can't synchronize with repository "(default)" (Unsupported version control system "svn": No module named svn). Look in the Trac log for more information.

Version 1 (modified by reflog@…, 14 years ago) (diff)

thought people might like it too

from splee.blog by Lee McFadden?

I like using ajaxy interfaces in my web apps, and as such I also like the type of status messages that you can achieve using Mochikit. However, sometimes you need to pass a status message between pages (when you’re using raise cherrypy.HTTPRedirect() for example) and I just don’t like having two different ways to display things.

To dissolve my perfectionist worries that the standard tg_flash message in a div just doesn’t cut it, I looked at ways of making the message look the same as a status message from my ajax calls.

Preparing the way

First, I have my simple div to contain the message within the body tags of my master.kid:

<div id="statusmessage"></div>

Then I created the CSS to make this message box look nice:

#statusmessage {
	position: absolute;
	top: -1px;
	left:200px;
	right: 200px;
	z-index: 5000;
}

#statusmessage div {
	width: 400px;
	margin: 0px auto;
	height: 50px;
	padding: 35px 10px 10px 55px;
	background-repeat: no-repeat;
	background-position: left;
	font-size: 18px;
 opacity: .75;
	filter: alpha(opacity=75);
}

#statusmessage div.success {
	background-color: #99CC99;
	border: 1px solid #006633;
	background-image: url("/static/images/dialog-information.png");
}

#rdsmsg div.error {
	background-color: #C00;
	border: 1px solid #600;
	background-image: url("/static/images/dialog-error.png");
}

Note the last two blocks of CSS. The background image, and colours of the status message can be modified depending on the type of status message. The only ones I’ve defined here are ’success’ and ‘error’, but you can have any number of message types.

The Code

The javascript workhorse to control the display of these messages is a simple function using the spanky Mochikit functions available to you.

function displayStatusMessage(status, msg) {

 swapDOM("statusmessage", DIV({'id': 'statusmessage'}, DIV({'class': status}, msg)));

 callLater(5, swapDOM, "statusmessage", DIV({'id': 'statusmessage'}, null));

}

What this function does is to swap out your empty statusmessage div for one packed with the info you give it. It then waits for 5 seconds before making it empty again.

As you can see, providing you have the CSS for the status type, you can pass any type of status that you can think of. Using with AJAX calls

To use these status messages with your AJAX calls is a cinch. Here is an example callback function from the app I’m developing:

function saveHandler(result) {

 data = evalJSONRequest(result);
 
 if (data['status'] == "success") {
 
 displayRdsmsg(data['status'], data['msg']);
 getElement('articleId').value = data['id'];
 
 } else {
 if(data['status'] == "error") {
 displayRdsmsg(data['status'], data['msg']);
 } else {
 displayRdsmsg('fatal', 'There was an unknown error!');
 }
 }
}

The result parameter to the saveHandler function is an XMLHttpRequest object as I’m POST’ing the request to the server rather than using GET. If you want to use Mochikit’s loadJSONDoc() function to handle the request it returns a javascript array for you so you just leave the first line of the above function out and change the parameter name from result to data.

This will provide you with a nice little message everytime you save a document, provided you return the variables status and msg along with the rest of your data in your controller function. Using with tg_flash

This is all fine and dandy when you’re displaying a status message after an async callback as you have some JSON to stuff the status message with. “How do I use this with tg_flash”, I hear you cry?

JSON

Since JSON is native to JavaScript? you can actually create javascript objects from any JSON formatted string. Considering how close JSON syntax is to python’s own lists and dictionaries, you should have no problem creating a string in your controller and passing it to tg_flash.

To provide an example I’ve created a controller function called testflash in my app. We need to import a few extras in your controllers.py:

from turbogears.jsonify import jsonify
import json

And the example for transferring a JSON string in tg_flash:

@turbogears.expose()
def testflash(self):
 flashData = {"status": "error", "msg": "The page was NOT saved!"}
 turbogears.flash(json.write(jsonify(flashData)))
 raise cherrypy.HTTPRedirect(turbogears.url("/"))

The key here is the string passed to turbogears.flash(). This is a JSON string. JavaScript? can recognise this string and build a javascript object out of it. To do this I have the following code within my master.kid’s head tags:

<script type="text/javascript">
 function flashedStatusMessage() {
 flashData = getElement('flashTransport').value;
 statusmsg = eval('(' + flashData + ')');
 displayStatusMessage(statusmsg['status'], statusmsg['msg']);
 }
 addLoadEvent(flashedStatusMessage);
</script>

I then need to add a hidden element in my master.py’s body tags:

<input type="hidden" id="flashTransport" name="flashTransport" py:attrs="value=tg_flash" />

The script will check for the value of the flashTransport element on every page load. If it fails to find anything there is no message, but if tg_flash has been called the value (already nicely escaped by Kid) will be used as the data for the status message.

You can use this method to insert extremely complex status and error messages into your app, not to mention a myriad of options for styling said messages. You are only limited by your ability to create JSON strings to feed tg_flash and your ability to translate those JSON strings into DOM elements using Mochikit.

Here are some screenshots of the (roughly) styled messages when they pop up in my app:

 http://node1.lmsrv.com/images/pretty-tg-flash.png  http://node1.lmsrv.com/images/pretty-tg-flash2.png

posted to wiki by reflog