Bill
Bill

Reputation: 3033

How To Insert a Link in a HTML Document At Runtime?

After a lot of searching for createElement and insertAdjacentHTML on the web I came up with this code. When the code is executed the link is not inserted into the HTML. The link is a to a local file. What am I doing wrong?

var
  HTMLDocument2Ifc: IHTMLDocument2;
  iLinkString: string;
  iTopicString: string;
  iLink: IHTMLElement;
begin
  FormInsertLink := TFormInsertLink.Create( Self );
  try
    if FormInsertLink.ShowModal = mrOk then
    begin
      // <A HREF="file://..\html\author.htm">Author</A>
      HTMLDocument2Ifc := TopicWebBrowser1.Document as IHTMLDocument2;
      iLinkString := FormInsertLink.EditLink1.Text; // file://..\html\author.htm
      iTopicString := FormInsertLink.EditTopic1.Text; // Author
      iLink := HTMLDocument2Ifc.createElement('a');
      iLink.InnerText := iLinkString;
      iLink.insertAdjacentHTML('afterEnd', '<A HREF="' + iLinkString + '">' + iTopicString + '</A>');
    end;
  finally
    FormInsertLink.Free;
  end;

Upvotes: 0

Views: 3147

Answers (1)

Remy Lebeau
Remy Lebeau

Reputation: 595961

You are not actually adding the new link to the DOM tree, that is why it does not appear in the HTML document. You are calling insertAdjacentHTML() on the new IHTMLElement when you need to call it on another IHTMLElement that is already present in the document instead, eg:

var 
  iDoc: IHTMLDocument2; 
  iElement: IHTMLElement; 
begin 
  FormInsertLink := TFormInsertLink.Create( Self ); 
  try 
    if FormInsertLink.ShowModal = mrOk then 
    begin 
      iDoc := TopicWebBrowser1.Document as IHTMLDocument2; 
      iElement := iDoc.all('some existing element'); 
      iElement.insertAdjacentHTML('afterEnd', '<A HREF="' + FormInsertLink.EditLink1.Text + '">' + FormInsertLink.EditTopic1.Text + '</A>'); 
    end; 
  finally 
    FormInsertLink.Free; 
  end; 

Or, use the appendChild() method instead:

var 
  iDoc: IHTMLDocument2; 
  iLink: IHTMLAnchorElement; 
begin 
  FormInsertLink := TFormInsertLink.Create( Self ); 
  try 
    if FormInsertLink.ShowModal = mrOk then 
    begin 
      iDoc := TopicWebBrowser1.Document as IHTMLDocument2; 
      iLink := iDoc.createElement('A') as IHTMLAnchorElement; 
      iLink.href := FormInsertLink.EditLink1.Text;
      (iLink as IHTMLElement).innerText := FormInsertLink.EditTopic1.Text;
      (iDoc.body as IHTMLDOMNode).appendChild(iLink as IHTMLDOMNode); 
    end; 
  finally 
    FormInsertLink.Free; 
  end; 

Update: to wrap selected text with an <a> tag:

var 
  iDoc: IHTMLDocument2; 
  iSelection: IHTMLSelectionObject;
  iRange: IHTMLTxtRange;
begin 
  FormInsertLink := TFormInsertLink.Create( Self ); 
  try 
    if FormInsertLink.ShowModal = mrOk then 
    begin 
      iDoc := TopicWebBrowser1.Document as IHTMLDocument2; 
      iSelection := iDoc.selection as IHTMLSelectionObject;
      iRange := iSelection.createRange() as IHTMLTxtRange; 
      iRange.pasteHTML('<a href="' + FormInsertLink.EditLink1.Text + '">' + FormInsertLink.EditTopic1.Text + '</a>');
      // or:
      // iRange.pasteHTML('<a href="' + FormInsertLink.EditLink1.Text + '">' + iRange.text + '</a>');
    end; 
  finally 
    FormInsertLink.Free; 
  end; 

Update: to change selected text into an <a> tag using IHTMLDocument2.execCommand():

FormInsertLink := TFormInsertLink.Create( Self ); 
try 
  if FormInsertLink.ShowModal = mrOk then 
  begin 
    (TopicWebBrowser1.Document as IHTMLDocument2).execCommand('CreateLink', False, FormInsertLink.EditLink1.Text);
  end; 
finally 
  FormInsertLink.Free; 
end; 

Upvotes: 8

Related Questions