Make blocked elements untababble
While the elements blocked cannot be clicked, it's still possible to use the tabulator to access them, and then use enter to activate it. Would it be possible to skip the blocked element when tabbing?
For now, we just stop the user from tabbing into the blocked elements, but this stops the user. It'd be better if they could skip the blocked ones.
var proxiedBlock = $.fn.block;
$.fn.block = function () {
var $elem = proxiedBlock.apply(this, arguments);
$elem.on('focusin.kj', function (evt) {
evt.preventDefault();
$(evt.relatedTarget).focus();
});
return $elem;
};
var proxiedUnblock = $.fn.unblock;
$.fn.unblock = function () {
var $elem = proxiedUnblock.apply(this, arguments);
$elem.off('focusin.kj');
return $elem;
};
I have the same issue, but this functionality was purposefully removed with this commit: https://github.com/malsup/blockui/commit/d5e5b7e06570e2fd142412ff5be29f0db4df9104
The commit comment reads "don't bind/unbind handler for element blocks" . I don't know why this was done, but I removed the !full check at line 515 in the version I downloaded and it works.
@JulianRussbach Thanks! We tried it, and the report I got was that it seems to work the same as my code above; it doesn't skip to the next tabbable element. Or does it work differently for you?
@SimenB I ended up going with a different approach that allows the blocked elements to be skipped. I changed the tabindex HTML attributes of the elements that were blocked. It ended up being the best approach for our app as we didn't have to modify the blockUI code. I used tabindex of "-2" because some of the normal elements I blocked already had a tabindex of -1. For example a date picker with a hidden div. I didn't want to overwrite the tabindex of the already hidden div and possibly confuse 3rd party JS. So I used -2 to distinguish between my calls and the other widgets.
$(this).block(); $(this).find('input,select,a').filter(':not([tabindex=-1])').attr('tabindex',-2);
$(this).unblock(); $(this).find('[tabindex=-2]').removeAttr('tabindex');
@JulianRussbach That works! Thanks :D
Ended up with this code:
var proxiedBlock = $.fn.block;
$.fn.block = function () {
var $elements = proxiedBlock.apply(this, arguments);
$elements.find(':not([tabindex=-1])').attr('tabindex',-2);
return $elements;
};
var proxiedUnblock = $.fn.unblock;
$.fn.unblock = function () {
var $elements = proxiedUnblock.apply(this, arguments);
$elements.find('[tabindex=-2]').removeAttr('tabindex');
return $elements;
};
Then we don't have to do it every time :smile:
If you provide an answer to my post on Stack Overflow, I can accept it: http://stackoverflow.com/q/31070335/1850276
Already existing tabindexes were messed up, so ended up with this slightly hackish one... If you don't have custom tabindex=0 (or any other values), the previous one should be good
var proxiedBlock = $.fn.block;
$.fn.block = function () {
var $elements = proxiedBlock.apply(this, arguments);
var $tabbables = $elements.find(':not([tabindex=-1])');
$tabbables.each(function () {
var $this = $(this);
if (!_.isUndefined($this.attr('tabindex'))) {
$this.data('origTab', $this.attr('tabindex'));
}
$this.attr('tabindex', -2);
});
return $elements;
};
var proxiedUnblock = $.fn.unblock;
$.fn.unblock = function () {
var $elements = proxiedUnblock.apply(this, arguments);
var $tabbables = $elements.find('[tabindex=-2]');
$tabbables.each(function () {
var $this = $(this);
if (_.isUndefined($this.data('origTab'))) {
$this.removeAttr('tabindex');
} else {
$this.attr('tabindex', $this.data('origTab'));
}
});
return $elements;
};