title: How to get elements by name in Delphi Chromium Embedded?
body: <p>To get a particular DOM node embedded in the current web document from a TChromium instance, using its ID, you use ICefDomDocument.getElementById().  But how do you find elements by the NAME attribute?  Javascript has the document.getElementsByName() method and TWebBrowser (that wraps IE) has a similar call, but I can't figure out how to do this with TChromium.  I need to find some DOM elements that have NAME attributes but no ID attributes.  I searched the <em>ceflib</em> unit and did not see anything that would do it.</p>
  
  <p>Side question.  If anyone has a link to a TChromium "recipes" style site or document I could use it.</p>
  
  <p>UPDATE: While waiting for an answer I have come up with the following code for doing getElementsbyName().  I'd like something faster than scanning the entire DOM tree.  If you see something wrong in the code let me know:</p>
  
  <pre><code>type
      TDynamicCefDomNodeArray = array of ICefDomNode;
  
  
  // Given a Chromium document interface reference and a NAME attribute to search for,
  //  return an array of all DOM nodes whose NAME attribute matches the desired.
  function getElementsByName(ADocument: ICefDomDocument; theName: string): TDynamicCefDomNodeArray;
  
      // Get all the elements with a particular NAME attribute value and return
      //  an array of them.
      procedure getElementsByName1(intfParentNode: ICefDomNode; theName: string; var aryResults: TDynamicCefDomNodeArray);
      var
          oldLen: integer;
          intfChildNode: ICefDomNode;
          theNameAttr: string;
      begin
          Result := nil;
          intfChildNode := nil;
  
          if Assigned(intfParentNode) then
          begin
              // Attributes are case insensitive.
              theNameAttr := intfParentNode.GetElementAttribute('name');
  
              if AnsiSameText(theNameAttr, theName) then
              begin
                  // Name attribute match.  Add it to the results array.
                  oldLen := Length(aryResults);
                  SetLength(aryResults, oldLen + 1);
                  aryResults[oldLen] := intfParentNode;
              end; // if AnsiSameText(intfParentNode.Name, theName) then
  
              // Does the parent node have children?
              if intfParentNode.HasChildren then
              begin
                  intfChildNode := intfParentNode.FirstChild;
  
                  // Scan them.
                  while Assigned(intfChildNode) do
                  begin
                      getElementsByName1(intfChildNode, theName, aryResults);
  
                      if Assigned(intfChildNode) then
                          intfChildNode := intfChildNode.NextSibling;
                  end;
              end; // if intfParentNode.HasChildren then
          end; // if Assigned(intfParentNode) then
      end;
  
      // ---------------------------------------------------------------
  
  var
      intfCefDomNode: ICefDomNode;
  begin
      intfCefDomNode := nil;
      Result := nil;
  
      if Assigned(ADocument) then
      begin
          // Check the header.
          intfCefDomNode := ADocument.Document;
  
          if Assigned(intfCefDomNode) then
          begin
              // Check the parent.
              getElementsByName1(intfCefDomNode, theName, Result);
          end; // if Assigned(intfCefDomNode) then
      end; // if Assigned(ADocoument) then
  end;
  
  // ---------------------------------------------------------------
  </code></pre>