Vlad
Vlad

Reputation: 105

Render template into Symfony2 with ajax

I have a action in my controller for the index route

routing.yml

index:
pattern: /index
defaults: { _controller:AcmeDemoBundle:Default:index }

Controller for this path

public function indexAction()
{
    return $this->render('AcmeDemoBundle:Plugin:index.html.twig');
}

And the index.html.twig template

{% extends'::base.html.twig' %}

{% block stylesheets %}
    {% stylesheets filter='cssrewrite' output='css/*.css'
            'bundles/acmedemo/css/*'  %}
    <link href="{{ asset_url }}" type="text/css" rel="stylesheet" />
    {% endstylesheets %}
    {% endblock stylesheets %}

{% block body %}
<br>
<div class="container">

<div class="wp_attachment_holder">

    <div class="imgedit-response" id="imgedit-response-8"></div>

    <div class="wp_attachment_image" id="media-head-8">
        <p id="thumbnail-head-8"><img class="thumbnail" src="http://localhost/wordpress/wp-content/uploads/2014/06/121-1024x583.jpeg" style="max-width:100%" alt=""></p>
        <p><a class="btn btn-sm btn-default" id="edik-wp-extended-edit">Редактировать</a> <span class="spinner"></span></p>
    </div>
    <div style="display:none" class="image-editor" id="image-editor-8">
    </div>
</div>
<div id="output"></div>
<img class="thumbnail"  data-attach-id="8" data-src="http://localhost/wordpress/wp-content/uploads/2014/06/121-1024x583.jpeg" style="max-width:100%" alt="">
    <script>
            $('#edik-wp-extended-edit').click(function() {
                window.location= Routing.generate('ajax');
//                $('#output').load('/ajax/index');
            });
        </script>
    </div>
{% endblock %}`

When the button Редактировать is clicked i want to load another template with ajax.

another.html.twig

<div>Hello</div>

routing.yml

ajax:
pattern: /ajax/index
defaults: { _controller :AcmeDemoBundle:Default:ajax }
options:
    expose: true

Controller for this path

public function ajaxAction()
{
    $template = $this->renderView('AcmeDemoBundle:Plugin:another.html.twig');
    return new Response($template);
}

But when i click the button my uri will be /ajax/index. What i want is that it stays by /index and the template will be rendered into my index template

What am i doing wrong?

Thanks.

Upvotes: 6

Views: 25151

Answers (2)

KhorneHoly
KhorneHoly

Reputation: 4766

First, your ajaxAction() should be a bit different as far as I know.

For me this works:

    $template = $this->forward('AcmeDemoBundle:Plugin:another.html.twig')->getContent();

    $json = json_encode($template);
    $response = new Response($json, 200);
    $response->headers->set('Content-Type', 'application/json');
    return $response;

The forward() function renders the template and returns the rendered HTML code.

Your JavaScript file should look like this:

$.ajax({
    type: "POST",
    dataType: 'json',
    url: Routing.generate('ajax'),
    async: false //you won't need that if nothing in your following code is dependend of the result
})
.done(function(response){
    template = response;
    $('#your_div').html(template.html); //Change the html of the div with the id = "your_div"                        
})
.fail(function(jqXHR, textStatus, errorThrown){
    alert('Error : ' + errorThrown);
});

You make an AJAX call to the your ajaxAction, which will return the HTML of the template you want to be rendered.

After that you just need to add a <div id="your_div"></div> at the position you want the template to be rendered. This workes perfectly for me.

To mention is that you need to break down the ajax template to just the code that should be shown.

Upvotes: 22

Alex O.
Alex O.

Reputation: 1192

Please try generate ajax route like this

window.location= '{{ path("ajax") }}';

Added:

For make ajax request change windows.location to ajax request

$( "#output" ).load( '{{ path("ajax") }}', function() {
  alert('Load done');
});

Added explanation of use:

js code will work only if you put it on Twig template. If you put it to js file it will not work. In case of original questions.

<div id="output"></div>
<img class="thumbnail"  data-attach-id="8" data-src="http://localhost/wordpress/wp-content/uploads/2014/06/121-1024x583.jpeg" style="max-width:100%" alt="">
<script>
      $('#edik-wp-extended-edit').click(function() {
            $( "#output" ).load('{{ path("ajax") }}');
      });
</script>

You can use something like FOSJsRoutingBundle to proper use SF2 routing in js

Upvotes: -1

Related Questions