3

I have a click event that is being called twice and I can't figure out why.

Razor/Html:

<li class="active">
    <a href="#" class="listitem">@Model[i].Name</a>
    <span style="display:none" class="id">@Model[i].ID</span>
</li>

^ This is inside of a for loop containing multiple list items.

JQuery:

$(".listitem").on("click", function () {
    var id = $(this).siblings("span").html();
    $.ajax({
        url: '@Url.Action("SelectItem", "Home")',
        type: "POST",
        data: $("#form").serialize() + "&id=" + id,
        success: function (result) {
            $('#partialView').html(result);
        }
    });
});

^ To handle click of a list item.

Ajax call to my controller refreshes the partial view. My js is contained in the partial view and refreshes but I don't understand why it would cause this event to be called twice (usually the id is undefined the second time). Maybe I'm just making a simple mistake that I'm not seeing?

I know there are many questions on click events being called twice, but I think my situation may be different enough to warrant a question. I also haven't seen many great answers.

aw04
  • 10,857
  • 10
  • 56
  • 89
  • The problem seems to be that with you making use of partial views is that the entire DOM is not reloaded on each jquery request. Therefore the `.on()` method will keep on registering your click event over and over again. Consider using `.off()` with `.on()` e.g. `$(".listitem").off("click").on("click", function() { ... });` – jacqijvv Feb 25 '14 at 15:21
  • I am not sure what is causing the issue so shooting in the dark here. I haven't ever tried to combine anything with a form.serialize. if you remove the + id part of it does it make any difference? – Matt Bodily Feb 25 '14 at 15:34
  • Why you are using $(".listitem").on instead of $(".listitem").click ?? Is it really needed – K D Feb 25 '14 at 15:38
  • @MattBodily same result – aw04 Feb 25 '14 at 15:38
  • .click and .on('click' are 2 different ways of writing the same thing – Matt Bodily Feb 25 '14 at 15:40
  • can you provide some more source.. the exact page to track the problem? it could be that your $(".listitem").on call is getting invoked twice – K D Feb 25 '14 at 15:40
  • we should use jquery.on only if the target element is not present on load of page and going to be added to dom later via ajax or javascript – K D Feb 25 '14 at 15:41
  • @KD it's just a preference, no reason. same result either way though. unfortunately i don't have the page live yet.. anything specifically you would like to see from the source? – aw04 Feb 25 '14 at 15:43
  • hmmm... if it is a preference.. prefer jquery.Click not On :) well we can review the code and it would be easily track the cluprit in page. – K D Feb 25 '14 at 15:45
  • @KD it's several thousand lines :) when you say $(".listitem").on could be invoked twice, how would that happen? what would you look for? i think that is more or less the problem i just don't know how/why – aw04 Feb 25 '14 at 15:50
  • @KD: check out this: http://stackoverflow.com/questions/9122078/difference-between-onclick-vs-click – Javier Jun 26 '15 at 03:02
  • @Javier Thanks :) It supports my comment which i mentioned for dynamically loaded elements ....."I would prefer .on over .click because the former can use less memory and work for dynamically added elements." – K D Jun 26 '15 at 09:15

2 Answers2

10

I think you may be missing a return false at the end of the function. Without it the browser will also to the a click.

Nigel Ellis
  • 601
  • 1
  • 8
  • 18
3

It is generally bad to put script in a partial view since it will be inserted into the middle of the page. I would recommend moving the script from the partial to the main page. To attach the click event to the dynamically added fields change your click event to trigger off of the document

$(document).on('click', '.listitem', function(){ ...

see if this helps

Also, with data I name the variables if I have more than 1. try changing the data like this

data: { form: $('#form').serialize(), id: id },

then just make sure that the input on the controller matches these names

Matt Bodily
  • 6,403
  • 4
  • 29
  • 48