Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    CKEditor Integration

    There's an article explaining how to do it in SmartClient (Javascript). I'll try to explain how to do it in SmartGwt (Java).
    You have to download CKEditor and extract "ckeditor" folder into "project/client/public", create it if it doesn't exist. This is to get CKEditor source copied into war module folder when compiled.
    Add the following to your module xml file
    Code:
    <script src="ckeditor/ckeditor.js"></script>
    Finally, edit project/client/public/ckeditor/config.js file to avoid z-index problems with CKEditor
    Code:
    config.baseFloatZIndex = 1000000;
    That's all you have to setup, now you can use the following classes as shown in the EntryPoint example below
    Code:
    public class CKEditorEntryPoint implements EntryPoint {
    
    	private CKEditorItem txtEditor;
    	private final static String DEFAULT_HTML_CONTENT="<h1>\n" + 
    			"	HTML Ipsum Presents</h1>\n" + 
    			"<p>\n" + 
    			"	<strong>Pellentesque habitant morbi tristique</strong> senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. <em>Aenean ultricies mi vitae est.</em> Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, <code>commodo vitae</code>, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui. <a href=\"#\">Donec non enim</a> in turpis pulvinar facilisis. Ut felis.</p>\n" + 
    			"<h2>\n" + 
    			"	Header Level 2</h2>\n" + 
    			"<ol>\n" + 
    			"	<li>\n" + 
    			"		Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</li>\n" + 
    			"	<li>\n" + 
    			"		Aliquam tincidunt mauris eu risus.</li>\n" + 
    			"</ol>\n" + 
    			"<blockquote>\n" + 
    			"	<p>\n" + 
    			"		Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus magna. Cras in mi at felis aliquet congue. Ut a est eget ligula molestie gravida. Curabitur massa. Donec eleifend, libero at sagittis mollis, tellus est malesuada tellus, at luctus turpis elit sit amet quam. Vivamus pretium ornare est.</p>\n" + 
    			"</blockquote>\n" + 
    			"<h3>\n" + 
    			"	Header Level 3</h3>\n" + 
    			"<ul>\n" + 
    			"	<li>\n" + 
    			"		Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</li>\n" + 
    			"	<li>\n" + 
    			"		Aliquam tincidunt mauris eu risus.</li>\n" + 
    			"</ul>\n" + 
    			"<pre>\n" + 
    			"<code>\n" + 
    			"#header h1 a { \n" + 
    			"	display: block; \n" + 
    			"	width: 300px; \n" + 
    			"	height: 80px; \n" + 
    			"}\n" + 
    			"</code></pre>"; 
    
    	@Override
    	public void onModuleLoad() {
    		try {
    			VLayout main = new VLayout();
    			main.setSize("100%", "100%");
    			DynamicForm frmEditor = new DynamicForm();
    			frmEditor.setBorder("2px solid blue");
    			frmEditor.setNumCols(1);
    			txtEditor = new CKEditorItem("txtEditor");
    			txtEditor.setValue(DEFAULT_HTML_CONTENT);
    			txtEditor.setShowTitle(false);
    			txtEditor.setWidth("50%");
    			txtEditor.setHeight("100%");
    			frmEditor.setItems(txtEditor);
    			IButton btnPrintHTML = new IButton("Print HTML");
    			btnPrintHTML.addClickHandler(btnPrintHTML_onClick);
    
    			frmEditor.setSize("50%", "80%");
    			main.setMembers(frmEditor, btnPrintHTML);
    			main.draw();
    
    		} catch (Exception exc) {
    			SC.warn("An exception has occured:<br>" + exc.toString());
    		}
    
    	}
    
    	private ClickHandler btnPrintHTML_onClick = new ClickHandler() {
    
    		@Override
    		public void onClick(ClickEvent event) {
    			if (txtEditor.getValue() != null)
    				SC.say("CKEditor value:<br>"
    						+ StringUtil.asHTML(txtEditor.getValue().toString()));
    			else {
    				SC.say("type something in the editor!");
    			}
    		}
    	};
    
    }
    CKEditor.java
    I don't know why draw method wasn't being called. So, instead of override, I subscribed to draw event.
    Code:
    public class CKEditor extends Canvas{
    	{
    		setOverflow(Overflow.VISIBLE);
    		setCanDragResize(false);
    		setRedrawOnResize(false);
    		setZIndex(0);
    	}
    	private boolean loaded=false;
    
    	public CKEditor(String id){
    		super(id);
    		addDrawHandler(new DrawHandler() {
    			
    			@Override
    			public void onDraw(DrawEvent event) {
    				loadCKEditor();
    			}
    		});
    	}
    	
    	@Override
    	public String getInnerHTML() {
    		if(this.getContents() != null){
    			return "<textarea style='width=100%;height=100%' id=" + this.getID() + "_ta>"+
    				getContents()+"</textarea>";
    		}
    		return "<textarea style='width=100%;height=100%' id=" + this.getID() + "_ta></textarea>";
    	}
    	
    //	@Override
    //	public void draw() {
    //		super.draw();
    //		loadCKEditor();
    //	}
    	
    	protected native void loadCKEditor()/*-{
    		if(!this.@tsj.ckeditor.client.CKEditor::loaded){
    			var ckEditorId=this.@tsj.ckeditor.client.CKEditor::getID()() + "_ta";
    			$wnd.CKEDITOR.replace(ckEditorId);
    	        this.@tsj.ckeditor.client.CKEditor::loaded=true;
    		}
    	}-*/;
    
    	public boolean isLoaded() {
    		return loaded;
    	}
    }
    CKEditorItem.java
    This class is to use CKEditor inside a form though I haven't tested it with smartgwt datasources. I overrode sizing methods to adjust canvas size when item's size changes -this allowed me to put CKEditor inside a Layout-
    Code:
    public class CKEditorItem extends CanvasItem {
    	private CKEditor ckeCanvas;
    
    	public CKEditorItem(String name) {
    		super(name);
    		ckeCanvas = new CKEditor(name);
    		this.setCanvas(ckeCanvas);
    	}
    
    	@Override
    	public void setWidth(String width) {
    		super.setWidth(width);
    		ckeCanvas.setWidth(width);
    	}
    	
    	@Override
    	public void setWidth(int width) {
    		super.setWidth(width);
    		ckeCanvas.setWidth(width);
    	}
    	
    	@Override
    	public void setHeight(String height) {
    		super.setHeight(height);
    		ckeCanvas.setHeight(height);
    	}
    	
    	@Override
    	public void setHeight(int height) {
    		super.setHeight(height);
    		ckeCanvas.setHeight(height);
    	}
    	
    	@Override
    	public Object getValue() {
    		return getCKEditorValue(ckeCanvas.getID()+"_ta");
    	}
    	
    	private native String getCKEditorValue(String ckEditorId)/*-{
    		if($wnd.CKEDITOR.instances[ckEditorId]){
    			return $wnd.CKEDITOR.instances[ckEditorId].getData();
    		}
    		return null;
    	}-*/;
    	
    	@Override
    	public void setValue(String value) {
    		super.setValue(value);
    		if(ckeCanvas.isLoaded())
    			setCKEditorValue(ckeCanvas.getID()+"_ta", value);
    		else
    			ckeCanvas.setContents(value);
    	}
    	
    	private native void setCKEditorValue(String ckEditorId,String value)/*-{
    	if($wnd.CKEDITOR.instances[ckEditorId]){
    		$wnd.CKEDITOR.instances[ckEditorId].setData(value);
    	}
    }-*/;
    }
    I hope this helps someone like the previous article helped me. Cheers!
    Last edited by cirovladimir; 8 Sep 2010, 07:08.

    #2
    The CKEditorItem object is not drawn, and messes up the entire layout draw.
    I did some basic tests:

    1. Removing the txtEditor item from the form, and I set a TextItem object to be a unique item in the form, and the entire form with border is well displayed.
    2. Let the txtEditor to be the unique item of the form, and nothing! is displayed. Apparently the main layout is affected, and it isn't drawn.

    I entered in debug mode and I am sure that loadCKEditor() is called from the onDraw method.

    What can it be?
    I-m using smartgwtpro 2.3, and Firefox/3.6.8

    As an additional info, but I guess not that relevant: The main layout is set as the pane for a Tab which is a part of a TabSet object.

    Code:
    [...]
            Tab ckEditorTab = new Tab("", "/images/ckeditor_logo.png");
            ckEditorTab.setPane(getCKEditorTestLayout());
    
            menuTabSet.addTab(ckEditorTab);
    [...]
            menuTabs.draw();

    Comment


      #3
      Sorry my mistake, I forgot to include the JS in my html file.
      Code:
      <script type="text/javascript" language="javascript" src="ckeditor/ckeditor.js"></script>
      And it is very imortant to place it above the yourfilename.nocache.js !

      Comment


        #4
        Originally posted by Lucianovici
        Sorry my mistake, I forgot to include the JS in my html file.
        Code:
        <script type="text/javascript" language="javascript" src="ckeditor/ckeditor.js"></script>
        And it is very imortant to place it above the yourfilename.nocache.js !
        You could've included the script tag in the module xml file as stated in the post and it would've been included automatically. Glad you've got it working though.

        Comment


          #5
          I've found a project called gwt-ckeditor which wraps a CKEditor in GWT, you could use it easily in SmartGwt like any other GWT widget. Just embed it in a Canvas, set z-index to a value grater than SmartGwt controls and set useFormPanel to false to avoid sizing problems. I explained how to do this here.

          It has advantages over the proposal shown here -toolbar customization, multiple instances and most importantly open sourced ;-) -

          Comment

          Working...
          X