dereuromark / cakephp-ajax Goto Github PK
View Code? Open in Web Editor NEWAJAX for CakePHP: A plugin to ease handling AJAX requests.
License: MIT License
AJAX for CakePHP: A plugin to ease handling AJAX requests.
License: MIT License
Hi Mark
I have your cakephp-ajax in my test environment. Yesterdad i was doing a composer update on cakephp, and it failed on cakephp-ajax
this is the result. What could hava happend ?
regards,
Tom
$ composer update
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 0 installs, 14 updates, 0 removals
- Updating symfony/process (v3.2.3 => v3.2.4) Downloading: 100%
- Updating symfony/finder (v3.2.3 => v3.2.4) Loading from cache
- Updating symfony/filesystem (v3.2.3 => v3.2.4) Loading from cache
- Updating symfony/debug (v3.2.3 => v3.2.4) Downloading: 100%
- Updating symfony/console (v3.2.3 => v3.2.4) Downloading: 100%
- Updating cakephp/chronos (1.0.4 => 1.1.0) Downloading: 100%
- Updating cakephp/cakephp (3.3.14 => 3.3.15) Downloading: 100%
- Updating cakephp/debug_kit (3.8.0 => 3.9.0) Downloading: 100%
- Updating nikic/php-parser (v3.0.3 => v3.0.4) Downloading: 100%
- Updating symfony/var-dumper (v3.2.3 => v3.2.4) Downloading: 100%
- Updating league/flysystem (1.0.34 => 1.0.35) Downloading: 100%
- Updating symfony/config (v3.2.3 => v3.2.4) Downloading: 100%
- Updating symfony/yaml (v3.2.3 => v3.2.4) Downloading: 100%
- Updating dereuromark/cakephp-ajax dev-master (1058903 => 985c009) Update failed (Failed to execute git show-ref --head -d
sh: 1: git: not found
)
Would you like to try reinstalling the package instead [yes]? yes
- Removing dereuromark/cakephp-ajax (dev-master)
[RuntimeException]
Failed to execute git show-ref --head -d
sh: 1: git: not found
Mark,
I am using this plugin in my app and I needed to skip the subdirectory for view file like this src\Template\ajax\ACTION_NAME.ctp as I am using a new controller for ajax requests.
So, I changed the code here https://github.com/dereuromark/cakephp-ajax/blob/master/src/View/AjaxView.php#L68-L70 and set it to -
$this->subDir = null;
Now, I am not sure if this make a good feature and if yes, how to make this option configurable so that it can be put in the repository. What are you comments on it?
Hello,
any particular reason? For example in my action i do the login and set a flash message via success()
I would like to see that message always (not only if i set a redirect).
Thanks
In most cases, this component is working brilliantly for me, it saves so much code in my controllers! I've come across one situation where I need to do special formatting of my flash message using helpers (e.g. the Time helper to format a date and time according to user preferences), and so I'm using a custom flash element, like:
$this->Flash->my_custom_element(null, ['params' => ['variable' => $variable]]);
And then src/Element/Flash/my_custom_element.ctp
looks something like this:
echo $this->element('BootstrapUI.Flash/default', [
'message' => __('Here is the custom message about {0}',
$this->Time->date($params['variable']->created)),
'params' => [
'class' => ['warning', 'alert', 'alert-dismissible', 'fade', 'in'],
'escape' => false,
'attributes' => ['role' => 'alert'],
],
]);
When this comes to my Ajax response handler, the _message parameter has an object with keys like so:
element: "Flash/my_custom_element"
key: "flash"
message: null
params: Object
variable: Object
(all the $variable data is here)
Seems that when you call $this->Controller->request->session()->consume
, you get back an array in such cases instead of just a message, and something further needs to be done to use the element to format this before setting it into _message.
Not sure if it makes a difference that I'm using the Friends Of Cake BootstrapUI plugin to nicely format flash output, but that works fine with all my "standard" flash messages (e.g. $this->Flash->info(__('Message goes here.'));
) Also, using this for non-Ajax requests renders the flash element correctly, so I know that much of it is okay.
I experienced strange behavior with this plugin, and I was unable to determine why. or the solution. I assumed you could have encountered this before.
I have a controller method changeTheme
that changes user preferences.
When using a normal POST, (with a page redirect) everything goes fine.
But, when I call the same method through AJAX, I got an error (probably before Ajax Component, since its a HTML error)
saying
Error: Authorization\AuthorizationService::can(): Argument #1 ($user) must be of type ?Authorization\IdentityInterface, Authentication\Identity given, called in /var/www/html/vendor/cakedc/auth/src/Traits/IsAuthorizedTrait.php on line 63
When I remove the line $this->Authentication->setIdentity($user);
everything work as expected.
Maybe this is related with the order plugins are loaded, or something like that, but I dont know internals of both your plugin and Authorization one to confirm that.
My method is:
public function changeTheme() {
if ($this->getRequest()->is(['patch', 'post', 'put'])) {
$table = $this->fetchTable();
// get logged User ID
$identity = $this->getRequest()->getAttribute('identity');
$identity = $identity ?? [];
$loggedUserId = $identity['id'] ?? null;
if (!$loggedUserId) {
$this->Flash->error(__d('cake_d_c/users', 'User was not found'));
return $this->redirect($this->getRequest()->referer());
}
// get the current user and set a view variable
$user = $table->get($loggedUserId, ['contain' => $this->contain]);
$user = $table->patchEntity($user, $this->getRequest()->getData());
if ($table->save($user)) {
$this->Authentication->setIdentity($user);
$this->Flash->success(__('Your theme has been saved'));
} else {
$this->Flash->error(__('Your theme mode could not be saved'));
}
}
return $this->redirect($this->getRequest()->referer());
}
Do you have any thoughts?
I'm trying to submit my forms using ajax in a similar way to
http://api.jquery.com/jquery.post or http://www.cakephp.4uk.pl/ajax/submit
I looked through some of the documentation and source, but I'm still not sure if this is the right tool.
Thanks
Notice: Deprecated (16384): Response::type() is deprecated. Use getType() or withType() instead. - /vendor/dereuromark/cakephp-ajax/src/View/AjaxView.php, line: 80
You can disable deprecation warnings by setting Error.errorLevel
to E_ALL & ~E_USER_DEPRECATED
in your config/app.php
Can someone show me a simple example code for AJAX Pagination? (CakePHP 4.x)
https://sandbox.dereuromark.de/sandbox/ajax-examples/pagination
I found an example demo here, but I can't find the code for it.
Hi Mark
After running the update on composer I got the following issues:
during update
issue: update ok by composer but /src folder was empty.
solution: remove manually the folder and settings on composer.json, composer.lock and vendor/cakephp-plugins.php
PS: same issue happened with PHPMailer
before on every action I was using
$this->viewClass = 'Ajax.Ajax';
but then after update I got this error message:
2015-09-27 08:53:24 Error: [Cake\View\Exception\MissingTemplateException] Template file "ajax/.ctp" is missing.
Request URL: /users/checkusername
Stack Trace:
#0 .../dereuromark/cakephp-ajax/src/View/AjaxView.php(98): Cake\View\View->_getViewFileName(NULL)
#1 .../cakephp/cakephp/src/Controller/Controller.php(598): Ajax\View\AjaxView->render(NULL, NULL)
#2 .../cakephp/cakephp/src/Routing/Dispatcher.php(120): Cake\Controller\Controller->render()
#3 .../cakephp/cakephp/src/Routing/Dispatcher.php(87): Cake\Routing\Dispatcher->_invoke(Object(App\Controller\UsersController))
#4 .../Cake\Routing\Dispatcher->dispatch(Object(Cake\Network\Request), Object(Cake\Network\Response))
#5 {main}
I solved changing:
$this->viewClass = 'Ajax.Ajax'; to => $this->viewClass = 'Ajax';
But, then I also need to move all *.ctp files from /Action/ajax folder to to /Action folder.
I got it running but if there is anything that I'm doing wrong it would be nice to know to avoid me to review and test all code everytime I upgrade.
Danke, Eduardo
hi there,
I started to use this nice one Plugin but I didn't find out how to do an Ajax Request but not have to create ajax/view.ctp. I wondering if it's possible to make an Ajax Request wihtout content field in json returned and not have to create ajax/view.ctp at each ajax request through the Plugin.
Even when calling in Ajax an url having json extension, the plugin wants me to create a view.
Hello, I've recently downloaded this plugin to have its AJAX candy in my CakePHP 4.3 app, but I cannot manage to make it work like in the CakePHP Sandbox app's examples.
Here's what I've done up until now:
...
public function initialize(): void
{
parent::initialize();
if (in_array($this->request->getParam('action'), ['delete'])) {
$this->loadComponent('Ajax.Ajax');
}
}
...
document.querySelectorAll('[data-ajax-delete="true"]').forEach((deleteButton) => {
document.querySelector(`#${deleteButton.id}`).removeAttribute("onclick");
deleteButton.addEventListener("click", async (event) => {
event.preventDefault();
let confirmMessage = deleteButton.confirm;
if (confirmMessage && !confirm(confirmMessage)) {
return false;
}
let form = deleteButton.previousElementSibling,
url = form.action + ".json",
tr = deleteButton.closest("tr");
const response = await fetch(url, {
method: "DELETE",
headers: {
"Content-type": "application/x-www-form-urlencoded",
},
});
response.json().then(data => {
console.log(data)
})
return false;
});
});
But the result is not what I expected, as there are a few problems that I don't know if are related to a bad implementation on my part. In fact when the button is pressed, and the delete method gets called, the row gets effectively deleted but there are a few problems that I'm facing:
public function beforeFilter(EventInterface $event)
{
parent::beforeFilter($event);
$this->FormProtection->setConfig('unlockedActions', ['delete']);
}
public function delete(?string $id)
{
$this->request->allowMethod(['delete']);
$thingToDelete = $this->Things->get($id);
if ($this->Things->delete($thingToDelete)) {
$result = true;
$this->Flash->success(__d('Crm', 'The custom variable has been deleted.'));
} else {
$result = false;
$this->Flash->error(__d('Crm', 'The custom variable could not be deleted. Please, try again.'));
}
$this->set(compact('result'));
$this->viewBuilder()->setOption('serialize', ['result']);
}
and this is the response object that I get after I press the button:
as you can see, only variables that I manually set inside the delete method get set in the response, in contrary to what I've seen inside the examples where everything gets passed down (Flash, redirect etc.)
Did I mess something up?
Hello,
I found a problem with Flash messages. I have seen that plugin is using consume()
method to get messages from sessions. This is a problem when we try to print Flash->render(...)
in the view. The content
will never has the messages. Any workaround?
Hi,
Using the Ajax Component in most my controllers and actions, I'd like to disable it for some actions where I want to use a classic jsonView via an Ajax request to get some datas. Component want me to create a view in /ajax/myAction.ctp as well ...
How can I disable the component for some actions only ?
Thanks
Because beforeRedirect is depreciated
So I've been trying to make this work in conjunction with https://github.com/FriendsOfCake/crud, but any time I have an action CRUD enabled the content is left out of the AJAX response.
I've tracked it down to this bit of code in View/AjaxView.php
if (isset($this->viewVars['success'])) {
$dataToSerialize['success'] = $this->viewVars['success'];
$view = false;
}
if ($view !== false && !isset($this->viewVars['_redirect']) && $this->_getViewFileName($view)) {
$dataToSerialize['content'] = parent::render($view, $layout);
}
As you can see from https://crud.readthedocs.io/en/latest/actions/index.html#serialize, CRUD will always set a success viewVar when a request works. Which then means that the Ajax plugin skips rendering.
Is there any particular reason for this behaviour? I'm not sure I understand why you would not want to render content, by definition, on a successful request?
Looks like _respondAsAjax
needs a bit of a tweak to properly support the new option of setting _serialize
to true
to serialize all view variables? It's currently assuming that $this->Controller->viewVars['_serialize']
is an array. I'd say that just checking if that is === true
and exiting early if so would work. Alternately, only doing the serializeKeys
portion if it's !== true
, if you prefer to have only one exit point from functions.
The new middleware-based plugin architecture does not trigger the beforeRedirect event, thus breaking the Ajax component. I built a workaround (my own "unauthorized" handler registered with the Authorization service) that triggers the event manually for now, but it seems the event needs to be triggered on the component registry's event manager, not the global one. I couldn't find a clean way to access the component registry in the handler, so I added a very ugly hack to make it available via a static property of my AppController class:
$event = new Event('Controller.beforeRedirect', null, [$url, $response]);
AppController::$__components->getEventManager()->dispatch($event);
if ($event->isStopped()) {
$response = $event->result;
}
Maybe we need a middleware version of the functionality? Seems like a straight-forward implementation, just adjusting the response some as the stack unwinds.
In reference to the docs
$this->viewClass = 'Ajax.Ajax';
Hi Mark!
This is not exactly the issue, but can you tell me please why this is not the part of Cake3 core? Cake includes AjaxView for example but it is doing only half of the job
Hi,
Using Ajax Component, I'd like to use Helper within AjaxView but I can't success at it.
There is some Helper that I use commonly in my AppView Class that I'd like to use in AjaxView class. Those Helpers comes from Plugin.
How can I mention to AjaxView to load some Helper ?
Would be nice to have something like:
$result = json_encode($response);
if (json_last_error() != JSON_ERROR_NONE) {
return json_encode(['error' => json_last_error_msg()]);
}
return $result;
@ AjaxView::render
What do you think about it?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.