1252748
1252748

Reputation: 15372

listen for shift keypress within .on() then perform a function with element that attached the listener

I have a function that listens for a shift key press

$("fieldset").on("change", "input[type='checkbox'].shift_selectable_box", function () {
    $(document).on("keydown keyup", listening_for_shift);

         var boxes = $(this).closest("fieldset").find("input[type='checkbox']"),
             any_selected = boxes.filter(":checked").size() > 0;

         if (any_selected) {
             $(document).on("keydown keyup", listening_for_shift);

         } else {
              $(document).off("keydown keyup", listening_for_shift);
         }

     });
});

function listening_for_shift(e) {

   if (e.keyCode == 16) {
       if (e.type === "keydown") {
           console.log(e);
        }

        if (e.type === "keyup") {
           console.log(e)
        }

     }

It there a way that I can, when the shift key is down, execute something on the element that called the listening_for_shift function: the input[type=checkbox] element that was changed?

Edit:

Apparently, I can do something like this:

    if (any_selected) {
        $(document).on("keydown keyup", function listening_for_shift(e) {

            if (e.keyCode == 16) {
                if (e.type === "keydown") {
                    console.log(self);

                }
                if (e.type === "keyup") {
                    console.log("no shift")
                }
            }

        });

    } else {
        $(document).off("keydown keyup", listening_for_shift);
    }

and the listener will be added. But my .off() fails to function.

Upvotes: 0

Views: 381

Answers (2)

adeneo
adeneo

Reputation: 318182

You have to listen for key events before the change event, inside the event handler the change has already happened, and it's too late to start checking if a key was pressed, and the change event on a checkbox has no concept of keys anyway, as it doesn't listen for key events :

$(document).on('keyup keydown', function(e) {
    $(this).data('shift', e.type==='keydown' && e.shiftKey);
});

$(".test").on("change", function (e) {
    if ( $(document).data('shift') ) {
        $(this).prevUntil('[type="checkbox"]:checked')
               .filter('[type="checkbox"]')
               .prop('checked', this.checked);
    }
});

FIDDLE

Upvotes: 0

UweB
UweB

Reputation: 4110

In your .off() call, the 2nd argument is a literal that doesn't exist in the context, as the handler function is declared in the if block. Change your code to:

function listening_for_shift(e) {
    if (e.keyCode == 16) {
        if (e.type === "keydown") {
            console.log(self);
        }
        if (e.type === "keyup") {
            console.log("no shift")
        }
    }
}

if (any_selected) {
    $(document).on("keydown keyup", listening_for_shift);
} else {
    $(document).off("keydown keyup", listening_for_shift);
}

Upvotes: 1

Related Questions