Results 1 to 15 of 15
  1. #1
    journeyman is offline Advanced Beginner
    Windows 11 Access 2016
    Join Date
    Dec 2022
    Posts
    85

    Inserting elements in Webbrowser control

    HI All,



    This post is a continuation from https://www.accessforums.net/showthread.php?t=88493 (ifd you need to know the history)

    I am attempting to insert a table at the cursor point in a webbrowser control.
    I am using the ActiveX webbrowser control.

    I have tried:

    Code:
    Me.WBControl.object.document.execCommand "insertHTML", False, "<Table>...</Table>"
    .execommand seems to work to allow most things, but inserting tables is not one of it's elements. So I tried insertHTML.

    However, insertHTML seems not to be supported. Following from this, I tried "InsertText", which also does not work.


    I tried using this:
    Code:
    Me.WBrowser.Object.Document.Writeln "<Table>....</Table>"
    But, using Write or Writeln seems only to clear the entire HTML code block and insert the required table on its own... or on occasion seems to insert the table at the bottom.

    One more attempt I tried:

    Code:
    Me.WBrowser.Object.Document.body.innerHTML = "<Table>....</Table>"
    Did the same as Write or Writeln. deleted the entire body and refused to behave.

    Searching around Google leads me on all kindsa wild pathways, which demonstrates it is possible to do... but, ah the how exactly. comes to a point where you just gotta ask.

    Bonus question: How can I inserttext at the cursor point also. might be nice to have a feature that auto inserts a paragraph.

  2. #2
    Edgar is offline Competent Performer
    Windows 8 Access 2016
    Join Date
    Dec 2022
    Posts
    306
    Working with the web browser control looks like this:


    First declare a web browser variable that lets you access the events of the browser object itself and its document property.
    Public WithEvents wbc As WebBrowser
    Public doc As Object


    Now, set the source of your browser control in the Load event of your form like
    Me.MyBrowserControl.ControlSource = """=""&"about:blank"
    Or the page you need to load.


    Then, initialize it with the Load event of your form:
    Set wbc = Me.MyBrowserControl.Object


    Now that you have the browser, you can also set its doc like:
    Set doc = wbc.Document

    So, now that the first thing that loads is a blank page, you can use the document complete event and set something like:
    doc.Open
    doc.Write "Hey there"
    doc.Close

    But if you want more control, you can use this syntax:
    Dim tbl As Object
    Set tbl = doc.createElement("Table")
    doc.appendChild tbl

    Same for the tr, td, th elements, and any other html element. Post something to play with and we'll see.

  3. #3
    isladogs's Avatar
    isladogs is offline MVP / VIP
    Windows 10 Office 365
    Join Date
    Jan 2014
    Location
    Somerset, UK
    Posts
    6,127
    Looks like you've discovered many of the issues that I experienced many years ago
    At that time, I used a work-round as follows

    Code:
    Private Sub cmdTable_Click()
    
        'Next line not supported
        'Me.WBrowser.Object.Document.execCommand "InsertTable", True, Null
    
        'This inserts a table at end of existing code!
        Dim msg, Style, Title, Response, MyString
           
        msg = "This inserts a 2x2 table at the end of the HTML message.  " & vbNewLine & _
        "This can be moved later by dragging & dropping" & vbNewLine & vbNewLine & _
        "Are you sure you want to create a table?    "
            
            Style = vbYesNo + vbInformation + vbDefaultButton2  ' Define buttons.
            Title = "WARNING"    ' Define title.
            Response = MsgBox(msg, Style, Title)
    
    
            'If user chooses No, return to selection box.
            If Response = vbNo Then Exit Sub
    
    
            'If user chooses Yes, insert table
            
        'first copy all existing HTML code to clipboard
        Me.WBrowser.Object.Document.execCommand "SelectAll", False, Null
        Me.WBrowser.Object.Document.execCommand "Copy", False, True
        
        'Add the 2x2 table
        With Me.WBrowser.Document
        .writeln "<table>"
        .writeln "<tr><td>Table Cell A1</td>"
        .writeln "<td>Table Cell B1</td>"
        .writeln "</tr>"
        .writeln "<tr><td>Table Cell A2</td>"
        .writeln "<td>Table Cell B2</td>"
        .writeln "</tr>"
        .writeln "</table>"
        End With
        
        'paste the original code from the clipboard
        Me.WBrowser.Object.Document.execCommand "Paste", False, True
    
    
    End Sub
    Hopefully it can be improved upon . . .
    Colin Riddington, Access MVP, Website, email
    The more I learn, the more I know I don't know. When I know I don't know, I keep quiet!

  4. #4
    journeyman is offline Advanced Beginner
    Windows 11 Access 2016
    Join Date
    Dec 2022
    Posts
    85
    Hey guys

    Thanks so much for your fast response.

    Edgar


    Code:
    Public WithEvents wbc As WebBrowser
    Public doc As Object
    Sub Form_Load
        Me.MyBrowserControl.ControlSource = """=""&"about:blank"
    End sub
    Setting the ControlSource like this presented an error, and would not work. I tried Me.MyBrowserControl.Object.Navigate "about:blank" instead. Not sure how this will affect things later, but seems to work for most everything I need so far, except tables.


    Code:
    Sub Button_Click()
        Set wbc = Me.MyBrowserControl.Object
        Set doc = wbc.Document
        Dim tbl As Object
        Set tbl = doc.createElement("Table")
        doc.appendChild tbl
    End sub
    I put this into a click event but got nothing. No error, no result, no code block. Nadda.

    Perhaps I'm using it wrong?

    I went here based on your input https://developer.mozilla.org/en-US/...de/appendChild to determine better usage, but could not find the solution.

    Colin

    Thanks again for your input. I wouldn't have got this far without it!
    writeln inserts the table and works.... except it does it only at the bottom of the page and on occasion deletes everything. I'm looking to insert the table at the point of the cursor without deleting or replacing the entire body.

  5. #5
    isladogs's Avatar
    isladogs is offline MVP / VIP
    Windows 10 Office 365
    Join Date
    Jan 2014
    Location
    Somerset, UK
    Posts
    6,127
    Yes I'm aware of both of those issues as you'll see from my comments in the code
    Colin Riddington, Access MVP, Website, email
    The more I learn, the more I know I don't know. When I know I don't know, I keep quiet!

  6. #6
    journeyman is offline Advanced Beginner
    Windows 11 Access 2016
    Join Date
    Dec 2022
    Posts
    85
    Colin

    I found this for you.

    With respect to Edgars post:

    Code:
        Set wbc = Me.MyBrowserControl.Object
        Set doc = wbc.Document
        Doc.Body.InsertAdjacentHTML Where:="BeforeEnd",html:="<p>Hello World<p>"
    InsertAdjacentHTML - inserts the HTML at one of 4 locations (Beforebegin, AfterBegin, BeforeEnd, AfterEnd). It outputs just like your example, except in just this one line, no copy pasting needed.

    It doesn't appear to insert into a selected location, but if you're not aware of it, hopefully it may help in later projects.

    I continue to search for an insert into that works, and will let you know should I find one - if some one else doesn't arrive with a solution!

  7. #7
    Edgar is offline Competent Performer
    Windows 8 Access 2016
    Join Date
    Dec 2022
    Posts
    306
    Give this a try, if it does not do anything, there are two things you can do:
    1. enable emulation of IE11, which requires adding one or two registry keys.
    2. early bind the objects
    Database13.accdb

    I still don't know the exact scenario you want to use. You keep mentioning something about "inserting" but where? is it a website? or a custom site or what is it?

  8. #8
    journeyman is offline Advanced Beginner
    Windows 11 Access 2016
    Join Date
    Dec 2022
    Posts
    85
    Thanks for this Edgar,

    There's a lot to unpack in this and I'm following threads you've offered to work out cade samples. The way this seems to want to work looks fantastic...

    ...however, This attached didn't work out so well for me.

    Code:
    Private Sub styleContainer()
        ruleIndex = styles.sheet.addRule(".container", " ") ' Failed Here
        With styles.sheet.rules.Item(ruleIndex).Style
            .minHeight = "100%" 'cover entire screen
            .backgroundColor = "#f5c7f7" 'container background
            .display = "flex" 'same row
            .flexWrap = "wrap" 'responsive
            .justifyContent = "center" 'center horizontally
            .padding = "20px" 'inner spacing
        End With
    End Sub
    1. I can't go changing registry keys - because then I'd have to change registry keys for any computer I used this on.
    2. Your example appears to use the standard webbrowser. I never got that to play nice with me. in the end I used the ActiveX webbrowser, which allows me to edit into it directly. If I can make the standard control work, then I'd use that one (presumably being the latest and the best)
    3. Inserting means typing out a bunch of stuff into the webbrowser control as if it were a rich text control, then anywhere in that text (or paragraph), insert something - like this table I need.
    However, I mean to insert at cursor location. Not at the end (see above post re: InsertAdjacentHTML)

    e.g.
    Do something
    <Insert something>
    Do something else

    Thanks so much for thoughts and efforts

    In adendum. I found this works to insert text at the selection point.

    Code:
    Dim rng as object
    Set rng = Doc.selection.CreateRange
    rng.text = "Inserted Text"
    Perhaps there is a way to say rng.HTMLText = "<Table></Table>"?
    Last edited by journeyman; 08-15-2023 at 09:11 PM.

  9. #9
    Edgar is offline Competent Performer
    Windows 8 Access 2016
    Join Date
    Dec 2022
    Posts
    306
    You almost had it right, use pasteHTML instead of HTMLText within the click event. Here's how I'd do it for automation, if you just want to add the html string directly, then add it directly.

    Code:
    Private Sub MyWebBrowser_Click()
        Dim rng As Object
        Set rng = doc.selection.CreateRange
        
        If Not rng Is Nothing Then
            Dim newTable As Object
            Set newTable = doc.createElement("table")
            newTable.border = 1
            
            Dim newRow As Object
            Set newRow = doc.createElement("tr")
            
            Dim newCell As Object
            Set newCell = doc.createElement("td")
            newCell.innerText = "Row 1, Cell 1"
            newRow.appendChild newCell
            
            Set newCell = doc.createElement("td")
            newCell.innerText = "Row 1, Cell 2"
            newRow.appendChild newCell
            
            newTable.appendChild newRow
            
            Set newRow = doc.createElement("tr")
            
            Set newCell = doc.createElement("td")
            newCell.innerText = "Row 2, Cell 1"
            newRow.appendChild newCell
            
            Set newCell = doc.createElement("td")
            newCell.innerText = "Row 2, Cell 2"
            newRow.appendChild newCell
            
            newTable.appendChild newRow
            
            'convert to string
            Dim tableHTML As String
            tableHTML = newTable.outerHTML
            
            'paste
            rng.pasteHTML tableHTML
        End If
    End Sub
    Give a try to this file, it's early bound now. Just keep in mind you'll need to add a reference to Microsoft HTML. Oh, by the way, you can add the registry keys programmatically. IIRC, it can be done with one liners.
    Database13.accdb
    Last edited by Edgar; 08-16-2023 at 01:50 PM.

  10. #10
    journeyman is offline Advanced Beginner
    Windows 11 Access 2016
    Join Date
    Dec 2022
    Posts
    85
    Thanks Edgar.

    pasteHTML seems to have been the missing piece of the puzzle.

    I looked at it, but thought that I would have to use the clipboard, so avoided it like the plague, not realising it would paste the string! Who knew.

    You did I guess, so thanks for the education - and your efforts. very much appreciated.

    I've made it work. I'll look at your example further since you seem to be using the standard web control - to determine if it's better or not.

    Thanks again and to Colin for your input.

  11. #11
    journeyman is offline Advanced Beginner
    Windows 11 Access 2016
    Join Date
    Dec 2022
    Posts
    85
    This is the current Webbrowser control - in which I got the webbrowser standard to work.

    The table insert function works.
    Changing class to allow for transpose to MS Word works.... e.g. <p> = <p Class="MsoBodyText> etc. And when the document is created, the style applies... although not always. see SPAN comment below.

    You may notice:

    Code:
        Sub BrowserElementIdentity()
        Debug.Print rng.parentElement.tagName                                                           'FONT
        Debug.Print rng.parentElement.parentElement.tagName                                             'SPAN
        Debug.Print rng.parentElement.parentElement.parentElement.tagName                               'H2 (Class)
        Debug.Print rng.parentElement.parentElement.parentElement.parentElement.tagName                 'BODY
        Debug.Print rng.parentElement.parentElement.parentElement.parentElement.parentElement.tagName   'HTML
        End Sub
    is there a way to make this more practical? so that I can find the <P> tag and apply the class.

    Also, see:

    Code:
    BtnInsertTable_Click
    This was how I used the code you guys gave me.

    I used a RND to create a table ID, which allows me to select the table I want to work with and create a new row in a selected table, and allows for the insertion of the table inline.
    Although to improve this, I'd like to be able to insert a row anywhere - and not just at the end.

    Questions: The class doesn't seem to work if there is a <SPAN> in the line. So I'm, curious about how to remove that SPAN. i don't even know what a SPAN is. or why it's important.
    How can I stop the cursor from vanishing whenever I press enter.
    Basically I'm trying to make this much more robust and unbreakable. It's pretty flimsy right now, but I'm uploading here because there's a couple guys who seem to know what they're talking about.

    Once I know these things, I feel I could be able to use combo box to define the font and the sizing.

    WB Demo A1.zip
    Last edited by journeyman; 08-21-2023 at 03:07 PM.

  12. #12
    Edgar is offline Competent Performer
    Windows 8 Access 2016
    Join Date
    Dec 2022
    Posts
    306
    I can't download your attachment, please upload it again.

  13. #13
    journeyman is offline Advanced Beginner
    Windows 11 Access 2016
    Join Date
    Dec 2022
    Posts
    85
    please try again.

    Cheers

  14. #14
    Edgar is offline Competent Performer
    Windows 8 Access 2016
    Join Date
    Dec 2022
    Posts
    306
    I'm sorry I couldn't inspect your code, I'm a bit late with my projects, but I created a little sample form in your file, check it out.

    Basically, you select using the click event of the web browser. Inside it, you use doc.getSelection(). After selecting, we add a CSS rule to the selected element in order to have a visual feedback of what is selected. For this, we must also make sure to only have one thing selected, the implementation in the file looks like this:

    Code:
    Private Sub MyWB_Click()
        'you'd expect the click event to be the selector, so...
        'check if there was something stored as selected, if so, remove class
        If Not prevSel Is Nothing Then prevSel.ClassName = ""
        'get selected item
        Set currSel = doc.getSelection()
        'set its class as Selected
        currSel.anchorNode.ParentNode.ClassName = "selected"
        'store as prev to check next time
        Set prevSel = currSel.anchorNode.ParentNode
    End Sub
    This way we can have only one element selected. As you can see, not only do we apply a class to the element but we also store the selected element.

    Now that we have a selection, we can do many things with it. I implemented a functionality to add rows and columns to a table. You select some cell and you click add and it adds a row below selection. I also implemented something to add columns to the right at the end. Getting it 100% as you need will depend on you, I'm just adding sample code for you to reach the desired effect.

    You got an error adding a class because you're likely not making sure there's a style tag in your document.

    A span tag is a little node that by default stays in line with the rest of the content, contrary to what a div does, which becomes a new line.

    Your cursor vanishes because on enter, it's probably going to another control, handle that.

    In order to make it more robust, add error handling. You have a lot of stuff going on there, so it's likely going to take a while, but you're on the right track.

    That pyramid looking code can be fixed using a while loop, I attached the implementation of that to the file as well. I added a button in the form and the code looks like this:
    Code:
    Private Sub btnCheckParent_Click()
        Set nodeRef = currSel.anchorNode.ParentNode
        While Not nodeRef Is Nothing And nodeRef.ParentNode.tagName <> "html"
            Debug.Print nodeRef.tagName, "current"
            'this is where we crawl up the dom tree
            Set nodeRef = nodeRef.ParentNode
            Debug.Print nodeRef.tagName, "parent of current"
            Debug.Print nodeRef.ParentNode.tagName, "parent of parent of current"
            Debug.Print "-------------------------------------------"
        Wend
        Debug.Print doc.documentElement.outerHTML
    End Sub
    As you can see, while some condition is not true, we crawl up the dom tree by simply using the current node reference and adding a .ParentNode to it. Once the condition is met, we're right in the node BEFORE the target node. So, we can simply set the node reference to its parent node again and we've reached the target.

    Check the attached.
    Attached Files Attached Files

  15. #15
    journeyman is offline Advanced Beginner
    Windows 11 Access 2016
    Join Date
    Dec 2022
    Posts
    85
    I think I got a good handle on the way it works now. Which is to say there is a lot to learn, and I'm still in the dark over a lot of things, but I'm getting a grip on it.

    Thanks a lot for your help. it's been very valuable and much appreciated.

Please reply to this thread with any new information or opinions.

Similar Threads

  1. Printing Image in Webbrowser control
    By WAVP375 in forum Access
    Replies: 0
    Last Post: 07-11-2018, 09:09 AM
  2. WebBrowser control requery
    By Historypaul in forum Forms
    Replies: 4
    Last Post: 11-12-2014, 09:09 PM
  3. Google Maps in webbrowser control
    By bfc in forum Forms
    Replies: 10
    Last Post: 08-27-2014, 10:53 PM
  4. WebBrowser Control to use Chrome?
    By kdbailey in forum Access
    Replies: 2
    Last Post: 07-15-2014, 11:30 AM
  5. sizing a url within a webbrowser control
    By Kirsti in forum Programming
    Replies: 4
    Last Post: 11-06-2012, 06:10 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Other Forums: Microsoft Office Forums