Posts tagged: webdev
All posts with the tag "webdev"
I am working on fokais.com’s signup page, and I want to hide the form input during an htmx request. I was seeing some issues where I was able to prevent spamming the submit button, but was still able to get one extra hit on it.
It also felt like nothing was happening while sending the email to the user for verification. Now I get the form to disappear and a spinner to show during the request.
html">HTML #
Let’s start off with the form. It uses htmx to submit a post request to the
post_request route. Note that there is a spinner in the post_request with the
htmx-indicator class.
The intent is to hide the spinner until the request is running, and hide all of the form input during the request.
<form
id="signup-form"
hx-swap-oob="outerHTML"
class="m-4 mx-auto mb-6 flex w-80 flex-col rounded-lg b p-4 shadow-xlc shadow-cyan-500/10"
method="POST"
action="{{ url_for('post_signup') }}"
hx-post="{{ url_for('post_signup') }}"
>
<!--markata-attribution-->
<input
class="mx-8 mt-6 mb-4 border border-black bg-zinc-900 p-1 text-center focus:bg-zinc-800"
<!--markata-attribution-->
type="text"
<!--markata-attribution-->
value="{{ full_name }}"
<!--markata-attribution-->
name="full_name"
<!--markata-attribution-->
placeholder="Full Name"
/>
<!--markata-attribution-->
{% if full_name_error %}
<!--markata-attribution-->
<label class="-mt-6 mb-6 mx-8 text-red-500 p-1 text-center">
<!--markata-attribution-->
{{ full_name_error }}
<!--markata-attribution-->
</label>
<!--markata-attribution-->
{% endif %}
<!--markata-attribution-->
<input
class="mx-8 mb-4 border border-black bg-zinc-900 p-1 text-center focus:bg-zinc-800"
<!--markata-attribution-->
type="text"
<!--markata-attribution-->
value="{{ username }}"
<!--markata-attribution-->
name="username"
<!--markata-attribution-->
placeholder="username"
/>
<!--markata-attribution-->
{% if username_error %}
<!--markata-attribution-->
<label class="-mt-6 mb-6 mx-8 text-red-500 p-1 text-center">
<!--markata-attribution-->
{{ username_error }}
<!--markata-attribution-->
</label>
<!--markata-attribution-->
{% endif %}
<!--markata-attribution-->
<input
class="mx-8 mb-4 border border-black bg-zinc-900 p-1 text-center focus:bg-zinc-800"
<!--markata-attribution-->
type="email"
<!--markata-attribution-->
name="email"
<!--markata-attribution-->
value="{{ email }}"
<!--markata-attribution-->
placeholder="email"
/>
<!--markata-attribution-->
{% if email_error %}
<!--markata-attribution-->
<label class="-mt-6 mb-6 mx-8 text-red-500 p-1 text-center">
<!--markata-attribution-->
{{ email_error }}
<!--markata-attribution-->
</label>
<!--markata-attribution-->
{% endif %}
<!--markata-attribution-->
<input
class="mx-auto w-32 mb-4 border border-black bg-purple-900 p-1 text-center focus:bg-zinc-800"
<!--markata-attribution-->
type="submit"
<!--markata-attribution-->
value="sign up"
/>
<!--markata-attribution-->
<div role="status" class="mx-auto htmx-indicator">
<!--markata-attribution-->
<svg
<!--markata-attribution-->
class="mx-auto animate-spin h-5 w-5 text-white"
<!--markata-attribution-->
xmlns="https://www.w3.org/2000/svg"
<!--markata-attribution-->
fill="none"
<!--markata-attribution-->
viewBox="0 0 24 24"
>
<!--markata-attribution-->
<circle
<!--markata-attribution-->
class="opacity-25"
<!--markata-attribution-->
cx="12"
<!--markata-attribution-->
cy="12"
<!--markata-attribution-->
r="10"
<!--markata-attribution-->
stroke="currentColor"
<!--markata-attribution-->
stroke-width="4"
></circle>
<!--markata-attribution-->
<path
<!--markata-attribution-->
class="opacity-75"
<!--markata-attribution-->
fill="currentColor"
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
></path>
<!--markata-attribution-->
</svg>
<!--markata-attribution-->
<p>Signing up...</p>
<!--markata-attribution-->
</div>
<!--markata-attribution-->
</form>
Yes this is styled using tailwindcss.
https://waylonwalker.com/still-loving-tailwind/
CSS #
Let’s take a look at how we achieve switching between only spinner an only form inputs using css.
.htmx-indicator {
@apply hidden;
opacity: 0;
transition: opacity 500ms ease-in;
}
.htmx-request button,
.htmx-request input[type="submit"],
.htmx-request input,
.htmx-request label {
@apply hidden;
}
.htmx-request .htmx-indicator {
opacity: 1;
@apply block;
}
.htmx-request.htmx-indicator {
opacity: 1;
@apply block;
}
Final Result #
Here is the final result of me signing up for a new account in fokais.
Looking for a Heroku replacement, What I found was shocking!
I’ve been using tailwind for a few months now and I can still say I’m loving it. I’ve been using it to create some rapid prototypes that may or may not ever become something, a document that is likely to go to print (a resume), and some quick dashboards.
I started using Tailwind a few month back #
A few months back in september of 2023 I made a case for tailwindcss. And have been using it on quite a few projects since.
- values are well thought out
- it’s really easy to use
- classes that make sense
- tree shakable
fokais.com #
I started working on fokais.com only a few weeks ago, It’s going to be a SAS to make blogging easier. I’ve started hosting some tools for this blog that I really like that I think I can turn into a service. It’s been fantastic to quickly pump out new pages with tailwind.
htmx">HTMX #
tailwind and htmx are a match made in heaven. They both really lean on Location of Behavior over Separation of concerns. They do really well at making small components that you can throw on and endpoint and stack into any page. With tailwind I just configure it to look at all my templates, and I can guarantee that the styles will be in app.css, and all I need to do is add classes to my component.
Heres a sample component for a user widget that will go on every page. It has everything it needs right in the template.
<div
hx-swap-oob="outerHTML"
id="user-header"
class="absolute top-0 right-0 mt-8 mr-4"
>
<!--markata-attribution-->
{% if current_user %}
<!--markata-attribution-->
<details
<!--markata-attribution-->
id="user-header-details"
<!--markata-attribution-->
open
class="group list-none px-4 py-2 self-center justify-self-center bg-neutral-600/10 shadow-lg shadow-zinc-950/20 ring-2 ring-zinc-950/5 rounded-xl flex justify-center align-center flex-col"
>
<summary style="list-style-type: none">{{ current_user.username }}</summary>
<!--markata-attribution-->
<div class="hidden group-hover:block my-4">
<!--markata-attribution-->
<a
class="mt-6 px-4 py-2 rounded bg-purple-950/5 ring-2 ring-cyan-500/30 text-cyan-500 font-bold"
<!--markata-attribution-->
href="{{ url_for('get_logout') }}"
>
<!--markata-attribution-->
Logout
</a>
<!--markata-attribution-->
</div>
<!--markata-attribution-->
</details>
{% else %}
<a
href="{{ url_for('post_login') }}"
class="mt-5 text-xl text-white font-bold text-shadow-xl text-shadow-zinc-950"
>
<!--markata-attribution-->
login
</a>
<!--markata-attribution-->
{% endif %}
<!--markata-attribution-->
</div>
internal apps #
I’ve built several interal apps, and tailwind has been really great for this. Its super quick to pop classes on components and get things to look decent quickly, or put some real polish into making them look nice.
My Website waylonwalker.com #
I’ve dropped my old decrepid css for some tailwind on my main site. My css was much smaller, but did not work quite as well on all devices, and most importantly was becoming a house of cards. Every time I fixed one thing several other things would fail. Colors were a bit muddy, and not as nicely configured as tailwind.
Most importantly was becoming a house of cards. Every time I fixed one thing several other things would fail.
One rough side of styling a blog in tailwind is that you don’t necessarily have control over granular details of how your pages get rendered without getting really deep into the markdown renderer, or writing your posts in html. It ends up looking a bit ugly, and is against the tailwind best practices, but it seems like the best way for a site like this.
@tailwind base;
@tailwind components;
@tailwind utilities;
@import "./highlight.css";
.social {
@apply font-bold;
@apply flex flex-row;
@apply gap-4;
@apply justify-center;
@apply py-8;
}
#posts ul ul {
@apply backdrop-blur-sm;
@apply flex flex-col sm:grid grid-flow-row-dense;
@apply gap-4;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
@apply p-4;
}
grid #
I’ve struggled to use grid on my projects, and I’ve tried a few different times with no real success or adoption, but started using it on my resume, to have a main middle column, with two outer full bleed columns where I can make some elements full bleed to the edge. tailwind made this easy, once done, I had an admonition that was beautiful full bleed with a touch of color.