Skip to content

Commit

Permalink
Merge pull request #15 from dimacurrentai/main
Browse files Browse the repository at this point in the history
  • Loading branch information
dkorolev authored May 30, 2024
2 parents 2a4c5ff + 3bd1ae9 commit 5577e85
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 30 deletions.
66 changes: 41 additions & 25 deletions src/lib_c5t_htmlform.cc
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#include "lib_c5t_htmlform.h" // IWYU pragma: keep

#include "typesystem/serialization/json/primitives.h" // IWYU pragma: keep

#include <sstream>

std::string current::htmlform::FormAsHTML(Form const& form) {
Expand All @@ -18,37 +20,51 @@ std::string current::htmlform::FormAsHTML(Form const& form) {
oss << R"(
<form id="form">)";
for (auto const& f : form.fields) {
std::string input_type = "text";
if (Exists(f.type) && Value(f.type) == "password") {
input_type = "password";
}
oss << R"(
<p>)"
<< (Exists(f.text) ? Value(f.text) : f.id) << R"(</p>
<input
type=)" + input_type;
if (Exists(f.type) && Value(f.type) == "readonly") {
<< (Exists(f.text) ? Value(f.text) : f.id) << R"(</p>)";
std::string input_type = Exists(f.type) ? Value(f.type) : "text";
if (input_type == "select" && Exists(f.options) && !Value(f.options).empty()) {
std::string const default_option = Exists(f.default_option) ? Value(f.default_option) : Value(f.options).front();
oss << R"(
disabled=disabled)";
}
oss << R"(
autocomplete=false
id=")"
<< f.id << '"';
if (Exists(f.placeholder)) {
<select id=")"
<< f.id << "\">";
for (auto const& o : Value(f.options)) {
oss << R"(
<option value=)"
<< JSON(o) << (o == default_option ? " selected>" : ">") << o << "</option>";
}
oss << R"(
placeholder=")"
<< Value(f.placeholder) << '"';
}
if (Exists(f.value)) {
</select>
<br>)";
} else {
oss << R"(
<input
type=)" +
input_type;
if (Exists(f.type) && Value(f.type) == "readonly") {
oss << R"(
disabled=disabled)";
}
oss << R"(
value=")"
<< Value(f.value) << '"';
autocomplete=false
id=")"
<< f.id << '"';
if (Exists(f.placeholder)) {
oss << R"(
placeholder=")"
<< Value(f.placeholder) << '"';
}
if (Exists(f.value)) {
oss << R"(
value=")"
<< Value(f.value) << '"';
}
oss << R"(
size="100"
/>
<br>)";
}
oss << R"(
size="100"
/>
<br>)";
}
oss << R"(
<br>
Expand Down
16 changes: 15 additions & 1 deletion src/lib_c5t_htmlform.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ CURRENT_STRUCT(Field) {
CURRENT_FIELD(text, Optional<std::string>);
CURRENT_FIELD(placeholder, Optional<std::string>);
CURRENT_FIELD(value, Optional<std::string>);
CURRENT_FIELD(type, Optional<std::string>);
CURRENT_FIELD(type, Optional<std::string>); // can be unset, "readonly", "password", or "select"
CURRENT_FIELD(options, Optional<std::vector<std::string>>);
CURRENT_FIELD(default_option, Optional<std::string>);

CURRENT_CONSTRUCTOR(Field)(std::string id = "id") : id(std::move(id)) {}

Expand All @@ -49,6 +51,18 @@ CURRENT_STRUCT(Field) {
type = "password";
return *this;
}
Field& Select(std::vector<std::string> arg_options) {
type = "select";
options = std::move(arg_options);
default_option = nullptr;
return *this;
}
Field& Select(std::vector<std::string> arg_options, std::string arg_default_option) {
type = "select";
options = std::move(arg_options);
default_option = std::move(arg_default_option);
return *this;
}
};

CURRENT_STRUCT(Form) {
Expand Down
13 changes: 9 additions & 4 deletions src/wss.cc
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@

CURRENT_STRUCT(StopResponseSchema) { CURRENT_FIELD(msg, std::string); };
CURRENT_STRUCT(SumResponseSchema) {
CURRENT_FIELD(sum, int64_t);
CURRENT_FIELD(result, int64_t);
CURRENT_FIELD(pw, Optional<std::string>);
CURRENT_FIELD(op, Optional<std::string>);
};

inline std::string BasePathOf(std::string const& s) {
Expand Down Expand Up @@ -124,6 +125,7 @@ int main(int argc, char** argv) {
using namespace current::htmlform;
if (r.method == "GET") {
auto const f = Form()
.Add(Field("e").Text("Operation").Select({"mul", "add"}, "add"))
.Add(Field("a").Text("First summand").Placeholder("3 for example").Value("3"))
.Add(Field("b").Text("Second summand").Placeholder("4 for example"))
.Add(Field("c").Text("Read-only caption").Value("Read-only text").Readonly())
Expand All @@ -136,7 +138,7 @@ int main(int argc, char** argv) {
if (isNaN(a)) return { error: "A is not a number." };
const b = parseInt(input.b);
if (isNaN(b)) return { error: "B is not a number." };
return { sum: a + b, pw: String(input.d) };
return { result: (input.e === "mul" ? a * b : a + b), pw: String(input.d), op: input.e };
})");
r(FormAsHTML(f), HTTPResponseCode.OK, current::net::constants::kDefaultHTMLContentType);
} else {
Expand All @@ -146,7 +148,10 @@ int main(int argc, char** argv) {
if (Exists(body.pw)) {
std::cout << "PW: " << Value(body.pw) << std::endl;
}
res.fwd = "/is/" + current::ToString(body.sum);
if (Exists(body.op)) {
std::cout << "OP: " << Value(body.op) << std::endl;
}
res.fwd = "/is/" + current::ToString(body.result);
} catch (current::Exception& e) {
res.msg = "error!";
}
Expand All @@ -155,7 +160,7 @@ int main(int argc, char** argv) {
});

routes += http.Register(
"/sum/is", URLPathArgs::CountMask::One, [](Request r) { r("the sum is " + r.url_path_args[0] + '\n'); });
"/sum/is", URLPathArgs::CountMask::One, [](Request r) { r("the result is " + r.url_path_args[0] + '\n'); });

routes += http.Register("/dlib", [](Request r) {
std::ostringstream oss;
Expand Down

0 comments on commit 5577e85

Please sign in to comment.