1

I have a simple textarea where users can input text which is then passed through via AJAX to a URL once they hit the return key. My issue is that on the first press of the return key the text data is sent once, on the second it's sent twice, and so on incrementing my one each time.

After some reading up I realise that if I was using a form submit I'd have to unbind it to prevent this happening. I've tried adding a value flag to prevent the multiple events, but have only got so far as to get it to trigger once only.

My code is as follows. Any guidance on how to prevent the incrementing events would be appreciated - as you can probably tell my confidence/knowledge in Javascript isn't the best. Thank you!

$(function() {
    $("#myTextarea").keypress(function(e) {
        // If the user hits the return key
        if(e.which == 13) {
            e.preventDefault();
            $.ajax({
            success: function(){
                var modal = $('#myModal'), modalBody = $('#myModal .modal-body');
                modal
                    // Load the webpage result within the modal Body
                    .on('show.bs.modal', function () {
                        modalBody.load('http://www.things.co.uk/things' + document.getElementById('myTextArea').value)
                    })
                    .modal();
                    // Hide the modal after five seconds
                    myModalTimeout = setTimeout(function() {
                        $('#myModal').modal('hide');
                            }, 5000);
                }
            });
        }
    });
});

Edit: I solved this by using one() for my modal event via http://www.andismith.com/blog/2011/11/on-and-off/. Thank you everyone.

2 Answers2

0

If there are no more event handlers on myTextarea div code below should suffice.
If there are multiple event handlers attached to keypress event you will have to use named function and remove it using $.unbind() more on how to do this.

$(function() {
    $("#myTextarea").off();
    $("#myTextarea").keypress(function(e) {
        // If the user hits the return key
        if(e.which == 13) {
            e.preventDefault();
            $.ajax({
            success: function(){
                var modal = $('#myModal'), modalBody = $('#myModal .modal-body');
                modal
                    // Load the webpage result within the modal Body
                    .on('show.bs.modal', function () {
                        modalBody.load('http://www.things.co.uk/things' + document.getElementById('myTextArea').value)
                    })
                    .modal();
                    // Hide the modal after five seconds
                    myModalTimeout = setTimeout(function() {
                        $('#myModal').modal('hide');
                            }, 5000);
                }
            });
        }
    });
});
Community
  • 1
  • 1
Matas Vaitkevicius
  • 58,075
  • 31
  • 238
  • 265
0

You must attach the event handler only once. I suppose you're getting the JS in your AJAX response, and executing it again and again on each AJAX load. Removing and re-attaching the handlers is a hacky solution.

To avoid to attach the event handlers more than once, simply put your script in a part of the page which is not reloaded by AJAX, so the event is attached only once.

You can even attach an event handler to an element that is reloaded by ajax using delegated events: Understanding Event Delegation

With this technique, you attach the event handler to a container parent element which is not reloaded by ajax, and handle the events of the reloaded children specified by a filter.

$( "#container" ).on("<event>", "<children filter>", function( event ) {
  // code to handle the event
});

Note that in this sample #container is the element which isn't reloaded by ajax. And <children filter> is a jquery selector that chooses the children whose event mus be handled. (<event> is obviously the event name, like click or keyPress).

Explanation: when the event is trigger in the child element, it pops up to the container. The container catches it, and checks that the children passes the filter. If so, the vent is handled.

JotaBe
  • 38,030
  • 8
  • 98
  • 117
  • Thank you, your explanation makes a lot of sense. Strangely I've attached the handler to my .container div class, but it's still incrementing. I will look into this, your solution is more logical than what I was previously attempting. – thelittleone May 29 '14 at 12:52