-
-
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
runat
attribute is useful only for server-side implementations, to differentiate between scripts that must run on the client.Comments welcome.