Problem ajax custom layout

I use ajax modal: http://github.com/kylefox/jquery-modal

When using the standard template layout/default.php it is displayed well without layout, only the content.

But if I set up a different page template:

    $this->viewBuilder()->setLayoutPath('domains');
    $this->viewBuilder()->setLayoutPath('other_domain');

So the modal is displayed, including the layout and console browser displayed:

[Deprecation] Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.

and

DevTools failed to load SourceMap: Could not load content for http://php/manage/init.js.map: HTTP error: status code 404, net :: ERR_HTTP_RESPONSE_CODE_FAILURE

Bad URL source file…

Modal does not work even if I put the template in the same folder as the default.php file
I want it to work the same as if I had a template in default.php

Please help

Hii there,

The first is a warning because your XHR requests are synchronous, causing them to block the main thread.
This can cause a variety of issues ranging from:

  • a slower time for a full page load (eg. by blocking other JS)
  • the page outright locking up until the request resolves.

Without knowing the code that causes it, it’s difficult to fix it.
My best bet would be to use promises and/or async/await for the request:

function makeRequest(){
  return new Promise((resolve, reject) => {
    // Make your request here
  });
}

// using the promise as-is
makeRequest().then((res, err) => {
  if(err) {
    // ... Handle errors
    return;
  }
  // ... Process result
});

// using await
async function myCaller() {
  let res;
  try {
    res = await makeRequest();
  } catch(err) {
    // ... Handle errors
    return;
  }
  // ... Continue processing request
}

This warning can be ignored but as the warning implies, it may be detrimental for the end user (your visitor) experience due to the reasons listed above.

As for the second error: this is a 404 error meaning it couldn’t find the file at http://php/manage/init.js.map.
Make sure that the sourcemap exists at the location it should be available at (most often in the same directory as the JS file you want to serve).
This error can be ignored if you want to.
It may make debugging a bit harder though (since your browser can’t “rebuild” the original JS so it can’t tell you the exact lines something went wrong).

How can I use the functions you wrote? In AppController.php ?

I think there is a bug in PHP CAKE, because if I set this in AppController:

$this->viewBuilder()->setLayout('default');

It is the same template as the default is /template/layout/default.php

When calling the modal, the entire contents are displayed, including the layout.

If I do not set setLayout … then when calling the modal, only the content from the controller without layout is displayed in the modal.

I believe that when you don’t set the layout, and it’s an Ajax request, it defaults to something other than template/layout/default.ctp. I can’t remember for sure, as I am using a plugin to change some aspects of Ajax handling. You should be able to do some debugging in the rendering functions to find what layout it’s using in that case, and do something similar with your custom one.

1 Like

No, the code I gave is JavaScript and has nothing to do with CakePHP itself.
The warnings you got are related to your JavaScript.

As for the template, well, without really seeing what the error itself is (eg. a screenshot), it’s difficult to guess what’s wrong.

Could it be debugged what layout will be used?

You could try the getTemplate and getTemplatePath functions in the view builder.

1 Like

That’s right, when calling ajax, it’s called ajax layout.

And the solution is as follows:

if($this->getRequest()->is('ajax')) {
    $this->viewBuilder()->setLayout('ajax');
} else {
    $this->viewBuilder()->setLayoutPath('domains');
    $this->viewBuilder()->setLayoutPath('other_domain');
}

Since the Ajax layout happens automatically, you could maybe simplify to

if(!$this->getRequest()->is('ajax')) {
    $this->viewBuilder()->setLayoutPath('domains');
    $this->viewBuilder()->setLayoutPath('other_domain');
}
2 Likes