I’ve headed out on a world tour of Gutenberg blocks. Third-party blocks. There are starting to be quite a few of them out there, sometimes singly, sometimes in groups of layout and design-related blocks. Especially for the groups of them, you’ve typically got to pony up a few bucks to license them.
But one I ran across—JetformBuilder—is both free (though there’s a pro version for $39 (unlimited sites for $79) per year) and a nice example of how blocks let you go about some kinds of page creation in rather different ways. Experimentation ensued.
The product is made by Crocoblock, which I only recently learned is a Ukrainian company. They have continued to run the company (even make product updates) from the basements where they are taking shelter. I don’t want to shill the product, but on the other hand I can imagine you could do a lot worse in supporting these Ukrainians directly by purchasing a license or two (and I think you’ll get your money’s worth, too, but Sláva Ukrayíni!).
Forms with blocks
The easiest way to explain JetFormBuilder, I think, is to just call it a block-native version of more traditional third-party WordPress forms packages like WPForms. You create a form and then you can embed it in your posts by way of a JetFormBuilder block with a dropdown that lets you select the form you want to appear.
What’s different is that you create the form within the block editor as well. There’s a custom post type for forms, the difference being that when you publish a form post, it’s just saved. Each field is a block. When you want to embed the form in a page, you use a block to place one of your previously created CPT forms.
What makes JetFormBuilder especially interesting is that it gives you a bunch of options you don’t generally get with the free versions of other forms packages. For one thing, you can store your form entries on the site (WPForms makes you upgrade if you want more than an email of the filled form). You can add multiple actions on form submission without upgrading.
You can create multiple-page forms. You can create fields that display calculated values. Indeed, that last bit means that you can create calculator-style tools for site users that aren’t possible in a typical WordPress forms package.
Let’s base a little calculator project on a block that allows you to hide or display fields on a form based on previously entered values.
Before we do that, let me just say that I’m not going to use this article to dig into what extras you get if you pay for the license. It’s a fairly long list of things and, if there’s interest, we can dig into that on another occasion.
All right, project time. I want to create a calculator that allows people to determine their dog’s age in human years.
As you know, no one can ever quite remember how many years you’re supposed to multiply the dog’s age by. Is it 3 years? Is it 7 years?
If it were, say, 3 years, then you could have a form field for the dog’s age, then a calculated field that multiplied the age field by 3. That’s trivially easy to do in JetFormBuilder.
Alas, I think the reason no one can ever remember what to multiply by is that, well, that’s not actually how it works, at least according to the American Kennel Club, which uses this chart:
Yeah, so people years are harder to come up with than simply multiplying by a number. We have to take the size of the dog into account. Of course it’s easy enough to ask what that is, but the real problem is that this chart doesn’t move in predictable increments. Giant dogs age slower in human years the first couple of years, then age faster than other dogs. The other three sizes age 15 years in year one, then 9 in year 2, then 4 years for each of the next 3 years.
If this is unclear, spend a couple minutes with the chart trying to derive a rule for how to convert years to human years–you’ll see what I mean.
Since the human age varies on a cell-by-cell basis, you need a table-driven way to retrieve and spit out the answer. You can imagine loading an array and then using two form fields to determine the right indexes into the array.
But there are no arrays in block forms. You can’t do this the easy way.
Thing is, even if it’s not straightforward, it’s at least possible. Color me impressed. Not one line of code gets written, and you wind up with a calculator that follows some wonky, non-mathematical rules.
Now you see it
My approach hinged on the conditional container block that JetFormBuilder includes, the one I mentioned above, which is visible (or not) depending on some other field’s value. I include several such containers, each containing a single field: a radio button selection of the dog’s size.
Which version of the size selection radio button you see is determined by which age you input. There are a bunch of different ones, but you only see the one corresponding to the age you entered and all the rest of them are hidden.
For the radio button you do see, there’s a value associated with each of the options. In other words, there’s the label or text you see, like “Giant,” but there’s also a value attribute, and I set the value for each option for a given age at the appropriate number for the size of dog.
In other words, if you say your dog is two years old, you see the two-year-old version of the radio button field. In that version, the value for the Giant dog selection is set to 22 and the other sizes are set to 24 (these come from the American Kennel Club’s chart).
Elsewhere in the form, I have a calculated form that simply takes the value associated with the selected radio button. So if you said your dog was 2 years old and then selected Giant, the number 22 is displayed in the calculated field. (In other words, in this case it isn’t really calculating anything, it’s just pulling in a value from another field and leaving it be.)
Effectively, each different version of the radio button field functions as one row of an array of year equivalents. It’s a little clunky, but when you work with it on the page, it’s shockingly clean because you aren’t aware of any of the multiple versions of the radio buttons that you don’t see.
I suspect you can do this sort of tomfoolery and come up with all sorts of ways to get real-world worksheets and calculators to work, which I find very intriguing. So, just by way of showing that it does in fact work, here’s a rudimentary version of the form that only handles years 1-4 (I got tired of duplicating the conditional radio-button blocks–indeed, it’s a bit of a kludgy hack as far as making a calculator goes, but it does work and, to be sure, something that was actually calculated rather than looked up in a table would be a fair bit more straightforward).
My initial thought was that the conditional field capability could be used to perform another bit of magic: progressive form fills.
A progressive form fill is a process whereby you only bother a site user for a piece or two of new information per visit, but you ask different questions each time around and eventually you have a fully filled form.
The first time a user shows up, for instance, you might ask for nothing more than a first name and email. If you were implementing this from scratch, you’d probably tie the process to a cookie on the user’s system, but in this case let’s assume the return user logs in (or, perhaps, stays logged in because of a cookie).
Let’s say there’s a private page each user is redirected to as they log in. There’s a form embedded in that page and what the user sees is something like “Welcome back – can we just ask two quick questions?” and then the two next questions.
I was wrong about Jetformbuilder being able to do this, though, and I mention it because the underlying reason is worth thinking about. Like other form packages, here we have form definitions (which happen to be made out of blocks) and then, as a user submits a form, the data is written to a row in a table of entries.
This is what you’d expect, but it means that, in the normal course of things, each time the form is filled, it’s a brand-new entry. As a nice extra, it actually is possible to prefill some limited information from the user account (like the user’s name) into a form, just to speed up the form filling process for users. But each entry is still filled de novo.
This is what you’d expect—I’m not knocking the plugin for being set up this way—but it’s interesting to contrast this to the way that data attributes in blocks are natively handled.
Let’s say I create a custom block that has an HTML form embedded in it (by way of React createElement calls). When you add that block to a page within the back-end editor, you’ll see a form. If you’ve set up the block to save the attributes you’ve associated with your form fields, then when you update the page, the data in the fields will be stored. Next time you come back, the data will be there. Additionally, you can use this saved data as part of what’s displayed on the public-facing page.
To take an obvious example, you could create a company address block that the page creator could fill in with an address when they added it to a page. When people viewed the page with the block in it, they’d see the address.
I’m spelling this all out because I want to point out that, should you happen to use this address block on some other page you’ve created, the address you entered before will not be there. The address data within your custom address block is stored with the instance of the block that’s within the individual post you’ve created.
Block data, unless you do something to make it work differently, works like custom fields within posts. Each post has different data. Indeed, you can build applications by treating each individual post as a record within a database table. (And of course that’s what the core of a post actually is: a row in a SQL database table.)
I think that blocks that do things and that store things are going to be where the really interesting developments in WordPress will be found in the next couple of years. JetformBuilder is interesting because it lets you build forms, and you get a lot of value even within the free version. But it’s probably just the tip of the iceberg as we move forward.