| 
									
										
										
										
											2008-06-15 03:38:12 -04:00
										 |  |  | ! Copyright (C) 2008 Slava Pestov | 
					
						
							|  |  |  | ! See http://factorcode.org/license.txt for BSD license. | 
					
						
							| 
									
										
										
										
											2008-11-13 22:49:37 -05:00
										 |  |  | USING: kernel accessors strings namespaces assocs hashtables io | 
					
						
							| 
									
										
										
										
											2009-01-30 20:28:16 -05:00
										 |  |  | mirrors math fry sequences words continuations | 
					
						
							| 
									
										
										
										
											2009-02-05 22:17:03 -05:00
										 |  |  | xml.entities xml.writer xml.syntax ;
 | 
					
						
							| 
									
										
										
										
											2008-06-15 03:38:12 -04:00
										 |  |  | IN: html.forms | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TUPLE: form errors values validation-failed ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : <form> ( -- form )
 | 
					
						
							|  |  |  |     form new
 | 
					
						
							|  |  |  |         V{ } clone >>errors | 
					
						
							|  |  |  |         H{ } clone >>values ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | M: form clone | 
					
						
							|  |  |  |     call-next-method | 
					
						
							|  |  |  |         [ clone ] change-errors | 
					
						
							|  |  |  |         [ clone ] change-values ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : check-value-name ( name -- name )
 | 
					
						
							|  |  |  |     dup string? [ "Value name not a string" throw ] unless ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : values ( -- assoc )
 | 
					
						
							|  |  |  |     form get values>> ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : value ( name -- value )
 | 
					
						
							|  |  |  |     check-value-name values at ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : set-value ( value name -- )
 | 
					
						
							|  |  |  |     check-value-name values set-at ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : begin-form ( -- ) <form> form set ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : prepare-value ( name object -- value name object )
 | 
					
						
							|  |  |  |     [ [ value ] keep ] dip ; inline
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : from-object ( object -- )
 | 
					
						
							|  |  |  |     [ values ] [ make-mirror ] bi* update ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : to-object ( destination names -- )
 | 
					
						
							|  |  |  |     [ make-mirror ] [ values extract-keys ] bi* update ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : with-each-value ( name quot -- )
 | 
					
						
							|  |  |  |     [ value ] dip '[ | 
					
						
							|  |  |  |         [ | 
					
						
							|  |  |  |             form [ clone ] change
 | 
					
						
							|  |  |  |             1+ "index" set-value | 
					
						
							|  |  |  |             "value" set-value | 
					
						
							|  |  |  |             @ | 
					
						
							|  |  |  |         ] with-scope
 | 
					
						
							|  |  |  |     ] each-index ; inline
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : with-each-object ( name quot -- )
 | 
					
						
							|  |  |  |     [ value ] dip '[ | 
					
						
							|  |  |  |         [ | 
					
						
							|  |  |  |             begin-form | 
					
						
							|  |  |  |             1+ "index" set-value | 
					
						
							|  |  |  |             from-object | 
					
						
							|  |  |  |             @ | 
					
						
							|  |  |  |         ] with-scope
 | 
					
						
							|  |  |  |     ] each-index ; inline
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | SYMBOL: nested-forms | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : with-form ( name quot -- )
 | 
					
						
							|  |  |  |     '[ | 
					
						
							| 
									
										
										
										
											2008-09-10 23:11:40 -04:00
										 |  |  |         _ | 
					
						
							| 
									
										
										
										
											2008-06-15 03:38:12 -04:00
										 |  |  |         [ nested-forms [ swap prefix ] change ] | 
					
						
							|  |  |  |         [ value form set ] | 
					
						
							|  |  |  |         bi
 | 
					
						
							|  |  |  |         @ | 
					
						
							|  |  |  |     ] with-scope ; inline
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : nest-form ( name quot -- )
 | 
					
						
							|  |  |  |     swap [ | 
					
						
							|  |  |  |         [ | 
					
						
							|  |  |  |             <form> form set
 | 
					
						
							|  |  |  |             call
 | 
					
						
							|  |  |  |             form get
 | 
					
						
							|  |  |  |         ] with-scope
 | 
					
						
							|  |  |  |     ] dip set-value ; inline
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TUPLE: validation-error value message ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | C: <validation-error> validation-error | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : validation-error ( message -- )
 | 
					
						
							|  |  |  |     form get
 | 
					
						
							|  |  |  |     t >>validation-failed | 
					
						
							|  |  |  |     errors>> push ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : validation-failed? ( -- ? )
 | 
					
						
							|  |  |  |     form get validation-failed>> ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : define-validators ( class validators -- )
 | 
					
						
							|  |  |  |     >hashtable "validators" set-word-prop ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : validate ( value quot -- result )
 | 
					
						
							|  |  |  |     [ <validation-error> ] recover ; inline
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : validate-value ( name value quot -- )
 | 
					
						
							|  |  |  |     validate | 
					
						
							|  |  |  |     dup validation-error? [ form get t >>validation-failed drop ] when
 | 
					
						
							|  |  |  |     swap set-value ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-09-23 23:01:26 -04:00
										 |  |  | : validate-values ( assoc validators -- )
 | 
					
						
							| 
									
										
										
										
											2008-09-10 23:11:40 -04:00
										 |  |  |     swap '[ [ dup _ at ] dip validate-value ] assoc-each ;
 | 
					
						
							| 
									
										
										
										
											2008-11-13 22:49:37 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | : render-validation-errors ( -- )
 | 
					
						
							|  |  |  |     form get errors>> | 
					
						
							|  |  |  |     [ | 
					
						
							| 
									
										
										
										
											2009-01-30 20:28:16 -05:00
										 |  |  |         [ [XML <li><-></li> XML] ] map
 | 
					
						
							|  |  |  |         [XML <ul class="errors"><-></ul> XML] write-xml | 
					
						
							| 
									
										
										
										
											2008-11-13 22:49:37 -05:00
										 |  |  |     ] unless-empty ;
 |