We are moving our forum in GitHub Discussions. For questions about Phalcon v3/v4 you can visit here and for Phalcon v5 here.

Solved thread

This post is marked as solved. If you think the information contained on this thread must be part of the official documentation, please contribute submitting a pull request to its repository.

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.8k

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.8k
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. :)