Rather than re-invent the wheel, I was wondering if anyone already has a form validation class that they're pretty happy with and wouldn't mind if I could get a hold of.
I'm hoping for something as generic as possible.
Thanks for any help,
Eli
| SitePoint Sponsor |




Rather than re-invent the wheel, I was wondering if anyone already has a form validation class that they're pretty happy with and wouldn't mind if I could get a hold of.
I'm hoping for something as generic as possible.
Thanks for any help,
Eli




Ideally, it would be completely generic so I don't have to write any more validation code.
maybe a function like this:
arg is the argumentCode:validate(arg, string argName, int minLen, int maxLen, bool allowEmpty, bool allowAlpha, bool allowDigits, string specialChars, string errCode) { }
argName is the name for in the error message
minLen, maxLen are self-explainitary
allowEmpty, allowAlpha, allowDigits also self explanitary
special chars are chars which are allowed, so might be "-_'!"
thats alot of params tho, and looks quite ugly for an interface.
But the only other way is to set it in objects and so will take more lines, which I would prefer not to do - cuz validation of 20 fields wil then take 80 lines instead of 20
Any ideas?
Eli





I don't think that the function you posted would be the best idea. There have been several other attempts posted here and Selkirk has written excellent examples how it can be done.
Rather than having one function you have a formcontroller and you assign rules for each of the form. Each formfield can have several rules. You would need to write the form and then the formcontroller. (I think)
Have a look at the source code / examples of http://wact.sf.net to get an idea.





At the moment I looking at having validation as custom tags within a form element, so I can easilly read them using the DOM extension.
Also another interesting angle would be to use an XSL stylesheet to validate user inputs, though unfortunately at the moment XSL-T 1.0 doesn't support Reg Exp
Version 2.0 does of courseThat'd be very neat IMO, and would simplify a lot of things, removing the need for a lot of scripting as well.
Tough luck for the time being I suppose![]()


In another post I attached the form generation / validation library I use at work. If you search for my posts I am sure you will find it.
Cheers,
Keith.


You may want to try this Forms Generation and Validation class. It is very popular and even comes with a plug-in to integrate with Smarty.Originally Posted by lazy_yogi
Manuel Lemos
Metastorage - Data object relational mapping layer generator
PHP Classes - Free ready to use OOP components in PHP




Taoism: I can't find it. If you have a link handy that'd be appreciated
I've found what I think to be the most generic form validation, and uses more than one line per field, but still keeps the number down. Similar to pears forms class.
You have
Validator->addRule(field, "fieldName", "required","errorMsg")
Validator->addRule(field, "fieldName", "digitsOnly","errorMsg")
etc...
Post number 8 here has an exceptional implementation of it:
http://www.sitepoint.com/forums/show...hreadid=114185
The interface is perfect, as is the implementation and class design and interaction. It also decouples the form creation objects from the validation. It doesn't have all the rules implemented in that post tho. I might have to do that if I can't get similar code.


GuiltyThere have been several other attempts posted here
http://www.sitepoint.com/forums/show...hreadid=114185
http://www.sitepoint.com/forums/showthread.php?t=140651
Although the code had saved me quite some time, it wasn't as flexible as I hoped it would be and due to lack of time the development stalled a bit. This weekend I took some time, sat down and started coding unit tests for the various Rule classes.
I can't help to mention it here, and some may find it wussy, others may find it boring, others will carry the opinion that I'm not qualified to make such a statement (rightfully so btw), but: if you are not making writing tests a part of your regular development process, you should definitely give it a try, I'll assure you, it'll change your life (well, the development part anyway).
Cannot recommend a library, basically because I lack the experience with any of them to tell you antything usefull about them, secondly, I'm assuming that you've already tried a few, but didn't quite like them, or they didn't quite fit into 'your way' of doing things.
So, what I'll try to do instead is kinda sum up the steps I took during this weekend and how I came up with a design I like far better (for the moment at least), but resembles WACT so much that people will probably think I've just copied the design
I'm hoping you'll find it somewhat more usefull than a standard 'Have you tried this class' recommendation.
First some tips:
1. Take a cold beer, a cup of coffe, a coke, water, chocolate, sigaret, amphetamines, grass, whatever your favorite coding drug might be.
2. Get a haircut, seriously, if you can't see what you are coding, you're gonna be in trouble.
3. Cats, they are supposed to be chasing mice, not p1ss in the keyboard.
ok, think I've got the hard part covered, what rests is pure fun:
When I started my weekend, my code was somewhere around that of what I had in the links I've mentioned in the beginning.
First I envisioned my needs:
What I wanted was a means of validating data syntactically in a way that it could be encapsulated, parametrized and made reusable in 'simple clear api' components.
This data should be able to come from anywhere and be of any type.
It should be possible to combine different validation processes and then apply them to a data collection (ex. form post).
It should be possible to combine different validation processes and then apply them to 1 piece of elementary data (ex. validating an email list for valid email and length < 70).
It should be possible to influence one validation part according to the value of another field in data collection.
When some validation process failed, it should be easily made known to a human being using an application, hence the components should have a way of handling errors language-independently.
Further more, if one validation process fails, the others should not stop.
From the code I had, I liked the concept of the Validators and the Rules. For the main method of the Rule, I opted for "apply()" in favor of "appliesTo()", for obvious reasons. I liked the concept that you'd just call the apply() method and it returns true or false to indicate the rule did or didn't apply.
I think the main part about my former code I that I really wasn't happy with, was the Validator, I was trying to implement validation of a collection (rules for different elements) and lists (one or more rules for 1 element), pulling the error codes out of the rules, then storing them internally for later retrieval, all in one "swift" validate() method. It just didn't work out that well and left me with awkward constructions in situations like; required fields (duhu, probably the most used validation) and applying rules on optional input fields.
So, started over, from scratch sort of speaking, and coded up some rule tests, at first, these tests were nothing more than (just the body of a test method):Coded a similar test for the rules I had (10 or so) and then just coded the rules until the tests ran ok.PHP Code:$r =& new LengthRule(5,10);
$this->assertFalse($r->apply(''));
$this->assertFalse($r->apply('123'));
$this->assertTrue($r->apply('0123456789'));
$this->assertFalse($r->apply('01234567890123456789'));
After those first runs, some issues popped up:
Values gotten from a form post are strings, I might need some stronger type checking, since I will not be always validating form submissions.
There needed to be done some refactoring on the test code, or I'd be ending up with some serious code duplication.
As far as new code went, I was nowhere near what I had before
But, there really is no substitute for the feeling you get when that green bar appears telling you the tests have passed.
Then, and this is also totally credited to "SimpleTesting", I went back over my initial requirements I had set out. I took the concept of combining rules. I decided I wasn't going to leave this to the validator, but do it in the rules themselves, this way I could combine some rules together and just use that, for example to validate some column in some tabular data.
English not being my forte, I came up with method names like "addRule()", "attachRule()", "add()", "attach()", ... but eventually I decided on "chain()", just sounded logical to me, "one chains rules together"...
Based on those thinkings, I started on the tests: first I threw all tests in a directory group test, then I coded up 2 fake rules and defined 2 sets of valid and unvalid values in constants, wrote the apply methods to act on that, and so I had a way of testing the chaining of the rules without actually using "real" rules from the components under test.I should've refactored these to mocks btwPHP Code:function testChainingOfRules()
{
$r1 =& new TestableRule1();
$r2 =& new TestableRule2();
$this->assertTrue($r1->apply(VALID_1));
$this->assertFalse($r2->apply(VALID_1));
$r1->chain($r2);
$this->assertFalse($r1->apply(VALID_1));
}
Then, when I was coding the errr 'real' code, I stumbled across this issue:
Since now rules should be able to be chained to eachother, each rule is responsible for applying its chained rules with the values that it gets passed.
So I split up the actual applying of a (chained) rule in the base class:This way sub classes only have to implement the check() method and have it return true or false, which seemed a far better idea than having to write the for loop everytime (duhu) or even than doing something like parent::apply()PHP Code:function apply($value)
{
$child_rules_apply = true;
if (! empty($this->_rules))
{
for ($i = 0, $j = count($this->_rules); $i < $j; $i += 1)
{
if (! $this->_rules[$i]->apply($value))
{
$child_rules_apply = false;
}
}
}
return $child_rules_apply && $this->check($value);
function check($value)
{
return true;
}
}
Also, I declared the method protected, so the basic, public api would remain clear and simple.
I refactored the TestableRuleX classes, basically they extend Rule and implement the the check() method only. (I just hear lastcraft scream "MOCKS! you ignorant $-#!")
Coded 'till the tests ran green, which went in a straightforward, almost natural manner.
Then, I felt the "return true;" in the base check() method should go, somehow, it felt "dangerous" to me to just return true by default in something like validation, it went like "suppose you forget to override it, it could have disastrous consequences" in my brain, so I substituted the return true; for an error trigger.This triggered the need of the error handling.PHP Code:function testNotImplementedError()
{
$r =& new Rule();
$r->apply(VALID);
$this->assertErrorPattern('/must_implement_method/');
}
Returning true or false on application of a rule just isn't enough: components handling the error messages after validation may well not be the same that created them, they may very well not know (or even care to check for that matter) which rules have been applied (and probably rightfully so).
Secondly, sometimes more information is needed than just true or false, ex. Applying a length/size/range rule whereby a value must be between 2 boundaries, when the validation of such a rule fails, it would be desirable if a message to the user could be relayed indicating whether the value he supplied was too small/little/low or too high/large/big, also an indication of whether or not those boundaries are considered valid must be given...
In the previous code I had, I handled this by having the rules store their own signaled errors, later on retrieving them via a getErrors() method in the validator. That turned out not so well: Firstly, all those errors in all the rules you combine, you have to get them out again, that's a real drag, especially when one rule has to get the errors from the rules chained to it.
Secondly, to remain reusable, the rule should have no knowledge of the context in which it is applied; suppose I have an EmailAddressRule, I could use it to validate an address in a submitted subscription form, but I could also be using it to validate 1000 email addresses from a database query result, what's more, I could be using the 2 validation processes in 1 request and since I've instantiated the rule for the form, I might as well use it for validating the list, cause I'm not instantiating 1000 EmailAddressRules, that's for sure
Well, that's why I didn't want to store the error messages in the rule itself. I didn't know of any better solution than to just pass an object around where Rules would register their errors. I compromised api simplicity by adding a second parameter to the apply() method of a rule (the entry point of the actual start of the validation process).
However, it appeared the gained functionality would make more then up for it: By passing different error-collecting objects, 1 rule could be used to validate unrelated data, by passing the same error collector different rules can be used to validate related data, and if no errors should be collected, I'd pull the Null.. object trick on it
At the time I had 2 possible class names for that error collector: ErrorManager, ErrorList, since I'm not that keen on naming objects managers (all of a sudden, your code is nothing but managers, and we all know that when you've got too many managers, things are really going down the drain) I decided on ErrorList, but as I'm writing this, I'm more thinking on the lines of ValidationErrorCollector, although I might drop the "Validation" part on grounds of exessive typing work, which I reckon is not really a valid reason.
This had of course its implications on the tests and code. This is also where I first implemented a mock and have experienced the wonderful joy they bring to testing...
This is also where WACT comes into the picture:
In coding my own collection of reusable components, I've looked at WACT for 2 distinct things: The way WACT is actually loaded, and the way it does the error handling.
I personally quite like the way error handling goes in PHP to a certain extend, however, I think it's too limited if you want to trigger some more info regarding an error, especially in a multi-langual situation. I've been resorting to things like errormessage files in php (global array or defines), flat text datafiles, hardcoded messages with slight variations for each situation (a mess), $err =& new Error(...); trigger_error(serialize($err)); ... and so on.
From what I've experienced in that area, I've found the WACT implementation a very decent compromise. And so I integrated a similar way of error handling and loading global behavior into my code collection.
Since the Error class definition is already known from loading 'the framework' I thought I'd use that for validation errors. Still I wanted the code of the rules to be simple (they should not be creating new error objects and then add them to the passed error list). Ideally, they'd do something like errorList->addError('value_too_small', array('min' => $this->_min))
I decided to encapsulate the adding of errors to the list in a base method, since I hadn't actually written any code for an "ErrorList", chances would be high its interface changed, this way I only would have to change 1 method in the base class if that actually would happen. Basically this was the setError() method I had before, but since it really didn't set an error, nor added at an error (it signaled an error), I called it plain and simple error()
Time had come to code on the test. First of I code up a mock, like this:Then I wrote up a base RuleTestCase where other rule tests should extend from, in which I implemented the setup and tearDown methods to create a new clean ErrorList every time a test method ran:PHP Code:class ErrorList
{
var $_errors = array();
function ErrorList()
{
}
function addError($group, $id, $info)
{
$this->_errors[] =& new Error($group, $id, $info);
}
}
Mock::generate('ErrorList');
This made it so much easier to write the tests to check if the rules were signaling the correct error codes:PHP Code:SimpleTestOptions::ignore('RuleTestCase');
class RuleTestCase extends UnitTestCase
{
var $errorList;
function setUp()
{
$this->errorList =& new MockErrorList($this);
}
function tearDown()
{
$this->errorList->tally();
}
}
Once again, writing the actual code went straightforward and without any hassles worth mentioning.PHP Code:class LengthRuleTest extends RuleTestCase {
function LengthRuleTest() {
$this->UnitTestCase('LengthRule');
}
function testCreationWithTwoParameter() {
$this->errorList->expectCallCount('addError', 3);
$this->errorList->expectArgumentsAt(
0, 'addError',
array('validation', 'charlength_too_small', array('min' => 5))
);
$this->errorList->expectArgumentsAt(
1, 'addError',
array('validation', 'charlength_too_small', array('min' => 5))
);
$this->errorList->expectArgumentsAt(
2, 'addError',
array('validation', 'charlength_too_big', array('max' => 10))
);
$r =& new LengthRule(5,10);
$this->assertFalse($r->apply('', $this->errorList));
$this->assertFalse($r->apply('123', $this->errorList));
$this->assertTrue($r->apply('0123456789', $this->errorList));
$this->assertFalse($r->apply('01234567890123456789', $this->errorList));
}
function testExactLength() {
$this->errorList->expectCallCount('addError', 2);
$this->errorList->expectArgumentsAt(
0, 'addError',
array('validation', 'charlength_not_exact', array('length' => 5))
);
$this->errorList->expectArgumentsAt(
1, 'addError',
array('validation', 'charlength_not_exact', array('length' => 5))
);
$r =& new LengthRule(5,5);
$this->assertTrue($r->apply('12345', $this->errorList));
$this->assertFalse($r->apply('1234', $this->errorList));
$this->assertFalse($r->apply('123456', $this->errorList));
}
//...
}
At the moment, I have all the tests for the rules that I had, and the rules themselves.
I've not started writing test code for the validator yet.
It's weird that, by copying the error handling from WACT, my rule system has almost turned out exactly the same way. WACT's system however is far more evolved, also it's implemented differently because of the DataSpace SuperLayerType, if I'm not mistaking.
Now, for the validator, I've not quite decided yet, in another thread someone uttered the name "firewall", kinda like that actually.
I'm also thinking: filters, it's like rules, you apply them, maybe I build a firewall, whereby one registers filters and rules (what's the collective name for such things? FirewallRules? FireFilterAndRuleWall ? )
But I think that'll be for another free weekend, I've waisted enough valuable forum space as it is, truly sorry, just felt like sharing this ...
As a report: I estimated the time spend on it (rewrite/factor the original code to something more uselfull) around 20-25 hours, it took me around 25-30 (including test code and writing up error messages (1 language only))
The original functionality exists, the api is simpler and cleaner, and the rule has become more flexible because of the elimination of the errorcide storage.
Most "php masters" out here are probably laughing at those figures and results, but given the fact that these are my first steps in "SimpleTesting" and that I'm truly happy about the design so far, I'm supprised it only took that long really.
And, I know I'm kinda late, but much much MUCH respect to lastcraft: You have created such an incredible tool, I don't think I ever got this excited about PHP development, not even the first time I read a voostind post
EDIT 20040401: changed some initial test code, that I'd copypasted from a wrong version..
Last edited by been; Apr 1, 2004 at 04:50.
Per
Everything works on a PowerPoint slide
I suggest you stick to the PEAR packages.
I spent two years chaisng good code and also writing alot of my own code spending precious parts of my life debugging code that has already been written so many times by every one else.
Looking at pear at the beginning is quite a daunting sight but if you spend the time to learn it will save you months in developing time in the future.
A good example is here http://www.thelinuxconsultancy.co.uk/quickform.html
If you want a head start grab a copy of Harrys new books PHP Anthology. These books took me from writing procedural (bug ridden) code to writing good solid applications.
I now look to PEAR every time.




Great post been.
Yeh, test driven development is definitely the way to go. I find I catch alot of possible bugs doing it that way that I wouldn't have found otherwise.
I really like ur interface because of the cleverly simple design. It's similar to pear's, but uses classes implemented for each rule rather passing another param. I don't think it needs to be too much more complex, but of course that's for you to decide.
Thanks so much for all your help, and letting us know about your experiences on this.
Eli




Hey Been, I'm thinking of creating the following Rule Classes:
Required
MinLength(min)
MaxLength(max)
RangeLength(min,max)
OnlyAlpha : Regex
NoAlpha : Regex
OnlyNumeric : Regex
NoNumeric : Regex
OnlyAlphaNumeric : Regex
NoPunctuation : Regex
Email : Regex
Date : Regex - "^\d{4}\-\d{2}\-\d{2}$"
Time : Regex - "^\d{2}\:\2{2}$"
Phone : Regex - "^\d{2,}[\-\d{2,}]*$"
Equal(cmp_item)
NotEqual(cmp_item)
InList(list)
Any comments, redundancy, missing classes?
How does QuickForm work with Smarty (if at all)
Here is a article I found on using Smarty with Quickform.
http://www.thelinuxconsultancy.co.uk/smarty-guide.html
I used this once. Not sure if this is what you are looking for or not.
http://www.x-code.com/vdaemon_web_form_validation.php




Ahh interesting blockcipher. Thanks for the link.
Tho, I'm using it in another language, and for a non-browser based application, and want something that I can use there.
Eli





Not sure, I'm still trying to get some idea's on how to do this myself ?Any comments, redundancy, missing classes?
I'm thinking that if I have each FORM as an XML file, I could use the DOM - or better yet, XPATH - to manipulate this file, for example to append an error message dynamically to the file before it's transformed ?
But I'm having some bother with layering. For example, should the error reporting parts could be seen as being presentation ?
A Controller (not directly of course) would handle the user inputs, and putting the XML file to the View, though if the View handles the error reporting, how'd the best method be to alert the View to the bad user inputs ?
As to what rules for validation, personally I cannot see how you'd need a MaxLength, since there is a tag just for this purpose.




Front end validation (ie javascript) would alert the user via java alert (popup) box. Back end validation allerts the user via a message on the page added to the page by the server page.Originally Posted by Widow Maker
Both front and back end validation have their advantages and disadvantages.
What tag are you talking about? I have no idea what tags you are refering to since I'm talking about validation classes.Originally Posted by Widow Maker
Eli





ObviouslyBack end validation allerts the user via a message on the page added to the page by the server page.
I was meaning should the Form Processor add the message, or the View add the message
As to the tag I was talking about, it's an attribute - should have been more clearer on this point - sorry
Building up some notes, I'm thinking I could build a form on the fly, and leave it that.
An XSL stylesheet could I suppose add in a generic message based on an attribute to act a flag within any given form element which has bad input from user - one way of doing it I suppose![]()




I think validation for forms is definitely two stage. One for detecting errors. Another for presenting them. The WACT design jumps through a lot of hoops to make sure these are separate stages. Including allowing validation error messages to be defined independently of the validation rule (which allows i18n or customization of validation error messages)Originally Posted by Widow Maker
the MAXLENGTH attribute is client side. You going to trust that incoming data from the client?Originally Posted by Widow Maker




May I ask why you didn't just take the validation layer out of WACT as is? The reason I ask is that I notice alot of people using WACT throw away this part and re-implement it themselves. Which leads me to believe there is something fundamentally wrong with it. I have some ideas what that might be, but I am interested in hearing some feedback.Originally Posted by been


The length limit is not a validation rule but rather a constraint, which is a different thing.Originally Posted by Selkirk
Since in normal conditions a browser would never submit a field value that has more characters then the MAXLENGTH, if a script gets more characters than it should, that maybe a buffer overflow attack.
What a forms processing script should do is to discard the exceeding characters. That is at least what this forms class does automatically when the MAXLENGTH attribute is specified. Most databases also discard exceeding characters.
Manuel Lemos
Metastorage - Data object relational mapping layer generator
PHP Classes - Free ready to use OOP components in PHP

Always spamming your classes and your site, are you? Time to dig up some old threads on the php-dev mailing list.




Take it easy mate, manuel is making a valid argument here, even if we don't agree with it. But that is no justification for an ad hominem attack.Originally Posted by plugged


(stupid) Pride, (stupid) vanity and (some) respect for other people's work.Originally Posted by Selkirk
I already had half a validation system, and wanted to build from there.
Think one of the biggest differences in both validation systems are the way Rules and the Validator interact (other than WACT's already a system and mine is just an attempt):
WACT's rules (the SingleFieldRules) are used to validate a collection of data, a rule will only validate that part of the collection it was set out to validate. This means that the data collection to validate can be passed as a whole to the validating method of the rule.
In the rule system I've implemented (so far), 1 rule is applied to a single value (which could be an array), meaning that the necessary value has to be "taken out" of the data collection and then be passed to the validating method of the rule.
Both implementations need to have a system so it can be determined which rule should apply to which part of the datacollection.
WACT does this by storing a fieldname in the rule and comparing DataSpace keynames. (Determined at rule level)
My intention is to do this by registering a keyname with the validator when registering a rule, so you'd register a certain rule for a certain key. (Determined at validator level)
It seemed to me that by taking out the fieldname dependency in the rules, you could use them to validate other datastructures then key-based ones like associative arrays or DataSpaces.
Mind you, I've never actually used WACT (I've browsed quite a bit through the code and online docs), so I'm not sure if I can tell you anything usefull about why people take out the validation part and implement their own.
Random things that come to mind:
- The aforementioned field name dependency, maybe making the rules not generic enough? Say you have a long list of email addresses and an EmailAddressRule of some kind; Validating this in WACT should need a little workaround converting the email addresses from the list into a DataSpace, no? Still, since DataSpace is somewhat the primary type in WACT, I reckon this shouldn't be really an obstacle?
- Extending the rules by using inheritance isn't as intuitive as it maybe should be? (Because of the different error id's of parent and child: If not taken care for, the parent will add it's error to the ErrorList before the child does, trying to find an elegant solution to this myself.)
- Maybe the documentation isn't clear enough?
- People don't like the api? Although, from what I looked at, can't really see what could be wrong with it, as far as interface goes.
One thing that caught my attention is how differently Rules and Filters are used: Filters are registered with a DataSpace, whereas rules rather "work on" a DataSpace. Could have a wrong perspective here on things, but other than that a rule leaves data unmodified and a filter changes it, I don't see much difference in the use of both.
On that issue, here's a something that keeps on popping up in my head lately:
PHP arrays are quite flexible, in WACT a DataSpace is used as a container for key/value pairs.
My intention is to stick to PHP arrays for that, and implement Filters the same way as Rules, both would then apply() to a value.
But, I'm also well aware of the fact that the collective knowledge of the whole WACT team exceeds mine by a multitude of times, so there are probably some things I haven't quite thought through or simply didn't notice, maybe you could post your main reasons why WACT doesn't use the PHP array as the SuperLayerType, if it's not asked too much?
Well, it wasn't much, still I hope it can be of some use.Originally Posted by Selkirk
I'd say, go with the flow; have your base classes ready and under test, then code up the tests and the rules as you go along: everytime you need validation, re-evaluate your rules and code up those that you need, refactoring as you go along.Originally Posted by lazy_yogi
I'm thinking that only then you can end up with a decent, usable system with a nice collection of rules covering most validation needs. As Joel Spolsky said: "Good software takes 10 years, get used to it"
On the Min- Max- and RangeLength rules: Think you can throw them together in 1 class, checking the method argument count on construction (or have an optional argument) to set the minimum and maximum range.
On the No* and Only* rules: Maybe this could be solved with a generic Negation/InvertionRule ? Not sure on this one.
Per
Everything works on a PowerPoint slide




I see. The WACT validation system is dependent on the DataSpace structure. I can see where not everyone would be interested in using this structure. I have been putting some thoughts into revamping DataSpace to make it more obviously useful.Originally Posted by been
On reason for using DataSpace is to be able to validate multiple related values, such as comparing two passwords to see if they are equal. There are other multi-field validations, such as determining a valid date based on month day and year. For example Feb 29 cannot be determined as a valid date without knowing the year.
Associative arrays are easily converted into DataSpaces, although perhaps objects are not. I see the distinction about a non-dataspace based validator being more flexible. With WACT, DataSpaces are all over, but to use the WACT validator without the rest of WACT you can hardly do so if you eschew DataSpace.
I haven't seen anyone do this, but one way around this is not to inherit rules, but to chain them. There is no reason why one rule cannot be registered as a sub-rule of another. That way, that rule is only triggered if the first rule allows it, solving the "error cascade" issue.Originally Posted by been
Ouch. So true.Originally Posted by been
This is an area which I have been looking at. There is an experimental new DataSpace checked into CVS that has the concept of filters and calculated fields. The issue is that we must be able to access the orginal value as well as the "filtered" value.Originally Posted by been
For example, lets say you want to trim spaces from input values. The trimming should be done pre-validation. The post-filtering values should be used in application calculations. However, when it is time to output the values back to the user, it would be inappropriate to write back the processed values. we always want to echo back to the user in the input fields exactly what they typed. This is more important for less trivial transformations than trim.
Without having a buffer area, you cannot do this. This is the purpose of the DataSpace and I have been changing it more toward this view. I have also been looking for a better name for it.
Interestingly, there is another place where this dual representation occurs and that is in the Data access layer. Internally, an application may interpret a value as a boolean, but in the database it might be stored as a character, or an integer, or even a boolean representation. The same buffering/conversion capabilities for input are applicable in a database abstraction layer.
The WACT database abstraction layer also uses DataSpace, but does not take advantage of its capabilities as this type of buffer (yet).
The DataSpace in WACT is very similiar to the (also) horribly named ActionForm class in struts.
A few future plans for the validation architecture in WACT includes the ability to validate arrays stored in a DataSpace. This would occur when using tables in forms with array syntax: <input name="fieldname[]">. A length validation rule for this field could then be bound to fieldname[] and the validation rule would know how to apply this to every value of the array, not just a single value, and the error reporting structure would also know how to report these kinds of errors.
Another future plan is to be able to automatically create some of the validation rules directly from the database structure. Is the fact that you name field must be less that 30 characters a real requirement, or just an artificial requirement imposed by your database implementation?
WACT already uses the validation rules to generate "client" side validation. Currently, the only client side validation generated is to fill in the maxlength fields on input components. Whatever maxlength is defined in the template is overridden by the value defined in the validation rules. other "client" side validation capabilities are possible, but unimplemented, such as javascript or xforms.
Put this together with database rule generation and it should be possible to simply change the length of fields in the database and have that constraint propagate all the way through to the generated HTML.
Thank you for the in-depth reply.
Bookmarks