Ckeditor in multi-page form

Community Driven Extensions Project
Post Reply
User avatar
undermensch
Posts: 109
Joined: 08 Jul 2010, 14:37
Location: Florida, United States

09 Jul 2012, 19:12

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,
PrimeFaces-6.2.14 / Wildfly 11

tandraschko
PrimeFaces Core Developer
Posts: 3529
Joined: 03 Dec 2010, 14:11
Location: Bavaria, DE
Contact:

09 Jul 2012, 20:15

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.
Always Bet On Prime (+ Extensions)!

Thomas Andraschko
PrimeFaces Developer | PrimeFaces Extensions Founder
Apache OpenWebBeans PMC | Apache DeltaSpike PMC | Apache MyFaces PMC

Personal Blog: http://tandraschko.blogspot.de/

User avatar
undermensch
Posts: 109
Joined: 08 Jul 2010, 14:37
Location: Florida, United States

09 Jul 2012, 22:17

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;
    }                
}
PrimeFaces-6.2.14 / Wildfly 11

tandraschko
PrimeFaces Core Developer
Posts: 3529
Joined: 03 Dec 2010, 14:11
Location: Bavaria, DE
Contact:

10 Jul 2012, 08:18

Hmm, the weird thing is that it works without p:ajax. Does it really work for 100% without p:ajax?
Always Bet On Prime (+ Extensions)!

Thomas Andraschko
PrimeFaces Developer | PrimeFaces Extensions Founder
Apache OpenWebBeans PMC | Apache DeltaSpike PMC | Apache MyFaces PMC

Personal Blog: http://tandraschko.blogspot.de/

User avatar
undermensch
Posts: 109
Joined: 08 Jul 2010, 14:37
Location: Florida, United States

10 Jul 2012, 16:28

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,
PrimeFaces-6.2.14 / Wildfly 11

Post Reply

Return to “Extensions”

  • Information
  • Who is online

    Users browsing this forum: No registered users and 1 guest