Dooderino
Dooderino

Reputation: 91

jQuery on keyboard function fires twice

The first time it runs smooth but when I repeat the proccess it fires two times adding 2 fields instead of one per Shift+Enter, could anyone explain me why and offer a solution?

$(document).on('click', "span.adbt", function () {
    $('.caddtask').toggleClass('inactive').html("<span class='tfields'><textarea autofocus placeholder='Shift+Enter adds another field' maxlength='30' class='tinput n1' /></span><span class='add'></span>").css({
        'height': '52px'
    });
    $('.add').click(function () {
        SaveTask(date)
    });
    $(document).on('keypress', "textarea.tinput", function (e) {
        if (e.which == 13 && e.shiftKey && $('.tinput:last-of-type').attr('class').slice(-1) < 4) {
            e.preventDefault();
            $('.tfields').append("<textarea autofocus maxlength='30' class='tinput n" + (Number($('.tinput:last-of-type').attr('class').slice(-1)) + 1) + "' />");
            $('.caddtask').css({
                'height': '+=44'
            });
            $('.add').css({
                'top': '+=22'
            });
        }
    });
});

function SaveTask(date) {
    var fields = $('.tinput:last-of-type').attr('class').slice(-1);
    if (Day[date.dayOfYear()].tasks == '') $('.tlist').html('');
    for (var i = 1; i <= fields; i++) {
        if ($('.n' + i).val() === '') {
            $('.tinput').attr('placeholder', 'Enter a task here');
            return;
        }
        if (tasks.length > 0) {
            var id = tasks.length;
            tasks[id] = {
                id: tasks[(id - 1)].id + 1,
                belongs: Number(String(2014).slice(2, 4).concat('00'.concat(date.dayOfYear()).slice(-3))),
                status: false,
                text: $('.n' + i).val()
            };
            $('.tlist').append("<li class='id" + tasks[id].id + "'><span class='status false'></span><span class='tasktext'>" + tasks[id].text + "</span></li>");
        } else {
            var id = 0; 
            tasks[0] = {
                id: 0,
                belongs: Number(String(2014).slice(2, 4).concat('00'.concat(date.dayOfYear()).slice(-3))),
                status: false,
                text: $('.tinput').val()
            };
            $('.tlist').html("<li class='id" + tasks[0].id + "'><span class='status false'></span><span class='tasktext'>" + tasks[0].text + "</span></li>");
        }
    }
    localStorage.setItem('tasks', JSON.stringify(tasks));
    $('.caddtask').toggleClass('inactive').html("<span class='adbt'>Add task</span>");
    $('.add').css({
        'top': '14px'
    });
    $('.inactive').css({
        'height': '26px'
    });
};

And why does it stop autofocusing the textearea on it's 2nd execution?

Upvotes: 1

Views: 76

Answers (1)

j809
j809

Reputation: 1499

Your Problem

Assigning event handlers inside other event handlers.
This will assign the event handlers on each click on span.adbt.
Hence, you get multiple execution of handlers, which will be twice on your second click like you said.

Solution

Keep your event handlers separate...

It should be:

$(document).on('click', "span.adbt", function () {
    $('.caddtask').toggleClass('inactive').html("<span class='tfields'><textarea autofocus placeholder='Shift+Enter adds another field' maxlength='30' class='tinput n1' /></span><span class='add'></span>").css({
        'height': '52px'
    });
});
$('.add').on('click',function () {
    SaveTask(date);
});
$(document).on('keypress', "textarea.tinput", function (e) {
    if (e.which == 13 && e.shiftKey && $('.tinput:last-of-type').attr('class').slice(-1) < 4) {
        e.preventDefault();
        $('.tfields').append("<textarea autofocus maxlength='30' class='tinput n" + (Number($('.tinput:last-of-type').attr('class').slice(-1)) + 1) + "' />");
        $('.caddtask').css({
            'height': '+=44'
        });
        $('.add').css({
            'top': '+=22'
        });
    }
});

Upvotes: 4

Related Questions