Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Advanced customization of CRUD forms and controllers in Play

What I'm looking for is the ability to quickly (DRY!) generate forms for given models, but in a less-controlled way than using CRUD forms/models; for instance, by being able to use crud tags without the full crud controllers/routes, or by strongly customizing them.

Let me explain through an example.

I have a model A than links (ManyToOne) to 2 models, B and C

class public A extends Model {
    public String name;
    @ManyToOne
    public A a;
    @ManyToOne
    public B b;
}

I would like to be able to write the following routes:

/A/{id}/B/               somecontroller
/A/{id}/C/               some(other?)controller

or even better:

/A/{id}/{submodel}/      somecontroller

And in the corresponding html view be able to do something like:

<div>object.name</div>

#{form action:@save(object.b._key()), enctype:'multipart/form-data'}
    #{crud.form object.b /}
    <p class="crudButtons">
        <input type="submit" name="_save" value="&{'crud.save', type.modelName}" />
        <input type="submit" name="_saveAndContinue" value="&{'crud.saveAndContinue', type.modelName}" />
    </p>
#{/form}

Where 'object' is not the "b" or "c" instance, but "a", and I can tell #{crud.form /} which model it should map (in this case, 'b')

Is there any way to achieve something similar?

The question could be solved either:

  • is there any simple #{form MODEL} #{/form} tag?!

or, by being able to somehow customize more the CRUD eg.

  • is there a way to modify the main crud module and override only desired methods (without copying it all!)?

I am afraid I can't achieve this goal by simply overriding a model CRUD controller, maybe I'm wrong but beside reading the CRUD code (which I'm doing), the official doc is a little limited on which methods can be overridden and how...

Related: how to create an html form for a model in playframework

I also just found this google mail thread that seems to go in the customize-crud direction. I was hoping for a more out-of-the-box solution for such a typical need...

like image 740
Stefano Avatar asked Dec 31 '11 00:12

Stefano


1 Answers

I found in this play! google group thread the answer I was looking for.. everything is already there, though undocumented!

It's as easy as using:

to display a creation form of the Model class.

#{crud.form class:'models.ModelName' /} 

to display the edition form of any existing instance

#{curd.form object:anyInstance /} 

Then you can go as you want but this is my pattern for editing existing objects:

In your template

#{form @Controller.Action, method="POST" ... }

<input type="hidden" name="object.id" value="${myobject.ID}" />
#{crud.form object:gun.gunEngraving}
#{/crud.form}
<p>
<input type="submit" value="Save Changes" />
</p>
#{/form}

the hidden input sets the special "id" field so that:

In your Controller.Action

function static void Action(routeParams, MyModel object) {
    some validation;
    object.save();
    render or renderTemplate or other action for redirect;
}

This is of course a simplified code, but I really like this pattern when I quickly need to embed a form into a view and can't/don't want to use the entire CRUD system!

[Edit] More advanced custom CRUD goodness

The crud tags actually don't need the crud module. So much that I ended up copying them all over to my project, hacking them to add additional cool features such as the ability to change the name of the object in the form from the default "object" (I decided to override the originals, but you can make your own just using a different folder than tags/crud for namespacing)

like image 178
Stefano Avatar answered Oct 20 '22 17:10

Stefano