Why Javascript event running multiple times per click?

55
September 03, 2019, at 7:50 PM

I wrote a js-class which handles the Ajax-calls when a user clicks on a button. So the user can simply click on open/close and can open/close a entity in my database.

All works fine. The button-icon changes and the popover title and text changes also. The user can click on the buttons again and again and the Ajax does the work and jQuery changes the look - BUT -

When I watch in my debug bar - I see that with every click a additional Ajax call is running. When I click the button 3 times - the same Ajax-call will run 4 times for changing the entity to open/close.

I inspected the handlers. Every time it is only one handler and one #close-course element.

I really don't understand why this Ajax calls get more and more with every click!

Here my js-class:

'use strict';
import $ from "jquery";
(function (window, $) {
class CourseApp {
    constructor($wrapper) {
        this.$wrapper = $wrapper.find('.js-wrapper');
        this.$body = $wrapper
        this.iconBtn = this.$wrapper.find('a').blur();
        this.$submitCount = 0;
        this.$wrapper.on(
            'click',
            'a',
            this.handleOpenCloseAction.bind(this)
        );
    }
    handleOpenCloseAction(e) {
        let popover = this.$body.find('.popover')
        // prevent popover to close - when open-button is hitted
        popover
            .on('mousedown', '#open-course', function (e) {
                e.preventDefault()
            });
        // prevent popover to close - when open-button is hitted
        popover
            .on('mousedown', '#close-course', function (e) {
                e.preventDefault()
            });
        // since open-course-link is clicked - open the course and
        // do some action
        popover
            .on(
                'click',
                '#open-course',
                function (e) {
                    const $btn = $(e.currentTarget);
                    let $icon = $btn.find('.icon-lock-open');
                    if (this.$submitCount === 0) {
                        this.$submitCount++;
                        $.ajax({
                            url: $btn.data('open-course-url'),
                            method: 'POST',
                        }).then(function (data) {
                            $('[data-toggle="popover"]').popover('hide');
                            this.iconBtn.blur();
                            this.iconBtn.attr('data-content', data);
                            this.iconBtn.attr('data-original-title', 'Kurs schließen');
                            $('.icon-lock').removeClass('icon-lock').addClass('icon-lock-open');
                        }.bind(this))
                        this.$submitCount = 0;
                    }
                }.bind(this)
            )
        // since close-course-link is clicked - close the course and
        // do some action
        popover
            .on(
                'click',
                '#close-course',
                function (e) {
                    const $btn = $(e.currentTarget);
                    if (this.$submitCount === 0) {
                        this.$submitCount++;
                        $.ajax({
                            url: $btn.data('close-course-url'),
                            method: 'POST',
                        }).then(function (data) {
                            $('[data-toggle="popover"]').popover('hide');
                            this.iconBtn.blur();
                            this.iconBtn.attr('data-content', data);
                            this.iconBtn.attr('data-original-title', 'Kurs öffnen');
                            $('.icon-lock-open').removeClass('icon-lock-open').addClass('icon-lock');
                        }.bind(this))
                        this.$submitCount = 0;
                    }
                }.bind(this)
            )
    }
}

window.CourseApp = CourseApp;

})(window, jQuery);

My html:

 <td class="col-1 js-wrapper">
            <a href="#"
               class="btn btn-primary pop"
               data-content="{% if entity.open %} {{ popoverContentClose }} {% else %} {{ popoverContentOpen }} {% endif %}" data-toggle="popover" tabindex="0" data-trigger="focus"
               title=""
               data-original-title="{% if entity.open %} Kurs schließen? {% else %} Kurs öffnen? {% endif %}"
               data-placement="left">
                {% if entity.open %}
                    <i class="icon icon-lock-open"></i>
                {% else %}
                    <i class="icon icon-lock"></i>
                {% endif %}
            </a>
        </td>

The popover (is in a twig block):

 Möchtest du diesen Kurs wirklich schließen? Die Teilnehmer dieses Kurses müssen somit jeden Kurszugang bestätigen.
<br>
<table class='table popover-table mb-0'>
    <tr>
        <td class='pl-0 border-top-0'>
            <a href='#'
               class='btn btn-danger-outline col-md-12 ml-0' id='close-course' data-close-course-url='{{ path('close_course', {'id' : entity.id}) }}'><i class='icon icon-lock'></i>Schließen</a>
        </td>
        <td class='pr-0 border-top-0'>
            <button class='btn btn-primary col-md-12' class='close'
                    data-dismiss='alert'>{{ 'common.close'|trans }}</button>
        </td>
    </tr>
</table>
READ ALSO
Jquery slider get ui.value on handle click event

Jquery slider get ui.value on handle click event

I have a jquery slider covering a range of 0 to 4 and populating a read only text box with the uivalue on the slide event as is usual usage

39
jquery hide and show checkbox event is not working

jquery hide and show checkbox event is not working

I'm using plugin to change checkbox templateNow i want to create hide and show in base the of checkbox

69
How to make the ajax search function output be clickable [on hold]

How to make the ajax search function output be clickable [on hold]

I have created a search function using ajax which communicates with my database and outputs the top five closest results to the search queryI now want the search results to be clickable, such that when it is clicked, it places the word into a different...

57
Add span tag dynamically to certain words in content editable div

Add span tag dynamically to certain words in content editable div

I have created a content editable div where users can write comments and tag other usersAs the user types, an API call will be made to check any username is specified in the comment

50