17

Now I know this basic question has been asked before, but I must be doing something wrong. I know that an appended element must bound before I can do anything to it. However, try as I might I can't get it to work.

I am pulling in a message and displaying when people click a radio select. When ever I try to bind the new element, it stacks in odd ways. It will start to stack the elements. eg- [Click 1]message 1, [Click 2] message 1 and 2 and so on.

I have tried a whole bunch of different ways to bind it. My hope was the remove would strip #feedback and then create and bind the next message. I must be doing something terribly wrong. I know this is very similar to other posts, but I went through all of them and was not able to find a clear enough answer to help. Thank you in advance.

The HTML

<div class="answers">
    <ul>
        <li>
            <input id="answer" type="radio" onclick="feedback('THE MESSAGE HTML')"><label>Label</label>
        </li>
    </ul>
</div>

JavaScript:

function feedback(message)
{
    $('#answer').live('click', function()
    {
        $('#feedback').remove();
    });

    $('#answer').live('click', function()
    {
        $('.answers').append('<div id="feedback">'+message+'</div>');
    });
};
DontVoteMeDown
  • 21,122
  • 10
  • 69
  • 105
user1197728
  • 181
  • 1
  • 1
  • 5

5 Answers5

26

If I understand your question correctly, I've made a fiddle that has this working correctly. This issue is with how you're assigning the event handlers and as others have said you have over riding event handlers. The current jQuery best practice is to use on() to register event handlers. Here's a link to the jQuery docs about on: link

Your original solution was pretty close but the way you added the event handlers is a bit confusing. It's considered best practice to not add events to HTML elements. I recommend reading up on Unobstrusive JavaScript.

Here's the JavaScript code. I added a counter variable so you can see that it is working correctly.

$('#answer').on('click', function() {
  feedback('hey there');
});

var counter = 0;

function feedback(message) {

  $('#feedback').remove();

  $('.answers').append('<div id="feedback">' + message + ' ' + counter + '</div>');

  counter++;    
}
richoffrails
  • 1,003
  • 8
  • 11
  • OK, that seems to be working now. Thank you so much! That is very helpful. Yeah, part of the problem was me not fully understanding the live function. I will have to look into that more. And thank you for the suggestions. – user1197728 Sep 25 '12 at 18:20
  • You're welcome. I'm glad I could help. The jQuery best practices change all of the time when it comes to registering event handlers. It used to be ``live()``, then it became ``delegate()`` and now it is ``on()``. – richoffrails Sep 25 '12 at 18:27
  • So event handlers on the dom are intrusive, but creating ids to access those elements is not. What's the difference in intrusiveness between an id string and an fn call string? It's 2014, and I still don't get it. – Carlos Dec 05 '14 at 16:55
4

The live function is registering a click event handler. It'll do so every time you click the object. So if you click it twice, you're assigning two click handlers to the object. You're also assigning a click handler here:

onclick="feedback('the message html')";

And then that click handler is assigning another click handler via live().

Really what I think you want to do is this:

function feedback(message)
{
    $('#feedback').remove();

    $('.answers').append('<div id="feedback">'+message+'</div>');
}

Ok, per your comment, try taking out the onclick part of the <a> element and instead, putting this in a document.ready() handler.

$('#answer').live('click',function(){
                     $('#feedback').remove();
                     $('.answers').append('<div id="feedback">'+message+'</div>');
                 });
jackotonye
  • 3,537
  • 23
  • 31
Phillip Schmidt
  • 8,805
  • 3
  • 43
  • 67
  • That's what I tried to begin with. The issue with that is that remove won't take away the first feedback. That solves the odd stacking issue, but not the issue with removing the previous message. That's exactly what I thought though. – user1197728 Sep 25 '12 at 17:48
  • Oh, I meant to say thank you because that does seem to explain why the stacking issue is happening. – user1197728 Sep 25 '12 at 17:50
  • I do appreciate the help Philip. Unfortunately, I can't remove the on click from the button because it's a legacy system that we are trying to get rid of that is being displayed in multiple places. In the transition from old to new, I have to make it work in a "as is" way. – user1197728 Sep 25 '12 at 18:26
  • @user1197728 I'm suggesting the same thing as Richoffrails did, and you said his worked :) – Phillip Schmidt Sep 25 '12 at 20:05
0

Do you have multiple Radio Buttons on the page..

Because what I see is that you are assigning the events to all the radio button's on the page when you click on a radio button

Sushanth --
  • 55,259
  • 9
  • 66
  • 105
0

I would do something like:

$(documento).on('click', '#answer', function() {
  feedback('hey there');
});
Lucas S.
  • 1
  • 1
0

you could use replaceAll instead of remove and append replaceAll

Masoud
  • 260
  • 2
  • 9