Pylons / deform

A Python HTML form library.
Other
417 stars 161 forks source link

RichtText content dissapear on form submission when embeded in a sequence #283

Open tonthon opened 9 years ago

tonthon commented 9 years ago

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

tonthon commented 9 years ago
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',))
dairiki commented 9 years ago

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.

tonthon commented 9 years ago

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.

tonthon commented 9 years ago

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);
miohtama commented 7 years ago

PR's still welcome :)

stevepiercy commented 4 years ago

@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!