XML Editing Part 2

The gem layout as described in XML Editing Part 1 works just fine in the development environment. As is often the case problems started to occur as soon as I tried it out on our test production instance. The issue was with serving the static file from the gem. Generally in production the application will not be configured to do this, as the server software (e.g. Apache) will be used instead. So the decision was between configuring Apache to serve the needed javascript file, or modifying the main XML editor javascript to use the asset pipeline. The latter option seemed the best approach, as although it meant modifying the original code, it did remove the need for the duplication of the cycle.js file, and also it meant everything was handled by the Rails asset pipeline.

The change required for this was fairly minor. Instead of trying to load the cycle.js file from the configured lib path, the URL to the file needs to be constructed using the asset path:

var cyclePath = 
   "<%= asset_path('jquery-xmleditor/vendor/cycle.js') %>"

The full URL is then just this path plus the base URL:

this.cyclePath = this.baseUrl + cyclePath;

The base URL can be constructed using the Document.location object:

var protocol = document.location.protocol
var host = document.location.host
var url = document.location.protocol + "//" 
        + document.location.host + "/"

This path can then be used to import the cycle.js script:

var blob = new Blob([
    "self.onmessage = function(e) {" +
    "importScripts(e.data.cyclePath);" 
    ...

The other fix needed was that the script orginally used a POST to submit the XML back to the server, whereas our application routes use a PUT. Also it seemed to be necessary to submit the request as a form to the Rails application:

dataType: "text",
// Need to change the content type from application/xml
contentType: "application/x-www-form-urlencoded",
method : "PUT", //changed from POST
data : { xml: xmlString }, //send the XML string as a form parameter

With these changes made it was possible to add the editor in a new view and have it displaying correctly in production. The editor is configured to retrieve and upload the XML metadata using the route helpers. Similarly helpers are used to get the asset pipeline URLs to the schema and javascript files.

<div id="xml_editor">
</div>
<script>
  $(function() {
    $("#xml_editor").xmlEditor({
      ajaxOptions: {
        xmlRetrievalPath: "<%= object_metadata_path(object) %>",
        xmlUploadPath : "<%= object_metadata_path(object) %>"
      },
      submitResponseHandler: function(response) {
        if (response.startsWith(
            "<%= t('dri.flash.notice.metadata_updated') %>")) 
        {
          return false;
        } else {
          return response;
        }
      },
      schema : '<%= asset_path("schemas/#{schema}") %>',
      libPath : '<%= asset_path("jquery-xmleditor/vendor") %>'
    });
 });
</script>

XML editor view in the application