TaurusHORN
TaurusHORN

Reputation: 66

What is VOLT macro for rendering a <form> tag?

In Phalcon one can create a custom form extending Phalcon\Form\Form. This class has method called setAction, but I cannot find any info on how to automatically render a <form> tag with action that I specified.

My form is called RegisterForm, and I am passing it to VOLT view like this:

$this->view->registerForm = new RegisterForm(new UserModel()); 

In my VOLT template I can use the registerForm.render('username') macro to automatically render input field registered in my form.

Is there any macro that will create the following?

<form action="/register" method="post">

assuming that I've used:

$this->setAction($this->url->get('index/register')); 

in the form definition.

Upvotes: 1

Views: 1452

Answers (2)

TaurusHORN
TaurusHORN

Reputation: 66

After another day of research, and chatting at Phalcon's Slack channel, I've came to realization that, there is no built-in way of doing what I intended.

Simplest solution is to create a BaseForm class that extends Phalcon\Forms\Form. Here is an example:

<?php

namespace MyNamespace\Common\Form;

use Phalcon\Forms\Form;

class BaseForm extends Form {
    /**
     * Creates <form> tag in VOLT view.
     */
    public function startForm($method = 'post') {
        return '<form action="'.$this->getAction().'" method="'.$method.'">';
    }

    /**
     * Creates </form> tag in VOLT view.
     */
    public function endForm() {
        return '</form>';
    }

    /**
     * Pushes all errors to flash container.
     */
    public function error($name) {
        if($this->hasMessagesFor($name)) {
            foreach($this->getMessagesFor($name) as $message) {
                $this->flash->error($message);
            }

            return true;
        }

        return false;
    }
}

With this, after extending a custom form definition, I'm able to use:

# IndexController.php
public function index() {
    $this->view->registerForm = new RegisterForm();
}

# index.volt
{{ registerForm.startForm() }}
{{ registerForm.endForm() }}
{{ registerForm.error('username') }}

Upvotes: 2

Nikolay Mihaylov
Nikolay Mihaylov

Reputation: 3884

Here is how to render a form in Volt:

{{ form('products/save', 'method': 'post') }}

    <label for="name">Name</label>
    {{ text_field("name", "size": 32) }}

    <label for="type">Type</label>
    {{ select("type", productTypes, 'using': ['id', 'name']) }}

    {{ submit_button('Send') }}

{{ end_form() }}

More info in the Docs.

You can also check Phalcon's project Vokuro for more examples.

Update: Lukasz asked for a solution to render form tag from custom form element with it's properties. Phlacon Form Decorators is the closest solution to the problem I can find.

Upvotes: 0

Related Questions