accessing $_POST in a presenter

jdan1131x
Member | 41
+
0
-

is it possible to access $_POST in a Presenter? I know how to pass args
to Render<View> using {link…} and LinkGenerator, but…
thanks for any help…
James

Marek Bartoš
Nette Blogger | 1165
+
+1
-

$this->getHttpRequest()->getPost();

jdan1131x
Member | 41
+
0
-

thanks!

i almost have it working with handle<Signal> but your method def looks great!

jdan1131x
Member | 41
+
0
-

i got past some issues, and tracy throws no errors. but the
return value from signal<Query> is not working right.

the situation is:
code: both in latte template:(abbreviated)

<input onkeyup=“mine(this.value)”>
<span id=“txtHint”></span>

and: javascript code in same latte template:
function mine(str) {
val = {link query! str}
document.getElementById(“txtHint”).textContent = val;
}

in the presenter code:
public function handleQuery(string $q="") { if ($this->isAjax() {} }

result on execution: (execution: typing any letter in the input field executes the mine method.

the return value is being assigned to ID “txtHint” above is:
“/MESSAGING-SYSTEM-SEND/?Q=STR&DO=QUERY”

so i think i am close…

i have tried in the presenter with no effect on the above:

$this->sendResponse(“test”);
$this->sendJson(‘id’ ⇒ ‘test’);

but the result is unchanged. I think i am close…

I've read through a lot of great docs on Nette for AJAX, HTTP stuff, but its
not helping me yet to get a simple simple signal working yet, since of course,
i am new on this …

my first objective is to get the word “test” into the ID “txtHint”
once i get this done, the rest will be cake :-)
James
ps. thanks very much for any assistance…

uestla
Backer | 796
+
0
-

Hello @jdan1131x !

It seems like you're not calling any request in your JS, just using the generated URL of the signal.

public function handleQuery(?string $str): void
{
	if (!$this->isAjax()) {
		$this->error('', 403);
	}

	$this->sendJson(['text' => $str]);
}
<script>
function mine(str) {
	$.getJSON({link query!}, { str: str }, function (payload) {
		$('#txtHint').text(payload.text);
	});
}
</script>
jdan1131x
Member | 41
+
0
-

Thanks so much! I'll try it out. looks very clean…
nice call, nice catch… Nette is amazing…will allow
real-time update of so many things…thanks again!
James

jdan1131x
Member | 41
+
0
-

i'm sorry i cant get this to work. the query works and responds
correctly when doing the code above, but when i try to
access $str in the handleQuery with live data from the form i am constantly getting undefined offset
errors or reports that null is being returned or received. tracy reports the var str is
getting filled properly before sending using the getJson call…

i just dont know what exactly the format handleQuery is getting into
the $str var. I have tried explode, list, $this->getHttpReques->getPost and many
combinations thereof. i dont know how to unwrap $str once handleQuery(?string $str) gets the signal…
do i need to unwrap the received optional like in Swift, somehow?

$this->sendJson([‘text’ ⇒ ‘test’]); ← this works perfectly as a hard coded return val
$this->sendJson([‘text’ ⇒ $str]); ← this fails because its a bad format but i dont know the format.

if i do the following in the handler as hardcoded…all works…

$myjson = 'text:string';
list($key,$val) = explode(":", $myjson);
$this->sendJson($key => $val);  // <- this works perfectly.

the root of all of this is in the jquery call
{ str: str } ← i understand this but what does handleQuery receive??? ‘t’:‘t’ OR ‘t:t’ OR ‘[{'t’:‘t’}]' OR ???
i looked it up but the docs are vague.

the objective is to get second str value from str:str but unfortunately i am an idiot on saturdays and
cant achieve this. many thanks if someone can put me out of my misery :-)
James

uestla
Backer | 796
+
0
-

Oh, I see – I used the same name for the signal parameter and for the variable in JS – now I see that you had originally named the signal argument $q.

In the JS call the {link query!} gets translated to URL, and the next token { str: str } is already a JS object that appends the key-val to the URL.

To use your original naming, you can update it like this:

<script>
function mine(str) {
	$.getJSON({link query!}, { q: str }, function (payload) { // the "q" gets appended to URL and can be used as $q variable as the signal argument
		$('#txtHint').text(payload.text);
	});
}
</script>

And the signal:

public function handleQuery(?string $q): void
{
	if (!$this->isAjax()) {
		$this->error('', 403);
	}

	$this->sendJson(['text' => $q]); // is accessed via payload.text in JS above
}

Since we're calling $.getJSON(), calling $this->getHttpRequest()->getPost() should return an empty array since it's not a POST request.

jdan1131x
Member | 41
+
0
-

This below now works perfectlly and i understand
the contents of $str. I think i can move on now…
please ignore my questions above.

public function handleQuery(?string $str): void {

			if (!$this->isAjax()) {
				$this->error('', 403);
			}


			//$str = $this->getHttpRequest()->getPost();

			if( is_string($str)) {

				$this->sendJson(['text' => $str]);

			}
}
uestla
Backer | 796
+
+1
-

It's logical, because you're not sending POST request, but GET request ($.getJSON).
That's why the POST data are empty.

The main idea is that the $str variable is of same name as the key in JS object you're passing in the $.getJSON call.
You don't need to serialize / unserialize any JSON – it's done by jQuery on the client side and by Nette on the server side.

Trivia:

<script>$.getJSON({link query!}, { myparameter: str });</script>
function handleQuery(?string $myparameter): void {}
jdan1131x
Member | 41
+
0
-

uestla wrote:

Oh, I see – I used the same name for the signal parameter and for the variable in JS – now I see that you had originally named the signal argument $q.

In the JS call the {link query!} gets translated to URL, and the next token { str: str } is already a JS object that appends the key-val to the URL.

To use your original naming, you can update it like this:

<script>
function mine(str) {
	$.getJSON({link query!}, { q: str }, function (payload) { // the "q" gets appended to URL and can be used as $q variable as the signal argument
		$('#txtHint').text(payload.text);
	});
}
</script>

And the signal:

public function handleQuery(?string $q): void
{
	if (!$this->isAjax()) {
		$this->error('', 403);
	}

	$this->sendJson(['text' => $q]); // is accessed via payload.text in JS above
}

Since we're calling $.getJSON(), calling $this->getHttpRequest()->getPost() should return an empty array since it's not a POST request.

I think I have it fixed. thanks so much for the effort!!
James

jdan1131x
Member | 41
+
0
-

thank god its done :-)
the objective here was to have a feature show matches as the users put in 1 letter, 2 etc.
basically an autocomplete feature. very useful for many things…
names, files, messages (in this case)

three elements for the feature are the html, javascript and presenter code in php
simple, yes, but not for me :-)

1. FORM in latte template

<form role="form" id="f2" n:name=sendMessageForm class=form autocomplete="on">
					<fieldset>
					<div class="form-group"><label>Send to:</label><input placeholder="User name" class="form-control"
							n:name="username" type="text" size=20 autofocus="" onkeyup="mine(this.value)"></div>

2. JAVASCRIPT in latte template

<script>
function mine(str) {

	$.getJSON({link query!}, { str: str }, function (payload) {
		$('#txtHint').text(payload.text);
	});
}
</script>

3. PRESENTER code in handle<SIGNAL>


	public function handleQuery(?string $str): void {

			if (!$this->isAjax()) {
				$this->error('', 403);
			}

			//array can be from file, database, etc.
			$members = ['james','melisa','cay','jack','uestla','george'];
			$hint = "";

			// lookup all hints from array if $str is different from ""
			if ($str !== "") {
				$str = strtolower($str);
				$len=strlen($str);

				foreach($members as $name) {
					if (stristr($str, substr($name, 0, $len))) {
						if ($hint === "") {
							$hint = $name;
      					} else {
	  						$hint .= ", $name";
      					}
    				}
  				}
			}
			$this->sendJson(['text' => $hint]);
	}

now i can walk the dog with a smile hehe
James

uestla
Backer | 796
+
+1
-

Glad to hear that and glad to be part of your $members array :-)
Tell your dog I said hi :-)