Download Jar. Libraryless. Click here for Pure Java version (13989L/96K).
1 | !7 |
2 | |
3 | srecord HCRUD_TextArea(S field, int cols, int rows) {} |
4 | |
5 | sclass HCRUD_Data { |
6 | //LS fields() { null; } |
7 | L<Map<S, O>> list() { null; } |
8 | S fieldNameToHTML(S name) { ret htmlencode(humanizeLabel(name)); } |
9 | S idField() { ret "id"; } |
10 | Map<S, O> emptyObject() { null; } |
11 | Map<S, O> getObject(O id) { null; } |
12 | |
13 | // return ID |
14 | O createObject(SS map) { throw unimplemented(); } |
15 | |
16 | // return text msg |
17 | S deleteObject(O id) { throw unimplemented(); } |
18 | |
19 | // return text msg |
20 | S updateObject(O id, SS map) { throw unimplemented(); } |
21 | } |
22 | |
23 | sclass HCRUD { |
24 | HCRUD_Data data; |
25 | S baseLink; |
26 | |
27 | S newLink() { ret appendQueryToURL(baseLink, cmd := "new"); } |
28 | S deleteLink(O id) { ret appendQueryToURL(baseLink, "delete_" + id, 1); } |
29 | S editLink(O id) { ret appendQueryToURL(baseLink, edit := id); } |
30 | |
31 | // also handles commands if withCmds=true |
32 | S render(bool withCmds, SS params) { |
33 | if (!withCmds) ret renderTable(false); |
34 | |
35 | try answer handleCommands(params); |
36 | |
37 | ret pUnlessEmpty(params.get("msg")) |
38 | + p(ahref(newLink(), "New entry")) |
39 | + renderTable(withCmds); |
40 | } |
41 | |
42 | S refreshWithMsgs(LS msgs) { |
43 | ret hrefresh(appendQueryToURL(baseLink, msg := htmlEncode_nlToBr(lines_rtrim(msgs)))); |
44 | } |
45 | |
46 | S handleCommands(SS params) { |
47 | new LS msgs; |
48 | |
49 | if (eqGet(params, "action", "create")) { |
50 | O id = data.createObject(subMapStartingWith_dropPrefix(params, "f_")); |
51 | msgs.add("Object created (ID: " + id + ")"); |
52 | } |
53 | |
54 | if (eqGet(params, "action", "update")) |
55 | msgs.add(data.updateObject(params.get("id"), |
56 | subMapStartingWith_dropPrefix(params, "f_"))); |
57 | |
58 | for (S toDelete : keysDeprefixNemptyValue(params, "delete_")) |
59 | msgs.add(data.deleteObject(toDelete)); |
60 | |
61 | ret nempty(msgs) ? refreshWithMsgs(msgs) : ""; |
62 | } |
63 | |
64 | S encodeField(S s) { |
65 | ret or(data.fieldNameToHTML(s), s); |
66 | } |
67 | |
68 | S renderTable(bool withCmds) { |
69 | L<Map<S, O>> l = data.list(); |
70 | if (empty(l)) ret p("No entries"); |
71 | //LS fields = data.fields(); |
72 | //if (fields == null) fields = allKeysFromList_inOrder(); |
73 | l = map(l, map -> { |
74 | Map<S, O> map2 = mapKeysAndValues( |
75 | s -> encodeField(s), |
76 | value -> htmlEncode2(strOrEmpty(value)), |
77 | map); |
78 | if (withCmds) { |
79 | O id = map.get(data.idField()); |
80 | map2.put("<!-- cmds -->", |
81 | ahref(editLink(id), "edit") + " | " |
82 | + ahrefWithConfirm( |
83 | "Really delete item " + id + "?", deleteLink(id), htmlEncode2(unicode_DEL())/*"delete"*/)); |
84 | } |
85 | ret map2; |
86 | }); |
87 | ret htmlTable2_noHtmlEncode(l); |
88 | } |
89 | |
90 | S renderForm(Map<S, O> map) { |
91 | ret htableRaw_valignTop( |
92 | map(map, (field, value) -> ll( |
93 | encodeField(field), |
94 | htextfield("f_" + field, strOrEmpty(value)) |
95 | )) |
96 | , border := 1, cellpadding := 4); |
97 | } |
98 | |
99 | S renderNewForm() { |
100 | Map<S, O> map = mapWithoutKey(data.emptyObject(), data.idField()); |
101 | ret hpostform( |
102 | hhidden("action", "create") + |
103 | renderForm(map) |
104 | + p(hsubmit("Create")), |
105 | action := baseLink); |
106 | } |
107 | |
108 | S renderEditForm(S id) { |
109 | Map<S, O> map = mapWithoutKey(data.getObject(id), data.idField()); |
110 | if (map == null) ret htmlEncode2("Object " + id + " not found"); |
111 | ret hpostform( |
112 | hhidden("action", "update") + |
113 | hhidden(+id) + |
114 | renderForm(map) |
115 | + p(hsubmit("Save changes")), |
116 | action := baseLink); |
117 | } |
118 | } |
119 | |
120 | concept Car { |
121 | S brand, model; |
122 | } |
123 | |
124 | p { db(); } |
125 | |
126 | html { |
127 | new HCRUD crud; |
128 | crud.baseLink = appendSlash(rawLink()); |
129 | crud.data = new HCRUD_Data { |
130 | //LS fields() { ret conceptFields(Car); } |
131 | L<Map<S, O>> list() { ret (L) conceptsToMaps_gen_withNullValues(main list(Car)); } |
132 | Map<S, O> emptyObject() { |
133 | ret conceptToMap_gen_withNullValues(unlisted(Car)); |
134 | } |
135 | |
136 | Map<S, O> getObject(O id) { |
137 | ret conceptToMap_gen_withNullValues(getConcept(Car, toLong(id))); |
138 | } |
139 | |
140 | O createObject(SS map) { |
141 | ret cnew(Car, mapToParams(map)).id; |
142 | } |
143 | |
144 | S updateObject(O id, SS map) { |
145 | Concept c = getConcept(Car, toLong(id)); |
146 | if (c == null) ret "Object " + id + " not found"; |
147 | cset(c, mapToParams(map)); |
148 | ret "Object " + id + " updated"; |
149 | } |
150 | |
151 | S deleteObject(O id) { |
152 | Concept c = getConcept(Car, toLong(id)); |
153 | if (c == null) ret "Object not found"; |
154 | deleteConcept(c); |
155 | ret "Object deleted"; |
156 | } |
157 | }; |
158 | if (eqGet(params, "cmd", "new")) |
159 | ret h1_title("New car") + crud.renderNewForm(); |
160 | if (nempty(params.get("edit"))) |
161 | ret h1_title("Edit car") + crud.renderEditForm(params.get("edit")); |
162 | ret h1_title("Cars") + crud.render(true, params); |
163 | } |
download show line numbers debug dex old transpilations
Travelled to 7 computer(s): bhatertpkbcr, mqqgnosmbjvj, onxytkatvevr, pyentgdyhuwx, pzhvpgtvlbxg, tvejysmllsmz, vouqrxazstgt
No comments. add comment
Snippet ID: | #1025991 |
Snippet name: | HTML CRUD Spike [OK] |
Eternal ID of this version: | #1025991/40 |
Text MD5: | ba80fe9bb88822ccddb92cf42d208e13 |
Transpilation MD5: | 4910f8d020d8942742d2a5f230e609c2 |
Author: | stefan |
Category: | javax / html |
Type: | JavaX module (desktop) |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2019-11-06 14:41:49 |
Source code size: | 4744 bytes / 163 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 380 / 1209 |
Version history: | 39 change(s) |
Referenced in: | [show references] |