Search code examples
delphicomboboxforeign-keysdelphi-5

How can I use a DBLookupComboBox to select a foreign key value without immediately changing the target table? (Delphi 5 Pro)


Basic Scenario:

  1. User clicks 'edit item'
  2. Edit dialog opens
  3. A combobox 'item type' should be populated with items form a table 'item_type'. The combobox should display 'item_type.name', but also know about 'item_type.id'
  4. User edits other item stuff and selects an item type, then clicks ok
  5. My program does some input validation
  6. if everything is ok, get the 'item_type.id' from the selected combo item and save it to the foreign key column of the item table ('item.fk_item_type').

If I understand this component correctly, I should set DataSource to point to the destination table 'item' and DataField to 'item.fk_item_type'. But that would immediately edit my item table before I get a chance the validate all the other input.

It feels like I am missing something here. Somewhere I read that I need to use a classic ComboBox and fill it manually. But then I don't understand how to get to the id of the selected item.

Thank you for any pointers.

Edit: I am starting to suspect that maybe I am missing a fundamental thing. All these DB* components, do they load values from that database automatically, but I have to call Post() myself? Meaning they do not automatically change values in the database?


Solution

  • If I understand you correctly, you want to use a DBLookupComboBox. You have to supply values for the following properties

    • datasource - linked to the table which you are editing, presumably 'items'
    • datafield - the name of the field in the table which you are editing, presumably 'item_type'
    • listsource - linked to the table which populated the combobox, presumably 'item_types'
    • list field - the name of the field from 'item_types' which you want to display, presumably 'name'
    • key field - the name of the field from 'item_types' which will be inserted into the items record, presumably 'item_type'

    The table which populated the combobox is never edited.

    You can validate the values before posting the new/edited 'items' record.

    I can show you how to use a non-data aware combobox if necessary, but it's easier to use the data aware version.

    Regarding validation, I use the following code template in edit dialogs.

    Function TEditQuestion.Execute (n: longint): boolean;
    var
     gen: longint;
    
    begin
     sdsEditQuestion.params[0].asinteger:= n;  // TSQLDataSet
     with qEditQuestion do                     // TClientDataSet
      begin
       open;
       if n = -1 then                          // new record
        begin
         caption:= 'New record';
         insert;
         fieldbyname ('alive').asinteger:= 1;
         // initialise necessary fields in the dataset
        end
       else caption:= 'Editing record ' + inttostr (n);
    
       edit;
       if showmodal = mrOK then
        begin
         // validation code comes here. Set 'result' to true if everything is ok
         if result then
          begin
           if n = -1 then
            begin
             with qGenID do
              begin
               open;
               gen:= fields[0].asinteger;    // get new value from generator
               close
              end;
    
             FieldByName ('id').asinteger:= gen;
            end;
           post;
           applyupdates (0)
          end
         else cancel  // showmodal = OK, result = false
       else           // showmodal cancelled
        begin
         cancel;
         result:= false
        end;
      end             // with qEditQuestion
     end;