Search Form's onSubmit not working

4 years ago

thomaspaulson
Member | 2
+
0
-

I have search form createComponentSearchForm in ParishPresenter,
And onsubmit event, form should process at ‘searchFormSubmitted’, but nothing happens.

<?php

namespace App\Presenters;

use Nette,
    Nette\Application\UI\Form;

class ParishPresenter extends Nette\Application\UI\Presenter
{

    /** @var Nette\Database\Context */
    private $database;

    public function __construct(Nette\Database\Context $database)
    {
        $this->database = $database;
        //$this->template->sidebarLayout = 'parish';
    }


    public function beforeRender(){
        //echo 'beforeRender()';
        $this->template->sidebarLayout = 'parish';
    }


    public function renderDefault()
    {
        $this->template->parishes = $this->database->table('Parish')
            ->order('Created DESC');
    }

    public function renderShow($parishId)
    {
        $this->template->parish = $this->database->table('Parish')->get($parishId);
    }


    public function actionEdit($parishId)
    {
        $parish = $this->database->table('Parish')->get($parishId);
        if (!$parish) {
            $this->error('Parish not found');
        }
        $this['postForm']->setDefaults($parish->toArray());
    }


    protected function createComponentPostForm()
    {
        $form = new Form();
        $form->addText('Title', 'Title:')
            ->setRequired();
        $form->addText('Location', 'Location:')
            ->setRequired();
        $form->addText('District', 'District:');
        $form->addText('Pincode', 'Pincode:');


        $form->addSubmit('send', 'Save');
        $form->onSuccess[] = array($this, 'postFormSucceeded');

        return $form;
    }

    public function postFormSucceeded($form, $values)
    {
        //print_r( $values); exit();
        $parishId = $this->getParameter('parishId');
        if ($parishId) {
            $parish = $this->database->table('Parish')->get($parishId);
            $parish->update($values);
            $this->flashMessage('Record updated', 'success');
        } else {
            $parish = $this->database->table('Parish')->insert($values);
            $this->flashMessage('Record created', 'success');
        }
        $this->redirect('show', $parish->ID);
    }


    protected function createComponentSearchForm()
    {
        $form = new Form();
        $form->addText('Title', 'Title:');
        $form->addText('Location', 'Location:');

        $form->setAction($this->link('search'));
        $form->setMethod('get');

        $form->addSubmit('search', 'Search');
        $form->onSubmit[] = array($this, 'searchFormSubmitted');
        // exit();
        return $form;
    }

    public function searchFormSubmitted($form, $values){
        print_r( $values); exit();
        $form->setDefaults($values);
    }
}

4 years ago

Caine
Member | 218
+
0
-

I think that the problem is with $form->setAction($this->link(‘search’)); do you have same component (searchForm) there? If not nothing can happen ofcurse..

PS: setDefaults should be called in createComponent methods, not in onSubmit events..

4 years ago

thomaspaulson
Member | 2
+
0
-

I want to show the search form on the side bar like http://ctrlv.in/641413, please check the url.
I new to nette framework, so i did not understand what you mean by component.

4 years ago

tomcat4x
Member | 22
+
0
-

One problem, that the function (handler) searchFormSubmitted($form, $values) will not been processed, is that you use

$form->setAction($this->link('search'));

So the hidden field with the do parameter in the html output page disappear.

Have a look at these post

https://forum.nette.org/…-singel-page

4 years ago

old.gandalf
Member | 17
+
0
-

Hello,

calling setDefaults() on a Form instance in a onSubmit callback is not a good practice. If your goal is to show the currently searched query filled in the form in the sidebar, I suggest either using persistent parameters or class properties (taking advantage of the presenter lifecycle, as seen here). If this is what you want to do, see following example:

<?php
//presenter

protected $searchTitle;
protected $searchLocation;

public function actionSearch($title = NULL, $location = NULL) { //the NULL defaults are there for the situation when the user has not yet searched anything
    $this->searchTitle = $title;
    $this->searchLocation = $location;
}

protected function createComponentSearchForm() {
    ...
    $form['title']->setValue($this->searchTitle);
    $form['location']->setValue($this->searchLocation);
    $form->onSuccess[] = $this->searchFormSuccess;
}

public function searchFormSuccess($form) {
    $this->redirect('Presenter:search', $form->values->title, $form->values->location);
}

?>

Like @tomcat4x said, the $form->setAction() will not cause the presenter pass the Form instance to the method, it will be NULL.

Also work with the database belongs to Model layer, not View (=Presenter) in the MVC architecture. That would mean following for you:

<?php
//file ParishService.php

class ParishService extends \Nette\Object {

    private $database;

    public function __construct(Nette\Database\Context $database) {
        $this->database = $database;
    }

    public function getParishById($parishId) {
        return $this->database->table('parish')->get($parishId);
    }
}

?>

Dependencies should be passed to Presenters using inject() since their constructs are called by the framework and should not be overriden. So in the presenter you can access ParishService like this:

<?php
public function injectSomePresenter(UserService $userService) { //the method has to start with 'inject', rest is up to you
    $this->userService = $userService;
}

...in render {
    $this->template->parish = $this->userService->getParishById($parishId);
}
?>

I hope this helps you.

Regards :)