Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

dionarap's avatar

Getting a button to change on the frontend with AJAX.

I have created a system where you can visit a place and have all the code that allows for an entry to be posted to the database and deleted from the database on button click with ajax but i am struggling to work out how to make the button change with ajax when its clicked depending on whether the record exists or not. At the moment the button only changes if the page is refreshed albeit the AJAX code works for adding or deleting from the database. How would i get my buttons to change and respond to the if statement with AJAX? here is what i have so far:

Html:

@if(Auth::user()->visitors()->where('place_id', $place->id)->first())
  <a class="btn btn-visited visit"  data-id="{{ $place->id }}">I've Visited <i class="fas fa-check"></i></a>
   @else
  <a class="btn btn-not-visited visit"  data-id="{{ $place->id }}">Visited?</a>
@endif 

AJAX JS:

var token = '{{ Session::token() }}';
var urlVisit = '{{ route('visitss') }}';

$('.visit').on('click', function (event) {
event.preventDefault();
$.ajax({
    method: 'POST',
    url: urlVisit,
    data: {
        place_id: $(event.target).data("id"),
        _token: token
    }
}).done(function() {
    //
});

});

php:

$place_id = $request['place_id'];
        $place = place::find($place_id);
    $visited = Auth::user()->visitors()->where('place_id', $place_id)->first();

if($visited == null) {
            $visited = new Visit();
            $visited->user_id = Auth::user();
            $visited->place_id = $place->id;
            $visited->save();
            return null;
        }
    else{

      $visited->delete();
         return null;
    }

How do i get the buttons to respond with AJAX?

0 likes
27 replies
jlrdw's avatar

Have you looked at the API? https://api.jquery.com/click/

A click event starts out like:

$("#myTable td:nth-child(1)").click(function(event)
{

    /// your code

Here I am clicking a table cell, but a button would be similar.

dionarap's avatar

Its not just a click though, the click needs to check whether the record exists and if it does then the visited button is shown and then if the visited button is clicked the record deletes and the not visited button is shown. the coding of that im struggling with, in terms of AJAX i can get it to work with laravel

jlrdw's avatar

Well before getting that advanced, perhaps you should learn (by taking a tutorial) on the basics of posting with ajax, using GET with ajax, etc.

But read replies here, some examples:

https://laracasts.com/discuss/channels/laravel/ajax-post-request-500-internal-server-error

A basic post

   $(function () {

        $("#postjq").click(function (event)
        {
            event.preventDefault();
            var $post = {};
            $post.petid = $('#petid').val();
            $post.species = $('#species').val();
            $post._token = document.getElementsByName("_token")[0].value
            $.ajax({
                url: 'petupdate', 
                type: 'POST',
                data: $post,
                cache: false,
                success: function (data) {
                    return data;
                },
                error: function () {
                    alert('error handing here');
                }
            });

        });
    });

controller

     public function petupdate(Request $request)
    {

        $petid = $request->input('petid');
        $species = $request->input('species');
        $postdata = [
            'species' => $species
        ];
        DB::table('pets')
                ->where('petid', $petid)
                ->update($postdata);

        //return redirect(Session::get('areturn'));  /// not here with ajax
    }

This was just a very quick example I did a while back for another post. But it works

And here is video:

https://drive.google.com/file/d/1rg9oMb8Ke9ZonzOjKuQ6MJWw_XNJgGUY/view?usp=sharing

and for a redirect after ajax use

window.location.href = "yourchoice";

Look at the jquery docs:

There will be examples of using get.

You need to query for existence of record, then do something. Just have your get response return a true or false, and do an action based on response.

But really you need to learn the basics of ajax and jquery javascript first.

But the jquery docs has examples, it doesn't matter if laravel, asp.net, jsp and servlet, it works the same.

1 like
dionarap's avatar

I don't think thats what i'm looking for to be honest

filipe1221 answer is the closest to what i'm looking for but doesnt implement on if or not the field exists. and just does one.

http://www.btsdumaroc.tk/2018/02/laravel-55-and-ajax-create-like-dislike.html

this is similar to what i'm looking for but used a boolean on the table which i do not have but i need a similar type of code that works for visited and not visited buttons. like im currently getting through laravel

filipe1221's avatar

but you want use ajax right? data was being was expect from db?

dionarap's avatar

Currently if i click the button it will upload and delete to the database through ajax/Laravel as seen in the OP. All i want to do is have two different buttons show for if the record exists in the table and if it doesn't as is shown in the controller and in the html i have at the minute which is working on laravel so i have to refresh the page to get the correct button. instead i want the correct button to show without refreshing.

Cronix's avatar

give the buttons an id

<a id="btn-visited" class="btn btn-visited visit"  data-id="{{ $place->id }}">I've Visited <i class="fas fa-check"></i></a>

<a id="btn-unvisited" class="btn btn-not-visited visit"  data-id="{{ $place->id }}">Visited?</a>
// hide the buttons initially
var btnVisited = $('#btn-visited').hide();
var btnUnvisited = $('#btn-unvisited').hide();

var token = '{{ Session::token() }}';
var urlVisit = '{{ route('visitss') }}';

$('.visit').on('click', function (event) {
event.preventDefault();
$.ajax({
    method: 'POST',
    url: urlVisit,
    data: {
        place_id: $(event.target).data("id"),
        _token: token
    },
    // show button depending on data
    success: function(data) {
         // you'll need to pass something back from controller to check here instead of null
         if (data.someCondition) { 
             btnVisited.show();
         } else {
             btnUnvisited.show();
         } 
    }
});
jlrdw's avatar

But if OP does not take tutorials and learn this stuff for themselves ...

Things like hide, display:none etc a good tutorial would cover.

@Cronix you don't do

var token = '{{ Session::token() }}';

in ajax.

The one in session is the one the posted one has to compare to. Of course the above would match. You need the _token from form to compare with token stored in session.

Cronix's avatar

@jlrdw Thanks, but I know how things work. That's from his original code and I just added the pertinent info to do what the OP was asking for showing/hiding the button depending on the ajax response. I'm not going to do everything...

dionarap's avatar

I don't think its as easy as click and hide as we need to find out if the database matches the button as has been shown in Cronx reply which has been most helpful so far. This is where im up to from that code suggested by cronx. Problem is the code i have only changes on the row being added to the database and doesnt change back when its deleted. here is the code i now have.

JS:

var token = '{{ Session::token() }}';
var urlVisit = '{{ route('visitss') }}';
        var isVisit =null;


$('.visit').on('click', function (event) {
event.preventDefault();
$.ajax({
   method: 'POST',
  url: urlVisit,
  data: {
     place_id: $(event.target).data("id"),
       _token: token
    isVisit: Boolean(isVisit)

 }
}).done(function() {
    if(isVisit = true){
            $('.btn.visit').removeClass('btn-not-visited').addClass('btn-visited').html('I\'ve Visited <i class="fas fa-check"></i>');
            }else{
            }
//
});

PHP:

$place_id = $request['place_id'];
    $place = place::find($place_id);
    $isVisit = $request['isVisit'] ==null;

  $visited = Auth::user()->visitors()->where('place_id', $place_id)->first();

if($visited == null) {
        $visited = new Visit();
        $visited->user_id = Auth::user();
        $visited->place_id = $place->id;
        $visited->save();
        return null;
        $isVisit=true;

    }
    else{

      $visited->delete();
        $isVisit=false;

     return null;
    }
Cronix's avatar

See the comments in my code. You need to pass something back from the controller instead of just null to indicate which button should be hidden/unhidden, and check for that condition in the response.

dionarap's avatar

As you can see Jlrdw i am trying with zero to limited knowledge on this area, so keep the snide comments to yourself if your not willing to help.

1 like
QuentinWatt's avatar

This will update the button without a browser refresh:

All you should have to do is wait for the ajax success, and change the button with normal jQuery. I made the button a variable in my example here since $(this) might reference the wrong item within the Ajax call.

$('.visit').on('click', function (event) {
event.preventDefault();
// Make the button a variable here
var buttonToChange = $(this);
$.ajax({
    method: 'POST',
    url: urlVisit,
    data: {
        place_id: $(event.target).data("id"),
        _token: token
    },
    success: function(){
    // Change the button here
        buttonToChange.addClass('btn-visited');
        buttonToChange.removeClass('btn-not-visited');
        buttonToChange.html('changed');
    },
});

From what I understand, you had the server side already working how you wanted it to.

dionarap's avatar

Jldrw, unfortunately some of us don't have the time to waste on a tutorial and was hoping that a forum where people are helped out with code would be able to fathom how to approach the idea rather than a load of cock stroking and teasing about how clued up you are on JS and how you know but won't say how to fix the problem, i .... A simple code and explanation would have helped far greater than hours wasted on tutorials.

dionarap's avatar

Ok Jlrdw no need to be upset because you've been called out for the pretentious wankstain you are. To be quite frank i've not much interest in JS hence why i asked for a pointer on here on the one problem im trying to fix. i'm sure if you werent such a wankstain you'd have not jumped to conclusions and just spent five minutes putting together the correct code and an explanation of how rather spending the whole day throwing coy comments out that you might know how to do that but you'd rather someone did a tutorial on something they may never use again rather than learn from an explanation of the correct code and saved everyone half a day. Now fuck off, off the thread you utter cockwomble.

QuentinWattL that code would be good if i was just changing the button and thats it, the button though can be clicked again and changed back and that also depends on how its loaded. ie a different button shows for if a record does or doesnt exist

jlrdw's avatar

that code would be good if i was just changing the button and thats it, the button though can be clicked again and changed back and that also depends on how its loaded.

Good grief the answer was provided

if this response do this

if that response do that

Will someone please write a complete application for this person.

dionarap's avatar

It wasn't provided was it, that was a pointer because another pretentious knob like you wanted to be coy rather than go to the trouble of just filling it in so it was working code or similar.

Jlrdw, have you ever kissed a girl?

Cronix's avatar

Man @jlrdw sometimes you really go off the deep end. Just stop responding here... you're not helping anything or anyone with these comments.

QuentinWatt's avatar
Level 3

@dionarap

Well it looks like there are only 2 options. So if you want to toggle back and forth.

$('.visit').on('click', function (event) {
event.preventDefault();
// Make the button a variable here
var buttonToChange = $(this);
$.ajax({
    method: 'POST',
    url: urlVisit,
    data: {
        place_id: $(event.target).data("id"),
        _token: token
    },
    success: function(){
    // Change the button here
        if(buttonToChange.hasClass('btn-visited')){
            buttonToChange.addClass('btn-not-visited');
            buttonToChange.removeClass('btn-visited');
            buttonToChange.html('An unvisited button');
        }
        else{
            // Do the opposite
            buttonToChange.addClass('btn-visited');
            buttonToChange.removeClass('btn-not-visited');
            buttonToChange.html('A visited button');
        }
    },
});
1 like
QuentinWatt's avatar

@dionarap There are better ways to do that though... But that should give you the right idea, you should be able to continue from there.

1 like
jlrdw's avatar

Well someone did the code for you please give @QuentinWatt best answer. But that same answer was given earlier, all you had to do is put the correct code in the if and the else.

If you get the time, there are good FREE tutorials on jquery.

Cronix's avatar

You sure are passive-aggressive. Just let it go...

jlrdw's avatar

Just let it go...

Well okay. Happy now having sloppy joes for supper.

Please or to participate in this conversation.