@@ -42,6 +42,7 @@ public class UserRestController {
42
42
- [ Apply filters] ( #apply-filters )
43
43
- [ Manage non-searchable fields] ( #manage-non-searchable-fields )
44
44
- [ Limit the exposed attributes of the entities] ( #limit-the-exposed-attributes-of-the-entities )
45
+ - [ Search on a rendered column] ( #search-on-a-rendered-column )
45
46
- [ Troubleshooting] ( #troubleshooting )
46
47
47
48
## Maven dependency
@@ -463,6 +464,77 @@ public class User {
463
464
}
464
465
` ` `
465
466
467
+ ### Search on a rendered column
468
+
469
+ Let's say you have an ` User` entity with two attributes, ` firstName` and ` lastName` .
470
+
471
+ To display the rendered column on the client-side:
472
+
473
+ ` ` ` js
474
+ $ (' table#sample' ).DataTable ({
475
+ ajax: ' /data/users' ,
476
+ serverSide: true ,
477
+ columns : [
478
+ {
479
+ data: ' fullName' ,
480
+ render : (_ , __ , row ) => ` ${ row .firstName } ${ row .lastName } ` ,
481
+ searchable: false ,
482
+ orderable: false
483
+ }
484
+ ]
485
+ });
486
+ ` ` `
487
+
488
+ Both ` searchable` and ` orderable` option are necessary, because the ` User` entity has no` fullName` attribute.
489
+
490
+ To filter on the server-side, you'll have to manually create the matching specification:
491
+
492
+ ` ` ` java
493
+ @RequestMapping (value = " /data/users" , method = RequestMethod .GET )
494
+ public DataTablesOutput< User> list (@Valid DataTablesInput input ) {
495
+ String searchValue = escapeContent (input .getSearch ().getValue ());
496
+ input .getSearch ().setValue (" " ); // prevent search on other fields
497
+
498
+ Specification< User> fullNameSpecification = (Specification< User> ) (root, query, criteriaBuilder) - > {
499
+ if (! hasText (searchValue)) {
500
+ return null ;
501
+ }
502
+ String [] parts = searchValue .split (" " );
503
+ Expression< String > firstNameExpression = criteriaBuilder .lower (root .get (" firstName" ));
504
+ Expression< String > lastNameExpression = criteriaBuilder .lower (root .get (" lastName" ));
505
+ if (parts .length == 2 && hasText (parts[0 ]) && hasText (parts[1 ])) {
506
+ return criteriaBuilder .or (
507
+ criteriaBuilder .and (
508
+ criteriaBuilder .equal (firstNameExpression, parts[0 ]),
509
+ criteriaBuilder .like (lastNameExpression, parts[1 ] + " %" , ' ~' )
510
+ ),
511
+ criteriaBuilder .and (
512
+ criteriaBuilder .equal (lastNameExpression, parts[0 ]),
513
+ criteriaBuilder .like (firstNameExpression, parts[1 ] + " %" , ' ~' )
514
+ )
515
+ );
516
+ } else {
517
+ return criteriaBuilder .or (
518
+ criteriaBuilder .like (firstNameExpression, searchValue + " %" , ' ~' ),
519
+ criteriaBuilder .like (lastNameExpression, searchValue + " %" , ' ~' )
520
+ );
521
+ }
522
+ };
523
+ return userRepository .findAll (input, fullNameSpecification);
524
+ }
525
+
526
+ private String escapeContent (String content ) {
527
+ return content
528
+ .replaceAll (" ~" , " ~~" )
529
+ .replaceAll (" %" , " ~%" )
530
+ .replaceAll (" _" , " ~_" )
531
+ .trim ()
532
+ .toLowerCase ();
533
+ }
534
+ ` ` `
535
+
536
+ You can find a complete example [here](https://github.com/darrachequesne/spring-data-jpa-datatables-sample).
537
+
466
538
Back to [top](#spring-data-jpa-datatables).
467
539
468
540
0 commit comments