deform
deform copied to clipboard
RichtText content dissapear on form submission when embeded in a sequence
Create a sequence of Mappings with RichTexts Add a sequence item Delete that item Add a sequence item Fill the text Submit your form
The text you filled has disappeared
import deform
import colander
class DemoMapping(colander.MappingSchema):
item = colander.SchemaNode(
colander.String(),
widget=deform.widget.RichTextWidget()
)
class DemoSeq(colander.SequenceSchema):
items = DemoMapping()
schema = DemoSeq()
form = Form(schema, buttons=('valid',))
I'm not sure whether this is the issue here, but I think the top-level schema should always (or usually?) be a MappingSchema
(aka Schema
). (FormWidget
inherits from MappingWidget
, and really wants to work with a value that is a mapping, not a sequence.)
See http://deform2demo.repoze.org/sequence_of_richtext/ for an example.
No, it's not related to the use of a MappingSchema or a SequenceSchema. It's related to the js code that binds the editor to the hidden textarea. Something like
delete tinyMCE.editors.<editor_name>
should be thrown while adding a sequence item.
tinyMCE.execCommand('mceAddEditor', false, 'editor_name');
should be thrown while adding a sequence item.
I should lead more investigation on this issue in the coming days. Hope I'll come with a solution.
The problem comes from tinymce's triggerSave method. Since we don't delete the tinymce instances we create, tinyMCE.editors contains editors not matching an existing textarea. tinyMCE.triggerSave() fails on the first editor not matching an element existing in the DOM.
1- I add an item in my sequence (item1) 2- I remove the line (the tinyMCE editor item1 still exists) 3- I add and fill a line (item2) 4- I submit 5- triggerSave fails while setting the content of the editor on the item1's textarea and doesn't set the content of the following one (item2). The error : NS_ERROR_UNEXPECTED (impl = node.ownerDocument.implementation;) 6- Most important point : :-1: The end user has lost his datas
The following hack fixes the issue. I'm not sure how it should be implemented in deform, if anyone has an idea, I'll be glad to make a PR
function cleanTinyMceEditors(event, form){
for (var i=0; i < tinyMCE.editors.length; i++){
var editor = tinyMCE.editors[i];
if ($("#" + editor.id).length === 0){
try{
i = i-1;
delete tinyMCE.remove(editor);
} catch (e){}
}
}
tinyMCE.triggerSave();
}
$('form').on('submit.cleanEditors', cleanTinyMceEditors);
PR's still welcome :)
@tonthon I'd like to see this get into an upcoming release of Deform. I'm happy to help. The function would go into deform.js
with a check, making sure it only loads for sequence of mappings of richtexts, if possible. I can also help with functional tests in deformdemo. Please let me know. Thank you!