CKEditor & preview

edited May 2012 in Modules
Hi,

I've been using CKEditor as my WYSIWYG of choice but have noticed only recently the "preview" button is very different to the Markitup equivalent. I've just skimmed through the CKEditor developers guide and could find no mention of editing the preview functionality to make it similar to the Markitup one (ie insert WYSIWYG content into the fuel preview template).

I don't imagine this discrepancy in functionality is an accident - but I thought I'd ask anyway!

I've seen a solution in the making though with this thread: http://stackoverflow.com/questions/4401693/ckeditor-preview-method

Comments

  • edited 2:46PM
    Perhaps a preview button could sit right next to the view source button and when clicked will post the contents of the form to the preview similar to what markItUp does... perhaps even leveraging the same function. I may take a look at something like that in a bit... let me know if you do too.
  • edited May 2012
    I've made a start on a CK Editor preview, here's where I got to: in PageController.js I added this to the add_edit function
    if($ckEditor) ckAddPreview();

    and then tacked on to the same script I added

    function injectCKContents(w) { var wysiwyg = $ckEditor.val(); var target = $('#'+w).contents().find('body'); target.append(wysiwyg); } function ckAddPreview() { iframePreview = document.createElement("IFRAME"); var iframeId = "ckPreview"; iframePreview.setAttribute("id", iframeId); $('#vars--body_viewsource').parent().append('&nbsp;<a class="btn_field editor_viewsource" onclick="injectCKContents(\''+iframeId+'\');">Preview</a>'); $('#vars--body_viewsource').parent().append(iframePreview); }

    That achieves a button (Preview) after the "View Source" and then the iframe to inject the CK Editor content into when the new button is pressed. Rudimentary, and for proof of concept only!

    An iframe mimics the preview of markItUp (and guarantees a complete DOM) - on balance better than a targeted DIV.

    I'm not sure what would be the best next step, that is how to put the wysiwyg into the preview frame as per the main layout. DOM injection is quick, but targeting the correct parent element would be tricky given that this is up to the end user's whim. The other way is to call the main layout (or specified layout) and perform the same functionality as a controller, adding the wysiwyg as vars to the view.

    But how is it achieved on the markItUp variant? Is the "fuel_preview" view used for this?

    A nice option would be to enable a preview by width, so that the admin would know what would happen to the content in a mobile view, tablet or destkop.
  • edited 2:46PM
    Thanks for the code. To answer your questions, the markItUp! and CKEditor previews are totally different. There is a fuel/modules/fuel/assets/js/editors/markitup/jquery.markitup.set.js file that contains the configuration for markItUp! In that file, there is a "previewParserPath" parameter that can be set and is currently set to:
    previewParserPath: __FUEL_PATH__ + "/preview",
    This points to the fuel/modules/fuel/controllers/preview.php controller file.

    We'll put down the preview widths on our future wish list.
  • edited 2:46PM
    The /preview url seems eminently reusable. I rejigged the code above to:

    if($ckEditor) ckAddPreview();
    in the add_edit function (as before), but altered the rest to:

    function ckAddPreview() { // add a link, form & iframe // link submits form, posts to iframe target var formContainer = $("#main_content_inner"); var container = $('#vars--body_viewsource').parent(); var previewUrl = __FUEL_PATH__ + "/preview"; var iframeId = "ckPreview"; var iframePreview = document.createElement("IFRAME"); iframePreview.setAttribute("src", ""); iframePreview.setAttribute("id", iframeId); iframePreview.setAttribute("name", iframeId); var previewForm = document.createElement("FORM"); previewForm.setAttribute("action", previewUrl); previewForm.setAttribute("target", iframeId); previewForm.setAttribute("method", "post"); var dataId = "ck-data"; var dataInput = document.createElement("INPUT"); dataInput.setAttribute("type", "hidden"); dataInput.setAttribute("name", "data"); dataInput.setAttribute("id", dataId); previewForm.appendChild(dataInput); var linkId = "preview-link"; var previewLink = document.createElement("A"); previewLink.setAttribute("class", "btn_field editor_viewsource"); previewLink.setAttribute("id", linkId) var linkName = document.createTextNode("Preview"); previewLink.appendChild(linkName); // append new elements formContainer.append(previewForm); container.append(previewLink); container.append(iframePreview); $("#"+linkId).click(function() { var input = $("#"+dataId); input.val($ckEditor.val()); input.parent().submit(); }); }

    This works nearly perfectly. The "nearly" being the currency of what is copied from the editor to the data input - it's not always the most recent edit from the form, often it's everything but the very last thing typed into CK editor. Perhaps there is a better way to capture the content than $ckEditor.val(). $ckEditor is defined in BaseFuelController.js, and seemed a handy shortcut. The toolbar preview in CKE achieves it though, so it can be done. I'll investigate further.
  • edited May 2012
    Mmh - that code works OK for "create", but not for "edit". Seems determining the parent element (td) of the editor is problematic for edit mode. If I change the selector for obtaining the parent (assigned to var container) to "vars--body" I can - fleetingly - see it is selected, but then it is voided by some other script. So the preview link and iframe never appear - although the triggering form does, because the selector for that isn't affected. Odd.
  • edited 2:46PM
    I was actually working on a version of this last night for the next release. However, the preview pops up in a new window instead of showing it below the input field. But it will be the same preview for both CKeditor and markItUp! which I think is the main goal for this.
  • edited 2:46PM
    Great - I gave up after meeting oddness with manipulating the "edit" page! Script that worked OK for "create" would flash and disappear on "edit".

    The new window is the better way.
Sign In or Register to comment.