Flash tag
Flash is a concept which does not exist in standard Java API, but is very useful in web applications. Flash is a snippet of HTML whose life cycle is limited by the next HTTP request. In other words, a flash is created during a request, then it can be used in a subsequent request (of the same session), after which it dies.
Flash messages are useful in cases when a POST/Redirect to GET pattern is used.
Use case 1: pass message from controller
Flash messages are created in controllers (or filters) like so:
@POST
public void create(){
Book book = new Book();
book.fromMap(params1st());
if(!book.save()){
flash("message", "Something went wrong, please fill out all fields");
flash("errors", book.errors());
flash("params", params1st());
redirect(BooksController.class, "new_form");
}else{
flash("message", "New book was added: " + book.get("title"));
redirect(BooksController.class);
}
}
In a code of controller above, a new book is submitted in a POST request.
Line 5 is making attempt to save the book information to DB.
Lines 6, 7, 8 - in case of failure, three instances of flash are created:
message
,errors
andparams
, wheremessage
is a generic message displayed at the top of page,params
is a map with submitted values (it is used to re-populate input fields) and theerror
is a map with error messagesLine 11 - In case of success request is redirected to BooksController index method and the flash message is sent to view. The file
/views/books/index.ftl
would have a flash message displayed withflash
tag:
For a complete example of using FlashTag, please refer to BooksController#create() and corresponding views. Also, please see ActiveJDBC Validation
The Flash tag automatically detects if a flash message exists and displays it. If a message is missing, nothing is rendered.
Since the user was redirected to the BooksController with an HTTP GET method, the page can simply be reloaded if a user presses Reload
button on browser. However, if a user actually reloads the page, the flash message will disappear, because it cannot survive across more than one request.
In general, POST/Redirect to GET is a good programming pattern to use in case you need destructive
operations. Leaving a user on a POSTed page is a bad idea, because the same request can be re-submitted if user presses Reload.
Use case 2: Named FlashTag with body
If you need to display a more complex HTML than a simple string, you can do so by placing a flash tag with body on the page:
and calling a single argument method inside the controller:
The body inside the flash tag lives by the same rules as any other in the template. You can use variables, normal syntax, lists or even partials:
It allows to organize code for error and warning messages into reusable componets.
Use case 3: Anonymous FlashTag with body
In case you only need one flash tag with body, no need to specify a name:
In controller:
Testing named flash with message
If you set this in the controller:
@POST
public class BooksController extends AppController{
public void create(){
// ...
flash("success", "Your book was saved successfully")
// ...
}
}
Then you can write a test like this:
public class BooksControllerSpec extends DBControllerSpec{
public void shouldSaveBook(){
request().params("title", "To Kill a Mockingbird", "author", "Harper Lee").post("save");
the(flash("success")).shouldBeEqual("Your book was saved successfully");
}
}
Testing named flash with body
If you set this in the controller:
@POST
public class BooksController extends AppController{
public void create(){
// ...
flash("success")
// ...
}
}
and your view looks like this:
Then you can write a test like this:
public class BooksControllerSpec extends DBControllerSpec{
public void shouldSaveBook(){
request().params("title", "To Kill a Mockingbird", "author", "Harper Lee").post("save");
the(flashExists("success")).shouldBeTrue();
the(responseContent()).shouldContain("Your book was saved successfully!");
}
}
Rendering dynamic snippets of HTML (old method)
Older method is still operational, but not recommended:
<#if (flasher.message) ??>
<span style="background-color:red">
<@flash name="message"/>
</span>
</#if>
The HTML code inside the IF condition has no restrictions to use any dynamic values from session of those passed into view by controller.
Internationalization of flash messages
The FlashTag is not internationalized. However, you can do this using one of two methods.
Method 1: Use class Messages in controller
Lets say your activeweb_messages_properties
file contains this entry:
book_added=A book {0} was added to your library. Author: {1}
Please, refer to org.javalite.activejdbc.Messages
In controller write this:
In view:
This will print:
Method 2: Use MessageTag
Lets say your activeweb_messages_properties
file contains this entry:
In controller:
In view:
This will print:
Method 1 should be used when you have parametrized messages. There is no way to pass a parameter to the MessageTag in method 2, because it is running in a different request (after redirect).
Choose a method that most appropriate for your app.
How to comment
The comment section below is to discuss documentation on this page.
If you have an issue, or discover bug, please follow instructions on the Support page