We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

Form->setAction()

Hi,

it is just a small question, but I want to put code together where it belongs to. Phalcon is very good in that, but I'm wondering about a thing with forms:

I define a form as a class, use it in the needed controller. Everything is fine (binding etc.), but for what function has the method $form->setAction('controller1/action2'), if in the view I have to put it again manually?!

Why is it not rendered, when I use: <?php echo $this->tag->form(array('id' => 'form_newtype', 'role'=>'form')); ?>

Seems to me some kind of useless ... :/



98.9k

This code:

<?php echo $this->tag->form(array('id' => 'form_newtype', 'role'=>'form')); ?>

Does not render a form, it produces an HTML tag for a form <form>, if you want to render a form you have to call render on the form's instance:

Create the form: https://github.com/phalcon/vokuro/blob/master/app/controllers/ProfilesController.php#L31 Render it: https://github.com/phalcon/vokuro/blob/master/app/views/profiles/index.volt#L7

edited Jul '14

Sorry I was not precise enough.

My question is: What is the method setAction() good for, if it is not used when the form is rendered?

I expected that when I call in my controller (see below): $form->setAction('controller1/action1'); that phalcon renders the form in the view with that action.

In my controller I do this:

$form = new SettingsTypeForm();
if ($this->request->isPost()) {
    $form->initialize($this->request->getPost());
}
$this->view->form = $form;

I build my forms in extra classes, e.g. SettingsTypeForm.php - FormBase extends Phalcon's Form-Class.

<?php

namespace SlipBOX\Forms;

use Phalcon\Forms\Form,
    Phalcon\Forms\Element\Text,
    Phalcon\Validation\Validator\PresenceOf;

use SlipBOX\Forms\FormBase;

class SettingsTypeForm extends FormBase
{
    public function initialize ($type = null, $options = null)
    {
        $this->add($this->_elementTitle());
        $this->add($this->_elementFields());

        parent::initialize($type, $options);
    }

    private function _elementTitle ()
    {
        $text = new Text('title', array(
            'id' => 'title',
            'required' => 'required',
            'class' => 'form-control',
            'placeholder' => 'PLACEHOLDER_ENTITIESTYPES_TITLE'
        ));
        $text->setLabel("LABEL_ENTITIESTYPES_TITLE");
        $text->addValidators(array(
            new PresenceOf(array(
                'message' => $this->_getTranslation('errors')->_('VALIDATION_FIELD_PRESENCEOF', array('field'=>'title'))
            ))
        ));
        return $text;
    }

    private function _elementFields ()
    {
        $element = new Text('fields', array(
            'id' => 'fields',
            'required' => 'required',
            'class' => 'form-control',
            'placeholder' => 'PLACEHOLDER_ENTITIESTYPES_FIELDS'
        ));
        $element->setLabel("LABEL_ENTITIESTYPES_FIELDS");
        return $element;
    }

}


98.9k
Accepted
answer

As I mentioned before, this is not the proper way of rendering a form because it has nothing to do with form instances, this code only produce the necessary code to show a HTML form up:

<?php echo $this->tag->form(array('id' => 'form_newtype', 'role'=>'form')); ?>

You have to pass the form instance to the view as you're already doing:

$form = new SettingsTypeForm();
$this->view->form = $form;

And render the form in the view:

<?php echo $form->render(); ?>

As the code above is not quite flexible, you may want to consider render every form's element in the HTML layout this way:

<form method="post" action="{{ form.getAction() }}">

    <div>

        <h2>Search profiles</h2>

        <div>
            <label for="id">Id</label>
            {{ form.render("id") }}
        </div>

        <div>
            <label for="name">Name</label>
            {{ form.render("name") }}
        </div>

        <div>
            {{ submit_button("Search") }}
        </div>

    </div>

</form>

Thanks alot. And sorry for the late reply. See it now. Maybe my head was too busy with the stuff behind to see it. :)