问题
I am using a jqgrid where I'd like to use inline editing and mask the entry such that the user is prompted to enter hh:mm where hh = hours and mm = minutes. I'm using the digitalBush masked jquery plugin. The issue is that when I call it from initData, it overwrites the current data in that field. I noticed that this behavior is different when you use a modal form to do the editing. Does anyone have a solution for this issue? I'll call the mask from any event, and I'm happy to use any available plugin. As far as I can tell, the jqgrid formatter does not provide a custom mask that guides the user entry in the format in which I need it. Also happy to be wrong about that (with a snippet of code to support it of course).
Thanks so much in advance.
Update: I managed to cobble together a demo of the problem I'm having. S-O obviously strips out the html that I wanted to wrap this in so that it could be plugged in and run as-is, so you'll need to wrap this in some html to see it work. Thanks again for the assistance. Here's the code:
<title>Mask Problem</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="stylesheet" type="text/css" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/themes/redmond/jquery-ui.css" />
<link rel="stylesheet" type="text/css" href="http://www.ok-soft-gmbh.com/jqGrid/jquery.jqGrid-4.2.0/css/ui.jqgrid.css" />
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script type="text/javascript" src="http://www.ok-soft-gmbh.com/jqGrid/jquery.maskedinput-1.3.min.js"></script>
<script type="text/javascript" src="http://www.ok-soft-gmbh.com/jqGrid/jquery.jqGrid-4.2.0/js/i18n/grid.locale-en.js"></script>
<script type="text/javascript" src="http://www.ok-soft-gmbh.com/jqGrid/jquery.jqGrid-4.2.0/js/jquery.jqGrid.src.js"></script>
<script type="text/javascript">
$.jgrid.no_legacy_api = true;
$.jgrid.useJSON = true;
</script>
<script type="text/javascript">
$(function () {
var lastSel = -1;
var mydata = [
{ HoursWorked: "0:00" },
];
$.mask.definitions['5'] = '[0-5]';
$.mask.definitions['2'] = '[0-2]';
var $grid = $("#MyGrid");
$grid.jqGrid({
datatype: "local",
data: mydata,
height: 'auto',
width: 700,
colNames: ["Hours Worked"],
colModel: [
{ name: "HoursWorked", index: "HoursWorked", width: 85, editable: true, edittype: "text", editoptions: { size: 20, maxlength: 30,
dataInit: function (elem) {
$(elem).mask("29:59");
}
},
align: "center", editrules: { custom: true, custom_func: validHourEntry }
}
],
multiselect: false,
caption: "My sample grid with Mask",
rowNum: 10,
cellEdit: true,
rowList: [5, 10, 20],
pager: '#MyGridpager',
gridview: true,
beforeSelectRow: function (rowid) {
if (rowid !== lastSel) {
$(this).jqGrid('restoreRow', lastSel);
lastSel = rowid;
}
return true;
},
cellsubmit: "clientArray"
}).jqgrid("navGrid", "#MyGrid", { add: false, del: false }); ;
});
function validHourEntry(value, colname) {
var editSuccess = true;
var errorMsg = "";
if (/^([0-1][0-9]|2[0-3]:[0-5][0-9])$/.test(value)) {
return [true, ""];
} else {
return [false, "is wrong time.<br/>Please enter the time in the form <b>hh:mm</b>"];
}
}
</script>
回答1:
You don't posted any code, so I tried to use digitalBush masked jQuery plugin for editing of hours myself. It seems good work and I received
in inline editing or
in the form editing.
I implemented this in the following way. First of all I defined two masks: one to enter digits from 0-2 and the next mask to enter digits from 0-5:
$.mask.definitions['2']='[0-2]';
$.mask.definitions['5']='[0-5]';
and used the following definition of 'time' column in the grid:
{name: 'time', index: 'time', width: 70, editable: true,
editoptions: {dataInit: function (elem) { $(elem).mask("29:59"); }},
editrules: {time: true}}
I added time validation with respect of editrules: {time: true} to prevent to enter the time like 27:20. Becease the standard time validation display not perfect error warning
we can improve the results using custom validation:
{name: 'time', index: 'time', width: 70, editable: true,
editoptions: {dataInit: function (elem) { $(elem).mask("29:59"); }},
editrules: {custom: true, custom_func: function (value) {
if (/^([0-1][0-9]|2[0-3]:[0-5][0-9])$/.test(value)) {
return [true, ""];
} else {
return [false, "is wrong time.<br/>Please enter the time in the form <b>hh:mm</b>"];
}
}}}
which changes the validation error message to the following
I am sure that you can improve the visibility with another customization of the mask plugin and validation. In any way my experiments show that one can do use successfully mask plugin in jqGrid.
You can see the demo here.
UPDATED: Sorry Ron, for writing of that, but the code which you posted is really good example how one should not write the program and how one should not use jqGrid. At the beginning I don't wanted to write any comments, but later I do decided to describe you what is wrong in the code and explain how one should modify the code.
The first problem in your code is that you used object class SampleJSObject instead of direct usage of functions. From the syntax how the constructor and the methods of an object should be defined the code is correct, but ...
- Which sense hast to make some general global settings inside of the object constructor. Yo used
$.mask.definitions['5'] = '[0-5]';for example. Every create of the instance ofSampleJSObjectthe global settings will be set or overwritten. It looks like side effects. - You defined
function SampleJSObjecton the top level of your code and not inside of$(document).readywhere you use it, so you defined global class. - Inside of
$(document).readyyou defined uninitialized variablelastSeland try to initialize it inside offunction SampleJSObjectdefined in another scope. So the variablelastSelstay uninitialized in$(document).ready, but you set another global variablelastSelinside of the constructor. - The methods like
minutesToHourshas nothing to do with your classSampleJSObject. Why the function orcalculateHoursAndMinutesshould be member of the class? It's error in design in my opinion. - The method
initset only thejqgridParmsproperty. You can do it in the same way in the constructor, but in both cases it is not clear for me why one need and method which defines so specific parameters like you do. I don't think that you will be create more then one instance of such specific class. Why one need have such class where you will have to overwrite almost any method to create the second instance of the class? - In the list of parameters of jqGrid you use
datatype: "local", but not usegridview: trueanddataparameter which allows to create the data together with grid. It improve the performance of grid in many times especially for grids with the large number of rows. The usage ofaddRowDatainloadGridin an example of the most slow method. Moreover in the case therowNum: 10will be ignored and no local paging will be done. the method
calculateTotaldemonstrate probably the most slowest implementation of the virtualWeekTotalcolumn. The most effective implementation of the feature would be the usage of custom formatter for theWeekTotalcolumn{ name: "WeekTotal", index: "WeekTotal", width: 55, align: "center" , formatter: function (cellvalue, options, rowObject) { /* here you can access the other columns of the same row just as rowObject.SundayMinutes and return from the function the calculatedWeekTotalvalue as string of HTML fragment */ }}If you nee to use many columns with the same properties you can define the column template (see here):
var myTimeTemplate = {width: 85, editable: true, edittype: "text", editoptions: { size: 20, maxlength: 30, dataInit: function (elem) { $(elem).mask("29:59"); }}and then reduce the definition of the column
SundayMinutesfor example to{name: "SundayMinutes", template: myTimeTemplate }
来源:https://stackoverflow.com/questions/8408104/jqgrid-mask-edit