1

I'm using Spring Boot with Thymeleaf and now I want to add Dandelion datatables, but it doesn't work.

Here is my maven dependencies:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.2.1.RELEASE</version>
    <relativePath /> <!-- lookup parent from repository -->
</parent>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-tomcat</artifactId>
    <scope>provided</scope>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>

<!-- Dandelion -->
<dependency>
    <groupId>com.github.dandelion</groupId>
    <artifactId>datatables-thymeleaf</artifactId>
    <version>0.10.1</version>
</dependency>

I'm following this guide http://dandelion.github.io/dandelion/docs/installation/thymeleaf.html and configured the following beans:

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

    @Bean
    public FilterRegistrationBean dandelion() {
        FilterRegistrationBean registrationBean = new FilterRegistrationBean();
        registrationBean.setFilter(new DandelionFilter());
        registrationBean.addUrlPatterns("/*");
        return registrationBean;
    }

    @Bean
    public ServletRegistrationBean dandelionServlet() {
        ServletRegistrationBean registrationBean = new ServletRegistrationBean();
        registrationBean.setServlet(new DandelionServlet());
        registrationBean.addUrlMappings("/dandelion/*");
        return registrationBean;
    }

    @Bean
    public ServletContextTemplateResolver defaultTemplateResolver() {
        ServletContextTemplateResolver resolver = new ServletContextTemplateResolver();
        resolver.setTemplateMode("HTML5");
        resolver.setPrefix("/WEB-INF/templates/");
        resolver.setSuffix(".html");
        resolver.setCharacterEncoding("UTF-8");
        resolver.setCacheable(false);

        SpringTemplateEngine engine = new SpringTemplateEngine();
        engine.setTemplateResolver(resolver);
        engine.addDialect(new DataTablesDialect());

        return resolver;
    }

}

I have made this HTML for testing:

<!doctype html>
<html 
 xmlns:th="http://www.thymeleaf.org" 
 xmlns:ddl="http://github.com/dandelion">
<head>
 <link type="text/css" href="/stylesheets/dataTables.css" media="screen" rel="stylesheet" />
 <script src="/javascripts/vendor/jquery191.js" type="text/javascript"></script>
 <script src="/javascripts/vendor/dataTables.js" type="text/javascript"></script>
</head>
<body>
 <br/>
 <table id="myTableId" ddl:table="true" ddl:url="@{/clientes}">
    <thead>
       <tr>
          <th ddl:property="telefone">Telefone</th>
          <th ddl:property="nome">Nome</th>
       </tr>
    </thead>
 </table>
</body>
</html>

I think Dandelion's servlet is not called. The namespace is not processed. enter image description here

tduchateau
  • 4,351
  • 2
  • 29
  • 40
leocborges
  • 4,799
  • 5
  • 32
  • 38

1 Answers1

8

There are several mistakes. Most of them are just same as what I did when i first used dandelion data tables. :)

I'm writing the full simple examples for each of the code below for anyone's reference in future. So make sure you add only the missing ones to your project

First add both these dependencies to your maven. (You already have the first. So add the later.)

<dependency>
    <groupId>com.github.dandelion</groupId>
    <artifactId>datatables-thymeleaf</artifactId>
    <version>0.10.1</version>
</dependency>
<dependency>
    <groupId>com.github.dandelion</groupId>
    <artifactId>datatables-spring3</artifactId>
    <version>0.10.1</version>
</dependency>

Then add these configurations. You have to create Beans for the dialects. I think you missed it..

@Configuration
public class DandelionConfig {

    @Bean
    public DandelionDialect dandelionDialect() {
        return new DandelionDialect();
    }

    @Bean
    public DataTablesDialect dataTablesDialect(){
        return new DataTablesDialect();
    }

    @Bean
    public Filter dandelionFilter() {
        return new DandelionFilter();
    }

    @Bean
    public ServletRegistrationBean dandelionServletRegistrationBean() {
        return new ServletRegistrationBean(new DandelionServlet(), "/dandelion-assets/*");
    }
}

And the view can be something like this

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
      xmlns:ddl="http://www.thymeleaf.org/dandelion"
      xmlns:dt="http://www.thymeleaf.org/dandelion/datatables">
<head lang="en"></head>
<body>
    <table id="myTableId"
        dt:table="true"
        dt:url="@{/clientes}"
        dt:serverside="true"
        dt:processing="true">
          <thead>
            <tr>
              <th dt:property="telefone">Telefone</th>
              <th dt:property="nome">Nome</th>
            </tr>
          </thead>
     </table>
</body>
</html>

Here you are using server-side processing. This requires your controller to have a mapping on /clientes which returns DatatablesResponse

@Override
@RequestMapping(value = "/clientes")
@ResponseBody
public DatatablesResponse<MyObject> data(HttpServletRequest request){
    List<MyObject> myObjectList = ... //logic to fetch a list of objects

    DatatablesCriterias criterias = DatatablesCriterias.getFromRequest(request);
    DataSet<MyObject> dataSet = new DataSet<>(myObjectList, (long)myObjectList.size(), (long)myObjectList.size());
    return DatatablesResponse.build(dataSet, criterias);
}

MyObject is the object you are passing to dandelion data tables

public class MyObject {
    private String telefone;
    private String nome;

    public String getTelefone() {
        return telefone;
    }

    public void setTelefone(String telefone) {
        this.telefone = telefone;
    }

    public String getNome() {
        return nome;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }
}
Somaiah Kumbera
  • 7,063
  • 4
  • 43
  • 44
Faraj Farook
  • 14,385
  • 16
  • 71
  • 97
  • I followed this one and got almost everything to work except that the DataTables is just showing "Processing". I got the data no problem, but it is not reflecting in the datatable. It just displays "Processing". – Rey Libutan Aug 13 '15 at 05:05
  • Can you check the response you get from the server from the ajax query. May be it gives an error. Check it from the network tab in the chrome console when you load the page. – Faraj Farook Aug 13 '15 at 12:28
  • Facing the same issue as @ReyLibutan. I am getting the response as expected I.e. I can see the data that has been sent from my controller, but the data table is blank. Also I tried with the default configurations using thymeleaf, spring controller as it was mentioned in the document but still getting the same issue. – BhaskerYadav May 19 '16 at 07:35
  • @BhaskerYadav, the reason you were getting the "Processing" text all the time was because all the attributes in criterias were null. To fix, change function param to be HttpServletRequest request. Then you can create the criterias object with: DatatablesCriterias criterias = DatatablesCriterias.getFromRequest(request); Change the return line to return DatatablesResponse.build(dataSet, criterias); Now you should see the table correctly. I have edited the answer to reflect these corrections. – Somaiah Kumbera Jul 28 '16 at 19:09