event.preventDefault() not working

ideAvi picture ideAvi · Feb 24, 2012 · Viewed 20.4k times · Source

i have this line of code in my view using the Telerik Grid:

      columns.Bound(o => o.URI).Width(10).Sortable(false)
                .ClientTemplate("<A class='btnGrid' id=source<#= ID #> onclick=GridSelection.addItem('<#= ID #>') >Add</A>").Title("").Width(50);

the GridSelection addItem and disableSelected functions' JS codes:

  GridSelection = {
      addItem: function (value) {

         var anchorOption = $("a[id=source" + value + "]");

         anchorOption.click(function (e) { // variable name changed from "event"
               e.preventDefault();
               return false;    // as suggested by mr. Hamdi
               });

         anchorOption.fadeTo("slow", .5);

         GridSelection.disableSelected(anchorOption, true);

         var data = $("#GridSource").data('tGrid').data;
         var selectedObject;
         for (var item in data) {
            if (data[item].ID == value) {
               selectedObject = data[item];
               break;
            }
         }

          var grid = $("#GridSelected").data('tGrid');
          var newData = $("#GridSelected").data('tGrid').dataSource._data;
          newData.push(selectedObject);
          grid.dataBind(newData);
          grid.sort("");
          anchorOption.fadeTo("slow", .5);
      },

      disableSelected: function (element, disable) {
              //false on IEs 6, 7 and 8
              if (!$.support.leadingWhitespace) {
                  if (disable) {
                      $(element).attr('disabled', 'disabled');
                  } else {
                      $(element).removeAttr('disabled');
                  }
              }
     },
         // other GridSelection subfunctions here...

As I run the MVC3 web app in IE, it runs well because of the GridSelection.disableSelected function, but in Chrome and Mozilla Firefox, the event.preventDefault(); doesn't work. The anchor link still adds the data item even after the user has already added it there.

Is it OK having the preventDefault method inside the GridSelection.addItemfunction that was being prevented?

Which attribute is being prevented by the preventDefault , is it the href or is it the onclick?

What wrong with this? How can I fix this bug? Anyone who can help?

Answer

nnnnnn picture nnnnnn · Feb 24, 2012

The markup for your link has an inline click handler and no href:

<A class='btnGrid' id=source<#= ID #> onclick=GridSelection.verify('<#= ID #>') >Add</A>

If it is the GridSelection.verify() that you're trying to prevent you should note that:

  1. The inline click handler is probably being called before your other event handler which means it is too late to cancel it from your other handler, and in any case
  2. e.preventDefault() doesn't stop other handlers from running, it stops the default action for the event which for a link is to navigate to the url specified in the href attribute. And you don't specify an href.

If you want to have multiple handlers for the same event on the same element you should assign them all with jQuery in the order you want them to be called, and then use the event.stopImmediatePropagation() method within one of the handlers if you want to stop the rest of them from running.

I don't know how to fit that within the code you've shown given that you don't show part of the code you want to prevent, but the general principle is:

<a id="myLink" href="someURL">My link</a>

<script>
$("#myLink").click(function(e) {
    // some processing
    if (someCondition)
       e.stopImmediatePropagation();
    // some other processing
});

$("#myLink").click(function(e) {
    // some processing
});
</script>

Having said all that, if the .verify() function calls your .addItem() function and it is your intention to prevent future click events from working on the same link because the first click should verify/add and then you don't want to be able to add again, then within your .addItem() function do something like this:

anchorOption.removeAttr("onclick");
// or
anchorOption[0].onclick = null;