PHP5 Forms with AJAX submit – best practices

Tuesday, April 5th, 2011|Beginner tips, Brainstorming, Version 3, Version 4|by Romans

Forms are the foundation of interactive web and what we call Web 2.0. In this article I will walk through the possible problems web developers encounter when creating web forms and solutions to those problems.

This article will be useful to people who are starting web development or who are experienced at it.

This article refers to Form implementation in Agile Toolkit. For documentation and demonstrations of forms in Agile Toolkit see http://agiletoolkit.org/doc/form

The Foundation

Basics of the form is that it may contain multiple input fields allowing web visitor to input some information in them. Form also may have one or several buttons and by clicking them data is being sent over to the server. Server can process the data and prepare the new page in return.

If you are using Agile Toolkit – it implements all the best form practices for you. Toolkit-related notes are listed in italic.

Agile Toolkit is Open-Source UI framework which can be used on it’s own or with other frameworks.

1. Submitting forms – POST, GET or $.ajax?

If you are going to save form data or email – then definitely POST. On other hand, GET is useful on search forms and in few other cases. For the framework use the POST dominates. In many cases forms require to send data to the server without changing page, that’s where “submit” event for the form can be re-defined and used to send AJAX request to the server.

My suggestion is to build forms which work through POST, however are enhanced with jQuery UI widget to enable submission through AJAX.

Agile Toolkit defaults to using POST for forms and if your client supports javascript, it will enhance form with jQuery UI widget. There is a built-in widget for form enhancement, however developers can use their own. PHP Form class will accept data either from POST or AJAX and will produce proper output. For instance error labels are being shown consistently.

POST (non-ajax) form in Agile Toolkit (demo)

Building a basic form in Agile Toolkit (demo)

2. Handling form data and security considerations.

When you show the form, you might be doing some security checks. Such as – will your user have permission to post comments? When form is being submitted, it’s very important to perform the same checks before you will actually put data into the database. If you have 2 pages – one to show the form and other to handle it’s submitted data – this design is prone to human-errors where certain validation will not be performed on submissions allowing skilled hackers to bypass validation. The best approach is to have exactly same code to initialize the form and handle form submission.

There are many ways to approach input sanitization, however since PHP5.2 it includes a native way of doing input filtering and sanitization. http://www.php.net/manual/en/function.filter-input.php

In Agile Toolkit form class has function “isSubmitted()” which returns true only if form was successfully submitted and validated. All the initialization and validation you perform before adding form on the page will still be executed for submission. Also form is always submitted to the same page where it was created. This promotes proper behavior which is secure and consistent.

Agile Toolkit does not implement sanitization on it’s own, however it suggest to use built-in PHP filter. However even without filter, internal approach of handling data is secure:

Agile Toolkit approach to Injection Handling (demo)

AJAX actions

In most cases when you submit your form through AJAX it will not change the page, but user will require some visual feedback on what has happened. Probably a common approach is to write a client-side JavaScript function which is executed and receives server-crafted data as argument. Then you would need to define number of possible server responses and handle them all inside your function.

This approach is highly ineffective and very unstable. Due to human error your function might not contain the logic for handling particular return type. What I am using and strongly suggest to use is to pass back a piece of JavaScript code which your browser would eval. However unless you have a powerful UI framework on the server – it will give you almost no benefit. You are also exposed to vulnerability of JS injection if your backend attempts to pass some field value as-is without properly escaping it.

When from is being submitted through AJAX request in Agile Toolkit, the expected output is being “eval” ed. However what’s important is how the backend is able to come up with the JavaScript code. Developer interacts with the PHP-side objects through a specific class called jQuery_Chain which is then translated into a valid jQuery chain. The main property of the chain is – it is transparent. It have only few methods, other methods are translated into JS through __call() catch-all function in PHP. Arguments you are passing are properly escaped and transformed into JSON, helping greatly to avoid any JS injections.

This approach allows developer to write things like: $field->js()->hide(‘slow’); and firing off some jQuery effects right from the backend without a writing a single line of actual JavaScript.

Using AJAX Form to add records and refresh Grid (demo)

Double-posts

When dealing with POST forms (without using AJAX), it is a good practice to issue “Redirect” on form submission. If you do not do that, web user might click refresh and send data to your form again. Many web software has this problem. So if you wish to display a success message to your user after form is submitted successfully – perform a redirect and forward user to a new page. If you pass message as GET argument, do not forget about threat of JS injection, htmlspecialchars($message) – should do the trick.

Agile Toolkit approaches double-posts by introducing a form submission verification. If user happens to click submit twice, it will ignore second click if first is still being processing.

Form Templates

In most cases today – form implementation in frameworks and web applications require developer to write the HTML code for all the forms independently. This design requires developer to either know HTML very well or sit in the same room with designer.

My suggestion is to categorize your forms into generic templates. Inside that template you would define header and footer of the form, button area and give generic template for the field.

If forms you create already have a generic template, they provide a number of benefits for development:

  • Forms are consistent. Developer might pick from several looks depending on the situation, however a good designer will be able to prepare a nice and universal templates which will work in most cases.
  • New form does not require anyone to write HTML.

In our typical web projects, I as developer can choose from several templates. If the form I’m creating is a data filter, I use horizontal template. If form goes into a sidebar, I use template with labels on top of fields. For the big forms I use the one with labels on the left and with space for field hints.

Actual layout of the forms is pretty common and is defined through HTML and CSS by our designer. As a result – I do not have to worry what will happen if label takes 2 lines of text instead of one and can create forms quickly and efficiently.

Creating a good and flexible form templates can take time – positioning hints, error messages and also allowing different types of fields to appear on form, testing those forms in multiple browsers is a hard work.

Agile Toolkit comes with few default templates and CSS themes for the forms allowing developers to create a new and stylish form with simply few lines of PHP code. Different projects may want to style forms, and it’s possible through use of CSS.

For developer not worrying about the looks and being able to produce forms on his own is really effective.

Form Layouts

Use of form templates brings in a systematic design, but it looses in flexibility. In your project it might be a low priority goal, but at one point you will want to organize your form layout and make them more compact depending on the situation. Typical benefits of forms with custom layout is being able to put multiple short fields on same line, insert additional text elements inside the form.

Such forms are typically more difficult to maintain. If some fields require to be hidden / shown on-demand through JavaScript you will need to worry about what will take up that space.

Agile Toolkit allows to define layout to any form. This allows designer to provide a separate template for the form, which defines the flow of input elements. Inputs are still being produced by the framework, but where they are inserted is entirely up to the layout. Form will still rely on form template to get the <form> tag and button arrangements, layout is for fields only.

Using other UI elements inside form

Suppose you have a registration form and you want to add a button saying [Check availability] next to your login name. If you are using form templates and even form layout this still is a challenging task. Without use of a UI framework, I’m not even sure how to create this.

In Agile Toolkit – anywhere where where templates are used you can place UI elements. When you add a field to the form it’s template contains 2 tags – ‘before_field’ and ‘after_field’. You can use those to add a button. After you can bind a JavaScript event to actually perform a AJAX request and verify validity of  the login name.

Adding icon before standard form fields in Agile Toolkit (demo)

Benefits of Form Widget

By using jQuery UI widget which works well with the back-end it allows to perform several useful tasks often required by a web applications.

Agile Toolkit comes with ui.atk4_form.js widget, which offers: field reloading, error display, form submission handling, tracking of un-saved data inside form and better file upload handling.

Apart from the form widget used in Agile Toolkit I am not aware of any other open-source implementation which help to tie together form and backend framework. If you know of any – please advise.

File Uploads

The way how file uploads are implemented today is a complete mess. <input type=’file’> provides with a element allowing web user to pick file. When form is then submitted it transfers file over to the server.

However if you are using file uploads with the form which requires validation, then it introduces a number of problems. What if some of the fields were filled in incorrectly – will user have to re-upload the files? If you want to keep files on the server – you certainly haven’t created data record yet (because of validation issues), where would the file be stored and how would we know it have to be attached to the form? What if user wants to remove file he has already uploaded?

Because of those problem, many web applications will include a separate step for file uploading – this helps them avoid some of the problems, but not solve them.

There are 3 techniques for asynchronous file upload. When file is selected it is being transferred to the backend while user fills out rest of the fields. A most universal approach would create <iframe> and use it as form submission target. Another approach is to use Adobe Flash Uploader. This gives benefit of showing upload progress, however is difficult when it comes to universal styling and will make your web application dependent on Adobe Flash. Last approach allows to send files through AJAX request, but it is part of HTML5 and is still not very well supported by browsers. This method also allows to show upload progress bar and is the way how files will be uploaded in the future.

Implementing IFrame approach is not easy. Especially if you wish to upload multiple files in your form. Think as being able to add multiple attachments to your form as in your email program.

Final problem is – if your users upload files before submitting form – how will you identify those files and how will you make sure he is not hacking and attaching files just uploaded by someone else. Also – how do you clean up those files if user decided not to finish the form. And if you do store those files in a directory, you might be loosing some of the meta-data such as mime type or original filename.

This is kind of problem is almost impossible to fully resolve without use of the framework or libraries. Among many other things this is what Agile Toolkit allows developers to do.

It contain a field type “upload” which will create asynchronous upload component which is using iFrames and allows to upload one or multiple files (simultaneously!). Toolkit also solves the problem of storing files temporarily by relying on FileStore implementation. FileStore keeps file’s meta-data but also can contain information about who and when uploaded the file so you can track and clean them up.

By not burdening forms with multi-part submission we can now always rely on AJAX submits even if form contains one or several upload fields. Therefore if your form contains error they will be highlighted without interrupting file uploads.

Once file upload is finished, the component will display the filename and links to view, download or delete file from the server.

Button click detection

In 90′ties without JavaScript any button would only submit a form. However it was required to have multiple buttons and those buttons were supposed to do different actions. Today many of the buttons will exist on their own and will perform JavaScript actions, however very often it’s important to be able and tell which form-submit button was clicked.

There are at least 3 ways to add a button to the form and they produce different results as well. <input type=submit name=a value=b> is the easiest to understand and handle. If you click such a button then a=b will be added to form input. However if user hits “enter” inside the form results can be quite interesting. Some browsers will make seem like the first button was clicked. Others will not allow to submit the form if it has more than one field or button – in other words – it’s a mess.

Then there are graphical buttons which use image. <input type=image name=a value=b>. Unfortunately instead of sending a=b they will send a_x=123&a_y=234 where numbers are coordinates of your click. This approach completely breaks consistency.

<button name=a value=b> element finally introduced some consistency and is a preferred way to go. It will also consistently send it’s value in normal POST forms.

However you might be using AJAX for submitting, right? Unfortunately AJAX submitters will most usually tap into form.submit() event and by that time information on which button was actually clicked is lost. As your favorite AJAX-form collects information from the field elements, it can no longer find out which button was actually clicked. As a result you need to create on-click handlers for all the buttons and pass this information through a hidden field of some sort.

In Agile Toolkit things like those take a couple of lines. Could be a single line, actually. $f->addSubmit(‘Save’)->isClicked(); Everything what happens between the browser and the backend would be sorted by Agile Toolkit.

Bottomline

Creating a good forms for your web application can be challenging at times. What seems to be initially simple can produce a lot of nasty problems. Some frameworks can help you to put HTML together, however they would be very limited at the interaction between the browser and the back-end.

Agile Toolkit is one of the UI libraries for the web trying to help. Comparing raw features it might be behind some of the other approaches, however the flexibility and simplicity of the design makes it advantageous in real commercial applications or open-source applications.

See Form implementation in Agile Toolkit