Cannot get values from an object in my search form

kolaloka
Member | 69
+
0
-

I have a search form within a search presenter:

<?php

protected function createComponentAdvancedSearchForm() {
		$form = new Form;
		$form->addText('firstname', 'Křestní jméno:');
		$form->addText('surname', 'Příjmení:');
        $form->addSubmit('send', 'Hledat');
		$form->onSuccess[] = [$this, 'renderAdvanced'];
		return $form;
	}

public function renderAdvanced($form,$values) {
		$this->template->loginstatus = $this->logInCheck();
		//print_r($values);
		$firstname = $values->firstname;
		$this->template->klient = $this->database->table('nekrolog')
			->where('firstname =?', $firstname)
	}
?>

Now, Tracy stops it and tells me that I am trying to: “get property of non-object”

but print_r($values) tells me:

<?php
Nette\Utils\ArrayHash Object ( [firstname] => Dominik [surname] => Winkler)
?>

So where have I made a mistake?

David Matějka
Moderator | 6445
+
0
-

On which line do you get that error?

kolaloka
Member | 69
+
0
-

90: $firstname = $values->firstname;

jiri.pudil
Nette Blogger | 1028
+
+1
-

The render* prefix is reserved for presenter's lifecycle methods and is called every time the respective page is rendered. It looks for the arguments in the request, and since there is no form nor values, they are null. The form's success handler should be a separate function or method.

kolaloka
Member | 69
+
+1
-

Ok, Jiri,
I am a simple person, so I need simple explanations, therefore, do I understand correctly that:

  1. I have to make a new method to push the values into variables
  2. and then I can use the variables within a render.

Yes?

jiri.pudil
Nette Blogger | 1028
+
+1
-

Exactly :) if you take a look at the presenter lifecycle, consider form's submission handler to be a signal handle*, in the interaction stage (because that's what it is, internally).

kolaloka
Member | 69
+
0
-

OK, I got part of it solved:

<?php
public function advancedSearchFormSucceeded($form,$values) {
		$firstname=$values->firstname;
		$surname=$values->surname;
		$this->template->klient = $this->database->table('nekrolog')
			->where('firstname =?', $firstname)
        	->where('surname =?', $surname)
			->order('id DESC');
	return $this->template->klient;
}
?>

and I get the result on the same page, which is kind of fine, but, how could I send it to another page?
The code I tried:

<?php
.
.
$mystuff=$this->template->klient
$this->redirect('result',$mystuff);
}
public function renderResult($mystuff){
print_r(mystuff);
}
?>

does not hand over the variables in the $mystuff object at all. Any help?

Last edited by kolaloka (2017-09-11 15:35)

jiri.pudil
Nette Blogger | 1028
+
+1
-

Redirect sends the data over HTTP in the URL, so they have to be a) serializable, and b) as simple as possible. I usually implement search in a way that the success handler redirects, passing the form values along as parameters:

$form->onSuccess[] = function ($form, $values) {
	$this->redirect('result', ['firstname' => $values->firstname, 'surname' => $values->surname]);
};

And the target action works with those request parameters:

public function renderResult($firstname, $surname) {
	$this->template->klient = $this->database->table('nekrolog')
		->where('firstname =?', $firstname)
		->where('surname =?', $surname)
		->order('id DESC');
}

As an added benefit, the search query is part of the URL, which means that the user can easily copy it and share or save the search results page.

kolaloka
Member | 69
+
0
-

Well, that'S the way! Thanks a LOT!!!