Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

150
LINES

< > BotCompany Repo | #1026001 - HCRUD - CRUD in HTML with pluggable data handler

JavaX fragment (include) [tags: use-pretranspiled]

Libraryless. Click here for Pure Java version (15401L/107K).

sclass HCRUD extends HAbstractRenderable {
  HCRUD_Data data;
  int defaultTextFieldCols = 80;
  bool mutationRights = true;

  *() {}
  *(HCRUD_Data *data) {}
  *(S *baseLink, HCRUD_Data *data) {}
  
  S newLink() { ret appendQueryToURL(baseLink, cmd := "new"); }
  S deleteLink(O id) { ret appendQueryToURL(baseLink, "delete_" + id, 1); }
  S editLink(O id) { ret appendQueryToURL(baseLink, edit := id); }
  S duplicateLink(O id) { ret appendQueryToURL(baseLink, duplicate := id); }
  
  // also handles commands if withCmds=true
  S render(bool withCmds, SS params) {
    if (!withCmds) ret renderTable(false);
    
    try answer handleCommands(params);
    
    ret renderMsgs(params)
      + p(ahref(newLink(), "New entry"))
      + renderTable(withCmds);
  }

  S handleCommands(SS params) {
    new LS msgs;
    
    if (eqGet(params, "action", "create")) {
      O id = data.createObject(subMapStartingWith_dropPrefix(params, "f_"));
      msgs.add("Entry created (ID: " + id + ")");
    }
    
    if (eqGet(params, "action", "update"))
      msgs.add(data.updateObject(params.get("id"),
        subMapStartingWith_dropPrefix(params, "f_")));

    for (S toDelete : keysDeprefixNemptyValue(params, "delete_"))
      msgs.add(data.deleteObject(toDelete));

    ret nempty(msgs) ? refreshWithMsgs(msgs) : "";
  }
  
  S encodeField(S s) {
    ret or(data.fieldNameToHTML(s), s);
  }
  
  // in table
  S renderValue(S field, O value) {
    if (value cast HTML) ret value.html;
    ret htmlEncode_nlToBr_withIndents(strOrEmpty(value));
  }
  
  S renderTable(bool withCmds) {
    ret renderTable(withCmds, data.list());
  }
  
  S renderTable(bool withCmds, L<Map<S, O>> l) {
    if (empty(l)) ret p("No entries");
    //LS fields = data.fields();
    //if (fields == null) fields = allKeysFromList_inOrder();
    l = map(l, map -> {
      Map<S, O> map2 = mapToMap(
        (key, value) -> pair(encodeField(key), renderValue(key, value)),
        map);
      if (withCmds) {
        O id = map.get(data.idField());
        map2.put(cmdsKey(),
          joinWithVBar(
            ahref(editLink(id), "edit"),
            ahrefWithConfirm(
            "Really delete item " + id + "?", deleteLink(id), htmlEncode2(unicode_DEL())),
            ahref(duplicateLink(id), "dup", title := "duplicate")
          ));
      }
      ret map2;
    });
    ret htmlTable2_noHtmlEncode(l, tdParams := litparams(valign := "top"));
  }
  
  S renderForm(Map<S, O> map) {
    ret htableRaw_valignTop(
      map(map, (field, value) -> {
        S help = data.fieldHelp(field);
        ret ll(
          encodeField(field),
          renderInput(field, value)
            + (empty(help) ? "" : "<br> " + small(help))
        );
      })
    , border := 1, cellpadding := 4);
  }
  
  S renderInput(S field, O value) {
    S name = "f_" + field;
    HCRUD_Data.Renderer r = data.getRenderer(field);
    if (r cast HCRUD_Data.TextArea)
      ret htextarea(strOrEmpty(value), +name, cols := r.cols, rows := r.rows);
    if (r cast HCRUD_Data.TextField)
      ret htextfield(name, strOrEmpty(value), size := r.cols, style := "font-family: monospace");
    if (r cast HCRUD_Data.ComboBox)
      ret hselect_list(r.entries, strOrEmpty(value), +name);
    ret renderInput_default(field, value);
  }
  
  S renderInput_default(S field, O value) {
    S name = "f_" + field;
    ret htextfield(name, strOrEmpty(value), size := defaultTextFieldCols);
  }
  
  S renderNewForm() {
    ret renderNewForm(data.emptyObject());
  }
  
  S renderNewForm(MapSO map1) {
    //printStruct("renderNewForm", map1);
    Map<S, O> map = mapWithoutKey(map1, data.idField());
    //printStruct("renderNewForm", map);
    ret hpostform(
      hhidden("action", "create") +
      renderForm(map)
      + p(hsubmit("Create")),
      action := baseLink);
  }
  
  S renderEditForm(S id) {
    Map<S, O> map = mapWithoutKey(data.getObject(id), data.idField());
    if (map == null) ret htmlEncode2("Entry " + id + " not found");
    ret hpostform(
      hhidden("action", "update") +
      hhidden(+id) +
      renderForm(map)
      + p(hsubmit("Save changes")),
      action := baseLink);
  }
  
  S renderPage(SS params) {
    if (eqGet(params, "cmd", "new"))
      ret frame("New " + data.itemName(), renderNewForm());
    if (nempty(params.get("edit")))
      ret frame("Edit " + data.itemName(), renderEditForm(params.get("edit")));
    if (nempty(params.get("duplicate")))
      ret frame("New " + data.itemName(), renderNewForm(data.getObject(params.get("duplicate"))));
    ret frame(ahref(baseLink, firstToUpper(data.itemNamePlural())), render(mutationRights, params));
  }
  
  HCRUD makeFrame(MakeFrame makeFrame) { super.makeFrame(makeFrame); this; }
  
  S cmdsKey() { ret "<!-- cmds -->"; }
}

download  show line numbers  debug dex   

Travelled to 4 computer(s): mqqgnosmbjvj, onxytkatvevr, tvejysmllsmz, xrpafgyirdlv

No comments. add comment

Snippet ID: #1026001
Snippet name: HCRUD - CRUD in HTML with pluggable data handler
Eternal ID of this version: #1026001/40
Text MD5: 298622f8c6c9a0752d067371dd2c4167
Transpilation MD5: be507ad576741c98dc8ff11fe874b410
Author: stefan
Category: javax / html
Type: JavaX fragment (include)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2020-05-07 21:21:28
Source code size: 4917 bytes / 150 lines
Pitched / IR pitched: No / No
Views / Downloads: 135 / 444
Version history: 39 change(s)
Referenced in: #1003674 #1026135

Formerly at http://tinybrain.de/1026001 & http://1026001.tinybrain.de