Struggling with AJAX request for a form

I am reopening a discussion from: https://forum.getkirby.com/t/contact-form-controller-with-i18n-template/

I can’t get my head around calling an AJAX-request to prevent page refresh in a form.
I have read through the forum and here and there are examples given but none fits my situation I think.

I started of without AJAX like this:

  1. I have a snippet which contains a contact form. This snippet I use on various pages of a multilingual website.
  2. Because I use this snippet on various pages, I use the site.php controller for handling the submit-data

This worked so far and now I wanted to implement an ajax-request to stop the page refresh.

The new snippet contains a script at the end like the following but I don’t know what url I have to pass.

Do I have to pass site.php? But how? Do I need routes?
Or can I use an individual controller for my snippet? But how would I call it?

My rough Snippet

<form method="post">
<!-- -->
</form>
<script>
        let contactForm = document.querySelector('form');

        const handleForm = async (e) => {
            var formData = {
                name: $("#name").val(),
                email: $("#email").val(),
                text: $("#text").val(),
            };
            e.preventDefault();
            $.ajax({
                    type: "POST",
                    url: ???,
                    data: formData,
                    dataType: "json",
                    encode: true,
                })
                .done(function(data) {
 
// ... //

                    )
                .fail(function(data) {

// ... //
                });
        }
        contactForm.addEventListener('submit', handleForm);
        </script>

My site.php Controller:

<?php
// Controller for mail form
return function($kirby, $pages, $page) {

    $alert = null;

    if($kirby->request()->is('POST') && get('submit')) {

// ... //

    }

    return [
        'alert'   => $alert,
        'data'    => $data ?? false,
        'success' => $success ?? false
    ];
};

Thank you for all the help.

Ok. I am on my way however I still have problems.
if($kirby->request()->is(‘POST’)) is not true. Why is that?

Only if i wrap everything in return function($kirby, $pages, $page) { }. But this gives me new errors.

My script in my template


<form>
<!-- -->
</form>

<script>
        let contactForm = document.querySelector('form');

        const handleForm = async (e) => {
            e.preventDefault();
            var formData = {
                website: $("#website").val(),
                name: $("#name").val(),
                email: $("#email").val(),
                text: $("#text").val(),
            };

            $.ajax({
                type: "POST",
                url: "sendmymail",
                data: formData,
                dataType: 'json',


            }).done(function(response) {
                if (response.success) {
                    console.log(response.success);
                    
                } else if (response.alert) {
                    console.log(response.alert);
                }

            }).fail(function(xhr, textStatus, error) {
                
                console.error(error);
            });
        }
        contactForm.addEventListener('submit', handleForm);
        </script>

My template for the ajax-call - templates/sendmymail.php

<?php

    $alert = null;

    if($kirby->request()->is('POST')) {

// form logic //

      $success = 'The message has been sent.';
        
    }

echo json_encode([
    'alert'   => $alert,
    'data'    => $data ?? false,
    'success' => $success ?? false
]);

Putting dump($_POST); at the beginning of my template sendmymail.php results in nothing

I am really lost…

Are you using jQuery? Your code looks like a somewhat weird mix of vanilla JS and jQuery code…

Actually I don’t exactly know. I have read so many posts here in the forum from 2015 till now and might have messed up some stuff.

To short it down. I just want to find an ajax solution to my form because of the page refresh issue. And as I use this as a snippet on various templates, I couldn’t go for the standard template/controller structure.

During my experiments I managed to get something to work with a route in the config.php but I didn’t want to put all the data logic in the config.php as it overloads the place in my opinion.

Thank you for any help.

I use a self-programmed captcha, the value of which would be renewed after every reload, which is not desirable. Google for “Quform - Responsive Ajax Contact Form”. I use it successfully in all my projects. However, it is a very extensive tool that requires training time and PHP knowledge.
I’m also looking for a more compact tool, but couldn’t find anything convincing.

Thank you for mentioning this but I expect that the right hint will help me to solve it without learning a newtool. As @texnixe already mentioned, I think I have just confused some logic here.

Stick with vanilla JS and use the Fetch API for your Ajax request (and remove all this other $-jquery stuff). If you don’t have the jQuery library loaded (and imo you shouldn’t), then jQuery code will not work.

This recipe has an example fetch request: Load more with Ajax | Kirby CMS. Totally different example, though with only a GET request, so you need to modify this to post the data instead.