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

163
LINES

< > BotCompany Repo | #1025991 // HTML CRUD Spike [OK]

JavaX module (desktop) [tags: butter use-pretranspiled] - homepage

Download Jar. Libraryless. Click here for Pure Java version (13989L/96K).

!7

srecord HCRUD_TextArea(S field, int cols, int rows) {}

sclass HCRUD_Data {
  //LS fields() { null; }
  L<Map<S, O>> list() { null; }
  S fieldNameToHTML(S name) { ret htmlencode(humanizeLabel(name)); }
  S idField() { ret "id"; }
  Map<S, O> emptyObject() { null; }
  Map<S, O> getObject(O id) { null; }
  
  // return ID
  O createObject(SS map) { throw unimplemented(); }
  
  // return text msg
  S deleteObject(O id) { throw unimplemented(); }
  
  // return text msg
  S updateObject(O id, SS map) { throw unimplemented(); }
}

sclass HCRUD {
  HCRUD_Data data;
  S baseLink;
  
  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); }
  
  // also handles commands if withCmds=true
  S render(bool withCmds, SS params) {
    if (!withCmds) ret renderTable(false);
    
    try answer handleCommands(params);
    
    ret pUnlessEmpty(params.get("msg"))
      + p(ahref(newLink(), "New entry"))
      + renderTable(withCmds);
  }
  
  S refreshWithMsgs(LS msgs) {
    ret hrefresh(appendQueryToURL(baseLink, msg := htmlEncode_nlToBr(lines_rtrim(msgs))));
  }

  S handleCommands(SS params) {
    new LS msgs;
    
    if (eqGet(params, "action", "create")) {
      O id = data.createObject(subMapStartingWith_dropPrefix(params, "f_"));
      msgs.add("Object 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);
  }
  
  S renderTable(bool withCmds) {
    L<Map<S, O>> l = data.list();
    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 = mapKeysAndValues(
        s -> encodeField(s),
        value -> htmlEncode2(strOrEmpty(value)),
        map);
      if (withCmds) {
        O id = map.get(data.idField());
        map2.put("<!-- cmds -->",
          ahref(editLink(id), "edit") + " | "
          + ahrefWithConfirm(
            "Really delete item " + id + "?", deleteLink(id), htmlEncode2(unicode_DEL())/*"delete"*/));
      }
      ret map2;
    });
    ret htmlTable2_noHtmlEncode(l);
  }
  
  S renderForm(Map<S, O> map) {
    ret htableRaw_valignTop(
      map(map, (field, value) -> ll(
        encodeField(field),
        htextfield("f_" + field, strOrEmpty(value))
      ))
    , border := 1, cellpadding := 4);
  }
  
  S renderNewForm() {
    Map<S, O> map = mapWithoutKey(data.emptyObject(), data.idField());
    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("Object " + id + " not found");
    ret hpostform(
      hhidden("action", "update") +
      hhidden(+id) +
      renderForm(map)
      + p(hsubmit("Save changes")),
      action := baseLink);
  }
}

concept Car {
  S brand, model;
}

p { db(); }

html {
  new HCRUD crud;
  crud.baseLink = appendSlash(rawLink());
  crud.data = new HCRUD_Data {
    //LS fields() { ret conceptFields(Car); }
    L<Map<S, O>> list() { ret (L) conceptsToMaps_gen_withNullValues(main list(Car)); }
    Map<S, O> emptyObject() {
      ret conceptToMap_gen_withNullValues(unlisted(Car));
    }
    
    Map<S, O> getObject(O id) {
      ret conceptToMap_gen_withNullValues(getConcept(Car, toLong(id)));
    }
    
    O createObject(SS map) {
      ret cnew(Car, mapToParams(map)).id;
    }
    
    S updateObject(O id, SS map) {
      Concept c = getConcept(Car, toLong(id));
      if (c == null) ret "Object " + id + " not found";
      cset(c, mapToParams(map));
      ret "Object " + id + " updated";
    }
    
    S deleteObject(O id) {
      Concept c = getConcept(Car, toLong(id));
      if (c == null) ret "Object not found";
      deleteConcept(c);
      ret "Object deleted";
    }
  };
  if (eqGet(params, "cmd", "new"))
    ret h1_title("New car") + crud.renderNewForm();
  if (nempty(params.get("edit")))
    ret h1_title("Edit car") + crud.renderEditForm(params.get("edit"));
  ret h1_title("Cars") + crud.render(true, params);
}

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