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:
The examples on this page assume that the page has been loaded into a
TWebBrowser called WebBrowser.
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;
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).
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');
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.
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;
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;
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;
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');
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:
These notes are believed to be correct for Delphi 6
and Delphi 7, and
may apply to other versions as well.
|