#Stop form submission from refreshing page

20 messages · Page 1 of 1 (latest)

waxen garnet
#

Hey guys I am not a web developer by any means (as you can tell), I am just an IT guy who got roped into remaking the company website. Its pretty simple just one page with some info and a contact form. Right now I have this code (well shortened, I just included one of the 9 fields

<div id="contactFormContainer">
        <form id="" class="grid-form" method="POST">
            <input class="half" name="contactFirstName" placeholder="First Name" />
            <button>Submit</button>
        </form>
</div>

And that calls this bit of javascript

if (Astro.request.method === "POST") {
  try {
    const data = await Astro.request.formData();
    const name = data.get("contactFirstName");
    console.log(name)
  } catch (error) {
    if (error instanceof Error) {
      console.error(error.message);
    }
  }
}

Whenever you hit submit on the actual web page it just refreshes, and doesn't actually print anything to the console (well maybe it is, since it clears the console on refresh anyways)

I did try reading the documentation and I found (a couple of)[https://github.com/withastro/astro/issues/9488] (questions)[https://stackoverflow.com/questions/19454310/stop-form-refreshing-page-on-submit] online but I couldn't get any of them to work :(

Any ideas? Again, I'm not a web developer so sorry if this is a really dumb question.

Docs

Learn how to build HTML forms and handle submissions in your frontmatter.

twin gyro
#

Hey there.
Yes, the unfortunate default legacy behaviour of a form submission is to refresh the web page.
You can prevent this behaviour by calling the preventDefault method on the form submission event.

You'll need in your code:

const form = document.getElementById(yourFormId);

form.addEventListener("submit", (e) => e.preventDefault()```
waxen garnet
twin gyro
#

Yes, a <script> tag needs to be found anywhere below your form, inside the html <body>.

Maybe the preventDefault disables the entire submission of the form, but I don't usually use the method="POST" approach.

Inside the submit function, you can actually access the form itself or the values of your input fields if you have references to them.

#

Something like that:

const form = document.getElementById("yourFormId");

form.addEventListener("submit", (e) => {
  e.preventDefault(); // Prevent the form from submitting normally

  // Access the input field by its id
  const contactFirstName = form.elements["contactFirstName"].value;

  // Do something with the value
  console.log("Contact First Name:", contactFirstName);
});```
waxen garnet
twin gyro
#

Yeah, it's fine to put it in your component.

#

I've found the example you were probably following:
https://docs.astro.build/en/recipes/build-forms/

This is a viable option only if you plan on running an Astro server, and not have plain static pages as your final build.
If that's what you're looking for, make sure your astro.config file does have output: 'server'.

Also, the console.log mentioned in the example will not appear in the browser, but on the server. So check your terminal rather than the browser console.

Docs

Learn how to build HTML forms and handle submissions in your frontmatter.

waxen garnet
#

Yeah thats the guide I followed (and the one I linked in my original question) and I have it set to server. Here is my entire config so far

// @ts-check
// @ts-check
import { defineConfig } from 'astro/config';

// https://astro.build/config
export default defineConfig({
    output: 'server'
});
waxen garnet
# twin gyro Yeah, it's fine to put it in your component.

But maybe I'm not understanding what you mean cause I tried this first and it just doesn't do anything. Here is basically my structure

---
import CONTACT_FORM from './contact_form.astro';
export const prerender = false;

if (Astro.request.method === "POST") {
    try {
        const data = await Astro.request.formData();
        const name = data.get("contactFirstName");
        console.log(name)
    } catch (error) {
        if (error instanceof Error) {
            console.error(error.message);
        }
    }
}
---
<style>
</style>

<div id="contactFormContainer">
  [my form here]
</div>
<script>
  [that bit of code you gave me]
</script>
twin gyro
#

Ah yes, I see! I'm not super familiar with that form handling approach, sorry.

With that approach, it's actually expected that the page will refresh. But it will as a POST request, containing the form values in its body. That's why you see a condition in the component's frontmatter (header), it's checking if you're submitting a form on this path.

#

So you can remove the snippet I gave you, and make sure you check your terminal for the console logging after form submission

#

Eventually, you'll send this data to your data collection endpoint instead of just logging.

waxen garnet
#

Haha I am not familiar with web dev stuff at all, I am an IT guy who considers scripts and automated piplines "programming" which is why i got stuck with this.

But I don't think I actually want the form to POST though? That refreshes the hole page, I don't want that

#

And I did try just removing your snippet but it's still not doing anything? The page isn't refreshing, I'm not seeing anything in the console, nothing

#

And I tried moving all of my javascript into the script tag to see if maybe I could force it with an onclick event but that didn't work either

#

Okay I think I figured out what you meant by the javascript running on the server and how to actually utilize that, its pretty neat

twin gyro
twin gyro
#

Once you get the hang of it, I suggest you look into Astro server actions, they are really neat to send data to your backend:
https://docs.astro.build/en/guides/actions/

But that will add a layer of abstraction and some complexity that you don't want right now 😄

Docs

Learn how to create type-safe server functions you can call from anywhere.