Cry about...
Delphi Programming with TWebBrowser
How to read and write form elements
This page provides notes on how to read from and write to forms that are displayed in a web page in a TWebBrowser.
Contents:
- Get the number of forms on a page
- Get a form by number
- Get the name of a form
- Get a form by name
- List the names of all the fields on a form
- Get the value of a named field
- Set the value of a named field
- Submit the form
- Other examples
The examples on this page assume that the page has been loaded into a TWebBrowser called WebBrowser.
Get the number of forms on a page
function NumberOfForms(document: IHTMLDocument2): integer; var forms: IHTMLElementCollection; begin forms := document.Forms as IHTMLElementCollection; result := forms.Length; end;
and to call it:
procedure TMyForm.Button1Click(Sender: TObject); var nForms: integer; begin nForms := NumberOfForms(WebBrowser.Document as IHTMLDocument2); ShowMessage('Form count: ' + IntToStr(nForms)); end;
Get a form by number
Pages can have more than one form on them. The following function will return an instance of a form by number - where the first form is numbered 0, the next 1 and so on:
function GetFormByNumber(document: IHTMLDocument2; formNumber: integer): IHTMLFormElement; var forms: IHTMLElementCollection; begin forms := document.Forms as IHTMLElementCollection; if formNumber < forms.Length then result := forms.Item(formNumber,'') as IHTMLFormElement else result := nil; end;
For an example of this function in use see "Get the name of a form" (below).
Get the name of a form
It should be appreciated that HTML does not require forms to be named.
var firstForm: IHTMLFormElement; document: IHTMLDocument2; begin document := WebBrowser.Document as IHTMLDocument2; firstForm := GetFormByNumber(document,0); if Assigned(firstForm) then ShowMessage('Name of first form is ' + firstForm.Name) else ShowMessage('This page does not contain any forms');
Get a form by name
Since forms can be named, if you know the name of a form it may be preferable to access the form by name rather than by number.
function GetFormByName(document: IHTMLDocument2; const formName: string): IHTMLFormElement; var forms: IHTMLElementCollection; begin forms := document.Forms as IHTMLElementCollection; result := forms.Item(formName,'') as IHTMLFormElement end;
This function will return nil if there is no form with the required name.
List the names of all the fields on a form
function GetFormFieldNames(fromForm: IHTMLFormElement): TStringList; var index: integer; field: IHTMLElement; input: IHTMLInputElement; select: IHTMLSelectElement; text: IHTMLTextAreaElement; begin result := TStringList.Create; for index := 0 to fromForm.length do begin field := fromForm.Item(index,'') as IHTMLElement; if Assigned(field) then begin if field.tagName = 'INPUT' then begin // Input field. input := field as IHTMLInputElement; result.Add(input.name); end else if field.tagName = 'SELECT' then begin // Select field. select := field as IHTMLSelectElement; result.Add(select.name); end else if field.tagName = 'TEXTAREA' then begin // TextArea field. text := field as IHTMLTextAreaElement; result.Add(text.name); end; end; end; end;
and to call it:
procedure TMyForm.Button1Click(Sender: TObject); var document: IHTMLDocument2; theForm: IHTMLFormElement; index: integer; fields: TStringList; begin document := TWebBrowser.Document as IHTMLDocument2; theForm := GetFormByNumber(WebBrowser.Document as IHTMLDocument2,0); fields := GetFormFieldNames(theForm); for index := 0 to fields.count-1 do ShowMessage('Field ' + IntToStr(index) + ' called ' + fields[index]); end;
Get the value of a named field
To get the value of a named field from a form:
function GetFieldValue(fromForm: IHTMLFormElement; const fieldName: string): string; var field: IHTMLElement; inputField: IHTMLInputElement; selectField: IHTMLSelectElement; textField: IHTMLTextAreaElement; begin field := fromForm.Item(fieldName,'') as IHTMLElement; if not Assigned(field) then result := '' else if field.tagName = 'INPUT' then begin inputField := field as IHTMLInputElement; if (inputField.type_ <> 'radio') and (inputField.type_ <> 'checkbox') then result := inputField.value else if inputField.checked then result := 'checked' else result := 'unchecked'; end else if field.tagName = 'SELECT' then begin selectField := field as IHTMLSelectElement; result := selectField.value end else if field.tagName = 'TEXTAREA' then begin textField := field as IHTMLTextAreaElement; result := textField.value; end; end;
and to call it:
procedure TMyForm.Button1Click(Sender: TObject);
var
document: IHTMLDocument2;
theForm: IHTMLFormElement;
index: integer;
begin
document := TWebBrowser.Document as IHTMLDocument2;
theForm := GetFormByNumber(WebBrowser.Document as IHTMLDocument2,0);
ShowMessage('Field "name" has value ' + GetFieldValue(theForm,'name'));
The "GetFieldValue" function is long because it tests to determine the type of field before extracting the value. If you are sure about the type of field (i.e. radio button, check box, text box etc, then you can shorted this function considerably.
For example, if you are absolutely sure that the field is an input field (i.e. in the HTML it is defined using the <input ...> tag) then you could simply use:
function GetInputField(fromForm: IHTMLFormElement;
const inputName: string;
const instance: integer=0): HTMLInputElement;
var
field: IHTMLElement;
begin
field := fromForm.Item(inputName,instance) as IHTMLElement;
if Assigned(field) then
begin
if field.tagName = 'INPUT' then
begin
result := field as HTMLInputElement;
exit;
end;
end;
result := nil;
end;
Calling it in the same way as you would GetFieldValue
(above).
Set the value of a named field
To set the value of a field:
procedure SetFieldValue(theForm: IHTMLFormElement; const fieldName: string; const newValue: string; const instance: integer=0); var field: IHTMLElement; inputField: IHTMLInputElement; selectField: IHTMLSelectElement; textField: IHTMLTextAreaElement; begin field := theForm.Item(fieldName,instance) as IHTMLElement; if Assigned(field) then begin if field.tagName = 'INPUT' then begin inputField := field as IHTMLInputElement; if (inputField.type_ <> 'radio') and (inputField.type_ <> 'checkbox') then inputField.value := newValue else inputField.checked := (newValue = 'checked'); end else if field.tagName = 'SELECT' then begin selectField := field as IHTMLSelectElement; selectField.value := newValue; end else if field.tagName = 'TEXTAREA' then begin textField := field as IHTMLTextAreaElement; textField.value := newValue; end; end; end;
and to call it:
procedure TMyForm.Button1Click(Sender: TObject);
var
document: IHTMLDocument2;
theForm: IHTMLFormElement;
index: integer;
begin
document := TWebBrowser.Document as IHTMLDocument2;
theForm := GetFormByNumber(WebBrowser.Document as IHTMLDocument2,0);
SetFieldValue(theForm,'name','Brian Cryer');
Submit the form
The above functions demonstrate how to read values from a form and how to set values in the form. The only thing remaining is how to submit a form. This is simply:
theForm.submit;
for example:
procedure TMyForm.Button1Click(Sender: TObject); var document: IHTMLDocument2; theForm: IHTMLFormElement; index: integer; begin document := TWebBrowser.Document as IHTMLDocument2; theForm := GetFormByNumber(document,0); SetFieldValue(theForm,'name','Brian Cryer'); theForm.submit;
Note: Be aware that there are cases where this will not achieve the expected effect. This is because some forms are not actually submitted, but the action is either performed in response to JavaScript on a button or by the "onsubmit" handler of the form.
Other examples
Other examples of reading and writing form elements can be found on the following pages:
- Example reading and setting a radio button on a web page in a TWebBrowser
- Example reading and setting a checkbox on a web page in a TWebBrowser
These notes are believed to be correct for Delphi 6 and Delphi 7, and may apply to other versions as well.
About the author: Brian Cryer is a dedicated software developer and webmaster. For his day job he develops websites and desktop applications as well as providing IT services. He moonlights as a technical author and consultant.