Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cancel event triggering (blur) from another element's event (click)

I have a few rows with text, which I can "edit" by replacing the row inline with an input, which gets the text from the row as its value attribute.

When the input looses focus, the previous text is restored.

When pressing return (keyCode 13), the new text is saved and will be written in the row.

Now, for the users who don't know to press return for saving the text, I want to add a "Save" button right next to the input field. But when pressing it, the blur event of the input field is getting fired first, discarding the changes.

So is there an easy way, that the .click() event of the button can cancel the .blur() event on the input field? Perhaps an "don't execute other events" or can I perhaps see in the blur event, which events will get called next to cancel it?

Here is a jsfiddle to see what I mean: http://jsfiddle.net/ykY5X/ (I'm working in Firefox (latest Nightly), where the button click won't work. I just tested the jsfiddle also in chrome, where also the keyup won't work as expected.)

$('#showEdit').click(function() {
    $('#row').data('text',$('#row').text());
    $('#row').html('<input type="text" id="editInput" /> <span id="editSave">Save</span>');
    $('#editInput').val($('#row').data('text')).focus();
});

$('#row').delegate('#editInput','keyup',function(e) {
    e.stopPropagation();
    var keycode = e.keyCode || e.which;

    if (keycode == 13) $('#editSave').click();
}).delegate('#editSave','click',function(e) {
    e.stopPropagation();

    $('#row').text($('#editInput').val());
}).delegate('#editInput','blur',function() {
    $('#row').text($('#row').data('text'));
});
like image 758
Wulf Avatar asked Oct 10 '22 02:10

Wulf


2 Answers

My final working solution is this:

$('#showEdit').click(function() {
    $('#row').data('textOriginal',$('#row').text());
    $('#row').data('textSave',$('#row').text());
    $('#row').html('<input type="text" id="editInput" /> <span id="editSave">Save</span>');
    $('#editInput').val($('#row').data('textOriginal')).focus();
});

$('#row').delegate('#editInput','keyup',function(e) {
    e.stopPropagation();
    var keycode = e.keyCode || e.which;
    if (keycode == 13) {
        $('#row').data('textSave',$(this).val());
        $('#editSave').click();
    }
}).delegate('#editSave','mousedown',function() {
    $('#row').data('textSave',$('#editInput').val());
}).delegate('#editSave','click',function(e) {
    e.stopPropagation();

    if ($('#row').data('textOriginal') == $('#row').data('textSave')) {
        $('#row').text($('#row').data('textOriginal'));
        return;
     }

    $('#row').text($('#row').data('textSave'));

}).delegate('#editInput','blur',function() {
    $('#editSave').click();
});

http://jsfiddle.net/RSUdx/

like image 178
Wulf Avatar answered Oct 14 '22 01:10

Wulf


You can use some delay before the code inside blur event handler gets executed. On Save button click you can cancel the blur timer so that it will not be executed.

Working demo

var blurTimer;
$('#showEdit').click(function() {
        $('#row').data('text',$('#row').text());
        $('#row').html('<input type="text" id="editInput" /> <span id="editSave">Save</span>');
        $('#editInput').val($('#row').data('text')).focus();
});

$('#row').delegate('#editInput','keyup',function(e) {
    e.stopPropagation();
    var keycode = e.keyCode || e.which;
    if (keycode == 13){
       $('#editSave').click();
    }
}).delegate('#editSave','click',function(e) {
    clearTimeout(blurTimer);
    $('#row').text($('#editInput').val());
}).delegate('#editInput','blur',function() {
    blurTimer = setTimeout(function(){
       $('#row').text($('#row').data('text'));
    }, 200);
});
like image 33
ShankarSangoli Avatar answered Oct 14 '22 01:10

ShankarSangoli