C++ Builder Tutorials

C++Builder - ClientDataSet, part 4

A database is more efficient if the user can search and filter it.

We added a "Find ID" and a "Find Name" functionality.

Filtering is also very useful. Let's filter on the Name of articles (or part of the Name).
To illustrate this, we changed the structure of the dataset. We added a field "Type", so that we can have articles with the same "Name" but of a different "Type".

Added field: Type

Preparations

  1. If you haven't done so already, create a new folder \CppProjects on your disk.
  2. Create folder XMLDatabase4 "under" \CppProjects.
  3. Download XMLDatabase4.zip and unzip it to folder XMLDatabase4.
  4. Compile and run the application, immediately stop it and next copy Articles.xml from folder XMLDatabase4 to folder XMLDatabase4\Win32\Debug.

Finding an ID or Name

In order to find an article with a certain ID, we added button btnFindID:

void __fastcall TForm1::btnFindIDClick(TObject *Sender)
{
  String ID = edFind->Text;
  ID = Trim(ID.UpperCase());
  edFind->Text = ID;
  cdsArt->IndexFieldNames = "ID";  // order on ID
  if (cdsArt->FindKey(ARRAYOFCONST((ID))))
    ShowStatus("browsing", "ID was found");
  else
    ShowStatus("browsing", "Not found: ID " + ID);
}

For finding an article Name or part thereof, we added button btnFindName:

void __fastcall TForm1::btnFindNameClick(TObject *Sender)
{
  String Name = edFind->Text;
  Name = Trim(Name);
  cdsArt->IndexFieldNames = "Name";  // order on Name
  cdsArt->FindNearest(ARRAYOFCONST((Name)));
  ShowStatus("browsing", "");
}

Filtering

We also added filtering on the article names.

To begin with, at the start of the program we set the FilterOptions, in the OnCreate event of the form:

TFilterOptions FilterOptions;
FilterOptions << foCaseInsensitive;
cdsArt->FilterOptions = FilterOptions;

Filtering is controlled by the checkbox cbFilter.

"Wildcard" filtering is ON by default. Use an asterisk (*) to include variations of a Name in the results.
The OnClick event handler of the checkbox:

void __fastcall TForm1::cbFilterClick(TObject *Sender)
{
  String Filt = Trim(edFind->Text);
  if (cbFilter->Checked) {
    cdsArt->Filter = "Name='" + Filt + "'";
    cdsArt->Filtered = true;
    ShowStatus("browsing", "filter ON");
  }
  else {
    cdsArt->Filtered = false;
    ShowStatus("browsing", "filter OFF");
  }
}

Updating the user interface

When the dataset is being modified, we must disable the searching and the setting of a filter.

Our new function UpdateUI() does this: it disables/enables controls depending on the boolean parameter IsBrowsing.
It also handles the editing panel and the datagrid, thus greatly simplifying the code of the other functions.

void TForm1::UpdateUI(bool IsBrowsing)
{
  DBNavigator1->Enabled = IsBrowsing;
  DBGrid1->Enabled = IsBrowsing;
  panEdit->Visible = ! IsBrowsing;
  if (! IsBrowsing)
    edID->SetFocus();
  btnFindID->Enabled = IsBrowsing;
  btnFindName->Enabled = IsBrowsing;
  cbFilter->Enabled = IsBrowsing;
}