jqGrid a défini le focus sur la cellule sur laquelle l’utilisateur a cliqué ET implémenté datepicker dans IE et Firefox

Excuses si cela a déjà été répondu. Il y a un certain nombre de questions à ce sujet mais je ne peux pas vraiment comprendre ce que je cherche.

J’ai un jqGrid. Un sélecteur de date est attaché à la première cellule (à la volée lorsque la cellule est modifiée, pas dans la définition de grid initiale).

Lorsque je double-clique sur une cellule au milieu de la grid, je souhaite que celle-ci passe en mode d’édition, active la cellule sur laquelle elle a cliqué et ne déclenche pas le sélecteur de date (car je n’y ai pas double-cliqué)

Avec le code ci-dessous, j’ai réalisé ce que je veux dans Firefox . Ceci est basé sur les excellents messages d’Olegs (et d’autres) sur le sujet.

Cependant, dans IE9 , bien que le focus soit défini comme il convient, il déclenche également le sélecteur de date dans la première cellule.

Je comprends que par défaut, jqGrid se déplace automatiquement vers la première cellule, activant ainsi le sélecteur de date s’il existe, que je clique deux fois dessus ou non. Comme solution de contournement, il me faudra peut-être créer une sorte de minuscule cellule factice en premier lieu, mais j’aimerais tout d’abord saisir cette occasion pour en apprendre davantage.

Voici un code abrégé jqGrid, vous reconnaîtrez des morceaux d’Oleg et d’autres publications. Désolé, je ne peux pas vous donner la version exacte de jqGrid pour le moment, il suffit de dire que je l’ai téléchargée début octobre 2012.

Je dirai simplement que je ne comprends pas tout à fait l’ordre des événements en cours. À première vue, il semble que le sélecteur de date est attaché (?) Avant que le champ cliqué ne devienne actif de toute façon.

En passant, cela se trouve dans un projet MVC ASP.Net. Je trouve amusant et ironique que la seule façon d’obtenir un contrôle de grid utile dans MVC / ASP.Net soit de commencer à apprendre le javascript.

$(document).ready( function () { var lastsel; $("#ts").jqGrid({ //============= // Grid Setup url: 'Timesheet/GridData/', datatype: 'json', mtype: 'GET', colNames: ['Date', 'Customer', 'Project', 'Description', 'Hours', '$'], colModel: [ { name: 'tsdate', index: 'tsdate', width: 80, editable: true }, { name: 'Customer', index: 'Customer', width: 250, align: 'left', editable: true, edittype: "select", editoptions: { dataUrl: 'Timesheet/CustomerList'} }, { name: 'Project', index: 'Project', width: 250, align: 'left', editable: true, edittype: "select", editoptions: { dataUrl: 'Timesheet/ProjectList'} }, { name: 'Desc', index: 'Desc', width: 300, align: 'left', editable: true }, { name: 'Hours', index: 'Hours', width: 50, align: 'left', editable: true }, { name: 'Charge', index: 'Charge', edittype: 'checkbox', width: 18, align: 'center', editoptions: { value: "0:1" }, formatter: "checkbox", formatoptions: { disabled: false }, editable: true } ], //============= // Grid Events // when selecting, undo anything else onSelectRow: function (rowid, iRow, iCol, e) { if (rowid && rowid !== lastsel) { $('#ts').jqGrid('restoreRow', lastsel); lastsel = rowid; } }, // double click to edit ondblClickRow: function (rowid, iRow, iCol, e) { // Go into edit mode (automatically moves focus to first field) $('#ts').jqGrid('editRow', rowid, true, onGridEdit); // Now set focus on selected field if (!e) e = window.event; // get browser independent object var element = e.target || e.srcElement $("input, select", element).focus(); }, postData: { startDate: function () { return $('#startDate').val(); } } }); // END jQuery("#ts").jqGrid // This is called when the row is double clicked function onGridEdit(RowID) { // onGridEdit is attached as the 'edit function' in the call to .jqGrid('editRow' above // Attach the datepicker to the tsdate field. For some reason this needs to be in the edit function // And does not work in IE 9. In IE9 it fires the datepicker. In Firefox it only fires when the field // gets the focus $("#" + RowID + "_tsdate").datepicker({ dateFormat: 'yy-mm-dd' }); } }); // END $(document).ready 

SOLUTION Lors de la comparaison du débogage entre Firefox et IE9, il est apparu que les événements firefox se déroulaient de manière séquentielle, contrairement à ceux de IE9.

Quoi qu’il en soit, la solution finale suggérée par Oleg consistait à envelopper la fonction oneditfunc dans une fonction setTimeout:

  ondblClickRow: function (rowid, iRow, iCol, e) { if (!e) e = window.event; //evt evaluates to window.event or inexplicit e object, depending on which one is defined var element = e.target || e.srcElement // Go into edit mode (automatically moves focus to first field) $(this).jqGrid( 'editRow', rowid, { keys: true, oneditfunc: function (rowId) { setTimeout(function () { $("input, select", element).focus(); $("#" + rowId + "_tsdate").datepicker({ dateFormat: 'yy-mm-dd' }); }, 50); } } ); // end jqGrid call }, // end ondblClickRow event handler 

Je suppose que le problème de focus peut être résolu en déplaçant l’appel de jQuery.focus intérieur du rappel oneditfunc . Si vous voulez implémenter le rappel en tant que fonction anonyme (au lieu de onGridEdit ), l’implémentation sera la plus simple:

 ondblClickRow: function (rowid, iRow, iCol, e) { if (!e) e = window.event; // get browser independent object var element = e.target || e.srcElement; // Go into edit mode (automatically moves focus to first field) $(this).jqGrid('editRow', rowid, { keys: true, oneditfunc: function (rowId) { $("input, select", element).focus(); // Now set focus on selected field $("#" + rowId + "_tsdate").datepicker({ dateFormat: 'yy-mm-dd' }); } }); } 

Comment vous pouvez voir que j’ai utilisé en plus $(this) au lieu de $('#ts') dans les fonctions de rappel. Cela rend le code facile à maintenir et un peu rapide. Les mêmes modifications que vous pouvez effectuer dans tous les rappels jqGrid (par exemple, dans onSelectRow ). De plus, je préfère utiliser le style d’object de l’appel à editRow . Cela rend le code plus lisible à mon avis car on utilise des parameters nommés.