Is there a way to have a Bootstrap icon in the header of a WebListBox’s column?
I need to replace the “Download” text in the header of the last column of the WebListBox with an appropriate icon:
In the cells of the same column I succeeded with the following code, in the Shown event, while populating the WebListBox with the AddRow method:
Me.CellTextAt(Me.LastRowIndex, 7) = "<img src='" + WebPicture.BootstrapIcon("download", Color.Black).URL +"'> "
I can replace the text in the header with another string, with the method HeaderAt(index); however, if the string contains html code, this code is not rendered even if it is enclosed in <raw></raw>
tags.
Anyone have any suggestions? Thanks!
I had this same problem…took me awhile figure it out. My listbox has 4 columns, the last column (column # 3) is where I wanted a bootstrap icon in the header. Here’s what I did:
EDIT: Turning off sort arrows may or may not be required. If you keep them, you’ll need to adjust your desired column width accoringly.
- in the inspector for the listbox I set the last column width to 26
- in the inspector for the listbox I set heading text(s) only for columns 0, 1, and 2.
NO heading text for col. 3, do not “tab” after col. 2 heading text. - Turn off sort arrows: if you want the sort arrows gone from ALL columns, add this to the listbox opening event:
for col as integer = 0 to ListBox1.ColumnCount -1
ListBox1.ColumnSortTypeAt(col) = WebListBox.SortTypes.UnSortable
next
- if you only want sort arrows gone from (in my case) col. 3, then do this:
ListBox1.ColumnSortTypeAt(3) = WebListBox.SortTypes.UnSortable
- Finally, I used CSS styles to import the bootstrap icon:
Either use the styles in the App HTML Header like this…
<style>
th:nth-child(4) {
width: 11pt;
background-image: url("<insert http link to your desired bootstrap icon>");
**// (do not keep angle brackets)**
background-repeat: no-repeat;
background-position: 50% 50%;
}
</style>
NOTE: change the number in “nth-child(4)” to match the column number you want the icon in…also note that nth-child counts do not start at zero, they start at 1.
OR put the styles in an external stylesheet (ie: styles.css) without the open & close style tags, and import it into your app at runtime by placing this in your App HTML Header:
<link href="<insert your http link to the style sheet here>/your_style.css" type="text/css" rel="stylesheet">
**// (do not keep angle brackets)**
Here’s what I get:
I hope this helps. I don’t think I left anything out, but it’s possible. Let me know how it works out for you.
html code between tags should render the html directly.
so some code in the listbox cell or header should render the html.
I would file an issue with this as a bug ?
@Ricardo_Cruz what do you think ?
Hi Bill,
thanks for your suggestions. How do you reference the image in the url of the background-image property?
So I did forget something after all. Sorry.
I downloaded the bootstrap icon (saves as an svg), and uploaded it to the same directory as my web app.
Then use your url to the svg. For example:
https://www.mydomain.com/mywebapp/x-circle.svg
Yours may be http, not https.
Yes, that looks like a bug. It’s replacing spaces with
, even when the HTML is enclosed using the <raw>
tag, making the <img>
tag unusable.
I’ve just created the Issue, thank you!:
Issue #72681
Well, that explains why it was such a headache for my poor old brain to figure out. LOL
Ok, I understand that’s the way to go in a web app already in production on a server…
But I can’t figure out where to put the image file and how to reference it in the css’s background-image attribute while working with the IDE in debug mode on a local machine…
Not sure. Maybe try something like this as the url:
file:///path/to/image.svg
Open the file in your browser from wherever it is located on your computer and copy the address from the browser’s address bar.
No idea if that will work in the CSS. If not, let me know…there is something else we can try.
I found the path to the file by opening the image in the browser and I pasted it in the css.
When I open the webpage with the weblistbox I get this error message:
Yeah, I had my doubts it would work. I have to step out for a bit, but I’ll post back later with another suggestion. BTW, are you familiar with setting svg’s up as constants? That has several benefits.
Ok, thank you.
Unfortunately not…
From that screenshot, for security, the browser seems to be refusing to open the image from your hard drive.
The image can be served using a WebPicture instead. You can create a WebPicture directly from a file, or from one of the pictures you’ve dropped into your project.
WebPicture comes with a URL property that can be loaded from an <img>
tag.
Edit: There is also a WebFile class that comes with the same URL property.
https://icons.getbootstrap.com/#usage
Scroll down to the “CSS” heading. You can set the size & color of the icon as well.
I know the URL property of WebPicture and WebFile.
I used the URL property of WebPicture to insert an icon in the cells of a column:
Me.CellTextAt(Me.LastRowIndex, 7) = "<img src='" + WebPicture.BootstrapIcon("download", Color.Black).URL +"'>"
However, this solution cannot be used in the WebListBox’s header, because the HTML tags (and therefore also the <img>
tag) are not rendered and if I enclose them in the <raw></raw>
tags, the spaces in the HTML code are replaced by the entity
and any “class” attribute of the opening html tag is replicated in the closing tag.
I don’t think it’s possible to use the URL property of the WebPicture in the CSS file, to try the method suggested by @Bill_Dawson, or am I wrong?
I tried uploading the icon to the server that currently hosts my organization’s website to have a direct link to the image and it works! Thanks @Bill_Dawson !
However, this solution is not usable for me, because I have more than one WebListBox in different webpages in the app and I need to customize two of them with different icons…
I don’t know if it’s possible to target different listboxes in the CSS since the “id” attribute of the <div>
containing them changes every time I launch the app while I’m in debug mode…
I found this other solution to replace the content of the header’s cell:
- In the App HTML Header I include the Bootstrap’s icon fonts stylesheet:
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.5/font/bootstrap-icons.css">
- In the WebListBox’s Shown event I add:
Me.ExecuteJavaScript("$(""th:nth-child(8)"").html(""<i class='bi-download'></i>"");")
This solution works because it allows you to customize multiple listboxes with different icons and, while changing the header content, it doesn’t change the value of the aria-label attribute, leaving it on the initial value defined for the column header.
However, when the listbox is displayed, the icon also appears for an instant under the header, with an annoying effect:
Is there any way to eliminate this problem? Or is this a bug?
I’m totally guessing here, but doesn’t the shown event happen after the opening event?
Is it possible to use ExecuteJavaScript
in the opening event?
Maybe @Ricardo_Cruz can help with this?
BTW, I like your solution MUCH better than mine! I hope this gets solved.
Since you’re adding the Bootstrap fonts CSS, you can try something like this.
- In App > HTML Header:
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.5/font/bootstrap-icons.css">
<style>
.TableWithDownloadIcon th span::before {
content: "\F30A";
font-family: "bootstrap-icons";
}
</style>
- In any table where you want to display the download icon, in its Opening event:
Me.ExecuteJavaScript("document.getElementById('" + Me.ControlID + "').classList.add('TableWithDownloadIcon');")
Me.HeaderAt(Me.ColumnCount - 1) = "<raw><span></span></raw>"
I’m assuming you will want to display the download icon in the last column, adjust if needed.
Instead of "\F30A"
, you can use any other icon code point. If you go to the list of icons and you press, for example, in the house
icon, it will redirect you to the House icon page. On the right side you will find the code point for this icon, "\F425"
.
And a more generic example, so that you can icons in multiple columns:
App > HTML Header:
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.5/font/bootstrap-icons.css">
<style>
.TableWithIcons th > span {
font-family: "bootstrap-icons";
}
</style>
WebListBox.Opening event:
Me.ExecuteJavaScript("document.getElementById('" + Me.ControlID + "').classList.add('TableWithIcons');")
Me.HeaderAt(0) = "<raw><span></span></raw> One"
Me.HeaderAt(1) = "<raw><span></span></raw> Two"
Me.HeaderAt(2) = "<raw><span></span></raw> Three"
Me.HeaderAt(3) = "<raw><span></span></raw> Four"
Result: