Add core validation hook for webforms

This is a brainstorming topic for a feature request because I am not sure yet how to implement this.

Introduction

Plugin authors and wiki admins will find it convenient if they can write checks for valid webform input.

Foswiki does have a validation method, but that is only used to check against malicious form submissions.

The current way a webform validation can be done is what FormPlugin uses:
  • it replaces the form action by a new url (view of the current page)
  • it stores the original action url in a hidden field (can be improved to hide this)
  • validation attributes are also stored in hidden fields (can be improved to hide this)
  • after submit, when the page is reloaded, the form input is checked against the rules
  • if not ok, error messages are shown in the redrawn form
  • if ok, the page is redirected to the orginal action url

This has several problems:
  • A page redirect doesn't work properly from a POST. Actually it only works with a 307 redirect, and Firefox (correctly) shows an ok/cancel panel before the redirect, which is annoying.
  • You need to write webforms with FormPlugin
  • Because we don't have a standard

Idea

I think the proper way to do webform validation is to:
  • Catch the posted form data as early as possible, just after the existing Validation process has taken place
  • On error: to show an oops page (if no javascript) with the form, plus error feedback
    • A plugin could use jquery's validation script for direct user feedback (of course the non-js must stay in place)
  • On ok: do nothing, just let the form be submitted

What is needed is a callback to let core code and plugins be notified of a form submission. Then the plugin can somehow trigger a "false" response and do something with the form data.

Any ideas how to proceed on this?

-- ArthurClemens - 27 Jan 2011

Discussion

There are two distinct ways to validate:

  • server side
  • client side

We need to distinguish them both as they result in considerably differrent information flows and user interaction. Sure, there's also the posibility to validate a form using a REST call on the client side in cases where only the server can decide whether the data about to be submitted is valid. Example: registration form - is this nick name already in use?

Using client side form validation we basically don't have a need to redirect a page thus being in danger to lose data while copying back and forth input fields between different form fields. jQuery.validate allows to hook into the submit() event and will intercept further processing of the submit event when one of the constraints registered for the form is violated.

Using jQuery.validate, simple constraints like "required" or "numeric" can be writen down as part of the markup of the form directly. More complicated constraints need javascript of their own. (see the docu of jquery.validate).

-- MichaelDaum - 28 Jan 2011

+1 on Michael's comments. Client side validation gives immediate feedback and does not require complex server-side flows. The requirement for server side validation is uncommon, and when it exists, more often than not the complexity of the constraint check is such that it's something you want to report as a full-blooded error anyway.

Of course if you don't have JS, then Catalyst/Django/Rails style validation is required. These generally work by redirecting to the original page with some sort of error feedback (e.g. a strategically placed block, a la the broadcast message) indicating the failure. You would need:
  1. A validation hook, (probably best in the form data retrieval process, getValuesFromQuery I think)
  2. A way to cleanly raise a validation failure exception, and handle it in UI.pm
  3. A way to find out the source page that initiated the request
  4. A way to pass the validation failure back to this URL
  5. A way to display the validation failure in the originating page

-- CrawfordCurrie - 28 Jan 2011

I have worked with jquery's validate, and it is my intention to offer this as client interface. But I don't think this is sufficient.

On creating the server side validation steps this is more or less what I had in mind. I just wondered how to create the hook. Should plugins be able to return a "false"? Is this possible in the plugin architecture?

-- ArthurClemens - 28 Jan 2011

Any checks done on the client side are probably important, so they should probably be repeated on the server side, too. Some of the checks will be relevant to the system security and to data(base) integrity, and so they must be repeated on the server side. This applies to REST-based checks, since it is easy for them to be vulnerable to race conditions. For example: imagine two people trying to register at the same time using the same username, or one user trying to reserve more than one resource at a time (e.g. books at a library, or tables at a restaurant, or conference sessions to attend, etc) by submitting requests at the same time from different windows.

Most of the time, if the client side checks pass, then the server side checks will also pass - so you could fall back on a "We're sorry, but something broke unexpectedly - please try again. If it still fails, contact your sysadmin" oops message, which people should never see.

For those things that are checked before submission, using REST, and also checked on the server side, it might be helpful if there was a convenient way to code the check only once. The server-side form-validation infrastructure should take this into account.

-- MichaelTempest - 28 Jan 2011

My idea for FormPlugin is to let it generate the javascript to be used by jquery's validate. But for a more generic approach perhaps an intermediate layer (json?) is needed.

-- ArthurClemens - 28 Jan 2011
Topic revision: r6 - 28 Jan 2011, ArthurClemens
The copyright of the content on this website is held by the contributing authors, except where stated elsewhere. See Copyright Statement. Creative Commons License    Legal Imprint    Privacy Policy