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

How to (re)display filtered Form-Values

Hi

i'm new to Phalcon and i realy do love the speed an simplicity. Unfortunately, it's very hard ( for an 'old' ZF-Dev ) to find out how the simpliest Tasks should be realized with Phalcon. Many solutions i try (not only this particular problem) don't work as expected/usual. In most cases "my way" is not working with Phalcon and i can't find informations on how it should be done with Phalcon :( ...

The (current) Problem:

I want to display a form, prefill it from DB/Model, submit it, filter and validate it, save it an display the saved data or display the error messages and submitted data again in the form.

In my opion an every-day-task for everyone of us. ... but i just don't get it fully to work with Phalcon.

Usualy i do something like this (bit simplified):

// Controller
public function editAction()
{
    $object = Model::fecthByPk($this->getParam('id'));

    $form = new Form(['defaults'=>$object]); // Form defines filtering and validation

    if ($this->isPost() && $form->isValid($this->getParams())) {
        $object->fromArray($form->getValues());
        $object->save();
    }
    $this->view->assign(array(
        'form' => $frm,
        'object' => $object,
    ));
}
// View
<form ...>
    <? if ($form->hasError()): ?>
        <div class="error">There was an error</div>
    <? endif ?>
    <div class="<?=$form->field->hasError() ? 'error' : ''?>">
    <?= $form->field->render() ?>
    </div>
    ...
</form>

After dozens of pitfalls with forms, form-elements, form-errors, form-validation vs. model-valitation and so on it's nearly working, except the display of the form after submisson.

The form always displays the submitted data, but i want it to display the sanitized and stored values.

Example:

    • field with "trim"-Filter:
    • submited value: " test "
    • stored value: "test" (as wanted/expected)
    • re(displayed) Value in the Form: " test " (why?)

(sry, markdown-list not working !?)

I tried to clear the form and (re)set the entity after validating saving, with no effect. :/

So, what's wrong, how can i solve it and what am i missing?

my current action


public function editAction($id=null)
{
    $success = null;

    $project = Projects::findFirst("id = {$id}");

    $this->_getProjectForm()->setEntity($project);

    if ($this->request->isPost()) {
        $this->_getProjectForm()->bind($this->request->getPost(), $project);
        $success = $this->_getProjectForm()->isValid() && $project->save();
    }

    $this->view->setVars(array(
        'project' => $project,
        'form'    => $this->_getProjectForm(),
        'success' => $success,
    ));
}

thanks in advace for your help (... to find my way through Phalcon)

(P.S.: I'm Missing a "Forms"-Category. )



3.5k
Accepted
answer

... found a/the(?) solution in vokuro

\Phalcon\Tag::resetInput();
if ($this->request->isPost()) {
    $this->_getProjectForm()->bind($this->request->getPost(), $project);
    if ($this->_getProjectForm()->isValid() && $project->save()) {
        // reset Tag
        \Phalcon\Tag::resetInput();
    }
}

Could somebody please explain the sense/background of globaly setting Tag-Values to me?

\Phalcon\Tag::setDefaults();

What if i have multiple forms on one page with samen field-names?



7.9k
edited Mar '15

my approach on edit actions,
might be usefull for you
major difference (in case of a successful update) from your approach is this line :

return $this->response->redirect('banks/index/'.$id);
public function editAction($id = 0)
    {
        $id = $this->filter->sanitize($id, 'int');
        $bankToEdit = Banks::findFirstById($id);
        $form = new BankForm($bankToEdit); // bind the form and the model
        if ($this->request->isPost() == TRUE)
        {
            $form->bind($_POST, $bankToEdit); //bind post and model to the form
            if ($form->isValid($this->request->getPost()) == false)
            {
                foreach ($form->getMessages() as $message){$this->flashSession->error($message);}
            }
            else
            {
                $success = $bankToEdit->update();
                if($success == TRUE)
                {
                    $this->flashSession->success($bankToEdit->name.' '.$this->translation->_('_update_success'));
                    return $this->response->redirect('banks/index/'.$id);
                }
                else
                {
                    $this->flashSession->warning($this->translation->_('_bank_update_failure'));
                    foreach ($bankToEdit->getMessages() as $message){$this->flashSession->error($message);}
                }
            }
        }
        $this->view->form = $form;
        $this->view->title = $bankToEdit->bankName;
        $this->view->subtitle = $this->translation->_('_edit');
    }


3.5k

Thanks for the reply!

I'm aware of this solution, and i know that this works. But i realy don't want this overhead. A completely new PageRequest (http-traffic, bootstraping, routing, data-retrieval, form-creation, rendering, ...) doesn't make any sense for only updating the inputs with values i already have. It's like "crack a nut with a sledgehammer".



7.9k

i understand your statement
i use ajax whenever i want to avoid extra traffic and overhead

i know that i still do not provide a solution to your original request
just for the sake of the conversation :D