Ajax dude
So now our application shows an initial page with the user’s friends we will use Ajax to refresh the page periodically and refresh the page.
Let’s first add a new method to our controller that returns the list of users as an ajax resource:
@Inject @Path("users.gtmpl") Template users; @Ajax @Resource public Response.Render users() { Collection[U] friends = whoIsOnline.getFriends("me"); return users.with().set("users", friends).render(); }
(For better code readibility, if you want to try it by yourself, it's here.)
Now we use the users template directly from the controller and this fragment will be returned to the JavaScript part of our application:
$(function() { var refresh = function() { $(".users").each(function() { $(this).jzLoad("Controller.users()"); }); }; // Wait 1/2 second (not realistic of course) // And we should use setInterval with 60 seconds setTimeout(refresh, 500); });
(For better code readibility, if you want to try it by yourself, it's here.)
The JavaScript code is quite trivial but there are two important points here
We use the jzLoad function instead of the jQuery load function : the jzLoad is a jQuery plugin provided by Juzu that allows to specify the reference to a controller instead of an URL. Under the hood Juzu will wrap the HTML with a block that contains the URLs.
The other point is that we don’t need any single script tag in the HTML. Instead we rely on the users CSS class to add behaviour, there are several key benefits to this
The code is in a self contained JavaScript file whoisonline.js and there are not script tag in our application. The whoisonline.js can be cached by the browser
The same JavaScript code works regardless of the number of the portlet we put on the page
In eXo Platform 4 we can serve this code as a JavaScript module and benefit from the advanced modularity provided by GateIn 3.5
Last but not least we provide the code for testing the Ajax load:
@Test @RunAsClient public void testIndex() throws Exception { driver.get(deploymentURL + "/embed/WhoIsOnline"); WebElement p = new WebDriverWait(driver, 10).until( new ExpectedCondition() { public WebElement apply(WebDriver input) { List users = input.findElements(By.cssSelector("div.users ul li")); if (users.size() > 1) { return input.findElement(By.cssSelector("div.users")); } else { return null; } } }); List users = p.findElements(By.tagName("li")); Assert.assertEquals(2, users.size()); }
(For better code readibility, if you want to try it by yourself, it's here.)
We use Selenium WebDriver until method that will block until more than one li tag is available. This will happen after the first Ajax refresh, if it does not happen it means there is a bug and after 10 seconds the until method will fail and make the unit test fail.
Additional Resources:
If you want to try it by yourself and use the code provided, please refer to this blog post.
To learn more about the Juzu Web Framwork, Three Days with Juzu: Write a Killer App, is the good starting point. It gives an overview of Juzu capabilities and then dive deeper in the specifics to use this new web framework efficiently.
|