Refactored alpinejs in forms for better maintainability
This commit is contained in:
@@ -15,6 +15,41 @@ templ ChangeBio(err string, bio string) {
|
|||||||
class="w-[90%] mx-auto mt-5"
|
class="w-[90%] mx-auto mt-5"
|
||||||
x-data={ templ.JSFuncCall("bioComponent", bio, user.Bio, err).CallInline }
|
x-data={ templ.JSFuncCall("bioComponent", bio, user.Bio, err).CallInline }
|
||||||
>
|
>
|
||||||
|
<script>
|
||||||
|
function bioComponent(newBio, oldBio, err) {
|
||||||
|
return {
|
||||||
|
bio: newBio,
|
||||||
|
initialBio: oldBio,
|
||||||
|
err: err,
|
||||||
|
bioLenText: '',
|
||||||
|
updateTextArea() {
|
||||||
|
this.$nextTick(() => {
|
||||||
|
if (this.$refs.bio) {
|
||||||
|
this.$refs.bio.style.height = 'auto';
|
||||||
|
this.$refs.bio.style.height = `
|
||||||
|
${this.$refs.bio.scrollHeight+20}px`;
|
||||||
|
};
|
||||||
|
this.bioLenText = `${this.bio.length}/128`;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
resetBio() {
|
||||||
|
this.bio = this.initialBio;
|
||||||
|
this.err = "",
|
||||||
|
this.updateTextArea();
|
||||||
|
},
|
||||||
|
init() {
|
||||||
|
this.$nextTick(() => {
|
||||||
|
// this timeout makes sure the textarea resizes on
|
||||||
|
// page render correctly. seems 20ms is the sweet
|
||||||
|
// spot between a noticable delay and not working
|
||||||
|
setTimeout(() => {
|
||||||
|
this.updateTextArea();
|
||||||
|
}, 20);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
</script>
|
||||||
<div
|
<div
|
||||||
class="flex flex-col"
|
class="flex flex-col"
|
||||||
>
|
>
|
||||||
@@ -78,40 +113,5 @@ templ ChangeBio(err string, bio string) {
|
|||||||
x-show="err"
|
x-show="err"
|
||||||
x-text="err"
|
x-text="err"
|
||||||
></p>
|
></p>
|
||||||
<script>
|
|
||||||
function bioComponent(newBio, oldBio, err) {
|
|
||||||
return {
|
|
||||||
bio: newBio,
|
|
||||||
initialBio: oldBio,
|
|
||||||
err: err,
|
|
||||||
bioLenText: '',
|
|
||||||
updateTextArea() {
|
|
||||||
this.$nextTick(() => {
|
|
||||||
if (this.$refs.bio) {
|
|
||||||
this.$refs.bio.style.height = 'auto';
|
|
||||||
this.$refs.bio.style.height = `
|
|
||||||
${this.$refs.bio.scrollHeight+20}px`;
|
|
||||||
};
|
|
||||||
this.bioLenText = `${this.bio.length}/128`;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
resetBio() {
|
|
||||||
this.bio = this.initialBio;
|
|
||||||
this.err = "",
|
|
||||||
this.updateTextArea();
|
|
||||||
},
|
|
||||||
init() {
|
|
||||||
this.$nextTick(() => {
|
|
||||||
// this timeout makes sure the textarea resizes on
|
|
||||||
// page render correctly. seems 20ms is the sweet
|
|
||||||
// spot between a noticable delay and not working
|
|
||||||
setTimeout(() => {
|
|
||||||
this.updateTextArea();
|
|
||||||
}, 20);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
</form>
|
</form>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,11 +13,25 @@ templ ChangeUsername(err string, username string) {
|
|||||||
hx-post="/change-username"
|
hx-post="/change-username"
|
||||||
hx-swap="outerHTML"
|
hx-swap="outerHTML"
|
||||||
class="w-[90%] mx-auto mt-5"
|
class="w-[90%] mx-auto mt-5"
|
||||||
x-data={ "{ err: '" + err + "'}" }
|
x-data={ templ.JSFuncCall(
|
||||||
|
"usernameComponent", username, user.Username, err,
|
||||||
|
).CallInline }
|
||||||
>
|
>
|
||||||
|
<script>
|
||||||
|
function usernameComponent(newUsername, oldUsername, err) {
|
||||||
|
return {
|
||||||
|
username: newUsername,
|
||||||
|
initialUsername: oldUsername,
|
||||||
|
err: err,
|
||||||
|
resetUsername() {
|
||||||
|
this.username = this.initialUsername;
|
||||||
|
this.err = "";
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
</script>
|
||||||
<div
|
<div
|
||||||
class="flex flex-col sm:flex-row"
|
class="flex flex-col sm:flex-row"
|
||||||
x-data={ "{username: '" + username + "'}" }
|
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="flex flex-col sm:flex-row sm:items-center relative"
|
class="flex flex-col sm:flex-row sm:items-center relative"
|
||||||
@@ -65,7 +79,7 @@ templ ChangeUsername(err string, username string) {
|
|||||||
class="rounded-lg bg-blue py-1 px-2 text-mantle sm:ml-2
|
class="rounded-lg bg-blue py-1 px-2 text-mantle sm:ml-2
|
||||||
hover:cursor-pointer hover:bg-blue/75 transition"
|
hover:cursor-pointer hover:bg-blue/75 transition"
|
||||||
x-cloak
|
x-cloak
|
||||||
x-show={ "username !=='" + user.Username + "'" }
|
x-show="username !== initialUsername"
|
||||||
x-transition.opacity.duration.500ms
|
x-transition.opacity.duration.500ms
|
||||||
>
|
>
|
||||||
Update
|
Update
|
||||||
@@ -76,9 +90,9 @@ templ ChangeUsername(err string, username string) {
|
|||||||
type="button"
|
type="button"
|
||||||
href="#"
|
href="#"
|
||||||
x-cloak
|
x-cloak
|
||||||
x-show={ "username !=='" + user.Username + "'" }
|
x-show="username !== initialUsername"
|
||||||
x-transition.opacity.duration.500ms
|
x-transition.opacity.duration.500ms
|
||||||
@click={ "username='" + user.Username + "';err=''" }
|
@click="resetUsername()"
|
||||||
>
|
>
|
||||||
Cancel
|
Cancel
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -1,22 +1,27 @@
|
|||||||
package form
|
package form
|
||||||
|
|
||||||
import "fmt"
|
|
||||||
|
|
||||||
templ ConfirmPassword(err string) {
|
templ ConfirmPassword(err string) {
|
||||||
{{
|
|
||||||
xdata := fmt.Sprintf(
|
|
||||||
"{ errMsg: '%s'}",
|
|
||||||
err,
|
|
||||||
)
|
|
||||||
}}
|
|
||||||
<form
|
<form
|
||||||
hx-post="/reauthenticate"
|
hx-post="/reauthenticate"
|
||||||
x-data="{ submitted: false, buttontext: 'Confirm' }"
|
x-data={ templ.JSFuncCall(
|
||||||
|
"confirmPassData", err,
|
||||||
|
).CallInline }
|
||||||
x-on:htmx:xhr:loadstart="submitted=true;buttontext='Loading...'"
|
x-on:htmx:xhr:loadstart="submitted=true;buttontext='Loading...'"
|
||||||
>
|
>
|
||||||
|
<script>
|
||||||
|
function usernameComponent(err) {
|
||||||
|
return {
|
||||||
|
submitted: false,
|
||||||
|
buttontext: 'Confirm',
|
||||||
|
err: err,
|
||||||
|
reset() {
|
||||||
|
this.err = "";
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
</script>
|
||||||
<div
|
<div
|
||||||
class="grid gap-y-4"
|
class="grid gap-y-4"
|
||||||
x-data={ xdata }
|
|
||||||
>
|
>
|
||||||
<div class="mt-5">
|
<div class="mt-5">
|
||||||
<div class="relative">
|
<div class="relative">
|
||||||
@@ -30,6 +35,7 @@ templ ConfirmPassword(err string) {
|
|||||||
placeholder="Confirm password"
|
placeholder="Confirm password"
|
||||||
required
|
required
|
||||||
aria-describedby="password-error"
|
aria-describedby="password-error"
|
||||||
|
@input="reset()"
|
||||||
/>
|
/>
|
||||||
<div
|
<div
|
||||||
class="absolute inset-y-0 end-0
|
class="absolute inset-y-0 end-0
|
||||||
@@ -52,7 +58,8 @@ templ ConfirmPassword(err string) {
|
|||||||
1 0 1 0 0 2 1 1 0 0 0 0-2z"
|
1 0 1 0 0 2 1 1 0 0 0 0-2z"
|
||||||
></path>
|
></path>
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div> - change username
|
||||||
|
- confirm password
|
||||||
</div>
|
</div>
|
||||||
<p
|
<p
|
||||||
class="text-center text-xs text-red mt-2"
|
class="text-center text-xs text-red mt-2"
|
||||||
|
|||||||
@@ -1,31 +1,34 @@
|
|||||||
package form
|
package form
|
||||||
|
|
||||||
import "fmt"
|
|
||||||
|
|
||||||
// Login Form. If loginError is not an empty string, it will display the
|
// Login Form. If loginError is not an empty string, it will display the
|
||||||
// contents of loginError to the user.
|
// contents of loginError to the user.
|
||||||
// If loginError is "Username or password incorrect" it will also show
|
// If loginError is "Username or password incorrect" it will also show
|
||||||
// error icons on the username and password field
|
// error icons on the username and password field
|
||||||
templ LoginForm(loginError string) {
|
templ LoginForm(loginError string) {
|
||||||
{{
|
{{ credErr := "Username or password incorrect" }}
|
||||||
errCreds := "false"
|
|
||||||
if loginError == "Username or password incorrect" {
|
|
||||||
errCreds = "true"
|
|
||||||
}
|
|
||||||
xdata := fmt.Sprintf(
|
|
||||||
"{credentialError: %s, errorMessage: '%s'}",
|
|
||||||
errCreds,
|
|
||||||
loginError,
|
|
||||||
)
|
|
||||||
}}
|
|
||||||
<form
|
<form
|
||||||
hx-post="/login"
|
hx-post="/login"
|
||||||
x-data="{ submitted: false, buttontext: 'Login' }"
|
x-data={ templ.JSFuncCall(
|
||||||
|
"loginFormData", loginError, credErr,
|
||||||
|
).CallInline }
|
||||||
x-on:htmx:xhr:loadstart="submitted=true;buttontext='Loading...'"
|
x-on:htmx:xhr:loadstart="submitted=true;buttontext='Loading...'"
|
||||||
>
|
>
|
||||||
|
<script>
|
||||||
|
function loginFormData(err, credError) {
|
||||||
|
return {
|
||||||
|
submitted: false,
|
||||||
|
buttontext: 'Login',
|
||||||
|
errorMessage: err,
|
||||||
|
credentialError: err === credError ? true : false,
|
||||||
|
resetErr() {
|
||||||
|
this.errorMessage = "";
|
||||||
|
this.credentialError = false;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
</script>
|
||||||
<div
|
<div
|
||||||
class="grid gap-y-4"
|
class="grid gap-y-4"
|
||||||
x-data={ xdata }
|
|
||||||
>
|
>
|
||||||
<!-- Form Group -->
|
<!-- Form Group -->
|
||||||
<div>
|
<div>
|
||||||
@@ -44,6 +47,7 @@ templ LoginForm(loginError string) {
|
|||||||
disabled:pointer-events-none"
|
disabled:pointer-events-none"
|
||||||
required
|
required
|
||||||
aria-describedby="username-error"
|
aria-describedby="username-error"
|
||||||
|
@input="resetErr()"
|
||||||
/>
|
/>
|
||||||
<div
|
<div
|
||||||
class="absolute inset-y-0 end-0
|
class="absolute inset-y-0 end-0
|
||||||
@@ -93,6 +97,7 @@ templ LoginForm(loginError string) {
|
|||||||
disabled:opacity-50 disabled:pointer-events-none"
|
disabled:opacity-50 disabled:pointer-events-none"
|
||||||
required
|
required
|
||||||
aria-describedby="password-error"
|
aria-describedby="password-error"
|
||||||
|
@input="resetErr()"
|
||||||
/>
|
/>
|
||||||
<div
|
<div
|
||||||
class="absolute inset-y-0 end-0
|
class="absolute inset-y-0 end-0
|
||||||
|
|||||||
@@ -1,36 +1,41 @@
|
|||||||
package form
|
package form
|
||||||
|
|
||||||
import "fmt"
|
|
||||||
|
|
||||||
// Login Form. If loginError is not an empty string, it will display the
|
// Login Form. If loginError is not an empty string, it will display the
|
||||||
// contents of loginError to the user.
|
// contents of loginError to the user.
|
||||||
templ RegisterForm(registerError string) {
|
templ RegisterForm(registerError string) {
|
||||||
{{
|
{{
|
||||||
errUsername := "false"
|
usernameErr := "Username is taken"
|
||||||
errPasswords := "false"
|
passErrs := []string{
|
||||||
if registerError == "Username is taken" {
|
"Password exceeds maximum length of 72 bytes",
|
||||||
errUsername = "true"
|
"Passwords do not match",
|
||||||
} else if registerError == "Passwords do not match" ||
|
|
||||||
registerError == "Password exceeds maximum length of 72 bytes" {
|
|
||||||
errPasswords = "true"
|
|
||||||
}
|
}
|
||||||
xdata := fmt.Sprintf(
|
|
||||||
"{errUsername: %s, errPasswords: %s, errorMessage: '%s'}",
|
|
||||||
errUsername,
|
|
||||||
errPasswords,
|
|
||||||
registerError,
|
|
||||||
)
|
|
||||||
}}
|
}}
|
||||||
<form
|
<form
|
||||||
hx-post="/register"
|
hx-post="/register"
|
||||||
x-data="{ submitted: false, buttontext: 'Login' }"
|
x-data={ templ.JSFuncCall(
|
||||||
|
"registerFormData", registerError, usernameErr, passErrs,
|
||||||
|
).CallInline }
|
||||||
x-on:htmx:xhr:loadstart="submitted=true;buttontext='Loading...'"
|
x-on:htmx:xhr:loadstart="submitted=true;buttontext='Loading...'"
|
||||||
>
|
>
|
||||||
|
<script>
|
||||||
|
function registerFormData(err, usernameErr, passErrs) {
|
||||||
|
return {
|
||||||
|
submitted: false,
|
||||||
|
buttontext: 'Register',
|
||||||
|
errorMessage: err,
|
||||||
|
errUsername: err === usernameErr ? true : false,
|
||||||
|
errPasswords: passErrs.includes(err) ? true : false,
|
||||||
|
resetErr() {
|
||||||
|
this.errorMessage = "";
|
||||||
|
this.errUsername = false;
|
||||||
|
this.errPasswords = false;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
</script>
|
||||||
<div
|
<div
|
||||||
class="grid gap-y-4"
|
class="grid gap-y-4"
|
||||||
x-data={ xdata }
|
|
||||||
>
|
>
|
||||||
<!-- Form Group -->
|
|
||||||
<div>
|
<div>
|
||||||
<label
|
<label
|
||||||
for="email"
|
for="email"
|
||||||
@@ -47,6 +52,7 @@ templ RegisterForm(registerError string) {
|
|||||||
disabled:pointer-events-none"
|
disabled:pointer-events-none"
|
||||||
required
|
required
|
||||||
aria-describedby="username-error"
|
aria-describedby="username-error"
|
||||||
|
@input="resetErr()"
|
||||||
/>
|
/>
|
||||||
<div
|
<div
|
||||||
class="absolute inset-y-0 end-0
|
class="absolute inset-y-0 end-0
|
||||||
@@ -96,6 +102,7 @@ templ RegisterForm(registerError string) {
|
|||||||
disabled:opacity-50 disabled:pointer-events-none"
|
disabled:opacity-50 disabled:pointer-events-none"
|
||||||
required
|
required
|
||||||
aria-describedby="password-error"
|
aria-describedby="password-error"
|
||||||
|
@input="resetErr()"
|
||||||
/>
|
/>
|
||||||
<div
|
<div
|
||||||
class="absolute inset-y-0 end-0
|
class="absolute inset-y-0 end-0
|
||||||
@@ -138,6 +145,7 @@ templ RegisterForm(registerError string) {
|
|||||||
disabled:opacity-50 disabled:pointer-events-none"
|
disabled:opacity-50 disabled:pointer-events-none"
|
||||||
required
|
required
|
||||||
aria-describedby="confirm-password-error"
|
aria-describedby="confirm-password-error"
|
||||||
|
@input="resetErr()"
|
||||||
/>
|
/>
|
||||||
<div
|
<div
|
||||||
class="absolute inset-y-0 end-0
|
class="absolute inset-y-0 end-0
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ templ Global() {
|
|||||||
// htmx.logAll();
|
// htmx.logAll();
|
||||||
</script>
|
</script>
|
||||||
<script>
|
<script>
|
||||||
const popups = {
|
const bodyData = {
|
||||||
showError: false,
|
showError: false,
|
||||||
showConfirmPasswordModal: false,
|
showConfirmPasswordModal: false,
|
||||||
handleHtmxBeforeOnLoad(event) {
|
handleHtmxBeforeOnLoad(event) {
|
||||||
@@ -78,7 +78,7 @@ templ Global() {
|
|||||||
</head>
|
</head>
|
||||||
<body
|
<body
|
||||||
class="bg-base text-text ubuntu-mono-regular overflow-x-hidden"
|
class="bg-base text-text ubuntu-mono-regular overflow-x-hidden"
|
||||||
x-data="popups"
|
x-data="bodyData"
|
||||||
x-on:htmx:error="handleHtmxError($event)"
|
x-on:htmx:error="handleHtmxError($event)"
|
||||||
x-on:htmx:before-on-load="handleHtmxBeforeOnLoad($event)"
|
x-on:htmx:before-on-load="handleHtmxBeforeOnLoad($event)"
|
||||||
>
|
>
|
||||||
|
|||||||
Reference in New Issue
Block a user