I tried to introduce you into validators yesterday. Now let's try to write on of our own. I will use the example I wrote just for showing you how the validation stuff may work, but this time I'll write one validator myself (to see wheter my assumptions made in ucwTutorialGettingABitFurther were correct
See ucwTutorialValidationCode example 1
As you can see we have used the NOT-EMPTY-VALIDATOR, now we'll try te replace it with an validator which just accepts letters (A-Za-z) but no numbers. Now usually I would looking into regular expressions. But for that we would need an extra dependency. Let's leave it out for now and accept that we may oversee some letters we probably do not want to have.
Here's my first try on implementing that validator.
(defmethod validate ((form get-some-input) (validator alpha-char-validator))
(let ((value (client-value (input-field form)))
(result t))
(setf result (and value
(not (string= "" value))))
(when result
(setf result (every #'alpha-char-p value)))
result))
Can we test it without the web form?
Let's try:
(defun alpha-char-validator-test (some-string)
(let ((form (make-instance 'get-some-input))
(validator (make-instance 'alpha-char-validator)))
(setf (client-value (input-field form)) some-string)
(assert (validate form validator))))
calling it from the command line:
There is no applicable method for the generic function #when called with arguments (:UNBOUND). [Condition of type SIMPLE-ERROR] Restarts: 0: [ABORT-REQUEST] Abort handling SLIME request. 1: [TERMINATE-THREAD] Terminate this thread (#
)
Aeh, hm, dead end. Now let's wait a bit, it seems something is lacking. Now we are in an uncomfortable situation. We can not test it that way separatly. But is there another way?
Let's step back and see the problem. We like to get some input from the user and this input should consist just of alpha-chars, we know that we'll get some kind of value from the input form. So it seems we can drag out the validation code in a separate function. Let's try this road:
(defun check-on-alpha-chars (some-string)
"Break out the validation test to a simple test
on a string."
(assert (stringp some-string)) ; just to be sure
(and (not (string= "" some-string))
(every #'alpha-char-p some-string)))
testing now should work
(check-on-alpha-chars "eins") T TUTORIAL> (check-on-alpha-chars "eins;") NIL TUTORIAL> (check-on-alpha-chars "eins1") NIL TUTORIAL> (check-on-alpha-chars nil) The assertion (STRINGP SOME-STRING) failed. [Condition of type SIMPLE-ERROR]Not exhaustive but probably on the right track. The other code now changes to:Restarts: 0: [CONTINUE] Retry assertion. 1: [ABORT-REQUEST] Abort handling SLIME request. 2: [TERMINATE-THREAD] Terminate this thread (#
)
(defmethod validate ((field string-field) (validator alpha-char-validator))
(let ((value (client-value field)))
(and value
(stringp value)
(check-on-alpha-chars value))))
Nice separation of concerns, I guess this was a "good idea" (tm) ;-)
Now we have to change the code to use our new validator:
(defcomponent get-some-input (simple-window-component)
((input-field :accessor input-field
:initform (make-instance
'string-field
:input-size 20
:validators (list (make-instance 'alpha-char-validator))))))
Load the web page to get the input and try a few examples.
!! GLITCH? Now a #\Space is obviously not allowed. Please modify the source that you accept any alpha-char + #\Space.
We now have in place
I invite you to write the needed code to get our example pages uses the validation.
The current sources can you get from Tutorial Sources 2006-03-17
Next: ucwTutorialAddingAValidatorToTheExample ; Previous: ucwTutorialGettingABitFurther
Page in this topic: ucwTutorialAddingAValidatorToTheExample
Also linked from: ucw Tutorial ucwTutorialGettingABitFurther
CLiki pages can be edited by anyone at any time. Imagine a fearsomely comprehensive disclaimer of liability. Now fear, comprehensively