Expressive Forms – Part 4


Previously, I talked through setting up a calculator form. This time, it’s a menu form. And, I’ll tell you where to get xf_form.js (free) for the helper routines.

A menu consists of several buttons. Each button links to a webpage, except those few buttons whose task it is to expand or collapse the menu. Since there is no submit button, this wouldn’t need to be a form. Yet, making it a form with readonly input fields, means that you have several less divs on your webpage. And I’m always grateful to have fewer divs to have to tell apart.

So, let’s make it a form. As with all the forms I’ve presented, there’s no action or method on the form. The form has an id, and it has an onsubmit attribute. For the menu, onsubmit is not really needed. Each button has the type of “button”. But, just in case the browser says to itself, there must be some onsubmit button, I added onsubmit=”event.preventDefault()”. This keeps the form from ending up with a blank menu.

You can go ahead and set up your menu buttons. If you want emoji on your buttons, my x_press.js library has several which are appropriate for menus. To use the home emoji, just enter &menu_home;. x_press() will interpret it for you. However, since your menu will be on every page, you’ll probably write it as a javascript function. If you do that, you’ll need to change &menu_home; to %menu_home; and call x_press a little differently. Or, you can just go to Emojipedia and copy-paste the emoji from there. xf_form.js relies on x_press.js, so you’ll be adding them both to your <head>. I’ll point the way at the end of this article.

xf_form.js helps with the expand / collapse menu buttons. These use the onclick event, rather than an <a href=…>. Each button has a data-menulevel attribute. I made the first level 0, then 1, then 2. But these routines allow you to assign whatever levels you want. You could start with 10, then 9. You don’t need to go in order, but why confuse yourself.

So, on my menu, all permanent buttons have data-menulevel=”0″. One of those permanent buttons is the menu button. This used to be a triple bar, now it’s a triple dot, as that takes less room. The menu button, expands the menu by opening menu level 1. The menu button also closes menu level 1 when it’s open. So, the menu button toggles menu level 1.

My menu has 3 levels (0, 1, and 2), so the onclick for the menu button is onclick=”xf_menu_close(‘menuform’,[2]);xf_menu_toggle(‘menuform’,[1])”. Close menu level 2 for form with id=”menuform”, then toggle menu level 1. There’s also xf_menu_open. These change the style visibility between visible and hidden.

For instructions on how to use my x_press.js and xf_form.js libraries, go to my Really Useful Javascript webpage. These libraries are light-weight, so they won’t slow down your site. Just keep in mind, that I change these libraries at will. Mostly I add new functions. But sometimes I have to revamp an existing function. And if you’re using that function, it may no longer work. So, contact me from my website to be notified of any changes I make. And, if enough people sign up, I may create new functions, rather than revamping existing ones. That way, the existing ones will still work. Yet, there are times when Google forces me to rewrite functions and not leave the old ones. So, sign up to stay informed. I promise I won’t spam you.

Expressive Forms – Part 3


Previously, I explained how to create a contact form. In this part, I’ll explain how to create a calculator form.

In order to evaluate a math equation, you first have to parse it. Then you have to evaluate portions of the equation in the correct order. There are javascript libraries which will evaluate equations for you. I looked at 5 or 6 of those. Not too hard to implement, however, you have to specify the equation the way they want you to, not in mathematical format. So, I wrote my own in xf_form.js.

To parse the equation (separate the values from the operators), you need some sort of parsing routine. Those are very complicated to write. So, instead, I make the website programmer place the separate values and operators into an array, in the order of the equation. I figure, they already know and have access to those various parts. So, parsing done! Oh, just make sure the values are numbers and not strings.

Then I wrote a simple routine to evaluate the equation from the array. You can use operators **, *, /, +, -. These are evaluated based on mathematical rules – ** first, then * and / left to right, Then + and – left to right. I was going to provide for % (remainder), but who knew what order you wanted that evaluated in.

I provide input fields for all the values and operators. The operator fields are readonly, though you could not make them readonly and let the user enter their own equation. Because the keyboard operators threw off my vertical alignment, I display other similar symbols, but the value is still the keyboard operator.

But, your equation still might have nested equations: 1+2*(3+4). 3+4 is nested. Innermost equations are evaluated first. I used data-calceq to specify the level. For 3, +, 4, data-calceq=”2″. For 1, +, 2, *, data-calceq=”1″. Now I need somewhere to store the result of 3+4. I call this hidden input field xf_calc_resultN where N is the level number – in this case 2. xf_calc_result2 has data-calceq=”1″.

Now I call my routine to evaluate the form, passing the form id. Form has data-calceqs=”2″ (the number of equations). My routine gets all the children (descendants) of the form. It evaluates the equation where data-calceq=”2″. Then it evaluates the equation where data-calceq=”1″. If you had 10 equations, it would evaluate them from 10 to 1.

The result of equation 1 needs to go somewhere. I place it in an output field with id=xf_calc_result1.

onsubmit=my form evaluation routine, evaulates the form when the user clicks the submit button, which I’ve titled Calculate. Everything’s fine, all javascript, all simple, all client-side. However, there’s one wee problem. As soon as the user clicks the submit button, the equation is evaluated and displayed, then the form is cleared. To keep the form from clearing, add another function to onsubmit. onsubmit=”xf_calc(form_id);event.preventDefault()”. The Default that is being prevented is clearing the form. That’s not technically correct, but that’s what appears to be happening. What is technically happening is not really important. What’s important is that your form isn’t being cleared and the user can see the results.

If your formula’s not too complicated, you can use xf_calc. Otherwise, you’ll need to call xf_math_eval(equation_array) multiple times and piece together the results. You can still use hidden input fields for intermediate results.

Stay tuned. Next time, I’ll finish up with a menu form. Then I’ll tell you where you can find out more about xf_form.js.

Expressive Forms – Part 2


Part 1 was an introduction to Expressive Forms. In Part 2, I’ll cover a contact form because a) that’s probably the one you’re most interested in, and b) it covers the most ground.

With a contact form, you want to collect at least an email address and receive that email address in an email to yourself. You probably also want to collect the potential client’s name. Perhaps their phone number. And, some info about why they’re contacting you.

Most email forms reach out and grab you. I hate when that happens, so I don’t advise doing that. Rather, make the form obvious (or the click of “Contact Me”). Let the user reach out. After all, I want clients who want to engage with me, rather than those who happen to be swept to my shore and almost drowned in the process.

So, go ahead and design your form. On my test contact form, I had Reason for Contacting Me. This is typically a list of choices including “Other”. If you want a list, use a <select> element, otherwise, use an <input type=”text”> element. With <select>, you place each option in <option> tags. And you can group <option>s in <optgroup>.

Next, I want their name – <input type=”text”>. For each field where the user will enter something (or select something), I use a <label>. <label> is related to <input>. <label for=”name”>Enter a Name</label><input id=”name”>. Note that the for of label is the same as the id of input. Also note that there is no </input>.

Next, for their email address. <input type=”email”>. When the user clicks the submit button, this field will be validated as an email address. The validation isn’t very robust. a@b is considered valid. You can greatly improve this validation by adding a pattern. Patterns can get long and complicated, so I won’t go into that here. The great thing is that you only have to supply the pattern. You don’t have to supply any real code to see if the email address matches the pattern.

For my test contact form, I grouped the client’s email address field and a check-box, using fieldset. The checkbox is for whether the client wants to be cc’d on the email. If they are cc’d, they will end up getting your email address. And, at this point, I think that’s a good thing. That way, they can contact me and I don’t have to bug them about it. Still, until that email goes out, my email address can remain hidden. With fieldset, I can include a legend (title for the group/set). No need in this case. Fieldset defaults to have padding which through off the alignment of my fields. I provide a class for that in xf_form.css.

A telephone number, if you wish. <input type=”tel”>. You can just as well say <input type=”text”>, since tel provides no validation. Again, you can use pattern to add validation. However, consider the reason that there is no validation. That’s because international telephone numbers can have a very wide variety of formats. If you want to limit to northern-hemisphere numbers, you can use a pattern for that. But, even UK numbers have a variety of valid formats. If you really want to make sure, the user enters a valid phone number you can use Twilio. However, if it’s me, I’m not going to give you my phone number until we’ve had some initial email conversation. So, why make me mad? You can somewhat validate the phone number with minlength=”6″. You can add a pattern to limit non-numeric input to #,(,), -, and space.

And, what is the real reason they want to contact me. For this, I used <textbox> and allowed them to enter some more text. You might want to add maxlength=”1000″ or possibly less.

Now, there’s one last field that needs to be on your form, and that’s your email address. However, if you wanted the user to be able to see your email address, you would have just supplied them with an email link. Well, it’s not so much the user, whom you don’t want to see your email address, but all those bots lurking about. The best thing you can do for that is to use an excellent webhost for your website. I’ve used Dreamhost for years – so far, so good.

Let’s continue to hide your email address – <input type=”hidden”>. Hidden fields can’t have labels. I tried checking for one and my javascript code just quit. Turns out I first needed to check and see whether my field could have a label before I checked to see if it did. So, I hid the email address. A bot can still easily see it. So, I encrypted it. I used a replacement technique to obfuscate it. I could have really encrypted it but, it’s not a password. It’s only an email address. I made the encryption easy to apply, but hard for a bot to notice and harder for it to reverse. I added that routine to xf_form.js. The routine encrypts and decrypts and allows you some control over the encryption.

I used the data-process attribute to tell this field what routine to call to decrypt the email address. data-… is an attribute that you can specify. The attribute starts with data-, and the rest is whatever you want. So data-process. You can easily retrieve whatever’s in data-… with element.dataset…. Typically, you might have data-email-part=”to” to tell you that this field goes into the to of the email. However, javascript sees that as dataset.emailPart. Since I think that emailPart is confusing – which letter should I make uppercase? – I used data-emailpart. Then I know that javascript uses dataset.emailpart.

Every field on my contact form gets a data-emailpart to tell it if this information goes into the To, CC, Subject, or Body of the email. You have to encode the spaces, and I use decodeURIContent for that.

xf_form.js provides xf_send_email(form_element) to send the email when I click the submit button. The flow of what happens is: The user enters the information into the form. They click Send Email which is a submit button. The form has no action or method. It does have onsubmit=”xf_send_email(form_element)”. First, the onsubmit action validates the form according to minlength, required, pattern, type, etc. attributes. Then it executes xf_send_email. xf_send_email goes through each element and places the information in the appropriate part of an email, encoding as needed. Then it mimics the user clicking on an email link. The user is presented with an email to send.

The drawback to this method is that the user has to click send email twice. That’s ok, you can label the first one create email. They’ll have a chance to grab my email address (though no need as they could have checked to cc them the email. And they can clean up the email, if needed. This also means they can remove information that you wanted to be required.

The good part is, no coding and their information isn’t sent over the web. Well, it isn’t sent over the web outside of the email. If you need something more, use smtp.js to keep your email address secure. In my opinion, what I’ve done is sufficient. And I didn’t have to resort to php and/or server-side code. You don’t even need to write any javascript, other than a little test script to call my routine to encode your email address in the first place.

Just create your form. Add some data- attributes. Add onsubmit=…. And, you’re done.

Stay tuned. In the next part, I’ll explain how to use xf_form.js to add a calculator form to your website. You can combine it with the contact form if you like. And, before I finish this series, I’ll tell you where you can get xf_form.js. It’s free. You don’t even have to fill out a contact form. I’m just waiting until I have the appropriate place to put that information.