Home   Archive   Permalink



General error function

Hi, I know what I want to do in my program but I'm not quite sure how to get it done with error objects and error tests etc. The idea is to make a function that is passed the condition I want to test for , the field I want to focus on when there is an error, and the message indicating what field it is . the error is alerted and the function returns an error value. Here is the messy code so far:R E B O L []
        
b: [ c f msg ] [
     if error? err: try [ reduce c]
         ][
         err: disarm err
         print ["Error:" Msg err/id " at " err/near]
         focus [reduce f]
         return 0
                
     ]
view layout[
f1: field
f2: field
        
button "val" [
c: [to-decimal f1/text]
f: "f1"
msg:"Yards Per Hour"
b c f msg
     ]
]

posted by:   John       12-Apr-2014/20:35:17-7:00



I want to hand all types of errors including possibly errorneous condition testing (script or syntax errors) ideally. Definitely I want to capture invalid data errors such as alpha characters in decimal fields etc..

posted by:   john       12-Apr-2014/20:37:50-7:00



Hi John,
    
You can make a function to do whatever you want with the data entered into a field. 'load converts string data to a data type:
    
R E B O L []
test: func [val typ] [
     if typ <> type? load val [
         alert rejoin ["Must be " typ " value"]
     ]
]
view layout [
     text "Enter a date:"
     field [test value date!]
     text "Enter an integer:"
     field [test value integer!]
     text "Enter a money value:"
     field [test value money!]
]
    
You can use 'parse to do just about any other sort of validation you'd like.

posted by:   Nick       15-Apr-2014/0:59:32-7:00



Hi Nick,
    
I used your program and entered "10/xx/14 in the date field and it blew up with a syntax error.

posted by:   John O'Rourke       15-Apr-2014/14:35:47-7:00



Hi John,
    
The code example demonstrated how to convert string data into recognized data types. Wrap it in "if error? try" to handle garbage data:
    
test: func [val typ] [
     if error? try [
         if typ <> type? load val [
             alert rejoin ["Must be " typ " value"]
         ]
     ] [alert "Not a valid data type"]
]
    
You can handle more complex validation in the error handler.

posted by:   Nick       15-Apr-2014/19:04:38-7:00



Hi,
Thanks for that. Is there a way to do a foreach loop on the layout itself to find the fields and their names and any of the block values that you put next to the fields on the layout? That way you wouldn't have to call the function from the fields .

posted by:   John       15-Apr-2014/20:17:54-7:00



I prefer to do it this way, so you can handle each particular type of widget appropriately:
    
R E B O L []
test: func [val] [
     typs: reduce [date! integer! money!]
     if error? try [
         if not find typs (type? txt: load val) [
             alert rejoin [mold txt " is not a value of type: " typs]
         ]
     ] [alert rejoin [mold val " is not a valid data type"]]
]
view layout [
     text "Enter a date:"
     f: field "3-xx-2014"
     text "Enter an integer:"
     t: text-list data ["1" "a"]
     text "Enter a money value:"
     a: area "asdf"
     btn "val" [
         txts: reduce [f/text t/picked/1 a/text]
         foreach txt txts [test txt]
     ]
]
    
This will go through each of the named faces automatically:
    
R E B O L []
test: func [val] [
     typs: reduce [date! integer! money!]
     if error? try [
         if not find typs (type? txt: load val) [
             alert rejoin [mold txt " is not a value of type: " typs]
         ]
     ] [alert rejoin [mold val " is not a valid data type"]]
]
view g: layout [
     text "Enter a date:"
     f: field "3-xx-2014"
     text "Enter an integer:"
     t: text-list data ["1" "a"]
     text "Enter a money value:"
     a: area "asdf"
     btn "val" [
         txts: copy []
            foreach face g/pane [
             if face/var [append txts get-face face]
         ]
         foreach txt reduce txts [test txt]
     ]
]
    
If you want to handle the event at the level where the event occurs, without having to copy your code to each face, you could for example, use 'style to create a special text field widget which runs any (set of) validation(s) for a particular type of widget:
    
R E B O L []
test: func [val] [
     typs: reduce [date! integer! money!]
     if error? try [
         if not find typs (type? load val) [
             alert rejoin ["Must be a value of type: " typs]
         ]
     ] [alert "Not a valid data type"]
]
view layout [
     style fld field [test value]
     text "Enter a date:"
     fld
     text "Enter an integer:"
     fld
     text "Enter a money value:"
     fld
]
    
You could also use 'insert-event-func or add your function to action of the base vid-face to selectively handle other general events.

posted by:   Nick       16-Apr-2014/7:59:27-7:00



I'm pressed for time to play with this, but I've used colors instead of blinking before:
    
R E B O L []
test: func [val fc] [
     typs: reduce [date! integer! money!]
     either error? try [
         either not find typs (type? txt: load val) [
             fc/colors: [250.0.0 255.240.120]
             show fc
             return
         ] [
             fc/colors: [240.240.240 255.240.120]
             show fc
         ]
     ] [
         fc/colors: [250.0.0 255.240.120]
         show fc
     ] [
         fc/colors: [240.240.240 255.240.120]
     ]
]
view g: layout [
     text "Enter a date:"
     f: field "3-xx-2014"
     text "Enter a money value:"
     a: area "asdf"
     btn "val" [
         txts: copy []
            foreach face g/pane [
             if face/var [append txts reduce [get-face face face]]
         ]
         foreach [txt fc] reduce txts [test txt fc]
     ]
]

posted by:   Nick       18-Apr-2014/9:00:03-7:00



Oops, meant to add that to the blink post.

posted by:   Nick       18-Apr-2014/9:01:08-7:00