Post Tutorial comments

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
9 messages Options
Reply | Threaded
Open this post in threaded view
|

Post Tutorial comments

Elliot Finley
Janko,
Thanks for fixing the truncated lines on the tutorial.  After
completing the tutorial I have a couple of questions:

#1) Where would I hook in data validations?

#2) UrlResolver: This is slick in a small tutorial but doesn't it mean
I can not scale past a single image?  It seems like it would also mean
I have to use image persistence because the urlResolver is holding a
reference to all the objects.  I'm hoping I'm way off the mark here.
_______________________________________________
Aida mailing list
[hidden email]
http://lists.aidaweb.si/mailman/listinfo/aida
Reply | Threaded
Open this post in threaded view
|

Re: Post Tutorial comments

Janko Mivšek
Hi Elliot,

On 11. 04. 2011 22:33, Elliot Finley wrote:
> Janko,
> Thanks for fixing the truncated lines on the tutorial.  After
> completing the tutorial I have a couple of questions:

Nice to hear that!
>
> #1) Where would I hook in data validations?

See the WebDemoApp>>ajaxValidationExample :
 ...
 field := e cell addInputFieldAspect: #year for: self size: 4.
 field
   onChangePost;
   validIfTrue: [:value | value asInteger = Date today year];
   errorText: 'Wrong!'.
 e newCell add: field errorElement.

So, #validIfTrue: aBlock is the main thing for making a validation of
your data. If this block doesn’t pass, submitting of a whole form is
blocked. Only until all fields on form are valid, submitting will succeed.

What you see in above demo is an additional ajaxified validation and
error reporting immediately after data entry.

> #2) UrlResolver: This is slick in a small tutorial but doesn't it mean
> I can not scale past a single image?  It seems like it would also mean
> I have to use image persistence because the urlResolver is holding a
> reference to all the objects.  I'm hoping I'm way off the mark here.

URLResolver is only one of possible resolvers and you can add you own of
you really need it. There is a WebRouter where you can register an
additional one and where you can see some more already. URLResolver
itself is also a two way resolver: url->object and also very important
object->url. Later is what makes navigation in Aida apps so easy so
powerful.

URLResolver itself is capable to resolve up to about 100K objects, after
this it becomes slow because of hashing, specially in object->url way.
But funny thing is that I didn't yet got so big web app to need more
that so much objects.

URLResolver is also meant for long living objects. For image persistency
or GLASS therefore. For relational mapping where you usually have very
short living objects in image just representing the data in relational
database, the standalone App approach is maybe a better path to go. Idea
is to have one App for all objects of one class you are presenting. Say
you have a table of persons, you prepare a PersonApp class and register
it as a class on some url:

        AIDASite default register: PersonApp onUrl: /persons

Hope this helps a bit
Janko



> _______________________________________________
> Aida mailing list
> [hidden email]
> http://lists.aidaweb.si/mailman/listinfo/aida
>

--
Janko Mivšek
Aida/Web
Smalltalk Web Application Server
http://www.aidaweb.si
_______________________________________________
Aida mailing list
[hidden email]
http://lists.aidaweb.si/mailman/listinfo/aida
Reply | Threaded
Open this post in threaded view
|

Re: Post Tutorial comments

Elliot Finley
2011/4/11 Janko Mivšek <[hidden email]>:

>> #1) Where would I hook in data validations?
>
> See the WebDemoApp>>ajaxValidationExample :
>  ...
>  field := e cell addInputFieldAspect: #year for: self size: 4.
>  field
>   onChangePost;
>   validIfTrue: [:value | value asInteger = Date today year];
>   errorText: 'Wrong!'.
>  e newCell add: field errorElement.
>
> So, #validIfTrue: aBlock is the main thing for making a validation of
> your data. If this block doesn’t pass, submitting of a whole form is
> blocked. Only until all fields on form are valid, submitting will succeed.
>
> What you see in above demo is an additional ajaxified validation and
> error reporting immediately after data entry.

how would I do a validation based on another form field.  For example
if I had a scheduling application and I had a startDate and endDate.
I would want to validate that both dates were in the future and I
would want to validate that startDate < endDate.

>> #2) UrlResolver: This is slick in a small tutorial but doesn't it mean
>> I can not scale past a single image?  It seems like it would also mean
>> I have to use image persistence because the urlResolver is holding a
>> reference to all the objects.  I'm hoping I'm way off the mark here.
>
> URLResolver is only one of possible resolvers and you can add you own of
> you really need it. There is a WebRouter where you can register an
> additional one and where you can see some more already. URLResolver
> itself is also a two way resolver: url->object and also very important
> object->url. Later is what makes navigation in Aida apps so easy so
> powerful.

Looking at URLResolver, it looks like if I want to scale past a single
image, I would need to persist allWebPages and allURLLinks to my
database (Magma for example).  The only problem is allWebPages is an
identityDictionary.  The identity will change each time it is brought
in from the database.

Am I looking at this the right way?  If so, do you know of a way to solve this?

> URLResolver itself is capable to resolve up to about 100K objects, after
> this it becomes slow because of hashing, specially in object->url way.
> But funny thing is that I didn't yet got so big web app to need more
> that so much objects.

perhaps a btree structure rather than a hash structure?  a little
slower with few objects but much much faster after the hash starts to
degrade.

> URLResolver is also meant for long living objects. For image persistency
> or GLASS therefore.

This makes sense but, I'd also like to be able to use Magma as an
option.  It appears that the only obstacle is the allWebPages
IdentityDictionary.  I don't know how to persist that in Magma since
the identity of an object will change each time it's resurrected from
the database.  Any thoughts on this would be appreciated.

Elliot
_______________________________________________
Aida mailing list
[hidden email]
http://lists.aidaweb.si/mailman/listinfo/aida
Reply | Threaded
Open this post in threaded view
|

Re: Post Tutorial comments

FDominicus
Elliot Finley <[hidden email]> writes:

> 2011/4/11 Janko Mivšek <[hidden email]>:
>>> #1) Where would I hook in data validations?
>>
>> See the WebDemoApp>>ajaxValidationExample :
>>  ...
>>  field := e cell addInputFieldAspect: #year for: self size: 4.
>>  field
>>   onChangePost;
>>   validIfTrue: [:value | value asInteger = Date today year];
>>   errorText: 'Wrong!'.
>>  e newCell add: field errorElement.

I think this block is not "enough". I've checked also with Iliad and
both Aida/Web and Iliad are just using a block. I think one should use a
class hierachy for that.

Pseudo Code

Klasse Validiation

       validate

....

Maybe this Validatian stuff needs some link or relationship to other
fields and or business rules.

One can see the "shortcomings" of this block int he book a mentoring
course in smalltal from Andres Vallhoud.

I suggest checking his SUnit based Validation code.

Just so much if we use ths blocks we'll have code duplication over and
over and over again

validIfTrue: [:value | value asInteger = Date today year];
   errorText: 'Wrong!'.



and it will end in somethin like

validIfTrue: [:value | (((value isEmpty not) and: (value isNumeric)))
and: value isFractional not .... ... ...


....
errorText: 'Value must be a non empty numeric value


I think we'd better have classes which encapsulate the Validations.

class Validaor

class NotISmptyValidator

   

and we just have to instantiate the proper classes and not "just" copy&
paste code blocks around.

>
> how would I do a validation based on another form field.  For example
> if I had a scheduling application and I had a startDate and endDate.
> I would want to validate that both dates were in the future and I
> would want to validate that startDate < endDate.
difficult with just von value indeed but if you'd have validators you
could have

DateValidatorWithDataRange
        fromDate:
        toDate:

        validate
              fromDate <= toDate if....


vl := DateValidatorWirthDataRange new
vl fromDate:
vl toDate


form addValidator: vl....

there ist still another problem the presenting of date.

we have code like:
columnAspects: #(#tanNr #date #amount #comment nil);
                column: 1 addBlock: [ :each |
                        (WebElement new) addLinkTo: each text: each tanNr];
            column: 2 addBlock: ... each date asString !!!
            column: 3 addBlock each amount transferAmountIntoString

                 column: 5 addBlock: [ :each | | el nL |


We need to "know" the class of all "variables." and so we can not get
this better automated. Now compare it to:

Presenter
        present
          ^ someStrinpresentation.

We'd just have to write than
columnAspects: #(#tanNr #date #amount #comment nil);

and the column calls the present message....  

So we'd may be able not  having to write this code over an over again.
In the end we probably can put all the Elements in another class and
just write

thisClass present.....




The problem comes if you see how the "transformation" between objects
and String are done:

autoConvertString: aString toObject: anObject
        "try to convert string depending on object type"
        (anObject isKindOf: String) ifTrue: [^aString].
        (anObject isKindOf: Integer) ifTrue: [^aString asInteger].
        (anObject isKindOf: FixedPoint) ifTrue: [^aString asFixedPoint: anObject scale].
        (anObject isKindOf: Date) ifTrue: [^Date readSloFrom: aString readStream].
        anObject isNil ifTrue: [^aString].
        ^aString

There's no way to change the presentation of Date but to add to rewrite
this method.

Blocks are surly fine but I think they are not good enough for such
repeating tasks. We should use classes for it and we'd  have much more
"reusability".

I know you mileage may vary. However I'm not alone with that
suggestions.... This also was implemented in CL-HTTP and CLIM earlier,
so it's IMHO a worthwhile pattern which is IMHO undervalued:

http://www.cl-http.org:8000/cl-http/frame.html

The different validators and Accepters are surely collectable and would
make it easier to build larger functional blocks.

Regards
Friedrich



--
Q-Software Solutions GmbH; Sitz: Bruchsal; Registergericht: Mannheim
Registriernummer: HRB232138; Geschaeftsfuehrer: Friedrich Dominicus
_______________________________________________
Aida mailing list
[hidden email]
http://lists.aidaweb.si/mailman/listinfo/aida
Reply | Threaded
Open this post in threaded view
|

Re: Post Tutorial comments - Magma persistency

Janko Mivšek
In reply to this post by Elliot Finley
On 18. 04. 2011 06:54, Elliot Finley wrote:

>>> #2) UrlResolver: This is slick in a small tutorial but doesn't it mean
>>> I can not scale past a single image?  It seems like it would also mean
>>> I have to use image persistence because the urlResolver is holding a
>>> reference to all the objects.  I'm hoping I'm way off the mark here.
>>
>> URLResolver is only one of possible resolvers and you can add you own of
>> you really need it. There is a WebRouter where you can register an
>> additional one and where you can see some more already. URLResolver
>> itself is also a two way resolver: url->object and also very important
>> object->url. Later is what makes navigation in Aida apps so easy so
>> powerful.
>
> Looking at URLResolver, it looks like if I want to scale past a single
> image, I would need to persist allWebPages and allURLLinks to my
> database (Magma for example).  The only problem is allWebPages is an
> identityDictionary.  The identity will change each time it is brought
> in from the database.

Yes, in case of ODB persistence the best way is to persist all AIDASite,
even more, start with SwazooServer then cut the persistence for things
that are transient. In SwazooServer #servers instvar, in Aida session
application state (instances of App classes in WebSession instvar
#appsForObjects), etc.

I have similar solution developed for Gemstone (GS) on VisualWorks (VW)
(not GLASS) long time ago, in this case GS objects are replicated to VW
image. GS uses special methods with directives on class side to
determine, which instance variables should be made persistent and which not.

I'm pretty interested to use Magma for persistency of Aida based
projects and if you are interested to help here, it would be really
nice. I think also Chris Muller, author of Magma will be happy to help.

Best regards Janko

>
> Am I looking at this the right way?  If so, do you know of a way to solve this?
>
>> URLResolver itself is capable to resolve up to about 100K objects, after
>> this it becomes slow because of hashing, specially in object->url way.
>> But funny thing is that I didn't yet got so big web app to need more
>> that so much objects.
>
> perhaps a btree structure rather than a hash structure?  a little
> slower with few objects but much much faster after the hash starts to
> degrade.
>
>> URLResolver is also meant for long living objects. For image persistency
>> or GLASS therefore.
>
> This makes sense but, I'd also like to be able to use Magma as an
> option.  It appears that the only obstacle is the allWebPages
> IdentityDictionary.  I don't know how to persist that in Magma since
> the identity of an object will change each time it's resurrected from
> the database.  Any thoughts on this would be appreciated.
>
> Elliot

--
Janko Mivšek
Aida/Web
Smalltalk Web Application Server
http://www.aidaweb.si
_______________________________________________
Aida mailing list
[hidden email]
http://lists.aidaweb.si/mailman/listinfo/aida
Reply | Threaded
Open this post in threaded view
|

Re: Post Tutorial comments - validation

Janko Mivšek
In reply to this post by Elliot Finley
Hi Elliot,

Let me split this thread in two branches, first one about validation:

On 18. 04. 2011 06:54, Elliot Finley wrote:

> 2011/4/11 Janko Mivšek <[hidden email]>:
>>> #1) Where would I hook in data validations?
>>
>> See the WebDemoApp>>ajaxValidationExample :
>>  ...
>>  field := e cell addInputFieldAspect: #year for: self size: 4.
>>  field
>>   onChangePost;
>>   validIfTrue: [:value | value asInteger = Date today year];
>>   errorText: 'Wrong!'.
>>  e newCell add: field errorElement.
>>
>> So, #validIfTrue: aBlock is the main thing for making a validation of
>> your data. If this block doesn’t pass, submitting of a whole form is
>> blocked. Only until all fields on form are valid, submitting will succeed.
>>
>> What you see in above demo is an additional ajaxified validation and
>> error reporting immediately after data entry.
>
> how would I do a validation based on another form field.  For example
> if I had a scheduling application and I had a startDate and endDate.
> I would want to validate that both dates were in the future and I
> would want to validate that startDate < endDate.

If you do Ajax single field posting as in above example, you have value
of first field already saved into domain object, so you can use it in
validation of second field, something like:

   field
        ...
        validIfTrue: [:endDate | self observee startDate < endDate ]
        ...

Best regards
Janko


--
Janko Mivšek
Aida/Web
Smalltalk Web Application Server
http://www.aidaweb.si
_______________________________________________
Aida mailing list
[hidden email]
http://lists.aidaweb.si/mailman/listinfo/aida
Reply | Threaded
Open this post in threaded view
|

Re: Post Tutorial comments - validation

Elliot Finley
2011/4/20 Janko Mivšek <[hidden email]>:

> Hi Elliot,
>
> Let me split this thread in two branches, first one about validation:
>
> On 18. 04. 2011 06:54, Elliot Finley wrote:
>> 2011/4/11 Janko Mivšek <[hidden email]>:
>>>> #1) Where would I hook in data validations?
>>>
>>> See the WebDemoApp>>ajaxValidationExample :
>>>  ...
>>>  field := e cell addInputFieldAspect: #year for: self size: 4.
>>>  field
>>>   onChangePost;
>>>   validIfTrue: [:value | value asInteger = Date today year];
>>>   errorText: 'Wrong!'.
>>>  e newCell add: field errorElement.
>>>
>>> So, #validIfTrue: aBlock is the main thing for making a validation of
>>> your data. If this block doesn’t pass, submitting of a whole form is
>>> blocked. Only until all fields on form are valid, submitting will succeed.
>>>
>>> What you see in above demo is an additional ajaxified validation and
>>> error reporting immediately after data entry.
>>
>> how would I do a validation based on another form field.  For example
>> if I had a scheduling application and I had a startDate and endDate.
>> I would want to validate that both dates were in the future and I
>> would want to validate that startDate < endDate.
>
> If you do Ajax single field posting as in above example, you have value
> of first field already saved into domain object, so you can use it in
> validation of second field, something like:
>
>   field
>        ...
>        validIfTrue: [:endDate | self observee startDate < endDate ]
>        ...

Okay.  This leads to another question though.  If the first field is
already committed to the domain object by the time they are at the
second field, then you have the possibility of leaving a domain object
in an invalid state.  i.e. the user could update some fields and not
others.  Ideally, you'd want to have an all or nothing approach.  Is
there a way to do total form validation before the fields are
committed to the domain model?  perhaps some non-javascript way?

Thanks,
Elliot
_______________________________________________
Aida mailing list
[hidden email]
http://lists.aidaweb.si/mailman/listinfo/aida
Reply | Threaded
Open this post in threaded view
|

Re: Post Tutorial comments - validation

Herbert König
Hi Elliot,


EF> others.  Ideally, you'd want to have an all or nothing approach.  Is
EF> there a way to do total form validation before the fields are
EF> committed to the domain model?  perhaps some non-javascript way?

while I accept the arguments on validation of Friedrich and see their
usefulness, just let me state two things:

- Ajax was a move away from whole form posts for good reasons. But I'm
sure you can still make every action a Form post in Aida.

- In my own application the web interface always works on a copy of
the model object which is only committed when it's in proper state
regarding the whole domain model. For example an appointment may
itself be in a valid state but may block the necessary travel time to
the next appointment in the calendar.

So for me validation is not a matter of the web interface.

Again, I'm not arguing against Friedrich's proposals on validation,
maybe you even want to scan the list archives for those validation
discussions. I just describe the way I'm doing it today.


Cheers,

Herbert                            mailto:[hidden email]

_______________________________________________
Aida mailing list
[hidden email]
http://lists.aidaweb.si/mailman/listinfo/aida
Reply | Threaded
Open this post in threaded view
|

Re: Post Tutorial comments - validation

FDominicus
Herbert König <[hidden email]> writes:

> Hi Elliot,
>
>
> EF> others.  Ideally, you'd want to have an all or nothing approach.  Is
> EF> there a way to do total form validation before the fields are
> EF> committed to the domain model?  perhaps some non-javascript way?
>
> while I accept the arguments on validation of Friedrich and see their
> usefulness, just let me state two things:
>
> - Ajax was a move away from whole form posts for good reasons. But I'm
> sure you can still make every action a Form post in Aida.
>
> - In my own application the web interface always works on a copy of
> the model object which is only committed when it's in proper state
> regarding the whole domain model. For example an appointment may
> itself be in a valid state but may block the necessary travel time to
> the next appointment in the calendar.
>
> So for me validation is not a matter of the web interface.
>
> Again, I'm not arguing against Friedrich's proposals on validation,
> maybe you even want to scan the list archives for those validation
> discussions. I just describe the way I'm doing it today.
I do not disagree. You just have to see it in the context of
presentatan and getting form/to a string representation of some object.

And if we follow the rules of having difference defence walls we surely
should have validation on the view side (and this  is what we are
talking here) and validation on the model site..

So in the end we probably have three levels of validation
1) validaton based on the input in one "input  area"
2) validation based on all the input files of a form
3) validaton on the model side.


You copy of the model side is somewhere between 2-3.

My proposal especially handles this sorry not very extensible
autoConvert function.
autoConvertToString: anObject
        "try to convert object to string depending on object type"
        "Squeak specific!"
        (anObject isKindOf: String) ifTrue: [^anObject].
        (anObject isKindOf: Integer) ifTrue: [^anObject printString].
        (anObject isKindOf: Point) ifTrue: [^anObject printDotString]. "???" "Squeak specific!"
        (anObject isKindOf: Date) ifTrue: [^anObject shorterPrintSloString].
        anObject aidaIsAssociation ifTrue: [^anObject]. "multilingual"
        ^anObject printString

You can not have a different presentation here but you "must" use
shorterPrintSloString. This is not good.

In the end one must admit. Validation is not really easy and sorry it
often just feels like an afterthought. Therfor I suggests an alternative
approach which I think is  at least better than what there currently
is...

YMMV of course.

Friedrich

--
Q-Software Solutions GmbH; Sitz: Bruchsal; Registergericht: Mannheim
Registriernummer: HRB232138; Geschaeftsfuehrer: Friedrich Dominicus
_______________________________________________
Aida mailing list
[hidden email]
http://lists.aidaweb.si/mailman/listinfo/aida