diff --git a/index.php b/index.php
index c5ef5a2..b4b845d 100644
--- a/index.php
+++ b/index.php
@@ -8,15 +8,16 @@
MKK Közivezető-választás
+
-
-
diff --git a/interface.php b/interface.php
index 74cc353..2712f21 100644
--- a/interface.php
+++ b/interface.php
@@ -31,23 +31,35 @@ function read_electable_people(string $fname): array
}
define("MINIMUM_NEEDLE_LENGTH", 3);
+define("HIDE_GROUP_OF_NON_DUPLICATES", true);
// keresés a nevek között
-function search_in_names(array $records, string $needle): array
+function search_in_names(array $records, string $needle, string $group = ""): array
{
+ // keresés
$needle = trim($needle);
if (strlen($needle) < MINIMUM_NEEDLE_LENGTH) {
return [];
}
+ $exact_match = [];
$hitpos_array = [];
- $filter = function(array $var) use (&$hitpos_array, $needle) : bool {
+ $filter = function (array $var) use (&$hitpos_array, &$exact_match, $needle, $group): bool {
+ // ha a csoporton belül keres
+ if ($group !== "" && $var["group"] !== $group) {
+ return false;
+ }
+
$hitpos = stripos($var["name"], $needle);
- if ($hitpos != false) {
+ // ha van egyezés...
+ if ($hitpos !== false) {
$hitpos_array[] = $hitpos;
+
+ // megvizsgálja, hogy exact egyezés van-e?
+ $exact_match[] = $var["name"] === $needle;
}
return $hitpos !== false;
@@ -58,9 +70,46 @@ function search_in_names(array $records, string $needle): array
if (count($filter_res) > 0) {
for ($i = 0; $i < count($filter_res); $i++) {
$filter_res[$i]["hitpos"] = $hitpos_array[$i];
+ $filter_res[$i]["exact_match"] = $exact_match[$i];
+ $filter_res[$i]["duplicate"] = false;
}
}
+ if (HIDE_GROUP_OF_NON_DUPLICATES) {
+ // nevek rendezése hossz szerint (substr gyorsítása n*(n-1)-ről (n-1)+(n-2)+(n-3)... vizsgálatra)
+ usort($filter_res, fn($a, $b) => strlen($a["name"]) - strlen($b["name"]));
+
+ // ha a név nem szerepel több, mint egyszer, akkor a csoportot törli (security reasons)
+ for ($i = 0; $i < count($filter_res); $i++) {
+ if ($filter_res[$i]["duplicate"]) {
+ continue;
+ }
+
+ $name_needle = $filter_res[$i]["name"]; // név, amit keresünk a többiben
+ $is_duplicate = false;
+ for ($j = $i + 1; $j < count($filter_res); $j++) {
+ // ha van találat, akkor kiugrunk a keresésből
+ if (stripos($filter_res[$j]["name"], $name_needle) !== false) {
+ $filter_res[$j]["duplicate"] = true;
+ $is_duplicate = true;
+ break;
+ }
+ }
+
+ $filter_res[$i]["duplicate"] = $is_duplicate;
+ }
+
+ // csoport törlése azokból a nevekből, amikből nem szerepel több
+ for ($i = 0; $i < count($filter_res); $i++) {
+ if (!$filter_res[$i]["duplicate"]) {
+ $filter_res[$i]["group"] = "";
+ }
+ }
+ }
+
+ // rendezés abc-rendbe
+ usort($filter_res, fn($a, $b) => $a["name"] > $b["name"]);
+
return $filter_res;
}
@@ -76,8 +125,9 @@ switch ($action) {
case "search":
{
$needle = json_decode($_POST["needle"]);
+ $group = json_decode($_POST["group"]);
$p = read_electable_people(ELECTABLE_PEOPLE_DATABASE);
- $hits = search_in_names($p, $needle);
+ $hits = search_in_names($p, $needle, $group);
$res = $hits;
}
break;
diff --git a/js/mkkkvv.js b/js/mkkkvv.js
index ccb1a98..c961507 100644
--- a/js/mkkkvv.js
+++ b/js/mkkkvv.js
@@ -1,39 +1,54 @@
const MINIMUM_NEEDLE_LENGTH = 3;
-const CANVAS = document.create
-
// keresés indítása a nevek között
function search_in_names(needle) {
let hintbox = document.getElementById("hintbox");
- if (needle.length < 3) {
- hintbox.innerHTML = "";
- }
-
if (needle.trim().length < MINIMUM_NEEDLE_LENGTH) {
+ hintbox.innerHTML = "";
+ hide("hintzone");
+ o("nameinput").setAttribute("validity", "");
return;
}
- request({
+ let request_data = {
action: "search",
- needle: needle
- }).then(resp => {
+ needle: "",
+ group: ""
+ };
+
+ // csoport és név szétválasztása
+ let group_regex = /(\[[a-záéíóöúü]+\]$)/gi;
+ let group_extracted = needle.match(group_regex);
+ if (group_extracted != null) {
+ request_data["group"] = group_extracted[0].substring(1, group_extracted[0].length - 1);
+ request_data["needle"] = needle.substring(0, needle.length - group_extracted[0].length - 1).trim();
+ } else {
+ request_data["needle"] = needle;
+ }
+
+ request(request_data).then(resp => {
hintbox.innerHTML = "";
let hits = JSON.parse(resp);
- console.log(hits);
- hits.forEach((key, val) => {
+ hits.forEach((val) => {
if (needle.length < 3) {
return;
}
let hit = document.createElement("span");
hit.classList.add("hit");
+ hit.addEventListener("click", () => {
+ let group_id = val["duplicate"] ? ` [${val["group"]}]` : "";
+ fill_name_input(`${val["name"]}${group_id}`);
+ hide("hintzone");
+ ninput.setAttribute("validity", "ok");
+ });
let name_node = document.createElement("span");
name_node.classList.add("name");
- let hp = key["hitpos"];
- let name = key["name"];
+ let hp = val["hitpos"];
+ let name = val["name"];
if (hp > 0) {
let name_begin = name.slice(0, hp);
@@ -52,12 +67,73 @@ function search_in_names(needle) {
hit.appendChild(name_node);
- let group = document.createElement("span");
- group.innerText = `(${key["group"]})`;
- group.classList.add("group");
- hit.appendChild(group);
+ let group = val["group"];
+ if (group.length > 0) {
+ let group_node = document.createElement("span");
+ group_node.innerHTML = ` ${print_from_group(group)}`;
+ group_node.classList.add("group");
+ hit.appendChild(group_node);
+ }
hintbox.appendChild(hit);
});
+
+ // doboz megjelenítése, ha szükséges
+ hits.length > 0 ? show("hintzone") : hide("hintzone");
+
+ // szövegmező színezése
+ let validity = "";
+ let ninput = document.getElementById("nameinput");
+ if (ninput.value.length > MINIMUM_NEEDLE_LENGTH) {
+ if (hits.length === 0) {
+ validity = "bad";
+ } else if (hits.length === 1 && hits[0]["exact_match"]) {
+ validity = "ok";
+ hide("hintzone");
+ }
+ }
+ ninput.setAttribute("validity", validity);
});
-}
\ No newline at end of file
+}
+
+// csoport kiírása ("...az Azúrból" -- no reference of course :D), ha megkapja a szervertől
+function print_from_group(group) {
+ group = group.trim();
+ if (group === "") {
+ return "";
+ }
+
+ let vowels = /[aáeéiíoóöőuúüű]/i; // magánhangzók regexe
+ let highpitched_vowels = /[eéiíöőüű]/i; // magas hangrendű maánhangzók regexe
+
+ // első betű megvizsgálása a névelő kiválasztásához
+ let b = group.charAt(0);
+ let article = (vowels.exec(b) != null) ? "az" : "a";
+
+ // hátulról az első magánhangzó keresése
+ let g_rev = group.split("").reverse().join("");
+ let last_vowel = g_rev.match(vowels)[0];
+
+ // megvizsgáljuk, hogy az utolsó betű volt-e a megtalált magánhangzó
+ let last_letter = g_rev.charAt(0).toLowerCase();
+ if (last_letter === last_vowel.charAt(0).toLowerCase()) {
+ if (last_letter === "a") {
+ last_letter = "á";
+ } else if (last_letter === "e") {
+ last_letter = "é";
+ }
+
+ // utolsó betű kicserélése
+ group = group.substring(0, group.length - 1) + last_letter;
+ }
+
+ // utolsó magánhangzó hangrendjének vizsgálata és rag kiválasztása
+ let suffix = highpitched_vowels.test(last_vowel) ? "ből" : "ból";
+
+ return `${article} ${group}${suffix}`;
+}
+
+// szöveggel kitölti a nevet
+function fill_name_input(str) {
+ document.getElementById("nameinput").value = str;
+}
diff --git a/js/o.js b/js/o.js
new file mode 100644
index 0000000..eabb5bf
--- /dev/null
+++ b/js/o.js
@@ -0,0 +1,25 @@
+function o(input) {
+ var o;
+ if (typeof input === "string")
+ o = document.getElementById(input);
+ else if (typeof input === "object")
+ o = input;
+ return o;
+}
+
+// megjelenítés / eltüntetés
+function show(obj) {
+ o(obj).setAttribute("shown", "true");
+}
+
+function hide(obj) {
+ o(obj).setAttribute("shown", "false");
+}
+
+function toggle_show(obj) {
+ o(obj).setAttribute("shown", o(obj).getAttribute("shown") === "false");
+}
+
+function scroll_enable(on) {
+ document.body.style.overflowY = on ? "scroll" : "hidden";
+}
diff --git a/mkkkvv.css b/mkkkvv.css
index f04313c..eb61a47 100644
--- a/mkkkvv.css
+++ b/mkkkvv.css
@@ -4,10 +4,14 @@ body{
--C_PRIMARY: #f89a17;
--C_SEC: #44968e;
--C_TER: #2a5999;
+ --C_OK: #67b60a;
--C_TRIADIC1: #85ea11;
--C_TRIADIC2: #11ea76;
--C_BG1: #c0ccdf;
--C_BG2: #e3ecf3;
+ --C_BG3: #e9f3e3;
+ --C_UNKNOWN: #f84c17;
+ --C_TEXTINPUT_COLOR: #2f4c6e;
font-family: 'Faustina', serif;
@@ -27,6 +31,18 @@ input[type="text"]:focus {
input#nameinput {
width: 100%;
+ color: var(--C_TEXTINPUT_COLOR);
+ transition: color 0.3s ease;
+}
+
+input#nameinput[validity="ok"] {
+ color: var(--C_OK);
+ transition: color 0.3s ease;
+}
+
+input#nameinput[validity="bad"] {
+ color: var(--C_UNKNOWN);
+ transition: color 0.3s ease;
}
section#hintbox {
@@ -41,14 +57,35 @@ span.hit {
display: block;
position: static;
padding: 0.2em 0.5em;
+ cursor: pointer;
+}
+
+span.hit:hover {
+ background-color: var(--C_BG3);
}
span.highlight {
font-weight: bold;
+ color: var(--C_SEC);
+ text-decoration: underline;
}
section#mainbox {
display: block;
position: absolute;
width: min(var(--MAINBOX_WIDTH), calc(100vw - 1em));
-}
\ No newline at end of file
+}
+
+*[shown="false"] {
+ visibility: hidden;
+ display: none;
+ opacity: 0;
+ transition: 0.3s ease;
+ width: 0;
+ height: 0;
+}
+
+*[shown="true"] {
+ opacity: 1;
+ transition: 0.3s ease;
+}