Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
XForms action in XML syntax and with tentative CoffeeScript syntax
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')
)
)
@ebruchez

This comment has been minimized.

Show comment Hide comment
@ebruchez

ebruchez Jan 21, 2011

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:

  • expose an object-oriented JavaScript API
  • provide native XML navigation into XML data, for example through E4X (JavaScript) or at least simple "dot" notation

The runat attribute is useful only for server-side implementations, to differentiate between scripts that must run on the client.

Comments welcome.

Owner

ebruchez commented Jan 21, 2011

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:

  • expose an object-oriented JavaScript API
  • provide native XML navigation into XML data, for example through E4X (JavaScript) or at least simple "dot" notation

The runat attribute is useful only for server-side implementations, to differentiate between scripts that must run on the client.

Comments welcome.

@avernet

This comment has been minimized.

Show comment Hide comment
@avernet

avernet Jan 22, 2011

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()

avernet commented Jan 22, 2011

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()
@ebruchez

This comment has been minimized.

Show comment Hide comment
@ebruchez

ebruchez Jan 22, 2011

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)
Owner

ebruchez commented Jan 22, 2011

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)
@ebruchez

This comment has been minimized.

Show comment Hide comment
@ebruchez

ebruchez Jan 22, 2011

I added an attempt at using jQuery syntax for both accessing controls and data.

Owner

ebruchez commented Jan 22, 2011

I added an attempt at using jQuery syntax for both accessing controls and data.

@avernet

This comment has been minimized.

Show comment Hide comment
@avernet

avernet Jan 24, 2011

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.

avernet commented Jan 24, 2011

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.

@ebruchez

This comment has been minimized.

Show comment Hide comment
@ebruchez

ebruchez Jan 24, 2011

Mmh, $('error', instance) means selecting an element called error in the document instance. It's the same as instance('instance')//error.

Owner

ebruchez commented Jan 24, 2011

Mmh, $('error', instance) means selecting an element called error in the document instance. It's the same as instance('instance')//error.

@avernet

This comment has been minimized.

Show comment Hide comment
@avernet

avernet Jan 24, 2011

Ah, yes, in that case I agree. I incorrectly assumed $('error', instance) meant instance('error') instead of instance('instance')//error.

avernet commented Jan 24, 2011

Ah, yes, in that case I agree. I incorrectly assumed $('error', instance) meant instance('error') instead of instance('instance')//error.

@fgeorges

This comment has been minimized.

Show comment Hide comment
@fgeorges

fgeorges Jan 26, 2011

Shouldn't this:

model.dispatch 'fr-visit-alerts'

actually be this instead?:

x.models['fr-persistence-model'].dispatch 'fr-visit-alerts'

Shouldn't this:

model.dispatch 'fr-visit-alerts'

actually be this instead?:

x.models['fr-persistence-model'].dispatch 'fr-visit-alerts'

@fgeorges

This comment has been minimized.

Show comment Hide comment
@fgeorges

fgeorges Jan 26, 2011

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):

See file

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):

See file

@ebruchez

This comment has been minimized.

Show comment Hide comment
@ebruchez

ebruchez Jan 26, 2011

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.

Owner

ebruchez commented Jan 26, 2011

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.

@ebruchez

This comment has been minimized.

Show comment Hide comment
@ebruchez

ebruchez Jan 26, 2011

@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?).

Owner

ebruchez commented Jan 26, 2011

@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?).

@avernet

This comment has been minimized.

Show comment Hide comment
@avernet

avernet Jan 26, 2011

@ebruchez You're saying that model could be automatically bound to an object representing the current model?

avernet commented Jan 26, 2011

@ebruchez You're saying that model could be automatically bound to an object representing the current model?

@ebruchez

This comment has been minimized.

Show comment Hide comment
@ebruchez

ebruchez Jan 26, 2011

@avernet Yes, as if the enclosing xf:action passed it as a function parameter.

Owner

ebruchez commented Jan 26, 2011

@avernet Yes, as if the enclosing xf:action passed it as a function parameter.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment