Submitting a CodeMirror'ed Field with JavaScript
Wednesday, December 9th, 2009 · 0 comments
This issue arose the other day while working on a code editor for a content management system. A little background information: it was just a single textarea that was submitted using AJAX to save the data; previously it was running CodePress, but it was decided to switch to CodeMirror to integrate with Tobias Lütke's Liquid Editor.
CodePress worked fine, it provided great syntax highlighting and saved properly with AJAX. Upon switching to CodeMirror, the saving process started malfunctioning. To sum it up, a user had to submit the form twice in order to send the correct params from the form. CodeMirror attaches a function onto a forms submit event called updateField, which as can be guessed, updates the form's field that CodeMirror is applied to, with the proper value (since CodeMirror hides the field and shows its own stuff in an iframe). So the problem was updateField wasn't being called, therefore, the old data was being submitted again.
The Fix
Let's get into some code! Here's the bit of code used to submit the form, which is called with the onsubmit= attribute on the form tag (note this is Prototype).
function submit_form(form) {
new Ajax.Request('/admin/update', {
asynchronous:true,
evalScripts:true,
parameters:Form.serialize(form)
});
}
When a user submits the form, it send an AJAX request to /design/update which handles the data and presumably saves it to the database. To get it all working properly, the form's textarea's value needed to be updated with the new (modified) one from CodeMirror. Here's the code used to initialize CodeMirror.
var editor = CodeMirror.fromTextArea("editor", {
parserfile: "parseliquid.js",
stylesheet: ["/codemirror/css/xmlcolors.css", "/codemirror/css/liquidcolors.css"],
path: "/codemirror/"
});
This puts the editor in place of a field with the ID of "editor". So from that example we know that we have access to an object called editor. CodeMirror provides a function called getCode which can be sent to editor. So essentially all that needs to be done is updateField manually!
function submit_form(form) {
$("editor").value = editor.getCode(); // The magic dust
new Ajax.Request('/admin/design/update', {
asynchronous:true,
evalScripts:true,
parameters:Form.serialize(form)
});
}
We set the field's value to the new value from CodeMirror, and continue on as normal, simple as pie! (Pie is not easy to make by the way.).
Hopefully this helps others who are encountering the same issue, and does a good job explaining the problem and solution!
