-
-
Save ebruchez/790257 to your computer and use it in GitHub Desktop.
| instance = model.instances['fr-persistence-instance'] | |
| resources = x.models['fr-resources-model'].vars['$fr-fr-resources'] | |
| $('error', instance).replaceWith event.response-body | |
| $('is-error', instance).replaceWith 'true' | |
| x.message 'Error with submission: ' + event.submission-id, 'xxf:log-debug' | |
| x.message event.response-body, 'xxf:log-debug' | |
| switch event['error-type'] | |
| when 'validation-error' | |
| $('message', instance).replaceWith $('detail messages form-validation-error', resources) | |
| $('#fr-message-validation-error').toggle() | |
| model.dispatch 'fr-visit-alerts' | |
| x.models['fr-sections-model'].dispatch 'fr-expand-all' | |
| when 'xxforms-pending-uploads' | |
| x.message resources.detail.messages['upload-in-progress'] | |
| else | |
| $('message', instance).replaceWith $('detail messages database-error', resources) | |
| $('#fr-message-fatal-error').toggle() |
| instance = model.instances['fr-persistence-instance'] | |
| resources = x.models['fr-resources-model'].vars['$fr-fr-resources'] | |
| instance.error = event.response-body | |
| instance['is-error'] = 'true' | |
| x.message 'Error with submission: ' + event.submission-id, 'xxf:log-debug' | |
| x.message event.response-body, 'xxf:log-debug' | |
| switch event['error-type'] | |
| when 'validation-error' | |
| instance.message = resources.detail.messages.form-validation-error | |
| x.toggle 'fr-message-validation-error' | |
| model.dispatch 'fr-visit-alerts' | |
| x.models['fr-sections-model'].dispatch 'fr-expand-all' | |
| when 'xxforms-pending-uploads' | |
| x.message resources.detail.messages['upload-in-progress'] | |
| else | |
| instance.message = resources.detail.messages.database-error | |
| x.toggle 'fr-message-fatal-error' |
| val instance = model.instances("fr-persistence-instance") | |
| val resources = models("fr-resources-model").vars("$fr-fr-resources") | |
| instance \ "error" setvalue event.responseBody | |
| instance \ "is-error" setvalue "true" | |
| message("Error with submission: " + event.submissionId, "xxf:log-debug") | |
| message(event("response-body"), "xxf:log-debug") | |
| event("error-type") match { | |
| case "validation-error" => | |
| instance \ "message" setvalue (resources \ "detail" \ "messages" \ "form-validation-error") | |
| toggle("fr-message-validation-error") | |
| model.dispatch("fr-visit-alerts") | |
| models("fr-sections-model").dispatch("fr-expand-all") | |
| case "xxforms-pending-uploads" => | |
| message(resources \ "detail" \ "messages" \ "upload-in-progress") | |
| case _ => | |
| instance \ "message" setvalue (resources \ "detail" \ "messages" \ "database-error") | |
| toggle("fr-message-fatal-error") | |
| } |
| <xf:action ev:event="fr-submit-error"> | |
| <!-- Remember there was an error --> | |
| <xf:setvalue ref="instance('fr-persistence-instance')/error" value="event('response-body')"/> | |
| <xf:setvalue ref="instance('fr-persistence-instance')/is-error">true</xf:setvalue> | |
| <!-- Log error --> | |
| <xf:message level="xxf:log-debug">Error with submission: <xf:output value="event('submission-id')"/></xf:message> | |
| <xf:message level="xxf:log-debug"><xf:output value="event('response-body')"/></xf:message> | |
| <!-- case validation-error => set error message and show validation error section in UI --> | |
| <xf:action if="event('error-type') = 'validation-error'"> | |
| <xf:setvalue ref="instance('fr-persistence-instance')/message" value="$fr-fr-resources/detail/messages/form-validation-error"/> | |
| <xf:toggle case="fr-message-validation-error"/> | |
| <!-- Mark all active alerts as visited --> | |
| <xf:dispatch name="fr-visit-alerts" target="fr-persistence-model"/> | |
| <!-- Open all sections --> | |
| <xf:dispatch name="fr-expand-all" target="fr-sections-model"/> | |
| </xf:action> | |
| <!-- case xxforms-pending-uploads => display a modal message --> | |
| <xf:action if="event('error-type') = 'xxforms-pending-uploads'"> | |
| <xf:message model="fr-resources-model" value="$fr-fr-resources/detail/messages/upload-in-progress"/> | |
| </xf:action> | |
| <!-- case _ => set error message and show fatal error section in UI --> | |
| <xf:action if="not(event('error-type') = ('validation-error', 'xxforms-pending-uploads'))"> | |
| <xf:setvalue ref="instance('fr-persistence-instance')/message" value="$fr-fr-resources/detail/messages/database-error"/> | |
| <xf:toggle case="fr-message-fatal-error"/> | |
| </xf:action> | |
| </xf:action> |
| let $instance := xf:instance('fr-persistence-instance') | |
| let $resources := xf:model('fr-resources-model', 'fr-fr-resources') | |
| let $messages := $resources/detail/messages | |
| return | |
| ( | |
| replace value of node $instance/error with xf:event('response-body'), | |
| replace value of node $instance/is-error with 'true', | |
| xf:message( | |
| ('Error with submission: ', xf:event('submission-id'), 'xxf:log-debug') | |
| 'xxf:log-debug'), | |
| xf:message(xf:event('response-body'), 'xxf:log-debug'), | |
| switch ( xf:event('error-type') ) | |
| case 'validation-error' return ( | |
| replace value of node $instance/message with $messages/form-validation-error, | |
| xf:toggle('fr-message-validation-error'), | |
| xf:dispatch('fr-visit-alerts', xf:model('fr-persistence-model')), | |
| xf:dispatch('fr-expand-all', xf:model('fr-sections-model')) | |
| ) | |
| case 'xxforms-pending-uploads' return ( | |
| xf:message($messages/upload-in-progress) | |
| ) | |
| default return ( | |
| replace value of node $instance/message with $messages/form-validation-error, | |
| xf:toggle('fr-message-fatal-error') | |
| ) | |
| ) |
Being more jQuery-like, for things that have ids (controls, instances, models…), you could imagine, instead of:
x.toggle "fr-message-validation-error"
To write:
$("#fr-message-validation-error").toggle()
That that would be an option. I see two distinct uses:
- XForms objects such as controls, models, binds (jQuery-like, as we might not actually have a DOM to work on)
- instance data (actual jQuery)
For access to instance data, there are several options:
- XPath API
- jQuery
- E4X or E4X-like
- DOM (don't need to use this directly, except if it's as basis for jQuery)
I added an attempt at using jQuery syntax for both accessing controls and data.
The following:
$('error', instance).replaceWith event.response-body
Feels like it perverts the jQuery interface. In jQuery, if something has an id, you'd expect to be able to use $("#id"), not $("id", collection). Also, maybe it is just fine to say xforms.instances["invoice"], which looks similar to document.forms["some-form"]. In some cases, this will allow one to write xforms.instances.invoice, which is syntactically lighter.
Mmh, $('error', instance) means selecting an element called error in the document instance. It's the same as instance('instance')//error.
Ah, yes, in that case I agree. I incorrectly assumed $('error', instance) meant instance('error') instead of instance('instance')//error.
Shouldn't this:
model.dispatch 'fr-visit-alerts'
actually be this instead?:
x.models['fr-persistence-model'].dispatch 'fr-visit-alerts'
In response to http://twitter.com/ebruchez/status/30046769760964608 . I thought more about integrating XForms within XQuery or the other way around, instead of replicating the XForms features in another language. But I guess something like the following would do (you know, more or less):
I think model.dispatch 'fr-visit-alerts' is right: model is implicitly pointing to the fr-persistence-model model. The idea was to have some JS objects automatically scoped for convenience, and model would tentatively one of them.
@fgeorges Thanks for the XQuery example. It looks similar enough to the JS and CS examples. I put it up as a file a the top (not sure how I can allow others to edit/add files?).
@ebruchez You're saying that model could be automatically bound to an object representing the current model?
@avernet Yes, as if the enclosing xf:action passed it as a function parameter.
The idea here is to explore how one can rewrite complex actions written with the XForms action syntax into a more lightweight notation, here CoffeeScript.
The original example is taken from an actual action in Form Runner. It is just one example of a non-trivial action (and there are way more complex ones in Form Runner!).
The API is very tentative. Ideas include:
The
runatattribute is useful only for server-side implementations, to differentiate between scripts that must run on the client.Comments welcome.