Hi, so i’ve managed to get a nice little PHP form with recaptcha 3 working, as a snippet to be reuseable on various pages.
Now i would love to add an ajax call to prevent the page reloading.
I have a script which prepares the data, then the ajaxmail.php controller which sends the email.
I have tried to use a controller “ajaxform.php”. but kirby didn’t recognize it as such.
How do i call a controller from a snippet?
My question leads to this piece of text:
xhr.open('POST', 'ajaxform.php');
I could use a special file directly in the domain directory, which works, but i really wanna use the kirby->email function, cause that is what cms is for
In my js
<script>
function process() {
// (A) GET FORM DATA
var data = new FormData();
data.append('name', document.getElementById("name").value);
data.append('email', document.getElementById("email").value);
data.append('text', document.getElementById("text").value);
// (B) AJAX
var xhr = new XMLHttpRequest();
xhr.open("POST", "https://mydomain/ajaxform.php");
// What to do when server responds
xhr.onload = function(){
console.log(this.response);
console.log('yay');
};
// Defining event listener for readystatechange event
xhr.onreadystatechange = function() {
// Check if the request is compete and was successful
if(this.readyState === 4 && this.status === 200) {
// Inserting the response from server into an HTML element
document.getElementById("result").innerHTML = this.responseText;
}
};
//xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhr.send(data);
// (C) PREVENT HTML FORM SUBMIT
return false;
}
</script>
I have tried to link it directly to the site.php which does not seem to work.
My question leads to this piece of text:
Hi thanks, that is indeed my question.
My files are: snippets/ajaxform.php with this code (simple, test one)
<script>
function process() {
// (A) GET FORM DATA
var data = new FormData();
data.append('name', document.getElementById("name").value);
data.append('email', document.getElementById("email").value);
data.append('text', document.getElementById("text").value);
// (B) AJAX
var xhr = new XMLHttpRequest();
xhr.open("POST", "site/controllers/sliderpage.php", true);
// What to do when server responds
xhr.onload = function(){
console.log(this.response);
console.log('yay');
};
// Defining event listener for readystatechange event
xhr.onreadystatechange = function() {
// Check if the request is compete and was successful
if(this.readyState === 4 && this.status === 200) {
// Inserting the response from server into an HTML element
document.getElementById("result").innerHTML = this.responseText;
}
};
xhr.send(data);
// (C) PREVENT HTML FORM SUBMIT
return false;
}
</script>
<div>
<h2>Anfragen</h2>
<h6>Hier kannst du was schreiben</h2>
</div>
<div id="result"></div>
<form onsubmit="return process()">
Name: <input type="name" id="name" required><br>
Email: <input type="email" id="email" required autofocus/><br>
Message: <input type="text" id="text" required/><br>
<input type="submit" name="submit" value="Absenden" class="g-recaptcha"
data-sitekey="reCAPTCHA_xyz"
data-callback='onSubmit'
data-action='submit'>
</form>
then, i have the controller code in
/controllers/pagenamewhereused.php
<?php
if($_SERVER["REQUEST_METHOD"] == "POST") {
$name = htmlspecialchars(trim($_POST["name"]));
$email = htmlspecialchars(trim($_POST["email"]));
$text = htmlspecialchars(trim($_POST["text"]));
// Check if form fields values are empty
if(!empty($name)) {
echo "<p>Hi, <b>$name</b>. Dein Zeugs wurde versendet.<p>";
echo "<p>Deine Email: <b>$email</b></p>";
echo "<p>Dein Text: <b>$text</b></p>";
} else {
echo "<p>NIXE</p>";
}
} else {
echo "<p>Something went wrong. Häng di auf.</p>";
}
?>
This is working so long as i hard-link it to https://domain/sliderpage.php
Can u please help me how to link/route it correctly to the site/controllers/pagenamewhereused.php ?
This: xhr.open("POST", "site/controllers/sliderpage.php", true);
Hi, thanks for hanging in with me on saturday.
yeah, that is what i am thinking, just calling the url of the php script won’t work.
This is what i have tried:
xhr.open("POST", "https://mydomain.com/site/controllers/sliderpage.php", true); //or the https://.. long url
xhr.open("POST", "sliderpage.php", true); //when in controllers
where sliderpage.php is JUST the handler of the form.
I tried the same with
controllers/nameofsnippet.php
didn’t work either. I think i am missing something important in the kirby logic.
Sry i am still new
BUT - when i will put the php script directly to the main domain folder outside of kirby and call it with
then it is working fine, i just will have to set the smtp email sending by myself.
But it is not the kirby way and i would really like to use the kirby->email function.
how do i call an url of a controller from a snippet?
You know with ajax you have
1 - the snippet file with the form + the script which is sending the $data to
2 - a php controller, which is then sending the data back to page
I am failing in linking these 2 together in kirby logic
i am trying to be calling the controller ^^
My code works if the php file with the controller code is outside of kirby system (domain root).
My question is how to tell the JS to call the controller php file with the code INSIDE the kirby system.
I hope you understand what i mean?
You cannot directly call the controller as php file. You have to pass the url to the page, e.g. something lile http://example.com/contact. When this page is called, the controller is automatically executed.
Calling php file indeed only works with files outside the Kirby system.
As I said, the alternative is to put the logic into a route and then call the pattern of this route.
For example, if you use a route like this:
'routes' => [
[
'pattern' => 'formhandler',
'action' => function () {
// your formhandling logic
}
],
],
You would call the url https://yourdomain.com/formhandler in your script.
Our formhandling logic is rather long and i would prefer not to put the php code in the config file, what is the best way to do this? With a custom controller? But how can we load it? And how to do this for multi language routes?
@pixelijn. Thank you. Could you give an example how to access in the config route my function? (Im not working with a plugin) Example i have the logic of all the forms in controllers/forms.php, forms does not exists as a page. I want to use the logic from the forms.php.
If the function is in a controller, it cannot be accessed without including the controller. I’d suggest you move the function to a plugin, ideally together with the route, so everything form related is together in one place.