Binding ACE editor with Rails form helper
ACE editor only can bind with a div
container which means rails form helper can’t help when you want to bind with an attribute.
I am going to work through my solution.
text_area
text_area
genererates <textarea>
which people can edit its content without any js. And this helper helps you forget about binding with model.
I will get the content from it for ACE. When the js can’t work, we can still get a functional editor.
Binding with ACE
HTML:
<div class="source-editor" data-mode="markdown">
<textarea></textarea>
</div>
Script is easy. Work though all the source-editor
, create a div and bind ACE within it. Then save back to textarea when submit.
You should set css for textarea
just like the div
in the ACE tutorial.
$('.source-editor').each(function() {
var container = $(this);
var mode = container.data('mode');
var editorArea = container.find('textarea');
// build a edit div for ACE since ACE can't load in a textarea
var editDiv = $('<div>', {
position: 'absolute',
width: editorArea.width(),
height: editorArea.height(),
'class': editorArea.attr('class')
}).insertBefore(editorArea);
// no need to display textarea
editorArea.css('display', 'none');
var editor = ace.edit(editDiv[0]);
editor.setFontSize('14px');
editor.setTheme('ace/theme/yesterday');
editor.getSession().setMode('ace/mode/' + mode);
editor.getSession().setValue(editorArea.val());
// save back to the textarea when submit
editorArea.closest('form').submit(function() {
editorArea.val(editor.getSession().getValue());
});
});
More complicated templates
Actually I forged Github-liked toolbar for the ACE editor which needs more HTML structures.
This can be done by Rails view partials. Separated HTML and passing form helper as a parameter. Then write its control logic in the component js. No need for customized helpers, simple is the best.
= render partial: 'components/source_editor', |
locals: { |
preview_url: '', |
ace_mode: 'markdown', |
indent_width: %w(2 4 8), |
tab_label: 'Edit content', |
preview_label: 'Preview', |
attribute: f.text_area(:raw) } |
Leave a Comment