POJO, JPA bindings and flags

Play uses "Unauthorized parameters are safely ignored. Type mismatches are also safely ignored." when binding parameters to POJO. It works great most of the time.

But this causes problems with checkboxes, because unchecked checkboxes are not checked in the parameter list.

The CRUD module solved this by inserting a hidden input field immediately after the checkbox. This works because Play only reads the first of two identical parameters to bind.

Source from CRUD module displaying a checkbox:

<input id="object_isInvoiceable" type="checkbox" name="object.isInvoiceable" /> <input type="hidden" name="object.isInvoiceable" value="false" /> 

Another way is not to pass the flag as a member of the object, but as a separate parameter. Then you can catch this in the Controller and set object.member there as follows:

 <input id="object_isInvoiceable" type="checkbox" name="isInvoiceableExtraParamFromHell" /> 

and in the controller:

 public static void save(Event object, Boolean isInvoiceableExtraParamFromHell) { if(isInvoiceableExtraParamFromHell == null) { object.isInvoiceable = false; } else { object.isInvoiceable = true; } ... validation etc ... object.save(); ... render etc ... } 

I do not like alternative 1 because, how can I be sure that the order of the parameters is sent correctly in all browsers.

I do not like alternative 2, because then I need to control individual parameters and change controller methods if I modify an object.

Is there a better way to do this? I'm completely new to the Play Framework, so maybe I missed some kind of annotation or something like that.

EDIT:

I was a little obscure before. The problem is not creating a new object, but that I can set it to FALSE by default, as Codemwnci suggested. The problem is snapping to an existing JPA object.

From the playframework tutorial :

You can automatically bind a JPA object using HTTP binding to Java.

You can specify the user.id field in the HTTP parameters. When Play finds the id field, it loads the corresponding instance from the database before editing it. Then, other parameters provided by the HTTP request are applied. Therefore, you can save it directly.

In this case, it will not set the item to its default value.

As an example, I already have a JPA object stored in the database that has an InVoiceable value of TRUE. I am moving this object to a template. If I uncheck now, the parameter will not be sent, so isInvoiceable will still be true.

+4
source share
2 answers

For new objects you can do the following

If you are connecting a POJO, then simply the default value inside the POJO should be sufficient.

for instance

 public class Event extends Model { public Boolean isInvoiceable = Boolean.FALSE; ... ... } 

For existing objects, you can make a small change to the theme that CRUD uses by setting the JQuery onclick action against it, so that the value of the checkbox always sets the hidden value, and this hidden value is displayed on the POJO.

So for example

 <input id="object_isInvoiceable_checkbox" type="checkbox" name="ignoredformfield" /> <input id="object_isInvoiceable_formfield" type="hidden" name="object.isInvoiceable" value="false" /> <script>$("#object_isInvoiceable_checkbox").click(function( $("object_isInvoiceable_formfield").value("$("#object_isInvoiceable_checkbox").is(":checked")"); ));</script> 

Note. I did not check javascript code, but you get the point.

+1
source

I have another solution that avoids the need to use hidden / extra fields in the template.

View Code:

 <input id="object_isInvoiceable" type="checkbox" name="object.isInvoiceable" /> 

Controller Code:

 public static void save(Event object) { if(params.get("object.isInvoiceable") == null) { object.isInvoiceable = false; } ... validation etc ... object.save(); ... render etc ... } 

Works well for me.

0
source

Source: https://habr.com/ru/post/1390123/


All Articles