@@ -39,11 +47,8 @@
{{ .lang.passwordRequirementsHeader }}
{{ range $key, $value := .requirements }}
- -
-
-
- -
-
+
-
+
{{ end }}
diff --git a/ts/form.ts b/ts/form.ts
new file mode 100644
index 0000000..0cfb596
--- /dev/null
+++ b/ts/form.ts
@@ -0,0 +1,178 @@
+import { Modal } from "./modules/modal.js";
+import { _post, toggleLoader } from "./modules/common.js";
+
+interface formWindow extends Window {
+ validationStrings: pwValStrings;
+ invalidPassword: string;
+ modal: Modal;
+}
+
+interface pwValString {
+ singular: string;
+ plural: string;
+}
+
+interface pwValStrings {
+ length: pwValString;
+ uppercase: pwValString;
+ lowercase: pwValString;
+ number: pwValString;
+ special: pwValString;
+ [ type: string ]: pwValString;
+}
+
+window.modal = new Modal(document.getElementById("modal-success"));
+declare var window: formWindow;
+
+var defaultPwValStrings: pwValStrings = {
+ length: {
+ singular: "Must have at least {n} character",
+ plural: "Must have a least {n} characters"
+ },
+ uppercase: {
+ singular: "Must have at least {n} uppercase character",
+ plural: "Must have at least {n} uppercase characters"
+ },
+ lowercase: {
+ singular: "Must have at least {n} lowercase character",
+ plural: "Must have at least {n} lowercase characters"
+ },
+ number: {
+ singular: "Must have at least {n} number",
+ plural: "Must have at least {n} numbers"
+ },
+ special: {
+ singular: "Must have at least {n} special character",
+ plural: "Must have at least {n} special characters"
+ }
+}
+
+const form = document.getElementById("form-create") as HTMLFormElement;
+const submitButton = form.querySelector("input[type=submit]") as HTMLInputElement;
+const submitSpan = form.querySelector("span.submit") as HTMLSpanElement;
+let usernameField = document.getElementById("create-username") as HTMLInputElement;
+const emailField = document.getElementById("create-email") as HTMLInputElement;
+if (!window.usernameEnabled) { usernameField.parentElement.remove(); usernameField = emailField; }
+const passwordField = document.getElementById("create-password") as HTMLInputElement;
+const rePasswordField = document.getElementById("create-reenter-password") as HTMLInputElement;
+
+const checkPasswords = () => {
+ if (passwordField.value != rePasswordField.value) {
+ rePasswordField.setCustomValidity(window.invalidPassword);
+ submitButton.disabled = true;
+ submitSpan.setAttribute("disabled", "");
+ } else {
+ rePasswordField.setCustomValidity("");
+ submitButton.disabled = false;
+ submitSpan.removeAttribute("disabled");
+ }
+};
+rePasswordField.addEventListener("keyup", checkPasswords);
+passwordField.addEventListener("keyup", checkPasswords);
+
+interface respDTO {
+ [ type: string ]: boolean;
+}
+
+interface sendDTO {
+ code: string;
+ email: string;
+ username: string;
+ password: string;
+}
+
+const create = (event: SubmitEvent) => {
+ event.preventDefault();
+ toggleLoader(submitSpan);
+ let send: sendDTO = {
+ code: window.location.href.split('/').pop(),
+ username: usernameField.value,
+ email: emailField.value,
+ password: passwordField.value
+ };
+ _post("/newUser", send, (req: XMLHttpRequest) => {
+ if (req.readyState == 4) {
+ let vals = JSON.parse(req.response) as respDTO;
+ let valid = true;
+ for (let type in vals) {
+ if (requirements[type]) { requirements[type].valid = vals[type]; }
+ if (!vals[type]) { valid = false; }
+ }
+ toggleLoader(submitSpan);
+ if (req.status == 200 && valid) {
+ window.modal.show();
+ } else {
+ submitSpan.classList.add("~critical");
+ submitSpan.classList.remove("~urge");
+ setTimeout(() => {
+ submitSpan.classList.add("~urge");
+ submitSpan.classList.remove("~critical");
+ }, 1000);
+ }
+ }
+ });
+};
+
+form.onsubmit = create;
+
+class Requirement {
+ private _name: string;
+ private _minCount: number;
+ private _content: HTMLSpanElement;
+ private _valid: HTMLSpanElement;
+ private _li: HTMLLIElement;
+
+ get valid(): boolean { return this._valid.classList.contains("~positive"); }
+ set valid(state: boolean) {
+ if (state) {
+ this._valid.classList.add("~positive");
+ this._valid.classList.remove("~critical");
+ this._valid.innerHTML = `
`;
+ } else {
+ this._valid.classList.add("~critical");
+ this._valid.classList.remove("~positive");
+ this._valid.innerHTML = `
`;
+ }
+ }
+
+ constructor(name: string, el: HTMLLIElement) {
+ this._name = name;
+ this._li = el;
+ this._content = this._li.querySelector("span.requirement-content") as HTMLSpanElement;
+ this._valid = this._li.querySelector("span.requirement-valid") as HTMLSpanElement;
+ this.valid = false;
+ this._minCount = +this._li.getAttribute("min");
+
+ let text = "";
+ if (this._minCount == 1) {
+ text = window.validationStrings[this._name].singular.replace("{n}", "1");
+ } else {
+ text = window.validationStrings[this._name].plural.replace("{n}", ""+this._minCount);
+ }
+ this._content.textContent = text;
+ }
+}
+
+const testStrings = (f: pwValString): boolean => {
+ const testString = (s: string): boolean => {
+ if (s == "" || !s.includes("{n}")) { return false; }
+ return true;
+ }
+ return testString(f.singular) && testString(f.plural);
+}
+
+var requirements: { [category: string]: Requirement} = {};
+
+if (!window.validationStrings) {
+ window.validationStrings = defaultPwValStrings;
+} else {
+ for (let category in window.validationStrings) {
+ if (!testStrings(window.validationStrings[category])) {
+ window.validationStrings[category] = defaultPwValStrings[category];
+ }
+ const el = document.getElementById("requirement-" + category);
+ if (el) {
+ requirements[category] = new Requirement(category, el as HTMLLIElement);
+ } else { console.log(category); }
+ }
+}
diff --git a/ts/typings/d.ts b/ts/typings/d.ts
index f09054c..013ea9b 100644
--- a/ts/typings/d.ts
+++ b/ts/typings/d.ts
@@ -59,7 +59,6 @@ declare interface Modals {
settingsRestart: Modal;
settingsRefresh: Modal;
ombiDefaults?: Modal;
- newAccountSuccess?: Modal;
profiles: Modal;
addProfile: Modal;
}