Calling fnFilter on blur/change events swallows tbody clicks
Calling fnFilter on blur/change events swallows tbody clicks
twadzilla
Posts: 5Questions: 0Answers: 0
The following code illustrates an issue when invoking fnFilter upon blur or change events. When the user focuses in the search textbox, then either clicks any of the links or inputs in the tbody, there should appear an alert stating 'clicked'. However most browsers behave as if there was no click event--it simply gets swallowed. Subsequent clicks on the same element or clicks on the links labeled "thead" or "outside" behave as expected.
Note that this behavior occurs regardless of how the click handler is attached--using bind, delegate, or the onclick/href attributes, whether on the search box provided by DataTables or externally defined text input.
This issue is reproduceable in IE 9.0.8112.16421, Chrome 18.0.1025.39 (beta), Safari 5.1.2 on Windows 7 x64. Firefox 10.0.2 does not seem to be affected by this issue.
[code]
thead
tbody
button
checkbox
radio
outside
$(document).ready(function () {
var oTable = $('table').dataTable({
'sDom': 'ft',
'bSort': false
});
$('body').delegate('.click', 'click', function () {
alert(this.id + ': clicked');
return false;
});
$('body').delegate('input[type="text"]', 'blur', function () {
oTable.fnFilter('');
});
});
[/code]
Note that this behavior occurs regardless of how the click handler is attached--using bind, delegate, or the onclick/href attributes, whether on the search box provided by DataTables or externally defined text input.
This issue is reproduceable in IE 9.0.8112.16421, Chrome 18.0.1025.39 (beta), Safari 5.1.2 on Windows 7 x64. Firefox 10.0.2 does not seem to be affected by this issue.
[code]
thead
tbody
button
checkbox
radio
outside
$(document).ready(function () {
var oTable = $('table').dataTable({
'sDom': 'ft',
'bSort': false
});
$('body').delegate('.click', 'click', function () {
alert(this.id + ': clicked');
return false;
});
$('body').delegate('input[type="text"]', 'blur', function () {
oTable.fnFilter('');
});
});
[/code]
This discussion has been closed.
Replies
[code]
then click here
[/code]
In Firefox the above code produces the 'clicked' dialog every time, while in other browsers, the initial click event gets swallowed. Apparently browsers react differently when an element that has a pending event is moved around in the DOM.
Attaching a click handler to rows is a common scenario (see http://www.datatables.net/release-datatables/examples/api/row_details.html) and adding a call to fnFilter on the blur/change event reliably handles the case where the user invokes cut/paste using the mouse or menu.
However since DataTables uses the appendChild/removeChild methods on the table rows in _fnDraw (lines 1414-1437), adding a call to fnFilter upon blur/change combined with a click handler on the table rows seems to trigger this issue.
As a workaround one can bind to the 'cut' and 'paste' events and utilize setTimeout to access the current input value, e.g.
[code]
function applyFilter() {
oTable.fnFilter($('input[type="text"]').val());
}
$('input[type="text"]').bind('keyup cut paste', function (ev) {
if (ev.type == 'keyup') {
applyFilter();
} else {
setTimeout(applyFilter,0);
}
});
[/code]
Perhaps in the future the 'input' event (http://www.w3.org/TR/DOM-Level-3-Events/#event-type-textinput) should solve this case, but at present compatibility is limited to WebKit: http://quirksmode.org/dom/events/keys.html#t010
Allan
Also, is there a reason why the filter input provided by DataTables doesn't listen by default for cut/paste events invoked by a mouse or menu command?
It uses a 'keyup' event to watch for text changes - hence a paste by a mouse will be missed. I'm not 100% sure how to capture that to be honest. Possibly mouse up. I'll experiment a bit.
Regarding the events issue - might you be able to put a working example together using the live site: http://live.datatables.net ?
Thanks,
Allan
http://live.datatables.net/ixadeg/4/
This attaches a 'click' handler on table cells and a 'change' handler on the filter input that invokes fnFilter to address precisely the case where the filter has been updated by cut/paste operations from mouse or menu actions, as opposed to keypresses. As you can see, once the filter is changed (by keypress or otherwise) and a table cell is directly clicked, the click handler is not fired in most browsers (Firefox and possibly Opera being the only exceptions).
Generally speaking, the 'cut' and 'paste' events are not reliable for determining the current filter value since they are triggered before the input element's value is updated. The workaround suggested above involving setTimeout seems to reliably handle this case in all browsers.
Allan