10

My form:

<form id="main-contact-form" name="contact-form" ata-request="onSend" data-request-success="alert('Message Sent')">

I cant seem to get a form to post; where do I place this file? Which file do I edit to make it send the form data fields to my email? I have already setup the backend mail settings:

function onSend()
{
    // Collect input
    $name = post('name');
    $email = post('email');
    $message = post('message');


    // Submit form
    $to = System\Models\MailSettings::get('sender_email');
    $params = compact('name','email');
    Mail::sendTo($to, 'temp.website::mail.newrequest', $params);
    return true;
}
dǝɥɔS ʇoıןןƎ
  • 1,674
  • 5
  • 19
  • 42
T2T
  • 115
  • 1
  • 1
  • 6

3 Answers3

9

Please refer to the documentation: Plugin Components.

You can create a component (SomeForm.php)

<?php namespace My\Plugin\Components;

use Cms\Classes\ComponentBase;

class SomeForm extends ComponentBase
{
    public function componentDetails()
    {
        return [
            'name'        => 'Form',
            'description' => 'Some form'
        ];
    }

    public function onSend()
    {
        // Collect input
        $name = post('name');
        $email = post('email');
        $message = post('message');

        // Submit form
        $to = System\Models\MailSettings::get('sender_email');
        $params = compact('name','email');
        Mail::sendTo($to, 'temp.website::mail.newrequest', $params);
        return true;
    }
}

And then create a view for it (e.g. default.htm)

<form id="main-contact-form" name="contact-form" data-request="{{ __SELF__ }}::onSend" data-request-success="alert('Message Sent')">
    ...
</form>

Usage in pages/layouts:

[someForm]
==
{% component "someForm" %}
  • I don't think it's a good idea to make a plugin just to send a form. This is a far trivial task so you can use the October backend CMS section to add the code.. – Saifur Rahman Mohsin Apr 02 '15 at 20:21
4

You goto the CMS section in your backend and paste that into the Code section of the default.htm layout. I already answered this question in the OctoberCMS.com forum. You can read about it here. Make sure that whatever form you use this on has a data-request="onSend" else it will not work. This is how it would ultimately look like...

enter image description here

Saifur Rahman Mohsin
  • 929
  • 1
  • 11
  • 37
  • I receive this error when sending a test message through mail templates and an ajax error on the actual form. An exception has been thrown during the rendering of a template ("Object of class Illuminate\Mail\Message could not be converted to string") in "

    Name: {{name}}

    Subject: {{subject}}

    Message: {{message}}

    " at line 1.
    – T2T Apr 08 '15 at 11:00
  • Ah this error means that the message variable doesn't not hold a string. Your mail template expects all the twig tags to be strings. Make sure a string is being passed, not an array or some other kind of object – Saifur Rahman Mohsin Apr 09 '15 at 12:31
  • is it possible to create a contact form for octaskin theme without making a plugin component and if so how would you approach this? – Artful_dodger May 21 '17 at 21:45
  • That’s exactly what I’ve done here. In the markup section put the form that you need. Instead of the action=“” use OctoberCMS’ data-handler=“onSend” and then go to the code section and implement the code as shown in my answer. – Saifur Rahman Mohsin May 26 '17 at 10:05
  • And what about `recpatcha` validation? With `data-request="{{ __SELF__ }}::onFormSubmit"`it works, but with `data-request="onSend"` it doesn't... – Kuzma Jan 08 '21 at 19:50
  • You can write the recaptcha validation too inside this same onSend handler. After all recaptcha is yet another POST field and you need to validate it server side before validation of other fields. As for the whole `{{ __SELF__ }}` thing. I think you maybe using the handler inside a component? The example I gave was for regular OctoberCMS pages. – Saifur Rahman Mohsin Jan 11 '21 at 11:38
2

You can add the Form's HTML either in your component partials directory, Theme's partial directory or just add it directly to any page / layout. It does not really matter.

Read more about including Partials

{% partial "contact-form.htm" %} 

Or

{% partial __SELF__ ~ "::contact-form.htm" %} // reference to component's partial

October's AJAX framework requires the use of the JavaScript API or data attributes. It is fine how you are doing it in the example but forgot to add the Component's Name before the onSend Handler

data-request="SendEmails::onSend" 

Where SendEmails = Component Name or Alias given in the page, if the form is in the component's partial just use {{ __SELF__ }}::onSend

or with the JavaScript API, just do :

$.request('onSend', {
    data:{email:email, message:message, name:name},
    success: function (data) {
      //
     },
    error:function(e){
      //
    }
 });

then in the component handling the request create a function onSend:

<?php namespace AuthorName\PluginName\Components;


use Cms\Classes\ComponentBase;
use Mail;
use Url;
use Input;
use Request;
use Response;
use ApplicationException;
use Validator;
use ValidationException;

class SendEmails extends ComponentBase
{

   public function onSend()
    {
        if (Request::ajax()) {

            try {

                $data = post();

                // Quick Validation rules for E-mail, Name & Message
                if (!array_key_exists('email', $data)) {
                    $data['email'] = post('email');
                }
                if (!array_key_exists('norad', $data)) {
                    $data['message'] = post('message');
                }
                if (!array_key_exists('name', $data)) {
                    $data['name'] = post('name');
                }    

                $rules = [
                    'email' => 'required|email|between:6,255',
                    'name' => 'required|between:4,255'
                    //..
                ];

                $validation = Validator::make($data, $rules);
                if ($validation->fails()) {
                    throw new ValidationException($validation);
                }

                // Check if E-mail Template Exists @ "author.plugin::mail.templatename"

                if (View::exists("author.plugin::mail.templatename")) {

                    Mail::send("author.plugin::mail.templatename", $data, function ($message)  {
                        $message->from('noreply@yourdomain.com', 'Site Name');
                        $message->to($data['email'], $data['name']);
                        $message->subject('Subject here..');

                    });

                    // Handle Erros
                    if (count(Mail::failures()) > 0) {
                        echo "Failed to send Mail "; // Handle Failure
                    } else {
                        // Mail sent
                        echo "Mail Sent!"; // Handle Success
                    }

                }

            } catch (Exception $ex) {

                throw $ex;
            }
        }
    }

}
Raja Khoury
  • 3,015
  • 1
  • 20
  • 19