MODX Forms via AJAX

Handle AJAX-submitted forms in MODX with JSON responses.

May 31, 2016

AJAX Forms FTW

Your website haz formz but you wanna do it all fancy with AJAX. You can do this in MODX by setting up a dedicated Resource that calls the FormIt Snippet. Your JS will POST the form to that Resource, and then you probably want it to return JSON so you can pass any errors and messages back to the user in the browser.

Hrmph

As it turns out, it's a bit of a slog to get FormIt to respond with JSON. You pretty much have to format the JSON in a tpl Chunk and insert the values via FormIt placeholders. The really annoying part is that the error messages don't come in JSON—often they're wrapped in HTML actually. You can customize most, if not all, the output, but that's overriding a lot of Chunks, and you have to call an output modifier on every placeholder to ensure the value is escaped for JSON. Ugh.

MODX and FormIt To The Rescue!

Well as of FormIt version 2.2.10, there's an easier way. I submitted a PR that the fine folks at Sterc kindly reviewed and merged—along with important security-related patches by other awesome MODX community members. (I <3 open-source!)

Note: the official docs for FormIt are here: https://rtfm.modx.com/extras/revo/formit

How It Works

You can find a usage example at the PR on Github but essentially you want to include these properties in your FormIt call:

&validationErrorBulkFormatJson=`1`
&validationErrorMessage=`{"success":false,"errors":[[+errors]]}`
&hookErrorJsonOutputPlaceholder=`hook_error_placeholder`
&errTpl=`[[+error]]`

Break It Down

  • "validationErrorBulkFormatJson" tells FormIt to JSONify the raw array of validation errors, instead of formatting each one with the Chunk specified in the "validationErrorBulkTpl" property.
  • "validationErrorMessage" is the default FormIt property for the message that there are validation errors. In this case, we add a bit of JSON, customized for our application, and insert the errors JSON into an object property with the key "errors". You could just return the errors JSON if you want, or put it inside whatever Javascript object you want.
  • "hookErrorJsonOutputPlaceholder" if this property is not empty, FormIt will send hook-generated errors (hooks can generate their own errors, which is not the same as validation errors) to this placeholder in JSON format. I chose not to entirely circumvent the normal hook error handling, because you might want to wrap the hook error message with HTML to insert directly in your DOM, or you might want a placeholder on the page somewhere to display the error message the old-fashioned way...I dunno, it just seemed a little too opinionated to skip the error processing entirely in this context.
  • The compromise is that if you don't want any formatting of your error message, you'll need to pass the naked error placeholder to the "errTpl" property, like the example above.

Your Resource that has the FormIt call, would also need these placeholders:

[[!+fi.validation_error_message]]

This shows the value of the "validationErrorMessage" property. If there was a validation error(s), you would get something like:

{
  "success": false,
  "errors": {
    "type": "This field is required.",
    "email": "This field is required."
  }
}
[[!+hook_error_placeholder]]

This is the placeholder key you specified in the "hookErrorJsonOutputPlaceholder" property, and if there was a hook error, you'd get something like:

{
  "errors": {
    "test": "bad kitty!",
    "FormItSaveForm": " "
  },
  "success": false,
  "message": "bad kitty!\n "
}
[[!+fi.successMessage:is=``:then=``:else=`{"success":true,"message":"[[!+fi.successMessage]]"}`]]

If the Form submission didn't trigger any errors, this placeholder would show the success message. In this case it would look like:

{
  "success": true,
  "message": "The message I customized with the 'successMessage' property."
}

There you have it. Hopefully this helps you deliver some AJAX goodness to your forms. Vive la MODX!