django-codemirror2 icon indicating copy to clipboard operation
django-codemirror2 copied to clipboard

New adding custom widget won't initiate with django inline UI

Open intp1 opened this issue 1 year ago • 2 comments

AdminUI Render

Hi there, django-codemirror2 helps me creating a custom widget, which maintains a model of sourcecodes. it works good in the django admin UI of the sourcecode model, I can create the widget with high light color、line numbers、line wrapping and so on.

class SourceCodeEditorAdminForm(forms.ModelForm):
    class Meta:
        model = SourceCode
        fields = '__all__'
      
        widgets = {            
            'code_content': CodeMirrorEditor(
                modes=["python", "css", "xml", "javascript", "htmlmixed"],
                options={                    
                    "mode": "python",                    
                    "lineNumbers": "true",
                    "lineWrapping":"true", 
                    "matchBrackets": "true",
                    # "theme": "lesser-dark",
                    "theme" : "blackboard",
                },
            )
        }
@admin.register(SourceCode)
class SourceCodeAdmin(ModelAdmin):
    '''Admin View for SourceCode'''

    list_display =  ('file_name', 'package_name', 'spu') 
    list_display_links = ('file_name','package_name', 'spu')   
    form = SourceCodeEditorAdminForm

sourcecode admin

InlineUI Render Failure

but it fails when comes to the inline interface. Since django inlines class insert my sourcecode model instances into another model product, and provide a add another sourcecode button for product model, the new adding item of sourcecode class with an empty textarea won't render codemirror2 widget correctly.

class SourceCodeInline(StackedInline):   
    ''' Inline View for SourceCode'''
    model = SourceCode
    min_num = 1
    max_num = 20
    extra = 0
    fields = ['file_name', 'code_content']  
    classes = ['show'] 
    form = SourceCodeEditorAdminForm

The original inlineUI without custom widget

inline create_0

The new inlineUI with custom widget

inline create_1

Analyses for debugging

It seems like codemirror2 widget need to be initiated before rendering to UI, but clicking add another sourcecode button does not help the initiation since it dose not refresh the page or reload any js or css.

In some circumstances by refreshing page, problems do solved, such as:

  • Save the new adding item with new data, and reopen the same page to see a widget shows up correctly;
  • Save the new adding item with some user input errors, the field validation will raise errors and force refresh page; Note: Directly refresh page by 'ctrl R' or 'F5' is not good, it will just lose the new adding item.

Anywary, none of these circumstances are friendly to user.

inline create_2

Is there a solution on codemirror side to help initiating and rendering correctly at the time clicking add another... button with inline UI ? Thanks for reading this long explanation.

intp1 avatar Feb 22 '24 06:02 intp1

Thank you for the detailed report!

Indeed, inlines don't properly initialize the editor instances. This should be feasible to fix using inline form events. I'm not sure this will work for removal, that's something to be tried (is that event called before or after the inline is removed?). I'll see if I find some time to fix this issue this weekend.

sk1p avatar Feb 22 '24 23:02 sk1p

Indeed, inlines don't properly initialize the editor instances. This should be feasible to fix using inline form events. I'm not sure this will work for removal, that's something to be tried (is that event called before or after the inline is removed?). I'll see if I find some time to fix this issue this weekend.

I'm not sure that event called before or after the removal. I tried to find some detail document about it but got nothing. However, GPT gives an answer:

The removed jQuery event for formsets fires after the form has been removed. This event is triggered after a form in the formset has been removed from the DOM.

intp1 avatar Feb 24 '24 14:02 intp1