Play Framework - Register a custom DataBinder for dynamic fields

KJ50

Using Play 2.3.7 (Java) I have the following scenario.

I have a class CSVData which contains a list of type CSVField. Here are the attributes for these classes:

public class CSVData{

private String name;
private String description;
private String dataFilePath;
private List<CSVField> fields;
private Double latitude;
private Double longitude;


// rest of class... }

and

public class CSVField {
    private String name;
    private String type;

...}

The difficulty when making a form to input CSVData is that I have this nested List<CSVField> attribute and CSVField is a custom type containing two strings. I need the form to be dynamic in that it should be able to accept an arbitrary amount of CSVFields (at least 1). According to the Java Form Documentation, it seems like I should register a custom DataBinder for CSVField, however I can't find any examples that do this with multiple input strings. This example is similar, but it only binds one field.

Here is a video of what type of user input I would like to have. I made my view using this example code for adding dynamic fields. The combination of the text field (name) and select dropdown item (type) is what I need to bind to a CSVField and then add to the List<CSVField> fields in the CSVData object. How can I do this using the Play Framework?


EDIT: In my controller I have tried this

Form<CSVData> formData = Form.form(CSVData.class).bindFromRequest();

And in the view I try this

@helper.repeat(csvForm("fields"), min = 1) { csvField =>

    @multiDataField(csvField,
        label = "Column Name and Type",
        gsnTypes,
        help = "Enter the column names and respective types for the data items in the file")

}

Where multiDataField is this template. But it doesn't bind the dynamic fields properly and throws an invalid validation error on fields. I think my problem is I don't know what name attributes to use in my multiDataField template. Any advice?

Didac Montero

You don't need any customer databinder. Lists with complex objects are supported without any additional binding registration.

In the view you can use the @repeat Helper and in the controller you are already doing it well.

Here you have a complete example about Play and Forms, or directly in TypeSafe

EDIT

Inside the repeat block, csvField is an instance of every Form object in your List. Then you will need to add all the HTML elements you need for your view. For example (simplified without Bootstrap):

@helper.repeat(csvForm("fields"), min = 1) { csvField =>
    Name: <input type="text" name='@csvField("name").name' value='@csvField("name").value'>
    Type: <input type="text" name='@csvField("type").name' value='@csvField("type").value'>
}

You can find a more complete example with the samples provide in Play 2.2.x. To compile it in 2.3.x maybe something need to be changed a bit and is not using Bootstrap 3.x, but the logic is the same.

EDIT (2)

If you want to add dynamically elements to the view, you will need to take care that when a new element is added, the right array number is set. For that you will need to use JQuery:

$('.addCSVField').click(function() {
    var CSVFields = $(this).parents('.CSVField');
    var template = $('.CSVField_template', CSVFields);
    template.before('<div class="clearfix CSVField">' + template.html() + '</div>');
    renumber();
})

$('.removeCSVField').click(function() {
    $(this).parents('.CSVField').remove();
    renumber(); 
})  

var renumber = function() {
    $('.CSVField').each(function(i) {
        $('input', this).each(function() {
            $(this).attr('name', $(this).attr('name').replace(/fields\[.+?\]/g, 'fields[' + i + ']'));
        })
    })
}

And then you will need to change your HTML/Scala code to something like that:

@fieldGroup(field: Field, className: String = "CSVField") = {
    <div class="well @className">
        <a class="removeCSVField btn danger pull-right">Remove this field</a>
        Name: <input type="text" name='@field("name").name' value='@field("name").value'>
        Type: <input type="text" name='@field("type").name' value='@field("type").value'>
    </div>
}   

@repeat(csvForm("fields")) { csvField =>
    @fieldGroup(csvField)
}

@**
 * Keep an hidden block that will be used as template for Javascript copy code
 **@
@fieldGroup(csvForm("fields[x]"),className = "CSVField_template")   
<a class="addCSVField btn success">Add another field</a>

And to add a CSS style .CSVField_template{display: none;}

I did not test any of that, so it may not compile. However, I just followed a similar apporach as in the Forms example (play 2.2.x

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

Play Framework: cannot register class in Ebean server

From Dev

Play framework dynamic template include

From Dev

Scala Play Framework - Dynamic Forms

From Dev

Play framework dynamic template include

From Dev

custom base path play framework

From Dev

How to register a custom hydrator in Zend Framework 2?

From Dev

How to register a custom hydrator in Zend Framework 2?

From Dev

Strongly typed form fields in Play Framework views

From Dev

Play Framework 2.4 - Injected fields are always null

From Dev

How to validate fields of form with in play framework

From Dev

How to validate fields of form with in play framework

From Dev

How To Register user Form with all dynamic fields name in php

From Dev

Display Dynamic Image in Play! Framework Template

From Dev

Purely Dynamic forms using play framework

From Dev

Long dynamic routes in play framework 2

From Dev

Dynamic value of textarea with Play framework with Silhouette

From Dev

Play Framework, Dynamic statement inside for loop

From Dev

Cannot register class in Ebean server (Play Framework 2 - Java)

From Dev

Play framework 2.3.x Server Error Cannot register class

From Dev

Django Rest Framework serializing with dynamic fields

From Dev

WooCommerce: Dynamic Custom Checkout Fields in admin

From Dev

Play Framework 2.4.1: How to migrate custom plugins

From Dev

Mapping Play Framework form element to custom type

From Dev

How do I redirect to a dynamic custom route after register with FOSUserBundle

From Java

Django REST Framework custom fields validation

From Dev

Serializing data in Django Rest Framework for custom fields

From Dev

Play Framework - play.data.validations vs. custom validations?

From Dev

How to bind dynamic form fields to a HashSet in Play! with Java?

From Dev

How to bind dynamic form fields to a HashSet in Play! with Java?

Related Related

  1. 1

    Play Framework: cannot register class in Ebean server

  2. 2

    Play framework dynamic template include

  3. 3

    Scala Play Framework - Dynamic Forms

  4. 4

    Play framework dynamic template include

  5. 5

    custom base path play framework

  6. 6

    How to register a custom hydrator in Zend Framework 2?

  7. 7

    How to register a custom hydrator in Zend Framework 2?

  8. 8

    Strongly typed form fields in Play Framework views

  9. 9

    Play Framework 2.4 - Injected fields are always null

  10. 10

    How to validate fields of form with in play framework

  11. 11

    How to validate fields of form with in play framework

  12. 12

    How To Register user Form with all dynamic fields name in php

  13. 13

    Display Dynamic Image in Play! Framework Template

  14. 14

    Purely Dynamic forms using play framework

  15. 15

    Long dynamic routes in play framework 2

  16. 16

    Dynamic value of textarea with Play framework with Silhouette

  17. 17

    Play Framework, Dynamic statement inside for loop

  18. 18

    Cannot register class in Ebean server (Play Framework 2 - Java)

  19. 19

    Play framework 2.3.x Server Error Cannot register class

  20. 20

    Django Rest Framework serializing with dynamic fields

  21. 21

    WooCommerce: Dynamic Custom Checkout Fields in admin

  22. 22

    Play Framework 2.4.1: How to migrate custom plugins

  23. 23

    Mapping Play Framework form element to custom type

  24. 24

    How do I redirect to a dynamic custom route after register with FOSUserBundle

  25. 25

    Django REST Framework custom fields validation

  26. 26

    Serializing data in Django Rest Framework for custom fields

  27. 27

    Play Framework - play.data.validations vs. custom validations?

  28. 28

    How to bind dynamic form fields to a HashSet in Play! with Java?

  29. 29

    How to bind dynamic form fields to a HashSet in Play! with Java?

HotTag

Archive