Clear persistent parameter in form action

Notice: This thread is very old.
Dragonn
Member | 12
+
0
-

Hi there!

I am trying to get VisualPaginator work with my search form. I (searched forum and) added persistent param $query to presenter which is holding searched string across pages and VP works pretty well now. I use AJAX to switch pages and it's Okay too.

Now I want to make URLs more friendly and strip off $query param where it's not needed (= everywhere but paginator). It's a bit anoying to add “query=>NULL” into every link leading to same presenter. I didn't find any other solution :-/, but OK … it works.

Only problem is in search form's action. First search is ok, there were NULL value in persistent param, URL is OK:

/profile/search?do=searchProfileForm-submit

but when I submit search again I can see $query param is in URL and I don't know how to strip it out:

/profile/search?query=foo&do=searchProfileForm-submit

I have tried some ways like force form action:

<?php
    protected function createComponentSearchProfileForm(){
        $form = new Form();

        $form->setAction($this->link("this", array("query" => NULL)));
        \Nette\Diagnostics\Debugger::barDump($form->getAction());

        $form->addText("name", "Name or e-mail:");

        $form->addSubmit("search", "Hledej!");

        $form->onSuccess[] = $this->searchProfileFormSent;

        return $form;
    }

    public function searchProfileFormSent(Form $form){
        $val = $form->getValues();

        $this->query = $val->name;
    }
?>

but even if dumped value is OK “/profile/search”, after submitting search form there is still $query param in URL.

I tried to search source code with no success … I don't even know which method is rendering form :-(.

Please can you give me any clue?

Oli
Member | 1215
+
0
-

I would say, that the $form->setAction is unnecessary. I guess, You can set persistent param NULL like this:

/** @persistent */
public $query;

<?php
    protected function createComponentSearchProfileForm(){
        $form = new Form();

	// Now query is null
	$this->query = null;

        $form->addText("name", "Name or e-mail:");

        $form->addSubmit("search", "Hledej!");

        $form->onSuccess[] = $this->searchProfileFormSent;

        return $form;
    }

    public function searchProfileFormSent(Form $form){
        $val = $form->getValues();

        $this->query = $val->name;
    }
?>

You will have your persistent param null, until you will send form and $val->name in $this->query after form sending.

Im not sure, if you can invalidate this form component. I guess yes, because if you invalidate it, you will send it again and $this->query will be reset but im not sure.

Dragonn
Member | 12
+
0
-

Thanks for replay, but it didn't help.

I don't send form via AJAX, searching is post request and page changing is handled by JavaScript. I'm invalidating just data and paginator (in separated snippets due to different redraw style).

<?php
    public function renderSearch(){
        if(!is_null($this->query)){
            $pg = $this["paginator"]->getPaginator();
            $pg->setItemCount($this->profileModel->searchUser($this->query));

            $this->template->searchUsers = $this->profileModel->searchUser($this->query, $pg->getLength(), $pg->getOffset());

            if($this->isAjax()){
                $this->invalidateControl("searchUsers");
                $this->invalidateControl("searchPaginator");
            }
        }
    }
?>

When I set $this->query to NULL in form factory, it would be rewritten when I am handling POST. Also I need it while rendering due to correct paginator links.

Oli
Member | 1215
+
0
-

I implement searching like this:

//search is component
class Search extends UI\Control
{
	...

	public function createComponentSearchForm()
	{
		...
		$form->onSuccess[] = callback($this, 'searchFormSubmitted');
		return $form;
	}

	public function searchFormSubmitted(UI\Form $form)
	{
		$this->getPresenter()->redirect('Search:detail', $form->values->search);
	}
}

// Presenter for searching
private $slug;

public function __construct(\SearchModel $searchM) {
	$this->searchModel = $searchM;
}

public function renderDetail($slug = null)
{
	$this->template->searchResults = $this->searchModel->doSearch($slug);
}

So i guess, it can work like this:

public function createComponentSearchPaginator()
{
	...
	return $paginator;
}

public function renderDetail($slug = null)
{
	if ($slug != null)
	{
		$pg = $this["paginator"]->getPaginator();
		$pg->setItemCount($this->profileModel->searchUser($slug));
		$this->template->searchUsers = $this->profileModel->searchUser($slug, $pg->getLength(), $pg->getOffset());

		if($this->isAjax()){
			$this->invalidateControl("searchUsers");
		}
	}
}

in template, you can have just something like this:

{snippet searchUsers}
{foreach $searchUsers as $searchUser}
	<a n:href="SomePresenter:detail $searchUser->id">{$searchUser->name}</a>
{/foreach}
{control searchPaginator}
{/snippet}

I hope, it can help you.

Dragonn
Member | 12
+
0
-

Great idea. Thanks!

I just added redirect at the end of form handling method:

<?php
    public function searchProfileFormSent(Form $form){
        $val = $form->getValues();

        $this->query = $val->name;

        $this->redirect("this");
    }
?>

Thank you very much Oli :-)