mcmurphy
mcmurphy

Reputation: 805

How to change CSS on UI elements after an .ajax call

I have a Symfony app for which I'm uisng a Bootstrap front end.

I'm trying to use ajax to toggle the state of an item in the database. Whenever a.isActive is clicked, my /admin/toggleProgramActive route should be called. This route contains code to update the database appropiately. When successful, .done ought to be called, and the jQuery therein should run (changing the styling on some elements).

However, here's what's happening instead: My Symfony route is being called, and the database is being updated. But... jQuery never triggers the UI changes.

Here's the relevent code:

HTML:

...
<tbody>
    <tr class="bg-primary no-hover">
        <th ...>
            <div>
                <a href="#" 
                   class="isActive" 
                   data-program-id="{{ program.programId }}">
                    <span class="fa fa-power-off {{ active  ?  'active'  :  'non-active' }}" > </span>
                </a>
            </div>
        </th>
    </tr>
</tbody>
...

JavaScript:

$(document).ready(function ()  {
    $(".isActive").on('click', function()  {
        var element = $(this);
        $.ajax({
            type: "post",
            url:  "/admin/toggleProgramActive",
            data: {"id": $(this).data('program-id')}
        })
            .done(function() {
                element.closest("tr").css('background-color', '#FF6600');
                element.closest("tbody").effect("highlight", {}, 600, function()  {
                    $(this).find("tr.bg-primary").css('background-color', "#337AB7")
                });
            })
    });
});

I know that .done is being called. If I place a console.log(element) after .done(function() { I can see it returning [a.isactive] in the Chrome console.

Any idea what I'm doing wrong? How should I go about changing CSS after an ajax call?

Upvotes: 2

Views: 3530

Answers (2)

Codemole
Codemole

Reputation: 3189

The correct approach will be following:

On server side, the route /admin/toggleProgramActiv should return programId as a response. For example, it should send the JSON response like following:

{
  programId: '215546'
}

And then do in your js code, do following:

$(document).ready(function ()  {
    $(".isActive").on('click', function()  {
        $.ajax({
            type: "post",
            url:  "/admin/toggleProgramActive",
            data: {"id": $(this).data('program-id')}
        })
            .done(function(response) {
                var pid = response.programId;
                var element = $('a[data-program-id=' + pid + ']');

                element.removeClass('isActive');
                element.closest("tr").css('background-color', '#FF6600');
                element.closest("tbody").effect("highlight", {}, 600, function()  {
                    $(this).find("tr.bg-primary").css('background-color', "#337AB7")
                });
            })
    });
});

Also, make sure that you have <tr> tag in your html, which includes <a>, because I do not see any <tr> in your question.

Upvotes: 1

Dekel
Dekel

Reputation: 62576

The a.isActive element has a click event attached, and once you click on that element - the above function will be called.

In that function you run an ajax request (that sends data to the server - but doesn't change anything in the document), and therefor the a.isActive element will not change.

If you want - you can change the element (before the ajax call, or inside the done call - after the ajax call returned.

You can use the toggleClass function to add/remove the isActive class from the element:

element.toggleClass('isActive')

Upvotes: 1

Related Questions