Dygne Dygne - 1 year ago 50
Twig Question

Symfony2 & AJAX - How to integrate an AJAX call with the toggleClass() method

I have a list of

News
objects. Every news has a
startDate
and an
expireDate
. Also, every news has a
state
property.
If the
expireDate
is
< date('now)
then
state
is set to 0.
state
is set to 1 when
expireDate > date('now)
.

When I render the list, for the news with
state == 1
I have a toggle switch (On & Off) to activate or deactivate the news (
state == 1
or
state == 0
respectively). I can't get the toggle work properly.

This is my html for the buttons and my jQuery function that gives the
active
class to the button the user clicks:

//news.html.twig
{% if news.state == 1 %}
<div class="btn-group btn-toggle">
<button class="btn btn-xs btn-primary active">On</button>
<button class="btn btn-xs btn-default ">Off</button>
</div>
{% endif %}

<script type="text/javascript">
$('.btn-toggle').click(function() {
$(this).find('.btn').toggleClass('active');

if ($(this).find('.btn-primary').length > 0) {
$(this).find('.btn').toggleClass('btn-primary');
}

$(this).find('.btn').toggleClass('btn-default');
});
</script>


I need to integrate here the
$.post
call to set the
state
for the news when the user clicks the button.
I have in mind something like this:

$.post('{{ path('set_news_state') }}', {id: 'news.id'}, function(response) {
if (response.code == 100 && response.success){
//do something
}
}, "json");


These would be my controller:

/**
* @Route("/setNewsState/{id}", name = "set_news_state")
* @Method("POST")
**/
public function setNewsOn(Request $request, $id) {
if ($request->isXMLHttpRequest()) {
return new JsonResponse(array('data' => 'this is a json response'));
}

$repository = $this->getDoctrine()->getRepository('AppBundle:News');
$news = $repository->findOneById($id);
if ($news->getState() == 0) {
$news->setState(1);
} else {
$news->setState(0);
}

$em = $this->getDoctrine()->getManager();
$em->persist($news);
$em->flush();

return new Response();
}


How can I integrate the
$.post
call in my already working jQuery function?

Thanks!

Answer Source

You're on the right track, but it's even simpler than what you have. If you POST to the correct URL, you can get the New's entity's ID from the route parameter.

// news.html.twig
// You can supply a second argument to path() to fill in the route params.
$.post("{{ path('set_news_state', {'id': news.id}) }}").done(function(response) {
    if (response.status === 'ok') {
        // ...
    }
});

Then in your controller

/**
* @Route("/setNewsState/{id}", name="set_news_state")
* @Method("POST")
**/
public function setNewsOn($id) {
    $em = $this->getDoctrine()->getManager();
    $news= $em->find('AppBundle:News', $id);

    if ($news->getState() == 0) {
        $news->setState(1);
    } else {
        $news->setState(0);
    }
    $em->persist($news);
    $em->flush();

    return new JsonResponse(array(
        'status' => 'ok'
    ));
}

Last thing,

$news = $repository->findOneById($id); is unnecessary because find() searches for ID by default (well, not really, it searches for the primary key by default, but that's almost always going to be ID).

news = $repository->find($id); is the same, but cleaner.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download