[Pas2js] Bootstrap & Helper techniques

Michael Van Canneyt michael at freepascal.org
Sat Sep 28 18:27:53 CEST 2019


Hello,

I'm probably kicking in an open door if I say that there are a lot of
javascript libraries available on internet.

Likewise, saying that the Twitter Bootstrap CSS and accompagnying 
library are popular for responsive design is an understatement: 
https://getbootstrap.com/docs/4.3/getting-started/introduction/

One of the many available tables (grids) is bootstrap table:
https://bootstrap-table.com/

But how to effectively use these libraries in pas2js ?

I've committed a set of class helper, in units libbootstrap, and
libbootstraptable.

You can see a demo on:

https://www.freepascal.org/~michael/bootstrap/bootstraptable.html

These units contain class helpers around the TJQuery class, in unit libjquery.

The library and demo is not just useful if you want to use bootstrap.

It also shows how easy and useful it is to create class helpers for 
external classes (such as jQuery). Doing so makes these libraries easy to
use. (I have finished a complete application in no time using this technique)

Additionally, they show how to implement a popular pattern in javascript:

Often, an object literal is used to pass options to a Jquery or other
function that configures some class or component. In this, it is important
to realize that having a member present or not can make a difference for the
library.

The reason is that such libraries merge the options you pass in with a 'default' 
set of options: any option not specified in your option is replaced with the default.

Now, if you were to define these options as a record in pas2js:

   TBootstrapModalOptions = record
     show : boolean;
     focus : boolean;
     keyboard : boolean;
     backdrop : boolean;
   end;

then all members would be present as this is expected in Pascal. 
But the merge operation performed by the Javascript library would yield
unexpected results:

All the fields in the record would be used even if you didn't specify a value 
for any of them.

The solution is to define a class:

   TBootstrapModalOptions = Class external name 'Object' (TJSObject)
     show : boolean;
     focus : boolean;
     keyboard : boolean;
     backdrop : boolean;
   end;

Note the name of 'Object' and the parent class of TJSObject.

When this class is instantiated, it creates a javascript object without any
members. When you do
O:=TBootstrapModalOptions.New;
O.focus:=True;
...

You will have in effect created an object literal with just 1 field.

You could achieve the same effect with
new(['focus',true]);
But it is clear that this is neither type safe nor can you use code
completion in the IDE.

Using the above technique, Pas2js and the IDE are happy, because you 
can use identifier completion and you know the types are correct. 
And the library is happy, because it received only the field for which you specified a value.
The price to pay is of course the create statement to construct the object.
  (which one would not have with a record)

Enjoy,

Michael.

PS. My thanks to Mattias for pointing out an embryonic version of 
this possibility. A life saver which had to be shared !


More information about the Pas2js mailing list