Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Play Framework Processing partial form

I'm using the Play Framework and I've got the common use case to update a model with a form in a controller action. But I've some issues understanding the concept behind it because this is just working if you have a form which includes ALL of the properties of the model. If you have a just a partial form, e.g. editing just a password of a user model, this method destroys the model, because it sets the other properties of the model to null. Is there any "official" solution to that problem? Any way Play updates just the existing properties?

public static Result update(Long id) {
    Model model = Model.findById(id);
    Form<Model> filledForm = modelForm.bindFromRequest();
    if (filledForm.hasErrors()) {
        return badRequest(edit.render(filledForm));
    } else {
        model.update();
        flash("message", "Created new Model!");
        return ok(index.render());
    }
}

Probably the solution lays somehow in the fact that the bindFormRequest() method can be called with additional parameters, like Strings or a Map of Strings? But I can not find out the purpose of that. Some insight into that would be great as well. Thanks a lot!

like image 261
linsenfips Avatar asked Jun 21 '13 06:06

linsenfips


People also ask

How do you set content type explicitly on play?

Changing the default Content-Type Will automatically set the Content-Type header to text/plain , while: JsonNode json = Json. toJson(object); Result jsonResult = ok(json); will set the Content-Type header to application/json .

Which component is responsible for building play framework?

Play Framework is an open-source web application framework which follows the model–view–controller (MVC) architectural pattern. It is written in Scala and usable from other programming languages that are compiled to JVM bytecode, e.g. Java.

What is SBT in play framework?

sbt : The sbt settings that describe building your application. /conf : Configuration files for your application. /project : Further build description information. /public : Where static, public assets for your application are stored. /test : Where your application's test code will be stored.

What is play framework used for?

Play Framework makes it easy to build web applications with Java & Scala. Play is based on a lightweight, stateless, web-friendly architecture. Built on Akka, Play provides predictable and minimal resource consumption (CPU, memory, threads) for highly-scalable applications.


1 Answers

On a recent project, I needed this kind of feature and I had to reimplement the Form class (based on the original Play Form) to allow an additional parameter to the bindFromRequest() method.

Taking your code as an example, it would become something like this :

Model model = Model.findById(id);
Form<Model> filledForm = CustomForm.form(Model.class).bindFromRequest(model);

The idea is to only modify the fields defined in your form and keep the other fields of your model unmodified.

To allow this specific binding, you have to redefine the bind(Map<String,String> data, String... allowedFields) method (along with the bindFromRequest) with something like this :

public Form<T> bind(T instance, Map<String,String> data, String... allowedFields) {

    DataBinder dataBinder = null;
    Map<String, String> objectData = data;
    if(rootName == null) {
        dataBinder = new DataBinder(instance);
    } else {
        dataBinder = new DataBinder(instance, rootName);
        objectData = new HashMap<String,String>();
        for(String key: data.keySet()) {
            if(key.startsWith(rootName + ".")) {
                objectData.put(key.substring(rootName.length() + 1), data.get(key));
            }
        }
    }

Instead of creating the DataBinder with blankInstance() as the standard Play Form class does, you create it with you model instance as the constructor argument.

like image 194
mguillermin Avatar answered Sep 28 '22 04:09

mguillermin