Why jQuery’s event.preventDefault() Couldn’t Stop a Link From Redirecting?

Hima Chitalia
Coffee and Codes
Published in
3 min readJul 28, 2017

--

For the my fourth project at Flatiron, I needed to add dynamic features to my Rails app that is possible only through jQuery and a JSON API.

After working on Rails for a couple of months, going back to Jquery was a little bumpy journey but there was one thing that really gave me a hard time — Making work anchor tag and jQuery’s event.preventDefault() with each other!

The jQuery’s one of the most useful method — event.preventDefault(), it stops the default action of an element from happening.

Such as:

* It prevents a submit button from submitting a form
* It prevents a link from following the URL

For Example:

$(“a”).click(function(event){
event.preventDefault();
});

The code above prevents a link from opening the URL.

Tip: Use the event.isDefaultPrevented() method to check whether the preventDefault() method was called for the event.

In my small Rails app, I had this code to delete a Goal from the habit:

delete_goal.html.erb<% if current_user == @habit.user %>
<% habit_id = @habit.id %>
<% goal_id = goal.id %>
<a href=”/habits/<%= habit_id %>/goals/<%= goal_id %>” data-confirm=”Destroy <%= goal.name %>?” data-method=”delete” class=”jquery-postback” rel=”nofollow”>Delete Goal</a>
<% end %>


goals.js
$(document).on(“click”, ‘a.jquery-postback’, function(event){
event.preventDefault();
var goal = this
goal.parentElement.remove()
$.ajax({
type: ‘DELETE’,
url: goal.href,
dataType: “json”,
data: {“_method”:”delete”},
complete: function(){
alert(“Deleted Successfully”);
},
error: function(result){
“something went wrong”
}
});
})

But somehow after deleting goal, it used to redirect me to the goal show page with id=’nil’. I understood id=’nil’ because the goal has been deleted but I really had a hard time figuring out why it was redirecting.

For hours and hours, I googled a lot to find a solution. I thought my event.preventDefault() is not working as it should be. I tweaked my code a lot with different versions, like this…

document.addEventListener(‘DOMContentLoaded’, function(event) { $(‘.jquery-postback’).on(‘click’, function(element) {
element.preventDefault();
var $this = $(this);$.post({
type: $this.data(‘method’),
url: $this.attr(‘href’)
}).success(function (data) {
alert(‘success’);
});
});
});
$(function() {
$(“a.jquery-postback”).click(function(element) {
element.preventDefault();
var $this = $(this);
$this.addClass(“disable-link”)
$.post({
type: $this.data(‘method’),
url: $this.attr(‘href’)

}).done(function (data) {
success(function (data) {
alert(‘success’);
});
});
});

And many different versions but nothing made my delete function work! But then a good friend Malki pointed me in a right direction and I realized that culprit was my anchor tag, not the event.preventDefault method!

Basically, Rails has some inbuilt helpers that create event handlers for all the “delete” actions generated by Rails.

This is the JQuery code that Rails uses:

https://github.com/rails/jquery-ujs/blob/master/src/rails.js

Based on this (from the link):

linkClickSelector: ‘a[data-confirm], a[data-method], a[data-remote]’

So, the Event handler will be the only one executed if anchor tag is without data-remote and data-method. Surprisingly, data-confirm hasn’t given me any trouble yet!

So, rewriting my anchor tag like this made it work!

<a href=”/habits/<%= habit_id %>/goals/<%= goal_id %>” data-confirm=”Destroy <%= goal.name %>?” class=”jquery-postback” >Delete Goal</a>

The solution was something that I had never thought of but might be useful for some one like me!

If you have any questions or suggestions, please feel free to write either in comment section or send me an email at hima.chhag@gmail.com.

Happy Coding!

--

--