OctoberCMS

Using backend forms in a frontend component


OctoberCMS is a nice CMS with which developers can build simple sites extremely fast. If you don’t know what it is, you are welcome to check it out by clicking here.

Even though I really enjoy using OctoberCMS, some tasks on it are just daunting. One of them is:

How do we use the same form (plus validation) in both backend and frontend?

In this short article I will try to explain a workaround for this problem.

If you are here just for the code— scroll to the bottom of the page for a link to the github repository.


I will assume that You already have build the backend form for Your application (controllers are in place, models are in place and migrations as well).

Lets dive right in by creating a brand new component.

<?php namespace Mja\Forms\Components;
use Cms\Classes\ComponentBase;
class EntryForm extends ComponentBase
{
public function componentDetails()
{
return [
‘name’ => ‘EntryForm Component’,
‘description’ => ‘Backend form used in the front-end’
];
}
  public function onRun()
{
// .. code goes here
}
}

Now that we have the basic code we will have to:

  1. load the backend form;
  2. serve it to the frontend;
  3. create a method that saves the data submitted.

Lets start off by loading the form (the controller). Once we have it loaded — create a new form with a brand new context — frontend.

public function onRun()
{
// Build a back-end form with the context of ‘frontend’
$formController = new \Mja\Forms\Controllers\Entries();
$formController->create(‘frontend’);
  // Append the formController to the page
$this->page[‘form’] = $formController;
}

Now that we have the system managing this form set up, we must visually display it. Edit your components/entryform/default.htm file.

<div class=”confirm-container bg-success hide”>
<p>Successfully created a new entry!</p>
</div>
<form role=”form”
data-request=”{{ __SELF__ }}::onSave”
data-request-success=”$el.hide();$(‘.confirm-container’).removeClass(‘hide’);”>
  {{ form.formRender()|raw }}
  <div class=”form-group”>
<button class=”btn btn-primary btn-block btn-lg” type=”submit” value=”register”>Create</button>
</div>
</form>

Once we try to submit this form we get an error. It’s because we have forgotten to create a onSave() method that actually handles the submitted data. Lets go on and create this new method in the EntryForm class.

public function onSave()
{
return [‘error’ => \Mja\Forms\Models\Entry::create(post(‘Entry’))];
}

If we tried submitting this form once more, it would still be throwing errors. What could be causing this? We forgot to set the required fields as “fillable”.

<?php namespace Mja\Forms\Models;
use Model;
/**
* Entry Model
*/
class Entry extends Model
{
public $table = 'mja_forms_entries';
protected $guarded = [‘*’];
protected $fillable = ['title', 'slogan', 'body'];
}

Great! Now we can test our code. It seems that everything is functioning properly now.

And that’s how to use a backend form right in the frontend of your application.

Bonus round: validation

Since this form will be accessible to your users, you may want to have some sort of validation for this form. With OctoberCMS this can be done extremely easily.

class Entry extends Model
{
use \October\Rain\Database\Traits\Validation;
  // .. previously used code ..
  public $rules = [
‘title’ => ‘required|min:3|max:255’,
‘slogan’ => ‘max:255’,
‘body’ => ‘required|min:5’,
];
}

For more information visit the OctoberCMS documentation.


Bonus round #2: styling backend forms

Edit: as of the newest OctoberCMS versions, the filename and path of time file below has been changed.

You may want to style your frontend forms just as they are styled in the backend. This can be accomplished by simply including the same backend CSS file in the frontend.

Edit your EntryForm component class.

public function onRun()
{
$this->addCss('/modules/backend/assets/css/controls.css', 'core');
}

The repository with a working example of this code can be found by clicking on this link.

Like what you read? Give Matiss Janis Aboltins a round of applause.

From a quick cheer to a standing ovation, clap to show how much you enjoyed this story.