This example will assume the use of the JPA extension (discussed in the Integration section).
Lets say you have an entity called User, it could be defined and compiled in
Java or Groovy:
User Entity in JavaToggle Line Numbers | 1
package org.ponder.gracelets.demo.userman; 2
3
import javax.persistence.Entity; 4
import javax.persistence.GeneratedValue; 5
import javax.persistence.Id; 6
7
@Entity public class User { 8
9
int id; 10
11
String name; 12
String username; 13
String password; 14
15
@Id @GeneratedValue public int getId() { 16
return id; 17
} 18
public void setId(int id) { 19
this.id = id; 20
} 21
public String getName() { 22
return name; 23
} 24
public void setName(String name) { 25
this.name = name; 26
} 27
public String getUsername() { 28
return username; 29
} 30
public void setUsername(String username) { 31
this.username = username; 32
} 33
public String getPassword() { 34
return password; 35
} 36
public void setPassword(String password) { 37
this.password = password; 38
} 39
40
}
|
You would put your entity (or entities) in your WEB-INF/classes folder along with your
persistence.properties setup (if using the Gracelets JPA extension).
We will assume the default persistence session name of 'storage'.
Next you could setup your controller (in the WEB-INF/gracelet/controller directory):
User ControllerToggle Line Numbers | 1
import org.ponder.gracelets.demo.userman.User 2
3
class UserManager { 4
5
static def name = "userman" 6
static def scope = "conversation" 7
8
static void initialize (binding) { 9
binding.DataModel("usermanUsers") { 10
def model = demodb.managedQuery("u", "User u", "", "").model 11
model.whereCriteria.putAll( 12
[name: "UPPER(u.name) LIKE UPPER(:name)", username: "UPPER(u.username) LIKE UPPER(:username)"] 13
); 14
return model 15
} 16
} 17
18
def subPage = "list" 19
20
def nameField = "u.name" 21
def usernameField = "u.username" 22
23
def getCriteria () { usermanUsers.criteria } 24
25
void newUser () { selectedUser = new User(); subPage = "edit" } 26
void editUser (user) { selectedUser = user; subPage = "edit" } 27
28
void remove (user) { demodb.remove(user); usermanUsers.clear() } 29
30
void userList () { subPage = "list" } 31
32
void save () { save(selectedUser); } 33
void save (user) { demodb.save(user); usermanUsers.clear(); subPage = "list" } 34
35
void search () { usermanUsers.applyCriteria() } 36
37
}
|
Above you may wonder about some of the facilities, like a query object (lines #19 and #23) off the data model. That
is specific to the JPA wrapper that is returned when using managed queries (line #12). Of course, all
this comes with gracelets.
You would then make your view to manage the users, a simple CRUD view:
User Manager ViewToggle Line Numbers | 1
xh.html { 2
3
head { 4
title("User Manager") 5
6
link(rel: "stylesheet", href: "style/userman.css", type: "text/css") 7
} 8
9
body { 10
11
h.messages() 12
13
g.subpages(value: Value { userman.subPage }) { 14
15
u.component(page: "list") { 16
17
g.form(id: "filter") { 18
xh.fieldset { 19
legend("User Search") 20
table(width: "100%") { 21
tr { td ("Name:"); td { 22
h.inputText(value: Value { userman.criteria.name }, converter: Converter( 23
toString: { val -> val.replaceAll("%","") }, toValue: { val -> "%$val%" } 24
)) 25
} } 26
tr { td ("Username:"); td { 27
h.inputText(value: Value { userman.criteria.username }, converter: Converter( 28
toString: { val -> val.replaceAll("%","") }, toValue: { val -> "%$val%" } 29
)) 30
} } 31
32
tr { 33
td (colspan: 2, align: "right", class: "button_bar") { 34
h.commandButton("New user...", immediate: true, action: { userman.newUser() }) 35
h.commandButton("Search", action: { userman.search() }) 36
} 37
} 38
} 39
} 40
} 41
42
g.form(id: "grid") { 43
g.grid(caption: "User List", value: { usermanUsers }, width: "100%", var: "user") { 44
45
h.column(facets: [header: { print "Name" }], sortable: { userman.nameField }) { 46
print { user.name } 47
} 48
h.column(facets: [header: { print "Username" }], sortable: { userman.usernameField }) { 49
print { user.username } 50
} 51
52
h.column(facets: [header: { div("Options", style: "text-align: right") }]) { 53
div (style: "text-align: right") { 54
h.commandLink("[ Edit ]", action: { userman.editUser(user) }) 55
h.commandLink("[ Remove ]", action: { 56
userman.remove(user); 57
jsfMessages.add("User has been removed: $user.name") 58
}, onclick: "if (!confirm('Are you sure?')) { return false; }") 59
} 60
} 61
62
} 63
} 64
65
} 66
67
u.component(page: "edit") { 68
69
g.form(id: "edit") { 70
71
xh.fieldset { 72
legend("User Edit") 73
table(width: "100%") { 74
tr { td("Name: "); td { h.inputText(required: true, value: Value { selectedUser.name }) } } 75
tr { td("Username: "); td { h.inputText(required: true, value: Value { selectedUser.username }) } } 76
tr { td("Password: "); td { 77
h.inputSecret(required: { selectedUser.id == 0 }, valueChangeListener: { evt -> 78
if (evt.newValue) { 79
selectedUser.password = evt.newValue 80
if (selectedUser.id) jsfMessages.add("Password for $selectedUser.name has been set") 81
} 82
}) 83
} } 84
85
tr { td (align: "right", colspan: 2, class: "button_bar") { 86
h.commandButton("Cancel", immediate: true, action: { userman.userList() }) 87
h.commandButton("Save Changes", action: { 88
userman.save(); 89
jsfMessages.add("User changes saved") 90
}) 91
} } 92
} 93
} 94
95
} 96
97
} 98
99
} 100
101
} 102
103
}
| |