Reputation: 27921
Free jqgrid first column is Jquery UI autocomplete using custom edit type.
Field is made focusable using focusField: true
$.extend(true,$.jgrid.inlineEdit, {
position: "beforeSelected",
focusField: true,
keys: true } );
If inline editing is started, jqgrid puts focus to autocomplete dropdown button. How to fix this that focus is put to autocomplete input element ?
Autocomplete button is defined with tabindex=-1:
<button type='button' class='btn btn-default btn-form-dropdown' tabindex=-1 aria-label='Open menu'>
<span class='caret'></span></button>
It does not receive focus if tab key is pressed in inline edit.
jqgrid code contains:
getFocusable = function (elem) {
return $(elem).find("input,textarea,select,button,object,*[tabindex]")
.filter(":input:visible:not(:disabled)");
},
So jqgrid puts focus to element even if it contains tabindex=-1
How to fix this ?
Posted also in https://github.com/free-jqgrid/jqGrid/issues/186
Update
Steps to reproduce the issue:
Observed:
Button receives focus
Expected:
input element should receive focus
Code to reproduce:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" type="text/css" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/redmond/jquery-ui.css" />
<link rel="stylesheet" href="http://rawgit.com/free-jqgrid/jqGrid/master/css/ui.jqgrid.css" type="text/css" />
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.js"></script>
<script src="http://rawgit.com/free-jqgrid/jqGrid/master/js/jquery.jqgrid.src.js"></script>
<script>
$(document).ready(function () {
var mydata = [
{ id: 0, Name: "Indiana", Category: "IN" },
{ id: 1, Name: "California", Category: "CA" },
{ id: 2, Name: "Pennsylvania", Category: "PA" },
{ id: 3, Name: "Texas", Category: "TX" }
];
var lastSel;
var grid = $("#list");
grid.jqGrid({
data: mydata,
datatype: 'local',
colModel: [
{
name: 'Name', editable: true, width: 200,
edittype: 'custom',
editoptions: {
custom_element: combobox_element,
custom_value: function (elem) {
return elem.find("input").val();
}
}
},
{ name: 'Category', index: 'Category', width: 50, editable: true }
],
ignoreCase: true,
gridview: true,
viewrecords: true,
rownumbers: true,
pager: '#pager',
editurl: 'clientArray',
ondblClickRow: function (id, ri, ci) {
grid.jqGrid('editRow', id, true, null, null, 'clientArray', {});
},
onSelectRow: function (id) {
if (id && id !== lastSel) {
if (typeof lastSel !== "undefined") {
grid.jqGrid('restoreRow', lastSel);
}
lastSel = id;
}
}
}).
jqGrid("inlineNav", '#pager');
});
var getColumnByName = function (grid, columnName) {
var cm = grid.jqGrid('getGridParam', 'colModel'), i = 0, l = cm.length;
for (; i < l; ++i) {
if (cm[i].name === columnName) {
return cm[i];
}
}
return null;
};
function combobox_element(value, options) {
var elemStr = '<div><input class="FormElement', newel, width;
if (options.id === options.name) {
elemStr += '" size="' +
options.size + '"' + ' id="' + options.id + '"';
}
else {
elemStr += ' form-control jqgrid-inlineedit-autocomplete" ' +
' style="width:' + width + 'px" ' + ' id="' + options.id + '_x"';
}
elemStr += ' value="' + value + '" lookup="' + options.lookup + '"/>';
elemStr += "<button type='button' class='btn btn-default btn-form-dropdown' tabindex=-1 aria-label='Open menu'>" +
"<span class='caret'></span></button>";
elemStr += '</div>';
newel = $(elemStr)[0];
setTimeout(function () {
input_autocomplete(newel);
}, 50);
return newel;
}
function input_autocomplete(newel) {
var input = $("input", newel);
input.autocomplete({
source: ["Indiana",
"California",
"Pennsylvania"
]
}
);
$("button", newel)
.bind({
click: function () {
input.focus();
}
});
}
</script>
</head>
<body>
<table id="list"></table>
<div id="pager"></div>
</body>
</html>
Upvotes: 0
Views: 1472
Reputation: 221997
I'm not sure what you do exactly. Which part of your code place <button type='button' ... tabindex=-1 ...
?
Placing of tabindex=-1
means only that the field should not get focus if the user press Tab or Shift-Tab, but it means that the field should do can be focusable via API call. In other wards, the existence of tabindex
make it focusable, but the negative value of tabindex
informs to exclude the element from sequential focus navigation only. W3 standard formulate it as (see here)
The user agent must set the element's tabindex focus flag, but should not allow the element to be reached using sequential focus navigation.
One should remove tabindex
attribute if one don't want to make the button be focusable.
If you don't create the attribute and it does some control which you use, but you still don't want to set the focus on <button>
, then you can just set the focus on another editable column. You can use focusField: "someColumnName"
or focusField: indexOfSomeColumn
to set the focus on specific column.
UPDATED: I posted the fix which adds the usage of .first()
before call of .focus()
. After the changes the demo which you posted works good.
Upvotes: 1