Dandelion 0.10.0
-
Upload
thibault-duchateau -
Category
Software
-
view
464 -
download
2
description
Transcript of Dandelion 0.10.0
Thibault Duchateau@tduchateau
http://dandelion.github.io
1 / 101
Quick introduction
Brief historyDandelion-Core
Dandelion-DatatablesSome statistics
FutureDemo
2 / 101
Quick introductionFree & Open Source Java framework
Focused on two aspects of Web development:
Assets management (js, css): organization in bundles, HTMLinjection, soon asset minification and merging
Integration of powerful Javascript librairies thanks to a set ofcomponents
Licensed under BSD 3-Clause
Hosted on Github
Current version: 0.10.0
3 / 101
Thanks to...
4 / 101
Quick introduction
Brief history
Dandelion-CoreDandelion-Datatables
Some statisticsFutureDemo
5 / 101
Quick introductionBrief history
Dandelion-Core
Dandelion-DatatablesSome statistics
FutureDemo
7 / 101
Overview
8 / 101
Asset bundles
Declarative approach, via JSON (soon XML and JavaConfig)
{ "bundle" : "jquery", "assets": [ { "name": "jquery", "version": "1.11.1", "type": "js", "locations": { "webapp": "/assets/js/jquery-1.11.1.js" } } ]}
Several locations are allowed for each asset: webapp, classpath, CDN, JAR,WebJar and API!
See the docs
9 / 101
Dependencies between bundles
You can declare one or more bundles as dependencies
{ "bundle" : "select2", "dependencies": [ "jquery" ], "assets": [ { "name": "select2", "version": "3.4.8", "type": "js", "locations": { "webapp": "/assets/js/select2.js" } }, { "name": "select2", "version": "3.4.8", "type": "css", "locations": { "webapp": "/assets/css/select2.css" } } ]}
10 / 101
Asset locators
Internal components used by Dandelion to fetch assets indifferent ways
Used via the corresponding location key in the bundle declaration
See the docs
11 / 101
Project your-project|__ src |__ main |__ webapp |__ assets |__ js |__ app.js
Asset locators — webapp
12 / 101
Project
Bundle
{ "bundle" : "my-bundle", "assets": [{ "name": "my-application", "version": "1.0.0", "type": "js", "locations": { "webapp": "/assets/js/app.js" } }]}
Asset locators — webapp
13 / 101
Project
Bundle
HTML
<script src="/[contextPath]/assets/js/app.js"></script>
Asset locators — webapp
14 / 101
Project your-project|__ src |__ main |__ resources |__ js |__ app.js
Asset locators — classpath
15 / 101
Project
Bundle
{ "bundle" : "my-bundle", "assets": [{ "name": "my-application", "version": "1.0.0", "type": "js", "locations": { "classpath": "js/app.js" } }]}
Asset locators — classpath
16 / 101
Project
Bundle
HTML
<script src="/[contextPath] /dandelion-assets /[cacheKey] /app.js"></script>
Asset locators — classpath
17 / 101
Bundle { "bundle" : "jquery", "assets": [{ "name": "jquery", "version": "1.11.0", "type": "js", "locations": { "cdn": "//cdnjs.cloudflare.com/.../jquery.js" } }]}
Asset locators — cdn
18 / 101
Bundle
HTML
<script src="//cdnjs.cloudflare.com/.../jquery.js"></script>
Asset locators — cdn
19 / 101
JAR datatables-core|__ src |__ main |__ resources |__ META-INF |__ resources |__ folder |__ js |__ app.js
Asset locators — jar
20 / 101
JAR
Bundle
{ "bundle" : "my-bundle", "assets": [{ "name": "my-app", "version": "1.0.0", "type": "js", "locations": { "jar": "folder/js/app.js" } }]}
Asset locators — jar
21 / 101
JAR
Bundle
HTML
Inside a Servlet 2.0+ container:
<script src="/[contextPath] /dandelion-assets /[cacheKey] /app.js"></script>
Inside a Servlet 3.0+ container:
<script src="/[contextPath]/folder/js/app.js"></script>
Dandelion automatically detects whether therunning server is using the Servlet 3.x API or lower
Asset locators — jar
22 / 101
Newdependency
<dependency> <groupId>com.github.dandelion</groupId> <artifactId>dandelion-webjars</artifactId> <version>0.10.0</version></dependency>
This artifact brings a new dependency to the webjars-locator project, which is internally used by the locator tolocate assets inside WebJars
Asset locators — webjar
23 / 101
Newdependency
WebJar
<dependency> <groupId>org.webjars</groupId> <artifactId>bootstrap</artifactId> <version>3.2.0</version></dependency>
Asset locators — webjar
24 / 101
Newdependency
WebJar
Bundle
{ "bundle" : "my-bundle", "assets": [{ "name": "bootstrap", "version": "3.2.0", "type": "css", "locations": { "webjar": "bootstrap.css" } }]}
Asset locators — webjar
25 / 101
Newdependency
WebJar
Bundle
HTML
Inside a Servlet 2.0+ container:
<link rel="stylesheet" href="/[contextPath] /dandelion-assets /[cacheKey] /bootstrap.css"/>
Inside a Servlet 3.0+ container:
<link rel="stylesheet" href="/[contextPath] /webjars /bootstrap /3.2.0 /css /bootstrap.css" />
Dandelion automatically detects whether therunning server is using the Servlet 3.x API or lower
Asset locators — webjar
26 / 101
Asset locators — delegateReads the content of an asset from a special parameter stored inside theAssetRequestContext
This special parameter:
must be stored under the DelegateLocator.DELEGATED_CONTENT_PARAMkey
must be a class that implements DelegatedContent and where thegetContent() method must return the asset content to be injected ]
27 / 101
Bundle { "bundle": "my-bundle", "assets": [{ "name": "my-generated-asset", "version": "1.0.0", "type": "js", "locations": { "delegate": "app.js" } }]}
Asset locators — delegate
28 / 101
Bundle
Generator
public class SomeJavascriptGenerator implements DelegatedContent {
@Override public String getContent(HttpServletRequest request) { return "alert('Hey!');"; }}
Asset locators — delegate
29 / 101
Bundle
Generator
ARC
AssetRequestContext .get(request) .addParameter("my-generated-asset", DelegateLocator.DELEGATED_CONTENT_PARAM, new SomeJavascriptGenerator());
Asset locators — delegate
30 / 101
Bundle
Generator
ARC
HTML
<script src="/[contextPath] /dandelion-assets /[cacheKey] /app.js"></script>
Where app.js:
alert('Hey!');
Asset locators — delegate
31 / 101
Bundle loaders
Scan for bundles in the classpath, in the following order:
VendorBundleLoader: intended to load vendor bundles (e.g. jquery.json)
ComponentBundleLoader: intended to load components bundles (e.g. ddl-dt.json)
DandelionBundleLoader: intended to load user bundles (e.g. custom-bundle.json)See the docs
32 / 101
Bundle graphOn the application startup, Dandelion creates a Context that will be injectedinto each request.
This Context provide several information:
all configuration options (coming from the properties files)a bundle graph (DAG), built from all scanned bundles
Example:
src|__ main |__ resources |__ dandelion |__ jquery.json |__ select2.json
See the docs
33 / 101
Interacting with the bundle graph
1/4) Using the JSP taglib
<%@ taglib prefix="dandelion" uri="http://github.com/dandelion" %>
<dandelion:bundle includes="select2" />
2/4) Using the Thymeleaf dialect
<!DOCTYPE html><html xmlns:th="http://www.thymeleaf.org" xmlns:ddl="http://github.com/dandelion" ddl:bundle-includes="select2"> ...</html>
See the docs
34 / 101
Interacting with the bundle graph
3/4) Using the fluent API
AssetRequestContext .get((HttpServletRequest) request) .addBundle("select2");
4/4) Using the configuration file ("permanent" bundles)
bundle.includes=select2
See the docs
35 / 101
Interacting with the bundle graph
Whatever the technology used, Dandelion automatically injects allrequested assets into the HTML code:
in the right orderin the configured position, by default CSS in <head> and JS just before</body>and (soon) applies the right HTTP headers, therefore optimizing browsercaching
<html> <head> <link href="/context/assets/css/select2.css" /> </head> <body> ... <script src="/context/assets/js/jquery-1.11.1.js"></script> <script src="/context/assets/js/select2.js"></script> </body></html>
36 / 101
Asset processors
Intended to process assets, in different ways...
Built-in processors:
jsMinYui:JS minification based on Yahoo's YUI CompressorcssMinYui:CSS minification based on Yahoo's YUI CompressorcssMin:CSS minification based on a fork of YUIjsMin:JS minification based on a fork of YUIcssUrlRewriting:Image URLs rewriting in CSS
Soon:
cssLess: Convert Less resources to CSScssSass: Convert Sass resources to CSScssImport: Processes @importcoffeeScript: Convert CoffeeScript to JavaScript...
See the docs
37 / 101
Development/production modes
Development mode
Built-in dev tools availableServer-side caching disabledBrowser caching disabled
Production mode
No bundle graph viewer, no bundle reloadingMinification enabledServer-side caching enabled(soon) Browser caching enabled(soon) GZIP compression(soon) Asset versioning(soon) JMX monitoring
38 / 101
Dev tools
Bundle graphviewer
Dev tool allowing to visualize how Dandelion-Corehandles assets, in the current request
http://example.com/context/some/uri?showGraph
Available in development mode only
See the docs
39 / 101
Dev tools
Bundle graphviewer
Assetreloading
During development, both server-side and client-sidecaching are disabled.
Client-side, Dandelion-Core applies the following HTTPheaders:
Cache-Control = no-cache, no-store, must-revalidate (HTTP 1.1)Pragma = no-cache (HTTP 1.0)Expires = 0 (Proxies)
40 / 101
Dev tools
Bundle graphviewer
Assetreloading
Bundlereloading
During development, all changes made in asset bundlescan be reflected.
Just manually append a new reloadBundles requestparameter to the current URL to perform a full bundlereloading.
http://example.com/context/some/uri?reloadBundles
Available in development mode only
41 / 101
Properties dandelion.properties
dandelion.mode=production
Configuration options
42 / 101
Properties
Filter initparam
filter init param > dandelion.properties
<filter> <filter-name>dandelion</filter-name> <filter-class>...DandelionFilter</filter-class> <init-param> <param-name>dandelion.mode<param-name> <param-value>production</param-value> </init-param></filter>
Configuration options
43 / 101
Properties
Filter initparam
Systemproperty
system property > filter init param >dandelion.properties
-Ddandelion.mode=production
Configuration options
See the docs
44 / 101
Quick introductionBrief history
Dandelion-Core
Dandelion-Datatables
Some statisticsFutureDemo
45 / 101
Introducing Dandelion-DatatablesFirst and most advanced component of the Dandelion framework
Facilitates the integration of DataTables, an awesome jQueryplugin which will add advanced interaction controls to any HTMLtable
Easy to use
Easy to extend
Inspired by the excellent DisplayTag library
46 / 101
Key featuresJSP & Thymeleaf supportTypical features such as paging, filtering and sortingDOM sources, AJAX sources and server-side processingResponsive designExport in multiple formatsSeveral themes available: Bootstrap 2, Bootstrap 3, jQueryUII18nIntegration with Spring/Spring MVC and other projects
47 / 101
What it looks like with JSP?
<%@ taglib prefix="datatables" uri="http://github.com/dandelion/datatables" %>
<datatables:table id="myTableId" data="${persons}"> <datatables:column title="Id" property="id" /> <datatables:column title="LastName" property="lastName" /> <datatables:column title="FirstName" property="firstName" /> <datatables:column title="City" property="address.town.name" /> <datatables:column title="Mail" property="mail" /></datatables:table>
id: HTML pass-through attributedata: DOM source, collection of POJOstitle: sets the content of the column headerproperty: name of the object's attribute of the collection being iterated on
48 / 101
What it looks like with Thymeleaf?
<table id="myTableId" dt:table="true"> <thead> <tr> <th>Id</th> <th>Firstname</th> <th>Lastname</th> <th>City</th> <th>Mail</th> </tr> </thead> <tbody> <tr th:each="person : ${persons}"> <td th:text="${person.id}">1</td> <td th:text="${person.firstName}">John</td> <td th:text="${person.lastName}">Doe</td> <td th:text="${person?.address?.town?.name}">Nobody knows!</td> <td th:text="${person.mail}">[email protected]</td> </tr> </tbody></table>
dt:table: enables the Dandelion-Datatables dialect in the current table
49 / 101
HTML The HTML is generated:
either by Dandelion-Datatables (JSP)or directly by Thymeleaf
<table id="myTableId"> <thead> <tr> <th>Id</th> <th>Firstname</th> <th>Lastname</th> <th>City</th> <th>Mail</th> </tr> </thead> <tbody> <tr> <td>1</td> <td>Wing</td> <td>Cunningham</td> <td></td> <td>[email protected]</td> </tr> ... </tbody></table>
How it works?
50 / 101
HTML
JavaScript
As well as the JS code that initializes DataTables
var oTable_myTableId = $('#myTableId');var oTable_myTableId_params = { "aoColumns":[ { "mData":"id", "sDefaultContent":"" }, { "mData":"lastName", "sDefaultContent":"" }, { "mData":"firstName", "sDefaultContent":"" }, { "mData":"address.town.name", "sDefaultContent":"" }, { "mData":"mail", "sDefaultContent":"" } ]}
$(document).ready(function(){ oTable_myTableId.dataTable(oTable_myTableId_params);});
How it works?
51 / 101
HTML
JavaScript
Requiredassets
An AssetRequestContext is filled with the required assets,either by the JSP taglib or by the Thymeleaf dialect...
AssetRequestContext .get(request) .addBundle("datatables") .addBundle("ddl-dt") ...;
... so that they will be injected by Dandelion-Core into theresponse
<link href="//cdn/jquery.dataTables.css"/>...<script src="//cdn/jquery.js"></script><script src="//cdn/jquery.dataTables.js"></script><script src="/[contextPath] /dandelion-assets /[SHA] /dandelion-datatables-0.10.0.js"></script>
How it works?
52 / 101
Usage examples
53 / 101
HTML (DOM) sourcesRead data directly from the DOM
Works well with small/medium data sources
54 / 101
Controller Example with a Spring MVC controller
@Controllerpublic class Controller {
@ModelAttribute("persons") public List<Person> populateTable() { return personService.findAll(); }}
HTML sources — example
55 / 101
Controller
JSP
<datatables:table id="myTableId" data="${persons}"> <datatables:column title="Id" property="id" /> ...</datatables:table>
HTML sources — example
56 / 101
Controller
JSP
Thymeleaf
<table id="myTableId" dt:table="true"> ... <tbody> <tr th:each="person : ${persons}"> <td th:text="${person.id}">1</td> ... </tr> </tbody><table>
HTML sources — example
57 / 101
AJAX sourcesRead data from virtually any JSON data source that can be obtained byAJAX
Client-side processing
Works well with small/medium data sources
58 / 101
Controller Example with a Spring MVC controller
@Controllerpublic class AjaxController {
@RequestMapping(value = "/persons") public @ResponseBody List<Person> findAll() { return personService.findAll(); }}
AJAX sources
59 / 101
Controller
JSP
<datatables:table id="myTableId" url="/persons"> <datatables:column title="Id" property="id" /> ...</datatables:table>
Dandelion-Datatables rewrites URLs by appending thecontext path, if needed.
AJAX sources
60 / 101
Controller
JSP
Thymeleaf
<table id="myTableId" dt:table="true" dt:url="@{/persons}"> ... <tbody> <tr th:each="person : ${persons}"> <td th:text="${person.id}">1</td> ... </tr> </tbody><table>
AJAX sources
61 / 101
AJAX sources + server-side processingRead data from virtually any JSON data source that can be obtained byAJAX
Server-side processing
Each draw of the table will result in a new AJAX request being made toget the required data
Works well with small/medium/large data sources
62 / 101
AJAX sources + server-side processing
Dandelion-Datatables provides a convenient API
DatatablesCriterias
Stores all DataTables parameters (current page, entries to display,sorted columns, ...)
@RequestMapping(value = "/persons")public @ResponseBody DatatablesResponse<Person> filter(HttpServletRequest request) {
// Maps request parameter to a DatatablesCriterias instance DatatablesCriterias criterias = DatatablesCriterias.getFromRequest(request);
...
63 / 101
AJAX sources + server-side processing
Dandelion-Datatables provides a convenient API
DataSet
All entries returned by the data access layer should be wrapped in thisclass in order to build a DataTablesResponse
...
// Get filtered and paged data DataSet<Person> persons = personService.findPersons(criterias);
...
64 / 101
AJAX sources + server-side processing
Dandelion-Datatables provides a convenient API
DataTablesResponse
Contains a builder that helps to return the data in the format requiredby DataTables
Must be converted into JSON
...
// Build the response that will be converted to JSON return DatatablesResponse.build(persons, criterias);}
65 / 101
Controller Example with a Spring MVC AJAX controller
@RequestMapping(value = "/persons")public @ResponseBody DatatablesResponse<Person> filter(HttpServletRequest request) {
// Maps request parameter to a DatatablesCriterias instance DatatablesCriterias criterias = DatatablesCriterias.getFromRequest(request);
// Get filtered and paged data DataSet<Person> persons = personService.findPersons(criterias);
// Build the response that will be converted to JSON return DatatablesResponse.build(persons, criterias);}
AJAX sources + server-side processing
66 / 101
Controller
JSP
<datatables:table ... url="/persons" serverSide="true"> <datatables:column property="id" /> <datatables:column property="firstName" /> <datatables:column property="lastName" /> <datatables:column property="address.town.name" /> <datatables:column property="mail" /></datatables:table>
AJAX sources + server-side processing
67 / 101
Controller
JSP
Thymeleaf
<table ... dt:url="@{/persons}" dt:serverSide="true"> <thead> <tr> <th dt:property="id">Id</th> <th dt:property="firstName">Firstname</th> <th dt:property="lastName">Lastname</th> <th dt:property="address.town.name">City</th> <th dt:property="mail">Mail</th> </tr> </thead></table>
AJAX sources + server-side processing
68 / 101
JSP <datatables:table ... pageable="false"> <datatables:column ... sortable="false" /> <datatables:column ... filterable="true" /> ...</datatables:table>
Paging, sorting, filtering
69 / 101
JSP
Thymeleaf
<table ... dt:pageable="false" > <thead> <th dt:sortable="false">Id</th> <th dt:filterable="true">LastName</th> ... </thead> ...<table>
Paging, sorting, filtering
70 / 101
Export — what formats?
Text-based formats: CSV, XML
Built-in support, no dependency or extra required.
71 / 101
Export — what formats?
Binary-based formats: PDF, XLS, XLSX
Some extras already exist and provide:
an export class that is used by default if the corresponding export formatis enabledthe corresponding library in compile scope (e.g. Apache POI for the XLSformat)
Available extras:
PDF: datatables-export-itextXLS: datatables-export-poiXLSX: datatables-export-poi-ooxml
72 / 101
Export — 2 ways
Filter-based
Fast to set upAlways export full data sourceOnly compatible with DOM sources
Controller-based
Requires a bit more work to set upWYSIWYE => What You See Is What You ... Export!Compatible with DOM and AJAX sources
73 / 101
Newdependency
<dependency> <groupId>com.github.dandelion</groupId> <artifactId>datatables-export-itext</artifactId> <version>0.10.0</version></dependency>
Export — filter-based
74 / 101
Newdependency
web.xml
<!-- Dandelion-Datatables filter used for basic export --><filter> <filter-name>datatables</filter-name> <filter-class>...DatatablesFilter</filter-class></filter><filter-mapping> <filter-name>datatables</filter-name> <url-pattern>/*</url-pattern></filter-mapping>
Export — filter-based
75 / 101
Newdependency
web.xml
JSP
<datatables:table ... export="pdf"> <datatables:column property="id" /> <datatables:column property="firstName" /> <datatables:column property="lastName" /> <datatables:column property="address.town.name" /> <datatables:column property="mail" /></datatables:table>
Export — filter-based
76 / 101
Newdependency
web.xml
JSP
Thymeleaf
<table id="myTable" dt:table="true" dt:export="pdf"> <thead> <tr> <th>Id</th> <th>Firstname</th> <th>Lastname</th> <th>City</th> <th>Mail</th> </tr> </thead> <tbody> <tr th:each="person : ${persons}"> <td th:text="${person.id}">1</td> <td th:text="${person.firstName}">John</td> <td th:text="${person.lastName}">Doe</td> <td th:text="${person.address.town.name}">Nobody knows!</td> <td th:text="${person.mail}">[email protected]</td> </tr> </tbody></table>
Export — filter-based
77 / 101
Newdependency
<dependency> <groupId>com.github.dandelion</groupId> <artifactId>datatables-export-itext</artifactId> <version>0.10.0</version></dependency>
Export — controller-based
78 / 101
Newdependency
JSP
<datatables:table id="myTableId" url="/persons" export="pdf"> <datatables:column property="id" /> <datatables:column property="firstName" /> ... <datatables:export type="csv" url="/export.pdf" /></datatables:table>
Export — controller-based
79 / 101
Newdependency
JSP
Thymeleaf
<div dt:conf="myTableId"> <div dt:confType="export" dt:type="pdf" dt:url="@{/export.pdf}"></div></div>
<table ... dt:url="@{/persons}" dt:export="pdf"> <thead> <tr> <th dt:property="id">Id</th> <th dt:property="firstName">Firstname</th> <th dt:property="lastName">Lastname</th> <th dt:property="address.town.name">City</th> <th dt:property="mail">Mail</th> </tr> </thead></table>
Export — controller-based
80 / 101
Newdependency
JSP
Thymeleaf
Controller(1/4)
@RequestMapping(value = "/export", produces = "application/pdf")public void pdf(@DatatablesParams DatatablesCriterias criterias, HttpServletRequest request, HttpServletResponse response) {
// Get data to export using the provided criteria List<Person> persons = personService.findPersons(criterias);
...
Export — controller-based
81 / 101
Newdependency
JSP
Thymeleaf
Controller(2/4)
...
// Build the export configuration ExportConf exportPdfConf = new ExportConf.Builder("pdf") .header(true) .exportClass(new PdfExport()) .build();
...
Export — controller-based
82 / 101
Newdependency
JSP
Thymeleaf
Controller(3/4)
...
// Build the table to export using the above data // and the export configuration HtmlTable table = new HtmlTableBuilder<Person>() .newBuilder("tableId", persons, request, exportPdfConf) .column().fillWithProperty("id").title("Id") .column().fillWithProperty("firstName").title("Firtname") .column().fillWithProperty("lastName").title("Lastname") .column().fillWithProperty("address.town.name").title("City") .column().fillWithProperty("mail").title("Mail") .column() .fillWithProperty("birthDate", "{0,date,dd-MM-yyyy}") .title("BirthDate") .build();
...
Export — controller-based
83 / 101
Newdependency
JSP
Thymeleaf
Controller(4/4)
...
// Render the export file in the browser ExportUtils.renderExport(table, exportPdfConf, response);}
Export — controller-based
84 / 101
I18n: DataTables' informationdatatables.properties: non-translatable properties
global.css.class=table table-striped table-bordered table-condensedglobal.extra.theme=bootstrap2
datatables_EN.properties: all EN translations
global.i18n.msg.processing=Processing...global.i18n.msg.search=Search:global.i18n.msg.info=Showing _START_ to _END_ of _TOTAL_ entries
datatables_FR.properties: all FR translations
global.i18n.msg.processing=Traitement en cours...global.i18n.msg.search=Rechercher :global.i18n.msg.info=Affichage de l'élément _START_ à _END_ sur _TOTAL_ éléments
85 / 101
I18n: column headersBased on LocaleResolver and MessageResolver interfaces
Built-in implementations:
SpringLocaleResolver / SpringMessageResolverJstlLocaleResolver / JstlMessageResolverStruts1LocaleResolver / Struts1MessageResolverStruts2LocaleResolver / Struts2MessageResolver
Possible to plug-in custom locale and message resolvers
86 / 101
Spring config <bean id="messageSource" class="..."> <property name="basename" value="classpath:messages" /></bean>
I18n: example with Spring
87 / 101
Spring config
Resourcebundles
Location:
src|__ main |__ resources |__ messages.properties |__ messages_FR.properties
messages.properties:
table.header.lastname=Lastnametable.header.firstname=Firstname
messages_FR.properties:
table.header.lastname=Nomtable.header.firstname=Prénom
I18n: example with Spring
88 / 101
Spring config
Resourcebundles
JSP
<datatables:table id="myTableId" data="${persons}"> ... <datatables:column titleKey="table.header.firstname" ... /> <datatables:column titleKey="table.header.lastname" ... /> ...</datatables:table>
I18n: example with Spring
89 / 101
Spring config
Resourcebundles
JSP
Thymeleaf
<table id="myTableId" dt:table="true"> <thead> <tr> ... <th th:text="#{table.header.firstname}">Firstname</th> <th th:text="#{table.header.lastname}">Lastname</th> ... </tr> </thead> ...</table>
I18n: example with Spring
90 / 101
ThemingSupported themes:
jQueryUI ThemeRollerBootstrap 2
TableclothResponsive
Bootstrap 3Responsive
91 / 101
JSP <datatables:table ... theme="bootstrap3" cssClass="table"> <datatables:column property="id" /> <datatables:column property="firstName" /> <datatables:column property="lastName" /> <datatables:column property="address.town.name" /> <datatables:column property="mail" /></datatables:table>
Theming
92 / 101
JSP
Thymeleaf
<table ... dt:theme="bootstrap3" class="table"> <thead> <tr> <th>Id</th> <th>Firstname</th> <th>Lastname</th> <th>Street</th> <th>Mail</th> </tr> </thead> <tbody> <tr th:each="person : ${persons}"> <td th:text="${person?.id}">1</td> <td th:text="${person?.firstName}">John</td> <td th:text="${person?.lastName}">Doe</td> <td th:text="${person?.address?.town?.name}">Nobody knows!</td> <td th:text="${person?.mail}">[email protected]</td> </tr> </tbody></table>
Theming
93 / 101
Quick introductionBrief history
Dandelion-CoreDandelion-Datatables
Some statistics
FutureDemo
94 / 101
Some statistics35 releases (source: GitHub, all repos)15 pull requests merged (source: GitHub, all repos)9 contributors from 6 countries (source: GitHub, all repos)1432 commits (source: Ohloh)121,770 LOC (source: Ohloh)98 GitHub stars (source: GitHub, all repos)~80 followers on Twitter (source: Twitter)~270 topics, ~10000 views in the forum (source: Nabble)3200+ redeploys/restarts prevented, saving about 106h (source: JRebel)
95 / 101
Quick introductionBrief history
Dandelion-CoreDandelion-Datatables
Some statistics
Future
Demo
96 / 101
Dandelion-Core
Full support for asset minification and mergingImprovements on asset bundles: externalization,configuration via XML, JavaConfigAdd new processors for meta-frameworks(CoffeeScript, Less, ...)Add support for conditionnal assets (e.g. IE8+, IE9+)Add support for CSS spritesNew AssetCache implementation based on HazelcastJBoss Forge plugin allowing to scaffold a project basedon DandelionAdd support for RequireJSBower integration
Future
97 / 101
Dandelion-Core
Dandelion-Datatables
New extension for editable tables (Editor, jEditable, ...)Add support for more DataTables' extensionsAdd support for DataTables 1.10.0New theme for FoundationAdd WebSocket support for continously-updatingtables (Atmosphere, Spring MVC 4)Add support for Spring Data REST
Future
98 / 101
Dandelion-Core
Dandelion-Datatables
Newcomponents!
Dandelion-GUA? (Google Universal Analytics)Dandelion-Forms?All ideas are welcome!
Future
99 / 101
Quick introductionBrief history
Dandelion-CoreDandelion-Datatables
Some statisticsFuture
Demo
100 / 101
Demo
https://github.com/dandelion/dandelion-samples
101 / 101