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: | 654 / 1851 | 
| Version history: | 39 change(s) | 
| Referenced in: | [show references] |