In Part 1 of this series, we explored a simple demonstration of a web application running with Delphi code inside a WebBroker application, and using HTMX as a kind of middle-man.
In this article we are going to further improve the demo, by making it look modern and up-to-date with just a few changes. If you haven’t read the prior article, I highly recommend you to do so, because you will need the knowledge and code of Part 1.
Table of Contents
Improvements
This is how our demo looked like. Perhaps a bit bland, right? For demonstrational purposes this was okay, but we want to take this to the next level. Since we are now fully on the web, we are not limited in any way when it comes to styles. By having our Delphi logic inside a web server, our logic and the web page itself are entirely separated, which makes the styling even easier.
In order to make this application more visually appealing, we could use some simple CSS. But, if you are from the Delphi world, it is understandable if you are not particularly familiar with CSS. This is why we are going to use PicoCSS, which is a minimal CSS framework and uses a fully semantic approach, which means there is no additional knowledge of HTML or CSS required.
Step 1: HTML
First we will add a few tweaks to the HTML code in the index.html file. The logic will remain the same, that’s why we are going to keep the GET and POST requests in the HTMX code.
Let’s start with the label on top and the “Click me” button below. We are going to wrap the label and the button in a container, and since HTML and Delphi perfectly support Unicode characters, we can use emoticons (just for the fun of it). Our code looks like this:
1 2 3 4 |
<main class="container"> <h1 id="header">Delphi & HTMX Rocks!💃</h1> <button hx-get="/helloworld" hx-target="#header">Click me</button> </main> |
As you can see, nearly nothing has changed compared to the prior code snippet, but this will significantly improve the design.
Let’s continue with the other controls below, which was a form with an edit control and an edit button within it. Again, we will wrap our code in a few containers and use emoticons, and we will do all this inside the container from above.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<main class="container"> ... <hr /> <article> <h3>Another test</h3> <form hx-get="/edit" hx-swap="outerHTML"> <fieldset role="group"> <input type="text" name="edit" placeholder="Disabled. Click Edit" disabled /> <input type="submit" value="Edit ✏" /> </fieldset> </form> </article> </main> |
Now there are more changes. Without going into too much detail about the HTML, we added a horizontal line below the “Click me” button and wrapped our entire form in an <article> container. Then we added another small header label and wrapped our edit control and “Edit” button in another container. As you may have noticed the “Edit” button is not a button anymore, but another <input> tag. This was done again for styling purposes, since PicoCSS will acknowledge the input of the type “submit” as a button right next to the edit control.
Step 2: Adding PicoCSS
Adding PicoCSS to our project is a very simple task. All we have to do is to add it as a stylesheet to our HTML file and we are ready to go.
1 2 3 4 5 6 7 8 |
<head> ... <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.min.css" /> ... </head> |
Now compile and run the web server and you should see a major improvement in design. It should look like this:
You should see that it might look visually appealing but editing the edit control after clicking “Edit” is not working properly. This is because we haven’t updated the HTML constants in our Delphi code yet.
Step 3: Cleaning up the Delphi code
Until now, we had our entire HTML code in the index.html file and had two extra constants including HTML code in the GET and POST request. For larger projects, it might be handy to put all of the HTML code as multi-line string constants in a single unit, which includes nothing more than those constants.
The most significant upside of this is to decrease the mix between the Delphi and HTML code, also because HTML can be long at times and will make your Delphi code untidy if you just use it in constants in your procedures. This way it will also be much easier for your web designers to work together with the Delphi developers. Another reason why this approach might be better is that you can abolish the index.html file, so that you can have your entire web application in a single binary file, without additional resources.So, let’s create a unit HTMLTemplates.pas and put the entire index.html contents and the two constants in this file:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
const HTML = ''' <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Delphi & HTMX Demo</title> <script src="https://unpkg.com/[email protected]"></script> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.min.css" /> </head> <body> <main class="container"> <h1 id="header">Delphi & HTMX Rocks!💃</h1> <button hx-get="/helloworld" hx-target="#header">Click me</button> <hr /> <article> <h3>Another test</h3> <form hx-get="/edit" hx-swap="outerHTML"> <fieldset role="group"> <input type="text" name="edit" placeholder="Disabled. Click Edit" disabled /> <input type="submit" value="Edit ✏"> </fieldset> </form> </article> </main> </body> </html> '''; cSubmit = ''' <form hx-get="/edit" hx-swap="outerHTML"> <fieldset role="group"> <input type="text" name="edit" placeholder="Disabled. Click Edit" disabled /> <input type="submit" value="Edit ✏"> </fieldset> <kbd>%s</kbd> </form> '''; cEdit = ''' <form hx-post="/submit" hx-swap="outerHTML"> <fieldset role="group"> <input type="text" name="edit" value="%s"/> <input type="submit" value="Submit ✅"> </fieldset> </form> '''; |
As you can see in the cSubmit and cEdit constants, we slightly changed their values according to our new code from Step 1. Compile and run the server, and everything should be working properly now, with a beautiful design.
Conclusion
What we have learned from these additions to the demo is that a small amount of effort is enough to create a visually appealing user interface, while also keeping the division of Delphi and the web. This again shows us how powerful this approach can be when it’s used in the right situations. It will be especially useful when it is applied to existing web and Delphi applications, because it is that easy to have Delphi logic in a web application, with relatively small amounts of effort and a good division of Delphi and HTML, which enables companies to have their Delphi and web design teams to work in parallel.
If you’re as excited about this approach as we are, stay tuned for more blog posts!
Article written by Elias Kassebaum.
Design. Code. Compile. Deploy.
Start Free Trial Upgrade Today
Free Delphi Community Edition Free C++Builder Community Edition
Good article, nice tech! Any idea how picoCSS & HTMX compare in functionality to ASP.Net?
Hmm, tricky to answer. They’re not really related, as such. The picoCSS really controls the look of the text and controls on the page, and the HTMX provides the refreshless update behavior. ASP.Net is kind of a different thing really. The main advantage of HTMX is that the whole page doesn’t need to be refreshed when you’re only wanting to update a small part of the page. With other technologies that’s more similar to Ajax although HTMX is a lot more than that and pretty much code free on the client side.
Well, regardless, I find it encouraging to see tech like this that Delphi can use and benefit from, especially in an area in which Delphi traditionally has not been that strong. Are you of the opinion that with these technologies, that entire comprehensive web page systems can be built?
Having done more than a little web with Delphi, but never having built a full and comprehensive web site with Delphi, I’m wondering how well this could work with the many excellent back-end web delivery systems available in the Delphi universe?
I’ve worked with WebBroker, WebSnap, WebHub, a little bit of RemObjects, kbmMW, Indy, TWebBrowser, TEdgeBrowser etc. etc., all with the idea of web tech delivery. I’m still trying to wrap my head around whether this tech is a “gap filler” for web front-ends with Delphi?
Your thoughts?
Thanks again for a fun intro to this new tech.
Developing a complex web app (like an ERP/CRM) is definitely doable with RAD Studio, but currently, it would require some external libraries to make it really scalable and maintainable in the long run. The main purpose of this series of blog posts is to introduce RAD Studio developers to new technologies and show potential new ways of working, but without making the demos too complex: focusing primarily on the new tech.
As you can see from the naming of these blog posts, this is a series we have just started, and we will be publishing more posts soon, so stay tuned! 😉
Hi,
thanks for sharing this great series on HTMX with Delphi.
I tried to follow the guide but when I copy the html code and try to display it in my browser of choice (Firefox or Chrome) the Unicode emojis are not displayed correct.
The HTML file is stored as UTF8 and in VS Code or in Delphi I can see the emojis / unicode pictures as in your demo.
What could be the problem?
Best regards
Bastian
I just found out, that in my case I had to enforce the encoding in the rendered output to UTF8.
The line in question was this:
Response.Content := TFile.ReadAllText(‘index.html’,TEncoding.UTF8);
Hi Bastian,
Glad to see you found a solution. That’s a bit odd. Theoretically TFile.ReadAllText should read the BOM of the file and detect the encoding automatically. I will definitely test this myself. Thanks!