$view->action points to parent page breaking ajax calls

Permalink
I wrote a custom single page which reads 2 additional parameters off the url

Typical URL: /index.php/mysinglepage/88/138
class mysinglepage extends PageController{   
   public function view($pram1 = null, $pram2 = null){
      //$pram1 = 88
      //$pram2 = 138
   }
}

This single page also allows additional blocks to be installed on it. However, when using $view->action("myAjaxfunction") to create an ajax route to the block's controller, it is actually being interrupted as parameters for the single page controller.

So, the $view creates a URL that looks like this
"http://mywebsite/index.php/mysinglepage/myAjaxfunction/205";


So obviously it get trapped by the single page and processed in the view function:
class mysinglepage extends PageController{   
   public function view($pram1 = null, $pram2 = null){
      //$pram1 = "myAjaxfunction"
      //$pram2 = 205 (bID)
   }
}


When what i'm hoping for is:
class Controller extends BlockController{   
   public function action_myAjaxfunction($bID  = false){
   }
}


Am I not using $view->action("myAjaxfunction") correctly or should my single page have code to pass calls from blocks back to the block's controller?

Thanks for your help!!!

rockface
View Replies: View Best Answer
WillemAnchor replied on at Permalink Reply
WillemAnchor
use $this instead of $view

in the block view.php use:
$this->action('myFunction');

in the block controller.php use:
public function action_myFunction() {}
rockface replied on at Permalink Reply
rockface
Life can be so simple when you know all the answers!

Thanks!
rockface replied on at Permalink Reply
rockface
Hmmm... I'm sorry, that actually did not fix the problem.
It looks like $view & $this return the same action URL.

The block works correctly on other pages. But when placed on my custom single page (which needs to read some parameters) the ajax request is being intercepted by the single page controller file.

I even tested on other pages which have URL parameters similar to mine (I.E. /members/profile/view/2)

I'm guessing my problem is in my single page... Is this the correct way to grab stuff off the URL?
class mySinglePage extends PageController {   
   public function view($fileID = null, $userID = null)
        ...
}

I really do not want to use the traditional get approach (?fileID=xxx&userID=xxx")

When the block tries to make the ajax call to "/index.php/mySinglePage/myAjaxFinction/207" is is picked up by the single page's view function.

Thanks again!
WillemAnchor replied on at Permalink Reply
WillemAnchor
it's not clear to me what you want to do now

1. block view -> block controller

2. block view -> singlepage controller

3. singlepage view -> singlepage controller

I thought you wanted 1, but you say
'When the block tries to make the ajax call to "/index.php/mySinglePage/myAjaxFinction/207"´
which indicates 2
rockface replied on at Permalink Reply
rockface
Sorry for the confusion.

1. is what i want.

The ajax calls (made in the blocks view.js) get intercepted by my single page's controller file. I'm expecting the call to be routed to me block's controller file.

Just ran a test...

1. Loaded the single page containing the block...
2. Ran the ajax call (was caught by the single page's controller)
3. Without refreshing the browser, I changed the single page's controller from:

public function view($fileID = null, $blockcID = null)
to:
public function view()

4. Ran the ajax call again and it correctly routed ajax to the block's controller.

So, I am thinking the problem is in my single page.
rockface replied on at Permalink Reply
rockface
when creating the route for my block's ajax call, i only get one option...

"/index.php/mySinglePage/myAjaxFunction/207"

It is the route given by both $view->action("myAjaxFunction") and $this->action("myAjaxFunction").

If the block is installed on another page, the path to that page is given.

The problem is, other pages will pass the action call to the block's controller... my custom single page captures the ajax call and does not pass it along to the block's controller page.
WillemAnchor replied on at Permalink Reply
WillemAnchor
mySinglePage shouldnt be in that url
I don't know how you do it...can't reproduce it. Maybe you are extending a page instead of a block for your block controller class, I dunno
A block on a single page works as good as on a normal page
WillemAnchor replied on at Permalink Reply
WillemAnchor
here is some code to test your block's view.php:
<div class="myfunction btn btn-primary">
<?php echo $myUrl = $this->action('MyFunction') ?>
</div>
<script>
   $(".myfunction").on("click", function () {
      doAjax();
   });
   doAjax = function() {
      $.ajax({
         dataType:   "json",
         type:         "post",
         url:         "<?php echo $myUrl ?>",
         data:         { name: "world" } ,
         success:      function (ret) {
            console.log("ret", ret);


It should give a 404 error (on firebug) cause it can't find the function until you create one in your block's controller.
rockface replied on at Permalink Reply
rockface
Thanks for sticking with me on this!

I put your code in my view.php for the block and added this to the block controller

public function action_MyFunction(){
      $data = array("ret" => "Hello from block controller");
      echo json_encode($data);
      exit();
   }


Then modified the page controller's view() function
public function view($fileID = null, $blockcID = null) {
   switch ($fileID){
   case "MyFunction":
      $data = array("ret" => "Hello from page controller");
      echo json_encode($data);
      exit();
      break;
   default: 
      ...
   }
}


The console window then displays:
ret Object {ret: "Hello from block controller"}


if I change the page controller to look like this
public function view() {
}


The console window then displays:
ret Object {ret: "Hello from page controller"}


If you would like to see the page yourself - I upload everything to a development site - here:

http://dev.gallerygig.com/index.php/spotlight/41/184...
WillemAnchor replied on at Permalink Best Answer Reply
WillemAnchor
Interesting
I tested this on a 5.7.5rc1 and get the opposite result
page controller view.php:
public function view() { do stuff }
gives a block answer
page controller view.php:
public function view($fileID = null, $blockcID = null) { switch ...}
gives a page answer

however:
public function view($fileID = null, $blockcID = null) {
      $cats = $this->getCats();
      $this->set('cats', $cats);
      switch ($fileID){
/*note*/      case "NotMyFunction":
            $data = array("ret" => "Hello from page controller");
            echo json_encode($data);
            exit();
            break;
         default:
            break;
      }
   }

will not give a block answer

I think the magic happens in PageController.php / setupRequestActionAndParameters

Anyways, if you wanna use view(with params), you will probably have to call the block's controller yourself, and the handler you are seeking.

But then better use Route

In your package controller (I did it in the single page package controller, but i think you could better do it in your block's package controller):
on_start() {
   Route::register('/MyFunction', '\Concrete\Package\YourPackage\Block\YourBlock\Controller::action_MyFunction');         // or leave the action_bit
}

In your block's view.php you can now do:
<?php echo $myUrl = URL::to('/MyFunction') //$this->action('MyFunction') ?>


if you wanna use params, you can register '/MyFunction{param}'
here's a nice link:http://c5hub.com/learning/ajax-57-style/...
rockface replied on at Permalink Reply
rockface
As you may have already assumed... I got my results backwards in my last post... page<-->block. thank you for trying it in your environment.

I will give your suggestions a go and report back.

An interesting point here is the block works correctly when installed on a core single pages which use view() parameters (I.E. /members/profile/view/4).
rockface replied on at Permalink Reply
rockface
Thanks WillemAnchor! that works.