10

I am facing some problems with CakePHP 2.4 in the moment while working with AJAX and JSON.

I want to render data with a view, but save the resulting html as a string in a variable. After that, I would like to set an array, containing this html string among other data to return as JSON object. Unfortunately I didn't find the right way yet.

My controller code so far makes use of the CakePHP json magic:

//Controller (just parts) 

$data = $this->paginate();

if($this->request->is('ajax')) {

        $jsonResponse = array(

            'jobs' => $data,

            'foci' => $foci,

            'jobTypes' => $jobTypes,

            'count_number'=> $count_number

        );

        $this->set('jsonResponse', $jsonResponse);

        $this->set('_serialize', 'jsonResponse');

    } else {

        // render regular view
        $this->set(compact('data', 'foci', 'jobTypes', 'count_number'));

    }

This outputs the perfect json in the javascript console, besides the fact, that the data in $data is plain data.

Is it somehow possible, to pass $data to a view, render it, save the output to a string variable $html, and pass $html to jobs in jsonResponse instead of $data?

zinky
  • 151
  • 1
  • 1
  • 8
  • Do you mean you want your json response to be the serialized result of the html? If you're going to do that, why wouldn't you just return the html. What is a (real) example of the output you're wanting to see? – AD7six May 05 '14 at 08:20
  • Thanks for your response! I want to use a infinite page scroll script with Cake, where I append data via Javascript, but I don't want to format the data with javascript, but get the data as html from the server. Besides, I need some raw numbers to update other elements on the page. – zinky May 05 '14 at 08:55

3 Answers3

25

Yes! You Can render a view into a variable. You just have to create a view object . Inside Your Controller Try This:

$view = new View($this,false);
$view->viewPath='Elements';  // Directory inside view directory to search for .ctp files
$view->layout=false; // if you want to disable layout
$view->set ('variable_name','variable_value'); // set your variables for view here
$html=$view->render('view_name'); 

// then use this $html for json response
Spandan Singh
  • 674
  • 1
  • 5
  • 15
14

For those of you using CakePhp3

$view = new View($this->request,$this->response,null);
$view->viewPath='MyPath';  // Directory inside view directory to search for .ctp files
$view->layout='ajax'; // layout to use or false to disable
$html=$view->render('view_name');

Don't forget to add this in your namespace

use Cake\View\View;
Franz
  • 645
  • 1
  • 9
  • 21
1

The Controller::render() function actually sets the body of the response by calling CakeResponse::body() and then returning the current CakeResponse object. This means that you can call the render() method inside the controller action, capture its return value and then again call the CakeResponse::body() and thus replacing the response body with the desired output.

Example code:

$data = $this->paginate();

// Pass the data that needs to be used in the view
$this->set(compact('data', 'foci', 'jobTypes', 'count_number'));

if($this->request->is('ajax')) {

    // Disable the layout and change the view 
    // so that only the desired html is rendered
    $this->layout = false;
    $this->view = 'VIEW_PASSED_AS_JSON_STRING';

    // Call the render() method returns the current CakeResponse object
    $response = $this->render();

    // Add any other data that needs to be returned in the response
    // along with the generated html
    $jsonResponse = array(
        'html'       => $response->body(),
        'other_data' => array('foo' => 'bar'),
        'bar'        => 'foo'
    );

    // Replace the response body with the json encoded data
    $response->body(json_encode($jsonResponse));

}