diff --git a/docs/callbacks.md b/docs/callbacks.md index 921aa6fd3d..233ef7ec06 100644 --- a/docs/callbacks.md +++ b/docs/callbacks.md @@ -229,7 +229,10 @@ $label->link($cb->getUrl()); When you trigger callback, you'll see the output: ``` -{"success": true, "message": "Success", "eval": "alert(\"ok\")"} +{ + "success": true, + "atkjs": "alert(\"ok\");" +} ``` This is how JsCallback renders actions and sends them back to the browser. In order to retrieve and execute actions, diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 3c18aae495..f98aab2463 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -399,4 +399,7 @@ parameters: message: '~^Parameter #1 \$object of method Atk4\\Ui\\App::add\(\) expects Atk4\\Ui\\AbstractView, array given\.$~' - path: 'src/Popup.php' - message: '~^Parameter #1 \$view of method Atk4\\Ui\\Callback::terminateJson\(\) expects Atk4\\Ui\\View, Atk4\\Ui\\AbstractView given\.$~' + message: '~^Parameter #1 \$ of closure expects Atk4\\Ui\\View, Atk4\\Ui\\AbstractView given\.$~' + - + path: 'src/Popup.php' + message: '~^Parameter #1 \$view of method Atk4\\Ui\\Callback::terminateJsonIfCanTerminate\(\) expects Atk4\\Ui\\View, Atk4\\Ui\\AbstractView given\.$~' diff --git a/src/Callback.php b/src/Callback.php index 8869d394a8..fe94f7ddf3 100644 --- a/src/Callback.php +++ b/src/Callback.php @@ -89,7 +89,7 @@ public function set($fx = null, $fxArgs = null) /** * Terminate this callback by rendering the given view. */ - public function terminateJson(View $view): void + public function terminateJsonIfCanTerminate(View $view): void { if ($this->canTerminate()) { $this->getApp()->terminateJson($view); diff --git a/src/Form/Control/Multiline.php b/src/Form/Control/Multiline.php index d19659f573..f836a5d907 100644 --- a/src/Form/Control/Multiline.php +++ b/src/Form/Control/Multiline.php @@ -685,9 +685,9 @@ private function outputJson(): void // no break - expression above always terminate case 'on-change': $rowsRaw = $this->getApp()->decodeJson($this->getApp()->getRequestPostParam('rows')); - $response = ($this->onChangeFunction)($this->typeCastLoadValues($rowsRaw), $this->form); - $this->renderCallback->terminateAjax($this->renderCallback->getAjaxec($response)); - // TODO JsCallback::terminateAjax() should return never + $this->renderCallback->set(function () use ($rowsRaw) { + return ($this->onChangeFunction)($this->typeCastLoadValues($rowsRaw), $this->form); + }); } } diff --git a/src/JsCallback.php b/src/JsCallback.php index 87d207431a..4ab03d722a 100644 --- a/src/JsCallback.php +++ b/src/JsCallback.php @@ -93,7 +93,7 @@ public function set($fx = null, $args = null) $ajaxec = $this->getAjaxec($response); - $this->terminateAjax($ajaxec); + $this->terminateAjaxIfCanTerminate($ajaxec); }); return $this; @@ -102,17 +102,13 @@ public function set($fx = null, $args = null) /** * A proper way to finish execution of AJAX response. Generates JSON * which is returned to frontend. - * - * @param ($success is true ? null : string) $msg General message, typically won't be displayed - * @param bool $success Was request successful or not */ - public function terminateAjax(JsBlock $ajaxec, $msg = null, bool $success = true): void + protected function terminateAjaxIfCanTerminate(JsBlock $ajaxec): void { - $data = ['success' => $success]; - if (!$success) { - $data['message'] = $msg; - } - $data['atkjs'] = $ajaxec->jsRender(); + $data = [ + 'success' => true, + 'atkjs' => $ajaxec->jsRender(), + ]; if ($this->canTerminate()) { $this->getApp()->terminateJson($data); diff --git a/src/JsSse.php b/src/JsSse.php index ca55bf93bd..66db2b8de8 100644 --- a/src/JsSse.php +++ b/src/JsSse.php @@ -83,13 +83,13 @@ protected function initSse(): void /** * Sending an SSE action. */ - public function send(JsExpressionable $action, bool $success = true): void + public function send(JsExpressionable $action): void { $ajaxec = $this->getAjaxec($action); $this->sendEvent( '', $this->getApp()->encodeJson([ - 'success' => $success, + 'success' => true, 'atkjs' => $ajaxec->jsRender(), ]), 'atkSseAction' @@ -100,14 +100,14 @@ public function send(JsExpressionable $action, bool $success = true): void * @return never */ #[\Override] - public function terminateAjax(JsBlock $ajaxec, $msg = null, bool $success = true): void + protected function terminateAjaxIfCanTerminate(JsBlock $ajaxec): void { $ajaxecStr = $ajaxec->jsRender(); if ($ajaxecStr !== '') { $this->sendEvent( '', $this->getApp()->encodeJson([ - 'success' => $success, + 'success' => true, 'atkjs' => $ajaxecStr, ]), 'atkSseAction' diff --git a/src/Loader.php b/src/Loader.php index 7b78ac2e93..d3c471adad 100644 --- a/src/Loader.php +++ b/src/Loader.php @@ -85,7 +85,8 @@ public function set($fx = null) $this->cb->set(function () use ($fx) { $fx($this); - $this->cb->terminateJson($this->getShimIfOwner()); + + $this->cb->terminateJsonIfCanTerminate($this->getShimIfOwner()); }); return $this; diff --git a/src/Modal.php b/src/Modal.php index 4895b50b76..9bd6815873 100644 --- a/src/Modal.php +++ b/src/Modal.php @@ -98,7 +98,8 @@ public function enableCallback(): void $this->cb->set(function () { ($this->fx)($this->cbView); - $this->cb->terminateJson($this->cbView); + + $this->cb->terminateJsonIfCanTerminate($this->cbView); }); } diff --git a/src/Panel/Content.php b/src/Panel/Content.php index 563705d425..fa931d5bf8 100644 --- a/src/Panel/Content.php +++ b/src/Panel/Content.php @@ -50,7 +50,8 @@ public function onLoad(\Closure $fx): void { $this->cb->set(function () use ($fx) { $fx($this); - $this->cb->terminateJson($this); + + $this->cb->terminateJsonIfCanTerminate($this); }); } diff --git a/src/Popup.php b/src/Popup.php index b194682b67..583a08b805 100644 --- a/src/Popup.php +++ b/src/Popup.php @@ -145,12 +145,15 @@ public function set($fx = null) $this->minHeight = '45px'; } - // create content view to pass to callback - $content = $this->add($this->dynamicContent); - $this->cb->set($fx, [$content]); - // only render our content view - // PopupService will replace content with this one - $this->cb->terminateJson($content); + $this->cb->set(function () use ($fx) { + // create content view to pass to callback + $content = $this->add($this->dynamicContent); + + $fx($content); + + // only render our content view, PopupService will replace content with this one + $this->cb->terminateJsonIfCanTerminate($content); + }); return $this; }