Page 1 of 1

Ckeditor in multi-page form

Posted: 09 Jul 2012, 19:12
by undermensch
Hello,

I'm using pe:ckEditor in a paginated form (i.e. not all form elements are on page at same time), pages loaded via ajax. Everything works fine if I don't use p:ajax tags or works fine the first time a page is loaded that includes the ckeditor. However, if I load another form page (that doesn't have a pe:ckEditor), I get the following error:

Code: Select all

Uncaught TypeError: Cannot read property 'document' of null
e.extend.getFrameDocument
j.add.init.C.on.C.addMode.getSnapshotData
j.add.init.n.on.o
a.event.on.m
a.event.fire
a.editor.fire
e.extend.getSnapshot
e.extend.checkDirty
PrimeFacesExt.widget.CKEditor.PrimeFaces.widget.BaseWidget.extend.isDirtyprimefaces-extensions.js.jsf:53
PrimeFacesExt.widget.CKEditor.PrimeFaces.widget.BaseWidget.extend.checkDirtyprimefaces-extensions.js.jsf:52
PrimeFacesExt.widget.CKEditor.PrimeFaces.widget.BaseWidget.extend.checkDirtyFromTimerprimefaces-extensions.js.jsf:52
bF.extend.proxy.b1
If I then return to the page, that had the ckeditor, I get this error:

Code: Select all

Uncaught TypeError: Cannot call method 'getFrameDocument' of null
j.add.init.C.on.C.addMode.getSnapshotData
j.add.init.n.on.o
a.event.on.m
a.event.fire
a.editor.fire
e.extend.getSnapshot
e.extend.checkDirty
PrimeFacesExt.widget.CKEditor.PrimeFaces.widget.BaseWidget.extend.isDirtyprimefaces-extensions.js.jsf:53
PrimeFacesExt.widget.CKEditor.PrimeFaces.widget.BaseWidget.extend.checkDirtyprimefaces-extensions.js.jsf:52
PrimeFacesExt.widget.CKEditor.PrimeFaces.widget.BaseWidget.extend.checkDirtyFromTimerprimefaces-extensions.js.jsf:52
bF.extend.proxy.b1
And here is an excerpt of the page:

Code: Select all

<ui:define name="topMenu">
        <h:form id="toolbar">
            <p:toolbar id="topToolBar">
                <p:toolbarGroup>
                    <p:commandButton value="#{testBean.dirty?'Save':'Saved'}" partialSubmit="true" icon="ui-icon-disk" actionListener="#{testBean.save}" id="saveButton" disabled="#{!testBean.dirty}" process="@this" update="@this :bottomToolbarForm:saveButton"/>
                    <p:commandButton value="#{testBean.submitted?'Submitted':'Submit'}" partialSubmit="true" id="submitButton" disabled="#{testBean.submitted or not testBean.test.complete}" process="@this" update="@this :bottomToolbarForm:submitButton :testForm" actionListener="#{testBean.submit}"/>
                    <p:separator />
                </p:toolbarGroup>                
                <p:toolbarGroup id="navButtons">
                    <p:commandButton id="firstButton" partialSubmit="true" onclick="ensureCleanliness()" oncomplete="resetPage();" disabled="#{testBean.currentSection==1}" icon="ui-icon-arrowthickstop-1-w" update=":testForm topToolBar :bottomToolbarForm:bottomToolbar" actionListener="#{testBean.loadFirstPage}" title="First Page"/>
                    <p:commandButton id="prevButton" partialSubmit="true" onclick="ensureCleanliness()" oncomplete="resetPage();" disabled="#{testBean.currentSection==1}" icon="ui-icon-arrowthick-1-w" update=":testForm topToolBar :bottomToolbarForm:bottomToolbar" actionListener="#{testBean.loadPreviousPage}" title="Previous Page"/>
                    <ui:repeat value="#{testBean.buttons}" var="button">
                        <p:commandButton value="#{button}" onclick="ensureCleanliness()" partialSubmit="true" oncomplete="resetPage();" disabled="#{testBean.test.currentPageNumber eq button}" update=":testForm :toolbar:topToolBar :bottomToolbarForm:bottomToolbar" actionListener="#{testBean.loadSpecificPage}" title="Page #{button}">
                            <f:param name="page" value="#{button}"/>
                        </p:commandButton>
                    </ui:repeat>
                    <p:commandButton id="nextButton" partialSubmit="true" onclick="ensureCleanliness()" oncomplete="resetPage();" disabled="#{testBean.currentSection==3}" icon="ui-icon-arrowthick-1-e" update=":testForm topToolBar :bottomToolbarForm:bottomToolbar" actionListener="#{testBean.loadNextPage}" title="Next Page"/>
                    <p:commandButton id="lastButton" partialSubmit="true" onclick="ensureCleanliness()" oncomplete="resetPage();" disabled="#{testBean.currentSection==3}" icon="ui-icon-arrowthickstop-1-e" update=":testForm topToolBar :bottomToolbarForm:bottomToolbar" actionListener="#{testBean.loadLastPage}" title="Last Page"/>
                </p:toolbarGroup>
                <p:toolbarGroup>
                    <p:outputPanel layout="block" styleClass="ui-state-default pass-header" style="margin: 0.5em 2em;font-size: 1.2em;opacity:0.4;filter:alpha(opacity=40);">
                        <h:outputText value="#{testBean.test.passClass.course.title} Unit #{testBean.test.unit} Test"/>
                        <h:outputText value=" (#{testBean.test.exam.title})" rendered="#{testBean.test.exam.title ne null}"/>
                    </p:outputPanel>
                </p:toolbarGroup>
                <p:toolbarGroup align="right">
                    <p:commandButton process="@this" partialSubmit="true" onclick="ensureCleanliness()" value="Pause" ajax="false" action="#{testBean.pauseTest}"/>
                    <p:commandButton process="@this" partialSubmit="true" onclick="ensureCleanliness()" value="Quit" ajax="false" action="#{testBean.stopTest}"/>
                    <p:commandButton process="@this" partialSubmit="true" onclick="ensureCleanliness()" value="#{bundle.logout}" ajax="false" action="#{testBean.logout}"/>
                </p:toolbarGroup>                
            </p:toolbar>            
        </h:form>                
    </ui:define>    

    <ui:define name="content">
        <p:outputPanel style="margin-left: 1em;margin-right: 1em;" id="testPage" layout="block">
            <h:form id="testForm" >
                <p:remoteCommand name="markDirty" actionListener="#{testBean.handleResponse}" update=":toolbar:topToolBar :bottomToolbarForm:bottomToolbar"/>
                <p:outputPanel>
                    <ui:repeat value="#{testBean.test.currentPage}" id="main" var="item" varStatus="count" >
                        ...
                        <p:outputPanel styleClass="question" layout="block" rendered="#{item.question.renderer.renderCode==1}">
                            <h:outputText styleClass="ui-widget-content pass-header" style="margin-top: 1em;font-size: 1.1em;display: block;" rendered="#{item.question.graphic.caption ne null and item.question.graphic.graphicPosition.value eq 0}" value="#{item.question.graphic.caption}"/>
                            <p:graphicImage style="margin-left: 2em;margin-top: 1em;margin-bottom: 1em;" height="#{item.question.graphic.height}" width="#{item.question.graphic.width}" alt="#{item.question.graphic.alt}" rendered="#{item.question.graphic.picture ne null and item.question.graphic.graphicPosition.value eq 0}" value="#{testBean.image(item.question.graphic.picture)}"/>
                            <h:panelGrid columns="2" rowClasses="prompt" >
                                <h:outputText escape="false" value="#{item.number}."/>
                                <h:outputText escape="false" value="#{item.question.prompt}"/>
                            </h:panelGrid>
                            <h:outputText styleClass="ui-widget-content pass-header" style="margin-top: 1em;font-size: 1.1em;display: block;" rendered="#{item.question.graphic.caption ne null and item.question.graphic.graphicPosition.value eq 1}" value="#{item.question.graphic.caption}"/>
                            <p:graphicImage style="margin-left: 2em;margin-top: 1em;margin-bottom: 1em;" height="#{item.question.graphic.height}" width="#{item.question.graphic.width}" alt="#{item.question.graphic.alt}" rendered="#{item.question.graphic.picture ne null and item.question.graphic.graphicPosition.value eq 1}" value="#{testBean.image(item.question.graphic.picture)}"/>
                            <p:selectOneRadio styleClass="choice" disabled="#{testBean.submitted}" converter="com.pass.converter.choice"  layout="pageDirection" value="#{item.selection}">
                                <f:selectItems value="#{item.question.choices}" var="choice" itemValue="#{choice}" itemLabel="#{choice.content}"/>
                                <p:ajax process="@this" partialSubmit="true" update=":toolbar:topToolBar :bottomToolbarForm:bottomToolbar" listener="#{testBean.handleResponse}"/>
                            </p:selectOneRadio>                            
                        </p:outputPanel>
                        ...   
                                                   
                        <p:outputPanel layout="block" styleClass="question" rendered="#{item.question.renderer.renderCode==5}">
                            <h:panelGrid columns="2" style="margin-bottom: 1em;" rowClasses="prompt" >                               
                                <h:outputText escape="false" value="#{item.number}."/>
                                <h:outputText escape="false" value="#{item.question.prompt}"/>
                            </h:panelGrid>
                            <pe:ckEditor  width="75%" height="#{item.question.responseHeight}" value="#{item.response}" toolbar="[['Bold','Italic','Underline','Strike','Subscript','Superscript','Format','Font','FontSize','-','RemoveFormat','-','Cut','Copy','Paste','PasteText','PasteFromWord','-','NumberedList','BulletedList','-','Outdent','Indent','-','SpellChecker']]">                                
                                <p:ajax event="dirty" onstart="callCleaner();return false;" partialSubmit="true"  listener="#{testBean.handleResponse}"/>
                                <p:ajax event="change" onstart="callCleaner();return false;" partialSubmit="true" listener="#{testBean.handleResponse}"/>                                
                            </pe:ckEditor>
                        </p:outputPanel>                       
                        ...
                <p:remoteCommand process="@form" actionListener="#{testBean.handleResponse}" name="submitTestForm"/>
                <p:remoteCommand name="sendOrder" process="@this" actionListener="#{testBean.handleOrderChange}"/>
            </h:form>
        </p:outputPanel> 
    </ui:define>

    
    </ui:define>

    
Again, If I use the pe:ckeditor tag without the p:ajax tags, these errors don't present.

Thanks,

Re: Ckeditor in multi-page form

Posted: 09 Jul 2012, 20:15
by tandraschko
Hi,

i can check it for you but could you please provide a simple maven sample app + issue?
I don't have enough time to create samples etc.

Thanks.

Re: Ckeditor in multi-page form

Posted: 09 Jul 2012, 22:17
by undermensch
Thanks for your reply,

I have been able to avoid the errors by destroying the ckeditor objects when changing form pages. This is perhaps not an optimal solution, but it seems to work as intended.

Code: Select all

<pe:ckEditor widgetVar="editor#{item.number}" width="75%" height="#{item.question.responseHeight}" value="#{item.response}" toolbar="[['Bold','Italic','Underline','Strike','Subscript','Superscript','Format','Font','FontSize','-','RemoveFormat','-','Cut','Copy','Paste','PasteText','PasteFromWord','-','NumberedList','BulletedList','-','Outdent','Indent','-','SpellChecker']]">                                
                                <p:ajax event="dirty" onstart="passTest.callCleaner();return false;" partialSubmit="true"  listener="#{testBean.handleResponse}"/>
                                <p:ajax event="change" onstart="passTest.callCleaner();return false;" partialSubmit="true" listener="#{testBean.handleResponse}"/>
                                <p:ajax event="initialize" onstart="passTest.registerEditor(editor#{item.number});return false;" partialSubmit="true" listener="#{testBean.handleResponse()}"/>
                            </pe:ckEditor>

Code: Select all

passTest.registerEditor = function(id){
    passTest.editors.push(id);
    passTest.editor=true;
}
And then when I load up (via ajax) another page, I call:

Code: Select all

passTest.removeEditors = function(){
    if(passTest.editor){
        for(var i=0, len=passTest.editors.length; i < len; i++){
            passTest.editors[i].destroy(true);       
        }
        passTest.editor=false;
        passTest.editors.length=0;
    }                
}

Re: Ckeditor in multi-page form

Posted: 10 Jul 2012, 08:18
by tandraschko
Hmm, the weird thing is that it works without p:ajax. Does it really work for 100% without p:ajax?

Re: Ckeditor in multi-page form

Posted: 10 Jul 2012, 16:28
by undermensch
Yes, it seems to. I replicated issue in simple example: http://undermensch.googlecode.com/svn/trunk/.
I also created an issue: http://code.google.com/p/primefaces-ext ... ail?id=217

Thanks,