Dylan Cross
Dylan Cross

Reputation: 5986

jQuery Ajax return html AND json data

I'm not sure if there is any way to do this or not, but this would solve so many of my problems if there is a simple solution to this.

What I need/want to be able to do is return HTML and JSON in my success of ajax request. The reason being, I want to request a file and return all of that page, but I also want to be able to return a specified set of information from the page in json, so I can use it for other things.

This is what I'm doing now:

     $.ajax({
    type: "POST",
    url: "inc/"+page+".php",
    data: "id="+encodeURIComponent(pageID),
    success: function(html){

        $("body > .container").html(html);

      }
      });

This is what I'd like to be able to do:

     $.ajax({
    type: "POST",
    url: "inc/"+page+".php",
    data: "id="+encodeURIComponent(pageID),
    success: function(html){
        $("body > .container").html(html);
            $("title").html(json.PageTitle)
      }
      });

on the page that is being returned, I would specify what I want the title to be. (For instance, if it's a profile, I would return the user's name)

Upvotes: 11

Views: 30619

Answers (4)

Jonathan Spiller
Jonathan Spiller

Reputation: 1895

HTML and data wrapped in JSON

You can do it by returning a 2 element JSON array. The first element contains HTML and the second element contains another JSON array with the data inside. You just need to unwrap it carefully without breaking anything.

Serverside

$html = '<div>This is Html</div>';
$data = json_encode(array('page_title'=>'My Page'));
$response = array('html'=>$html, 'data'=>$data);
echo json_encode($response);

Clientside

//Ajax success function...

success: function(serverResponse){
    $("body > .container").html(serverResponse.html);
    var data = JSON.parse(serverResponse.data);
    $("title").html(data.page_title)
  }

Note 1: I think this is what @hakre meant in his comment on your question.

Note 2: This method works, but I would agree with @jheddings that its probably a good idea to avoid mixing presentation and data. Coding karma will come back to bite.

Upvotes: 12

NoPyGod
NoPyGod

Reputation: 5067

You also have the option of including the data in html5 data attributes

For instance, if you're returning a list of Animals

<ul id="ZeAnimals" data-total-animals="500" data-page="2">
    <li>Cat</li>
   <li>Dog</li>
   ...
</ul>

You can then collect the data you require using

$('#ZeAnimals').data('total-animals')

Sometimes separating your request into two different ajax calls makes sense also.

Upvotes: 1

pocesar
pocesar

Reputation: 7050

You may use a library that does that automatically, like http://phery-php-ajax.net. Using

Phery::instance()->set(array(
  'load' => function(){
    /* mount your $html and $json_data */
    return 
      PheryResponse::factory()
      ->json($json_data)
      ->this() // points to the container
      ->html($html); 
  }
))->process();
$(function(){
  var $container = $('body > .container');
  $container.phery('make', 'load'); // or $container.phery().make('load')
  $container.bind('phery:json', function(event, data){
    // deal with data from PHP here
  });
  $container.phery('remote');
});

You may, as well, use phery.views to automatically load a portion of the site automatically, without having to worry about client-side specific code. You would have to put a unique ID on the container, container in this example:

$(function(){
  phery.view({
    '#container': {}
  });
});
Phery::instance()->views(array(
  '#container' => function($data, $params){
    /* do the load part in here */
    return 
      PheryResponse::factory()
        ->render_view($html)
        ->jquery('.title')->text($title);
  }
))->process();

Upvotes: 0

jheddings
jheddings

Reputation: 27563

Trying to mix the retun value to contain presentation and data seems like a potential for confusion. Why not split it into two calls and fetch the data on success of the other?

Something like:

 $.ajax({
  type: "POST",
  url: "inc/"+view_page+".php",
  data: "id="+encodeURIComponent(pageID),
  success: function(html) {
    $("body > .container").html(html);
    $.ajax({
      type: "POST",
      url: "inc/"+data_page+".php",
      data: "id="+encodeURIComponent(pageID),
      success: function(json) {
        $("title").html(json.PageTitle);
      }
    });
  });

Upvotes: 10

Related Questions