3

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?

ideAvi
  • 139
  • 2
  • 3
  • 13
  • How sure are you that the click handler is even being called? Does the `anchorOption.fadeTo("slow", .5);` work? – nnnnnn Feb 24 '12 at 04:27
  • That's also one of my impulses. I have here a Developer Tools app which I use in debugging my app. I've added breakpoints on the code lines of the scrips to know whether it passes by these lines and it does. – ideAvi Feb 24 '12 at 05:42
  • @nnnnnn: please see my added questions in my edited post. thanks – ideAvi Feb 24 '12 at 06:04
  • Have you checked Error Console in Mozilla ? Is there any error? Can you add alert line before `e.preventDefault();` to make sure that function is called. – Hamdi Feb 24 '12 at 06:05
  • Did you forget to add semicolon after `return false`. It shouldn't give error but worth trying. – Hamdi Feb 24 '12 at 06:10
  • sorry about that, thats a typo error here in my post but not in my code ;) – ideAvi Feb 24 '12 at 06:13
  • @Hamdi: thanks for a nice debugging tip, I've added alert("Foo") before and after the Function call, and before and after the .preventDefault(). All of them popped up, therefore each line was read, but then, the function to be _prevented_ was not being _prevented_ to happen. – ideAvi Feb 24 '12 at 06:25
  • Well now I somehow understood your problem. What happens if you remove the if statement `if (!$.support.leadingWhitespace) ` in disableSelected function. You will just have the body of that condition – Hamdi Feb 24 '12 at 06:28
  • I was typing my answer while you were editing your post, and purely by luck I think I've answered your extra questions. But I'm not sure my answer will actually solve your problem - please clarify how your `GridSelection.addItem()` function is actually called (and how it related to the `.verify()` function in the markup). – nnnnnn Feb 24 '12 at 06:29
  • I'm very sorry for that typo error. My app must prevent the `.addItem()` and not the `.verify()`. `.verify()` was one of my previous solutions, that is, to create a separate function to be called in the onclick. But I've deleted it and chose not to have it. My apologies again. – ideAvi Feb 24 '12 at 07:05

5 Answers5

4

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;
nnnnnn
  • 147,572
  • 30
  • 200
  • 241
  • That was precise. But where should I put the `preventDefault()` ? should I put it inside the `.addItem()`still? or should I put it inside another event handler outside the `.addItem()`? – ideAvi Feb 24 '12 at 07:21
  • 1
    With the updated version of the question I'd say you don't want `preventDefault()` or `stopImmediatePropagation()` at all, nor should you be creating a `click` handler inside `addItem()` like you currently do because that won't help. Try the code from the very end of my answer and see what happens - the idea is to "turn off" the _existing_ click handler that was set with the inline `onclick` attribute in your html. – nnnnnn Feb 24 '12 at 10:24
3

Have you tried adding return false; instead of event.preventDefault();

Hamdi
  • 931
  • 13
  • 31
  • Actually you can add `return false;` statement after `event.preventDefault();`. You don't need to delete `event.preventDefault();` – Hamdi Feb 24 '12 at 04:08
  • Thanks, I've tried adding it with my code, but still, it doesn't change anything. – ideAvi Feb 24 '12 at 05:52
  • That is really weird. I faced with same problem before and return false; worked for me. – Hamdi Feb 24 '12 at 06:04
  • please see my updated post. I've added few questions that bother me, maybe you could help me answer them. – ideAvi Feb 24 '12 at 06:12
2

Have you tried renaming the event variable? call me crazy but I seem to recall having issues just try function(e) {e.preventDefault();} and see what happens

Mike L.
  • 1,936
  • 6
  • 21
  • 37
1

The magic sauce in vanilla (without jQuery) is stopPropagation. In order to stop any possible event bubbling, you usually want to pair the two. When combined, you achieve both:

  1. Prevent default environment/browser behavior (preventDefault) and
  2. Not triggering any other scripts attached to DOM ancestors (stopPropagation).

Making the final solution:

evt.preventDefault();
evt.stopPropagation();

The difference between the two has been discussed in greater detail here, and many other places.

Domi
  • 22,151
  • 15
  • 92
  • 122
  • For me stopPropagration didn't work, but stopImmediatePropagation did - eg evt.stopImmediatePropagation(). Something must have been calling other events within my JQuery! – Andy Brown Mar 27 '23 at 08:04
  • stopPropagation solved my issue on an input field when trying to prevent the enter keydown from submitting a form. – seagulledge May 16 '23 at 18:26
1

If the anchor has an id use the id selector instead of using it as attribute selector.

Change

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

To

$("#source" + value)

I am not saying this is the issue but you can try changing this.

Update:

event.preventDefault() stops the browser to follow the link set into href attribute of anchor element. It will not prevent or stop the click event.

ShankarSangoli
  • 69,612
  • 13
  • 93
  • 124
  • Thanks but this is not the issue because I've used this syntax too in my other functions, and that just works with it. – ideAvi Feb 24 '12 at 05:49