Previously Mike Orr wrote:
> If you could write a little howto about using it with Ajax and styling
> different categories, I'm sure it would help a fair number of people.

I didn't see a login for that trac, so I'll post it here:



Implementation example
======================

Lets show a standard way of using flash messages in your site: we will
demonstrate *self-healing messages* (similar to what Growl does on OSX)
to show messages in a site.

To send a message from python just call the flash helper method::

   from myapp.lib.helpers import flash

   flash(u"Settings have been saved")

This will tell the system to show a message in the rendered page. If you need
more control you can specify a message category as well: one of *warning*,
*notice*, *error* or *success*. The default category is *notice*. For example::

   from myapp.lib.helpers import flash

   flash(u"Failed to send confirmation email", "warning")

We will use a very simple markup style: messages will be placed in a ``div``
with id ``selfHealingFeedback`` at the end of the document body. The messages
are standard paragraphs with a class indicating the message category. For
example::

  <html>
    <body>
      <div id="content">
        ...
        ...
      </div>
      <div id="selfHealingFeedback">
        <p class="success">Succesfully updated your settings</p>
        <p class="warning">Failed to send confirmation email</p>
      </div>
    </body>
  </html>

This can easily created from a template. If you are using Genshi this
should work:

  <div id="selfHealingFeedback">
    <p class="notice" py:for="message in h.flash.pop_messages()"
       py:attrs="{'class' : message.category}" py:content="message">
      This is a notice.
    </p>
  </div>


The needed CSS is very simple::

    #selfHealingFeedback {
        position: fixed;
        top: 20px;
        left: 20px;
        z-index: 2000;
    }
    
    #selfHealingFeedback p {
        margin-bottom: 10px;
        width: 250px;
        opacity: 0.93;
    }
    
    p.notice,p.error,p.success,p.warning {
        border: 3px solid silver;
        padding: 10px;
        -webkit-border-radius: 3px;
        -moz-border-radius: 3px;
        border-radius: 3px;
        -webkit-box-shadow: 0 0 5px silver;
    }

Choosing different colours for the categories is left as an excersize
for the reader.

Next we create the javascript that will manage the needed behaviour (this
implementation is based on jQuery)::

    function _SetupMessage(el) {
        var remover = function () {
            msg.animate({opacity: 0}, "slow")
               .slideUp("slow", function() { msg.remove() }); };
    
        msg.data("healtimer", setTimeout(remover, 10000))
           .click(function() { clearTimeout(msg.data("healtimer")); remover(); 
});
    }

    function ShowMessage(message, category) {
        if (!category)
            category="notice";
    
        var container = $("#selfHealingFeedback");
    
        if (!container.length)
            container=$("<div id='selfHealingFeedback'/>").appendTo("body");
    
        var msg = $("<p/>").addClass(category).html(message);
        SetupMessage(msg);
        msg.appendTo(container);
    }

    $(document).ready(function() {
        $("#selfHealingFeedback p").each(function() { SetupMessage($(this)); });
    }
    
The ``SetupMessage`` function configures the desired behaviour: a message
disappears after 10 seconds, or if you click on it. Removal is done using
a simple animation to avoid messages jumping around on the screen.

This function is called for all messages as soon as the document has fully
loaded. The ``ShowMessage`` function works exactly like the ``flash`` method
in python: you can call it with a message and optionally a category and it
will pop up a new message.
    

JSON integration
================

It is not unusal to perform a remote task using a JSON call and show a
result message to the user. This can easily be done using a simple wrapper
around the ShowMessage method::

    function ShowJSONResponse(info) {
        if (!info.message)
            return;
    
        ShowMessage(info.message, info.message_category);
    }

You can use this direct as the success callback for the jQuery AJAX method::

   $.ajax({type: "POST",
           url:  "http://your.domain/call/json";,
           dataType: "json",
           success: ShowJSONResponse
   });

if you need to perform extra work in your callback method you can call
it yourself as well, for example::

   <form action="http://your.domain/call/form";>
     <input type="hidden" name="json_url" value="http://your.domain/call/json";>
     <button>Submit</button>
   </form>
    
   <sript type="text/javascript">
      $(document).ready(function() {
          $("button").click(function() {
              var button = $(this);
  
              button.addClass("processing");
              $.ajax({type: "POST",
                      url:  this.form["json_url"].value,
                      dataType: "json",
                      success: function(data, status) {
                          button.removeClass("processing");
                          ShowJSONResponse(data);
                       },
                       error: function(request, status, error) {
                          button.removeClass("processing");
                          ShowMessage("JSON call failed", "error");
                       }
              });

              return false;
          });
      });
   </script>

This sets up a simple form which can be submitted normally by non-javascript
enabled browsers. If a user does hava javascript an AJAX call will be made
to the server and the result will be shown in a message. While the call is
active the button will be marked with a *processing* class.

The server can return a message by including a ``message`` field in its
response. Optionally a ``message_category`` field can also be included
which will be used to determine the message category. For example::

    @jsonify
    def handler(self):
       ..
       ..
       return dict(message=u"Settings succesfully updated")




-- 
Wichert Akkerman <wich...@wiggy.net>    It is simple to make things.
http://www.wiggy.net/                   It is hard to make things simple.

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"pylons-discuss" group.
To post to this group, send email to pylons-discuss@googlegroups.com
To unsubscribe from this group, send email to 
pylons-discuss+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/pylons-discuss?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to