0
votes

Fairly new to JavaScript. When the page loads, it binds the removeFav/addFav function to the click event of the anchor tag. Everything works as intended, but when user clicks on the link, it takes user to the top of the page. I tried a preventDefault() in different places of each of the functions. It would stop the click default, but it would prevent the rest of the code from running or break the functionality.

Is preventDefault() still the right way to go? Where should preventDefault() go? How can I stop the page from returning to the top every time the link is clicked. Any help would be appreciated.

JavaScript Code:

 // Add a favorite
 function addFav() {
    var id = $(this).data('id');
    var url = '/listings/' + id + '/favorite';
    $.ajax({
      url: url,
      type: 'put',
      success: function(){
        $('this')
          .addClass('active')
          .off('click')
          .on('click', removeFav)
        ;
        console.log("success in add function");
      },
      error: function() {
        console.log("error in add function");
      }
   });
 }

  // Remove a favorite
  function removeFav() {
    var id = $(this).data('id');
    var url = '/listings/' + id + '/unfavorite';
    $.ajax({
      url: url,
      type: "post",
      dataType: "json",
      data: {"_method":"delete"},
      success: function(){
        $('this')
          .removeClass('active')
          .off('click')
          .on('click', addFav)
        ;
      console.log("success in remove function")
      },
      error: function() {
        console.log("error in remove function")
      }
     });
  }

  // Attach the add or remove event handler to favorite links
  function attachFavHandler() {
   $('a#fav').each( function() {
    var status = $(this).hasClass('active');
    if (status) {
      $(this).on('click', removeFav);
    } else {
      $(this).on('click', addFav);
    }
    console.log(status)
   });
  }

  // Lets get the 'favorites' party started
  attachFavHandler();

Rails Code:

          <% if user_signed_in? %>
            <% if current_user.favorites.where(:listing_id => listing.id).first.nil? %>
              <%= link_to "", "", :id => "fav", :class => "", :'data-id' => "#{listing.id}" %>
            <% else %>
              <%= link_to "", "", :id => "fav", :class => "active", :'data-id' => "#{listing.id}" %>
            <% end %>
          <% end %>
1
Why are you giving same ID to every anchor element ?Vigneswaran Marimuthu
preventDefault should be present at top of your removeFav and addFav functions.Vigneswaran Marimuthu
Like Vigneswaran said, you should not have same id for multiple elements, your $('a#fav').each() will always return 1 element even when you have multiple elements with same id. If you want to bind some handler for all elements, give your a elements, some class like link and use $('.link').each() to attach handlers.Arkantos
Also in your removeFav(), in the success callback of AJAX call, it should be $(this) instead of $('this') - no quotes around thisArkantos

1 Answers

1
votes

What you need to do is call the preventDefault() method on the event itself. To get the event, you'll need to pass in the event to your handlers - which the event bindings already do automatically.

So all you need to do is use this event in your handlers.

function removeFav(e) {
    e.preventDefault()
    ...
}