Multiple PHP Function handlers in HTML Form?

- 1 answer

Ad

I'm using OctoberCMS based on Laravel and Twig.

I'm trying to call 2 different functions form 2 php files using 1 form and 2 submit buttons.

form

I connect components I made, Edit.php and Delete.php, to a page.

Instead of directing the Form action to /Edit.php, I direct it to the current url and use a handler to call the php function onEdit() in Edit.php, using the Edit submit button.

In the same form, how can I call onDelete() in Delete.php using the Delete submit button?

It only selects 1 handler and calls its function.

I cannot merge the two functions into 1 php file.

https://jsfiddle.net/t3t5e2Ln/

Form

<!-- Edit or Delete -->
<form method="POST" action="{{ url_current() }}" enctype="multipart/form-data">

    <!-- Edit Handler -->
    <input type="hidden" name="_handler" value="onEdit" />

    <!-- Delete Handler -->
    <input type="hidden" name="_handler2" value="onDelete" /> 

    <!-- Title -->
    <input type="text" name="title" maxlength="255" />

    <!-- Edit Submit -->
    <input type="submit" name="edit" value="Edit" />

    <!-- Delete Submit -->
    <input type="submit" name="delete" value="Delete" />

</form>

Edit.php

public function onEdit() {
    //edit
}

Delete.php

public function onDelete() {
    //delete
}
Ad

Answer

Ad

Both previous answers are incorrect. See http://octobercms.com/docs/cms/components and http://octobercms.com/docs/plugin/components for more information on developing custom components for October.

First off, I would put both handlers within the same component (RecordData.php as an example of a name). Secondly, you should be taking advantage of October's excellent AJAX framework: http://octobercms.com/docs/ajax/introduction.

Here's an example of what your RecordData.php component class could look like:

<?php namespace MyVendor\MyPlugin\Components;

use Auth;
use Flash;
use Cms\Classes\ComponentBase;

use MyVendor\MyPlugin\Models\MyRecord as MyRecordModel;

class RecordData extends ComponentBase
{    
    /**
     * Provide information about the component
     */
    public function componentDetails()
    {
        return [
            'name'        => 'RecordData Component',
            'description' => 'Used for editing and deleting custom record data'
        ];
    }

    /**
     * Register any component properties
     * http://octobercms.com/docs/plugin/components#component-properties
     */
    public function defineProperties()
    {
        // return [];
    }

    /**
     * Get the record that will be edited, factoring in the user's access to the specified record
     *
     * @return MyRecordModel
     */
    public function getRecord()
    {    
        $user = Auth::getUser();

        if ($user) {
            return MyRecordModel::findOrFail(post('recordId'));
        } else {
            throw new \Exception("You do not have access to do that.");
        }
    }

    /**
     * AJAX Handler for editing data
     */
    public function onEdit()
    {
        // Get the record
        $record = $this->getRecord();

        // Modify the record
        $record->title = post('title');

        // Save the modifications to the record
        $record->save();

        // Notify the user that the record has been edited
        Flash::success("Record successfully edited");
    }

    /**
     * AJAX Handler for deleting data
     */
    public function onDelete()
    {
        // Get the record
        $record = $this->getRecord();

        // Delete the record
        $record->delete();

        // Notify the user that the record has been deleted
        Flash::success("Record deleted");
    }
}

And then your default.htm partial to render that component would look like this:

{{ form_open() }}

    {# Hidden form field containing the record id. Passing the record id through the URL or other means is possible as well #}
    <input type="hidden" name="recordId" value="{{ __SELF__.recordId }}">

    {# Title #}
    <input type="text" name="title" maxlength="255" />

    {# Edit Button #}
    <button type="button" data-request="{{ __SELF__ }}::onEdit">Save changes</button>

    {# Delete Button #}
    <button type="button" data-request="{{ __SELF__ }}::onDelete">Delete record</button>

{{ form_close() }}

Let me walk you through the Twig markup that is pasted above:

{{ form_open() }} and {{ form_close() }} are Twig helper functions registered by October to simplify the act of creating form elements because they will automatically make sure that the correct markup is generated and it includes the csrf token hidden field if you choose to enable that on your site.

{# #} represent a comment block in Twig, I usually prefer to use them instead of <!-- --> because that way the comment will only be visible to people viewing the actual source code of the Twig file, not all your website's users.

data-request utilizes the attributes API of the October AJAX framework to indicate to the AJAX framework what method on the server will be responsible for handling requests triggered by the element that the data-request attribute is included on.

{{ __SELF__ }} refers to the current component, it will essentially drop in the value of that component's alias. Basically, all you need to know is that using it will enable to you put more than one component on the page at a time in the future. ::onDelete and ::onEdit after the {{ __SELF__ }} is what tells the server what method you want to run on the component specified by {{ __SELF__ }} to handle that AJAX request.

Ad
source: stackoverflow.com
Ad