Blog
All Blog Posts | Next Post | Previous Post
Extend TMS WEB Core with JS Libraries with Andrew:
Introduction
Tuesday, April 5, 2022
So. Many. JS Libraries.
- Helpers. Provide developers with shortcuts for common tasks. JQuery and Bootstrap fall into this category.
- Assets. Icons, fonts, themes and so on that are likely to make a big impact on the look and feel of your web application. FontAwesome is an example. Bootstrap offers a set of icons as well.
- Controls. Interactive UI elements that provide functionality roughly equivalent to what a Delphi component might offer. There are countless date/time pickers, for example FlatPickr.
- Tools. Similar to Helpers, these are used to extend or otherwise enhance the component's core controls that you are already using. Interact.js adds drag+resize functionality to any element, for example.
- Services. These include libraries for connecting to external services or communications, and libraries that help with sending e-mail and SMS messages, that sort of thing.
- Devices. Typically these are APIs that allow for interacting with local devices or other hardware. Almost anything to do with Raspberry Pi, for example, would fall into this category.
Managing JavaScript Libraries.
Most often, JavaScript Libraries are added to a web application by adding entries to the <head> stanza of the main HTML page. Usually, it is just one or two lines. A reference to a JavaScript file and a corresponding CSS file in situations where there are visual elements to the library. These can be added by editing the main Project.html file directly, or by using the Manage JavaScript Libraries tool from within the Delphi IDE. TMS WEB Core v1.9.8 introduced the ability to add your own libraries to this managed list. So it can be as simple as that - select a JavaScript library from the list and you're done!
- CDN. A content delivery network like jsDelivr hosts many such libraries and is often the preferred choice. The main benefit is that you don't have to handle the traffic that comes from delivering the JavaScript library to the visitor's browser. For small libraries, or if you have a small number of visitors, this is likely not an issue. But if you have thousands of daily visitors and a JavaScript library that is several megabytes, it certainly can be. If your visitors are geographically spread out, the CDN may also be able to serve the content faster than you can by virtue of them having typically many more servers located strategically for explicitly this purpose.
- JavaScript library Vendor. If the JavaScript library is popular enough (and commercially supported) the vendor may offer links to its own servers for you to use. This has many of the same benefits as a CDN. The delivery is handled by others. Some vendors may provide such functionality but may also have service limits to be aware of. Typically these are very high. Some might even require custom API keys or other means of authentication before the JS library can be used in this fashion. We'll cover more of this when we get to FontAwesome, which does all of these things.
- Self-hosted. The JS library can also be downloaded and included directly in your project, living alongside the rest of your HTML, JavaScript, and CSS files. The very nature of the web means that if you can link to a JavaScript library at a CDN, you can also download it and include it directly in your project. This may also be needed if you're wanting to use a JavaScript library that isn't hosted by a CDN and isn't hosted by the vendor. But there's another reason why you want to do this which we'll get to next.
- Either the CDN or the vendor will offer a link to the "latest" version of a JavaScript library. For non-critical web applications or those in active development, this is probably the best approach. Any updates are automatically included in your app without having to do anything at all. For JavaScript libraries that are responsibly supported, widely deployed, and that have been around for a long time, this is great. If something does break there are thousands of people that will let the developer know in short order.
- If the developer routinely breaks things with each new build, then it may be an idea to use a specific version of a library instead, using any of the methods we've covered. CDNs and vendors typically don't take away prior versions specifically because of this. Some even offer some middle ground, like being able to have the latest updates for the current major release via the same link, but a different link when upgrading to a new major release.
- Finally, if your project is mission-critical, is behind a firewall, or is particularly sensitive to changes in the JavaScript libraries being used, then we're back to self-hosting the JavaScript library. This means that you have the responsibility of updating it as well if there are security-related or other critical issues. The upside is that your application isn't going to fail due to newly introduced bugs in an obscure JavaScript library.
- JQuery. As a helper library, many, many other JavaScript libraries rely on its availability in their own projects. This has become less of an issue in recent years, and many projects are actively working on removing dependencies on JQuery.
- Frameworks. Many JavaScript libraries are either crafted or customized for a particular JavaScript framework. In this context, by a framework, I mean the JavaScript environment that is used. React, Angular, and even TMS WEB Core are all frameworks in this context. There are many such frameworks. So if a JavaScript library has been crafted to work specifically within React, for example, that JavaScript library may not always work directly in TMS WEB Core. Often this just means there's a different version of the JavaScript library that is needed instead.
From our perspective, a dependency just means that the JavaScript library must come after whatever it is dependent on in the Project.html file. Fortunately, the Manage JavaScript Libraries tool allows you to change the order that JavaScript libraries are loaded. So if something is dependent on JQuery, then make sure it appears after JQuery in the list. Note that it is rare, but some JavaScript libraries need to be loaded before JQuery. Generally, this isn't something that you have to worry about too much. Put JQuery at the top and everything else follows. If something is amiss there will likely be a console.log message about it and it won't be difficult to sort out.
It Looks the Same.
- Some JavaScript libraries just work by being present. Adding Bootstrap or FontAwesome, for example, means that you can style a TWebButton from the IDE. Adding "btn btn-primary" to its ElementClassName property, and "<i class='fas fa-flag'></i> Flag" to its caption, and a dramatically different-looking button will be the result, without having to change anything else at all.
- A handful of components included in TMS WEB Core depend on a JavaScript library. For example, if you want to use the Ace Editor component, you'll need to be sure the relevant JavaScript library has been added. Then you can use the component as you do all the other IDE components, setting properties and so on, none the wiser that the JavaScript library is even there.
- In order for a JavaScript library to be functional, it may need to be initialized. This is typically done through code, most often in the WebFormCreate method, inside of an "asm ... end" block
- Visual controls will often need to be linked to a <div> element or something similar that is included in your page. We'll cover the details separately for each JavaScript library. As an example, I'm fond of using a TWebHTMLDiv component and assigning it an ElementID property that is then passed to the JavaScript library when it is initialized.
- Many JavaScript libraries offer the ability to customize what they do via some kind of property mechanism. This translates generally into what we're accustomed to in terms of Delphi IDE component properties. But as JavaScript doesn't have a native IDE, this is done in code and typically also done using something akin to JSON. We'll touch ever so briefly on JSON in a moment.
- Perhaps less familiar, some properties can be passed as a JavaScript function reference or even in-line JavaScript code. So familiarity with JavaScript will be hugely beneficial for some JavaScript libraries.
About that JS Coding.
- Normally, using "asm ... end" works without the IDE complaining at all.
- Sometimes it helps to use "asm { ... } end" if the JavaScript code has bits that look like Delphi code that the compiler doesn't like.
- For the worst offenders, using "{$IFNDEF WIN32} asm { ... } end; {$ENDIF}" gives it the most separation and the IDE really won't care what you're doing. The pas2js compiler will still complain if you have egregious JavaScript errors, though.
- JavaScript is case-sensitive. Delphi is not case-sensitive. If you pass variables from Delphi to JavaScript, however, the Delphi declarations need to match the case of the JavaScript code in order to work properly.
- Many JavaScript libraries have 'callbacks' that can be used to call Delphi functions, and Delphi functions can call JavaScript functions as well. All good.
- Context is important. How to call a function or how to reference a variable in different scopes can be tricky. The frequently used 'this' qualifier is anything but unambiguous.
- The JavaScript console is a hugely powerful tool even for debugging regular Delphi code, so do take advantage of it.
Choices. Choices. Choices.
TMS WEB Core offers tremendous flexibility when it comes to how a complete web application is crafted. The layout of the page (the actual HTML) can be generated directly from a form designed in the Delphi IDE. Or an HTML template can be used and the various fields and other elements within the template can be mapped back and forth using ElementID properties to fully separate the design and layout of the page from the logic of the application. Or a combination of both can be used. Theming (the actual CSS) can also be done either using properties in the components of the IDE or directly in CSS files, using ElementClassName and ElementID properties to provide a link between the two. Or components might just draw themselves into <canvas> elements much like they would in a VCL environment. These can all be intermixed to best suit whatever environment the developer finds themselves in.
JavaScript libraries add another dimension to all of this. They often bring along their own CSS. Sometimes they draw their own components into <canvas> tags. Sometimes they are really well-behaved and CSS can be used to override the appearance of virtually anything.
And then ultimately the browser can come along and decide that IT wants to display an element in its own way, regardless of what anyone else might want. Mobile browsers tend to take over when displaying combo boxes for example.
All this to say that whatever you're designing, you'll need to test it in whatever environment your clients are most likely to be using. Some JavaScript libraries in fact can help facilitate a more uniform user experience across different browsers by abstracting away some of the differences between them.
It's all about JSON.
Finally, we can't talk about JavaScript libraries without at least touching upon the topic of JSON. JavaScript Object Notation. Sounds simple enough, right? I'm sure there are hundreds of books written about JSON and its many uses. For our purposes, for now, at least, the main takeaway is that it is used heavily all over the place. From passing simple parameters to handling large datasets and everything in between.
If you have a property that supports multiple choices, that list will most likely be formatted as some form of JSON. When looking at the documentation for a particular JavaScript library, it is important to keep an eye out for this kind of thing. Usually, there are examples to follow and it isn't particularly difficult once you've seen it in use a few times. But it is a departure from what a Delphi developer might normally be accustomed to using. We'll be sure to cover more about JSON as it comes up in different JS libraries.
Wrap-Up.
Thanks for sticking with me this far! Next time we'll delve into one of the most popular JavaScript libraries - Bootstrap. We've got quite a number of other JavaScript libraries we're planning to cover in the coming weeks and months. Is there a JavaScript library you'd like to see covered? Tell us a bit about it and we'll consider adding it to the list. Do you have a TMS WEB Core problem that might be overcome with a JavaScript library? We'd love to hear about that as well.
Follow Andrew on 𝕏 at @WebCoreAndMore or join our 𝕏 Web Core and More Community.
Andrew Simard
This blog post has received 8 comments.
Simard Andrew
Richard Hazell
Simard Andrew
Poullet Eddy
Monterisi Stefano
Simard Andrew
Simard Andrew
All Blog Posts | Next Post | Previous Post
Borbor Mehmet Emin