View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0004606 | JEDI VCL | 00 JVCL Components | public | 2008-11-26 08:13 | 2011-06-09 22:02 |
Reporter | cguser | Assigned To | jfudickar | ||
Priority | normal | Severity | minor | Reproducibility | always |
Status | resolved | Resolution | fixed | ||
Product Version | 3.33 | ||||
Target Version | Fixed in Version | ||||
Summary | 0004606: JvDBSearchEdit user input validation | ||||
Description | If JvDBSearchEdit.DataField is connected to TIntegerField, on change it will trigger a "DataSet.Locate(..." passing whatever the user typed in. If the user types any text instead of a valid integer (TIntegerField), locate will give an error. Code at "fault": procedure TJvDBCustomSearchEdit.CMChanged(var Msg: TMessage); ... if DataSet.Locate(FieldName, Text, FSearchOptions) then A quick and dirty fix was to encapsulate the call on a try/except block, but it lacks in... elegance, to put it mildly. procedure TJvDBCustomSearchEdit.CMChanged(var Msg: TMessage); ... try begin if DataSet.Locate(FieldName, Text, FSearchOptions) then begin LText := Text; Text := DataSet.FieldByName(DataField).AsString; SelStart := Length(LText); SelLength := Length(Text) - SelStart; end; end; except end; Would be way better to auto mask the editor on setting DataField, or (if too tricky) at least have the option to set an Edit Mask manually. I don't think this is strictly a bug in itself, but it would be quite helpful to not have to *manually* fiddle in what the user can type in or not. To expose the relevance of this a little better, JvDBSearchEdit.DataField may (and does in my situation) point to any TField type (like TFloatField or TDateTimeField and not only TStringField) in a dynamic grid where the search field can be set to whatever field the user choose. As mentioned, DataSet Locate will "crash" with invalid data to find. It just occurred to me that maybe there is some generic input mask/validator in Jedi that can be plugged into JvDBSearchEdit? Just a thought. Thank you. cg | ||||
Tags | No tags attached. | ||||
|
Please provide the zipped sources of an autonomous sample application showing this. |
|
Sorry for the late reply (still on vacations till next week). Anyway, I cooked some code to show this (call it from anywhere like the OnClick of a TButton): TClientDataSet *cds = new TClientDataSet(this); TField *i = new TIntegerField(cds); i->FieldName = "Field1"; i->DataSet = cds; i->FieldKind = fkData; cds->CreateDataSet(); cds->Open(); for (int j=0;j<10;++j) // Some dummy records... cds->AppendRecord(ARRAYOFCONST((j))); TDataSource *ds = new TDataSource(this); ds->DataSet = cds; TJvDBSearchEdit *search = new TJvDBSearchEdit(this); search->Parent = this; search->DataSource = ds; search->DataField = "Field1"; // Type say "abc"... and it should crash on DataSet.Locate // inside of TJvDBCustomSearchEdit.CMChanged message handler Please advise if the provided sample is insufficient. As mentioned, I'm not sure if it's a bug by itself, maybe it's more of a shortcoming of the expected functionality. Of course we can't pass a generic string to the Locate function of a DataSet *if* that field happens to be of an integer type. On normal coding I would force the user to type only integers with a mask on the edit, or, do a StrToIntDef() on the user input before calling Locate. Now, with TJvDBSearchEdit how can we handle it (generic user input)? The quick fix that I've used was just to patch the source and wrap the Locate call inside a try/catch block. It works... basically "ignores" invalid inputs from the user. Hardly a proper patch, but surely a pretty easy it is. |
|
No worries for the late reply, but I really want the sources with the associated database, so that I can test in the same conditions as you did. |
|
Ok, as soon as I'm back in the office (next Wednesday) I shall attach a sample. Nevertheless, it will be exactly the following steps: 1) Make a new C++ VCL Application 2) put the code that I pasted above on the form constructor 3) ... that's it! there is no third step. Just press F9 and type an "a", it should crash as mentioned. The code above was tested and it works. There is no need for any other database. TJvDBSearchEdit is connected into a dataset with a single integer field. Should I add Project1.cbproj or just Form1.cpp/Form1.dfm/Form1.h? |
|
Add everything, except the compiled files, please. |
2009-01-07 03:09
|
Project1.7z (3,554 bytes) |
|
Project has been attached. |
|
Every time I download a new version from the svn I need to remember to fix this as above (just encapsulate the Locate call within a try/catch): procedure TJvDBCustomSearchEdit.CMChanged(var Msg: TMessage); ... try begin if DataSet.Locate(FieldName, Text, FSearchOptions) then begin LText := Text; Text := DataSet.FieldByName(DataField).AsString; SelStart := Length(LText); SelLength := Length(Text) - SelStart; end; end; except end; would it be possible to have this commited, as anything fancier would be too much time consuming? |
|
I've added a property RaiseLocateException. Deactivate it and you got your wanted behaviour. |
Date Modified | Username | Field | Change |
---|---|---|---|
2008-11-26 08:13 | cguser | New Issue | |
2008-12-22 05:59 | obones | Note Added: 0015159 | |
2008-12-22 05:59 | obones | Status | new => feedback |
2008-12-29 08:51 | cguser | Note Added: 0015189 | |
2008-12-30 02:39 | obones | Note Added: 0015196 | |
2009-01-02 15:53 | cguser | Note Added: 0015202 | |
2009-01-05 00:51 | obones | Note Added: 0015208 | |
2009-01-07 03:09 | cguser | File Added: Project1.7z | |
2009-01-07 03:11 | cguser | Note Added: 0015215 | |
2009-07-06 14:05 | obones | Status | feedback => acknowledged |
2011-06-08 18:19 | cguser | Note Added: 0018701 | |
2011-06-09 22:02 | jfudickar | Note Added: 0018713 | |
2011-06-09 22:02 | jfudickar | Status | acknowledged => resolved |
2011-06-09 22:02 | jfudickar | Resolution | open => fixed |
2011-06-09 22:02 | jfudickar | Assigned To | => jfudickar |