[CKEditor] Discussion

[CKEditor] Discussion

  
Forge Component
(11)
Published on 12 Oct by OutSystems Labs
11 votes
Published on 12 Oct by OutSystems Labs
How to change configuration files and source code in CKEditor component?

Sometimes you may want to change/update the actual CKEditor code. Although this is not recommended since it may cause trouble upgrading to future CKEditor versions, here's how to do it:
  1. Open the Resources folder in your eSpace tree
  2. Select the file you want to change from your filesystem
  3. Republish the CKEditor eSpace;
  4. Don't forget to republish your consumer eSpaces.

You will now have the new new files on the server. Check it out!


How to specify CKEditor's dialog height/width?

If you want to specify the height or width of your CKEditor dialog you must use the resize() API function that can be found in CKEditor's documentation.

To avoid hard-coding these values you can add 2 more parameters in the CKEditor weblock - Height and Width - and initialize the dialog with the following unescaped expression (Javascript): "<script type='text/javascript'> setTimeout('CKEDITOR.instances." + InputId + ".resize(" + Width + "," + Height + ")',500);</script>"


Hello, i would like to change the Height and Width using the API resize() but i'm having some dificulties. Following  this tip, Where i can paste this code ?


CKEDITOR.instances.MyCKEditorElementId.resize(1000,300)


Thanks in advance
CkEditor not working in popup window!

Hi.
I start working with CkEditor and it's very good to work with. Meantime, I tried to put in a popup window and it won't work, because it doesn't bind the text box.
What I mean is that, when we put the editor in a popup and bind it to a textbox, we can write the text in the editor but the textbox content won't get it.

Is there a way to solve this problem?

Thank you.
In reply to António Rodrigues:

 Hello, i would like to change the Height and Width using the API resize() but i'm having some dificulties. Following this tip, Where i can paste this code ?
 CKEDITOR.instances.MyCKEditorElementId.resize(1000,300)
 Thanks in advance


Please see the post above: How to specify CKEditor's dialog height/width
I've updated it to use setTimeout() function due to loading issues.

Kind regards,
Pedro
In reply to Alexandre Alves: CkEditor not working in popup window!

Hi Alexandre,

I did manage to set up CKEditor on a popup. Are you setting the correct parameters in the webblock?

Check out the sample in attach containing the above discussed features: resizing and popup.

Here's a demo, too: http://screencast.com/t/ZDIyMzRkMWU

Happy coding!
Hi Pedro.

Thaks for your reply.

I can put the editor in a popup and it works just fine, like in your sample.

I think i didn't make myself clear.
What I meant is that, when we put the CKEditor in a popup and bind it to a textbox you can't get the textbox text aftrerwords. When we save the content of the textbox it's always empty.

Thak you.


Hi again Alexandre,

I remember that happening when my field was set as mandatory. 
You probably need to use the CKEDITOR.instances.editor.updateElement() function. It forces CKEditor's dialog to transfer its contents to the text input.

Check out the details here: http://docs.cksource.com/ckeditor_api/symbols/CKEDITOR.editor.html#updateElement

Also, see the attached sample. Hope it helps.

Cheers!
Hi Pedro,

First off all thanks for the component! What is the simplest way to have a completely stripped CKEditor with no toolbars whatsoever and no possibility to resize?

Thanks,
Hermínio Mira
Hello -

I noticed that when I view the page over HTTPS, the text area appears as a normal text area (no CKEditor), but when viewed over HTTP it works fine.

Any idea why this could be happening?

Thanks!

J.Ja
Hi Hermínio,

Sorry for the long delay.

In order to have a completely stripped CKEditor with no toolbars whatsoever please take a look at the Developer's Guide > Toolbar chapter. For no resizing, I think you may find it somewhere in the javascript API.

Have fun!
Hello Justin,

Thanks for sharing that issue.

Seeing the text area appearing as a normal text area (no CKEditor) is probably due to a bad initialization of the javascript code that starts the editor.

I haven't tried CKEditor on HTTPS connections and I can't really think of what may be causing that, so I'd recommend you inspect the short javascript code that is initializing it. Clue: start by looking at the CKEDITOR webblock...

And please do share your findings :)
Pedro
Hi Pedro,

Yeah, I'm already using it with a costumized toolbar. :)

cheers
Pedro -

It turned out to be the oddest issue. the server is behind a reverse proxy. The component was loading fine when accessed by the server's internal FQDN, and over the public FQDN with normal HTTP. But the proxy server had issues loading it via HTTPS. I am working those out now, but it was very, very odd.

Thanks, great contribution to the OutSystem community!

J.Ja

Hi, i just checked and there is a newer version of CKEditor (3.4.2) , with a little component that i believe to be of interest :"Navigate on the Server".

I was wondering how can one update the resources on the oml, using version 5.1... I just wanted to replace all the resources once, withou having to change resources one by one.... Is there any way to do this?

On the other hand, all i wanted was for the client to browse on his local system and add an image to the rich text editor. Is this possible with CKEditor?

Best Regards,

Diogo C S Cordeiro

How do I go about enabling the upload to server feature of the image properties dialog?
I have run CKEditor in webscreens, but I have to call a CKEditor in a WebBlock and appears this error:


"An exception occurred in the client script.
Error: CKEDITOR is not defined"

this happens when you do refresh the page, in this case the refresh  WebBlock.

can help?
Hello,

We have some trouble with the CKEditor.

On our development server it works like a charm, no problems there. We publised the solution to test, pre production and production and on test and pre-production server, the CKEditor doesn't work. On production it works like a charm again.

I found out that on those 2 servers it seems that the CKEditor javascript file can't be loaded.. The errormessage I see is:
"Loading of the source failed for:  http://<servername>/CKEditor/ckeditor/ckeditor.js"

Also when I use that URL in the browser it don't see anything. But chaning the servername to the development server the CKEditor javascript is shown.

Hope that somebody know what the problem is.

Kind Regards,
Evert


Hi guys,

Thanks for posting.

@ Pedro Coelho: have you tried following the recommendation on my post above (http://www.outsystems.com/NetworkForums/ViewTopic.aspx?Topic=[[]CKEditor]-Discussion#Post12) ? Use Firebug, it's a charm for those kinds of issues.

@Evert van der Zalm: Have you checked to see if the file really exists on those servers' path?
Hello Pedro,

When I submitted my post I was thinking: damn, should have checked that :).

I can't acces the server's fileSystem, so I asked the network manager to check it for me.

When I know more, I let you know.

Kind Regards,
Evert
Pedro,

The file exist on all the servers in the same folder.

Kind regards,
Evert
Perdo,

Some additional information:

When the url with the javascript is called, the screen shows the following message: '/CKEditor/URLRedirector.aspx' does not exist.

And the message in SC is:
Stack: at System.Web.UI.Util.CheckVirtualFileExists(VirtualPath virtualPath)
at System.Web.Compilation.BuildManager.GetVPathBuildResultInternal(VirtualPath virtualPath, Boolean noBuild, Boolean allowCrossApp, Boolean allowBuildInPrecompile)
at System.Web.Compilation.BuildManager.GetVPathBuildResultWithNoAssert(HttpContext context, VirtualPath virtualPath, Boolean noBuild, Boolean allowCrossApp, Boolean allowBuildInPrecompile)
at System.Web.Compilation.BuildManager.GetVirtualPathObjectFactory(VirtualPath virtualPath, HttpContext context, Boolean allowCrossApp, Boolean noAssert)
at System.Web.Compilation.BuildManager.CreateInstanceFromVirtualPath(VirtualPath virtualPath, Type requiredBaseType, HttpContext context, Boolean allowCrossApp, Boolean noAssert)
at System.Web.UI.PageHandlerFactory.GetHandlerHelper(HttpContext context, String requestType, VirtualPath virtualPath, String physicalPath)
at System.Web.UI.PageHandlerFactory.System.Web.IHttpHandlerFactory2.GetHandler(HttpContext context, String requestType, VirtualPath virtualPath, String physicalPath)
at System.Web.HttpApplication.MapHttpHandler(HttpContext context, String requestType, VirtualPath path, String pathTranslated, Boolean useAppConfig)
at System.Web.HttpApplication.MapHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
-Env-
eSpaceVer: 3 (Id=363, PubId=451, CompiledWith=5.1.0.21)
RequestUrl: http://127.0.0.1/CKEditor/URLRedirector.aspx?Token1=ckeditor&Token2=ckeditor.js&
AppDomain: /LM/W3SVC/1/Root/CKEditor-1099-129393826781093750
FilePath: C:\...\PS\running\CKEditor.1032204042\
Locale: en-US
DateFormat: dd-MM-yyyy
PID: 14552 ('w3wp', Started='12/10/2010 11:14:40 AM', Priv=316Mb, Virt=883Mb)
TID: 1
.NET: 2.0.50727.3082

We use the seo URL's but these are the same on all the servers.

Kind regards,
Evert
Evert,

From the error stack above I'd guess that your eSpace is not deployed. To troubleshoot this I'd suggest:
  1. Go to SCenter and redeploy your eSpace (click button Redeploy published version);
  2. If that doesn't work check if you have the Deployment services activated in your machine;
  3. If this doesn't work check what's wrong with the filesystem (IIS permissions?)
These are all guesses. Good luck!
Pedro were you able to solve the issue with CKEDITOR is not defined ???

I'm getting the same thing and it's when I refresh with ajax...can anybody help me?
New message, new e-mail and seeing that I didn't posted what solved the solution...

Pedro,

You're 3 options didn't worked. The eSpace was succefully publised.

The error was having troubles with the SEO url's (it kept redirecting to the 'default' eSpace and some settings in the IIS (don't know exactly which, our network manager did it :)).

Kind regards,
Evert

I'm seeing problems with CKEditor on an AJAX Refresh as well, it says "Loading..." (in the Late Load item) endlessly. :(

I'm sure that if I took a look at the JS error stack I'd see the same thing.

J.Ja

Hi carlos,

The error appeared to me because I was trying to reinstate the CKEditor and was already started
in my case resulted to add this javascript:

"<script type='text/javascript'>
if (CKEDITOR.instances['" + InputId + "'])
{CKEDITOR.remove(CKEDITOR.instances['" + InputId + "']);}
</script>"

before CKEDITOR.replace( '" + InputId + "' ....
and in button "Save" add onclick "CKEDITOR.instances."+InputId+".updateElement();"

Cheers
Many thanks! I will try it later!!
I'm having a problem with using CKEditor. I have it connected to a mandatory Input box that has an OnChange action attached. The problem is that when i try to save the value, it says the Variable is empty, no matter what i write. Not only that, but the onChange action is never run. And since the field is mandatory, i can't advance.

However, this doesn't happen in Internet Explorer, only in Chrome or Firefox. Is this a problem with the editor itself?
Hi

What are the steps to install CkEditor into an eSpace web screen?

Hi Robert,
 
You'll need to add an input with height>1 and set its name (e.g. myCKEditor).
After you just drag a CKEditor web block to the page and set the InputId parameter to the input you have just declared (e.g. myCKEditor.Id).
Inside the solution you can find a CKEditor_Sample.oml where you can find an example. 
 
Cheers,
Tiago Simões
Hi Tiago

Thanks for the response.

See attachment. It did not work.

Hi Robert,

1 - Move the CKEditor web block after the input.
2 - Config parameter should be something like:
"height:'300px', toolbar:[['NumberedList', 'BulletedList', '-', 'Link']]"

Cheers,
Tiago Simões
Tiago

Great the editor panel now appears on the screen.

But there is two problems
  1. When Textbox is set to mandatory=true, and you try to use it, an error occurs.  "An exception occurred in the client script.Error: undefined"
  2. if you set mandatory to false, you can enter text, and this will work, however the content variable is always empty.
Hi Robert,

Make sure the Button Method is set to Submit, otherwise CKEditor wont work.

Cheers,
Tiago Simões
Tiago

thanks,
Hey guys

I'm having an issue with this component. I have a page that works perfectly well when ckeditor textbox is visible from the start. 

However, when I refresh the page thru ajax and the component becomes visible, the value of the textbox and associated variable is always empty.

Even the onchange event, defined in outsystems, doesn't change anything.

I've modified this component to clean all the instances, if exist, before draw the component. This way, I can avoid an error!!! I don't know if this is related to my problem.
Hi Carlos,

Have you tried to set the visibility through the Visible property of a Containter widget?
These way the elements will be in the html but they wont be visible.

Also please bear in mind that the action that saves ckeditor content needs to be a submit (and not an ajax), otherwise ckeditor will not work.

Cheers,
Tiago Simões
Hi!

When I have more than one CK editor instance per page, only one works, do  you know why? 
Somebody else had this problem?...
 
I may have found why ckeditor multiple instances doesn't work:

<body onpageshow="event.persisted &amp;&amp; (function(){var allInstances = CKEDITOR.instances, editor, doc;for ( var i in allInstances ){ editor = allInstances[ i ]; doc = editor.document; if ( doc ) { doc.$.designMode = &quot;off&quot;; doc.$.designMode = &quot;on&quot;; }}})();;event.persisted &amp;&amp; (function(){var allInstances = CKEDITOR.instances, editor, doc;for ( var i in allInstances ){ editor = allInstances[ i ]; doc = editor.document; if ( doc ) { doc.$.designMode = &quot;off&quot;; doc.$.designMode = &quot;on&quot;; }}})();">
    
It should only appear:

<body onpageshow="event.persisted && (function(){var allInstances = CKEDITOR.instances, editor, doc;for ( var i in allInstances ){ editor = allInstances[ i ]; doc = editor.document; if ( doc ) { doc.$.designMode = "off"; doc.$.designMode = "on"; }}})();">

In other words for every new instance it writes the event.persisted code in onpageshow. I still don't know how to correct this :/

 
The problem  isn't  sloved with that :/
I have the same probleme I solved adding a new parameter to the editor WebBlock :



The new parameter is a boolean to indicate if the init code is to be executed, only the first instance of the editor must include the code.
The first editor must have the InitEditor = True all others must have  InitEditor = False.
Hi!

Thanks! It is a simple solution and works!
Can anybody post a sample OML showing how to have a custom toolbar active
I've tried several options but up till now no luck.
Hi, in the config parameter you can put your configuration, 
Example  :
"height:'400px', contentsCss:'web.css', 
removePlugins:'save,templates,forms,about,bidi,print,flash,pagebreak,smiley,specialchar', 
toolbar:[
    ['Source','-','Preview'],
    ['Cut','Copy','Paste','PasteText','PasteFromWord'],
    ['Undo','Redo','-','Find','Replace','-','RemoveFormat'],
    ['Link','Unlink','Anchor'],
    ['Image', 'Table','HorizontalRule','CreateDiv'],
    ['Maximize', 'ShowBlocks'],
    '/',
    ['Styles','Format','Font','FontSize'],
    ['Bold','Italic','Underline'],
    ['NumberedList','BulletedList','-','Outdent','Indent'],
    ['JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock'],
    ['TextColor','BGColor']  
]"
Joaquim

You're my hero :-)
Stupid documentation telling me to go with configuration and adding toolbars did not work out.

Thanks
Hi again!

Do you happen to know how to remove de p tag from the text?

I've tried to insert in the config file this code:
config.autoParagraph = false;
config.enterMode = CKEDITOR.ENTER_BR;
config.shiftEnterMode = CKEDITOR.ENTER_BR;

But it only works if I don't delete all the text typed inside the ckeditor. 

 
Just go for the simple replace function at the point you save the HTML :-)
Hum yes that could be a solution but I need to have the text without it as it is typed.
The reason: I was trying to make a maxlength function, but it gets the length all messed up with so many html tags. 

Anyway thanks for your time and effort. I'll try something like insceasing the maxlength everytime a <p> or <br/> tag is found.
Does anyone have any idea how to just capture plain text with this editor. Love the SpellCheck function but when I save any text I would rather it wasn't HTML.

Have been looking up some developer stuff and it looks like http://docs.cksource.com/ckeditor_api/symbols/CKEDITOR.dom.element.html#getText may help but I'm not sure how to implement it in to an eSpace.

Cheers,

Tom
Hi Tom, 
I don't know if that can be done solely with CKEditor, but as an alternative you can implement a StripHTML function in an extension. It's fairly easy:

public void MssStripHTML(string ssHTMLString, out string ssString) {
            string pattern = @"<(.|\n)*?>";
            ssString = Regex.Replace(ssHTMLString, pattern, string.Empty);
}

Then you can just pass the HTML string through the function before saving it to the database, effectively stripping all HTML tags. :-)
Thanks Antonio!

Going to try putting this in to an extension although I have never created one before. Do I need Visual Studio to paste that code in to the extension?

Cheers.

Tom
Yes, you do need Visual Studio for that. Great opportunity for your first simple extension. :D
If anything, I can provide you with a XIF with that function. (In case you find some trouble with that)
Hi Antonio,

I've given it a go, downloaded VS and got the code together:

using System;
using System.Collections;
using System.Data;
using OutSystems.HubEdition.RuntimePlatform;
using GotDotNet.ApplicationBlocks;
 
namespace OutSystems.NssExtension {
 
public class CssExtension: IssExtension {
 
/// <summary>
/// 
/// </summary>
/// <param name="ssHTMLString"></param>
/// <param name="ssString"></param>
            public void MssRemoveHTML(string ssHTMLString, out string ssString) {
            string pattern = @"<(.|\n)*?>";
            ssString = Regex.Replace(ssHTMLString, pattern, string.Empty);
            }
 
} // MssRemoveHTML
 
 
} // CssExtension
 
} // OutSystems.NssExtension

Keep on getting an error Error 1 Type or namespace definition, or end-of-file expected.  

If you could help me out with an extension or with the coding I would appreciate it. Tried with my first extension but failed! By the way I am using 6.0.

Cheers

Tom
Hey Tom, there seems to be an extra } at the end of your code. Also, a reference to System.Text.RegularExpressions.

using System;
using System.Collections;
using System.Data;
using OutSystems.HubEdition.RuntimePlatform;
using System.Text.RegularExpressions;
using GotDotNet.ApplicationBlocks;
 
 
namespace OutSystems.NssExtension {
public class CssExtension: IssExtension {
/// <summary>
/// 
/// </summary>
/// <param name="ssHTMLString"></param>
/// <param name="ssString"></param>
public void MssRemoveHTML(string ssHTMLString, out string ssString) {
string pattern = @"<(.|\n)*?>";
ssString = Regex.Replace(ssHTMLString, pattern, string.Empty);
}
} // MssRemoveHTML
} // CssExtension
Thanks Antonio, worked a absolutely treat!
Hey guys. I also had the Ajax problem, so I made a few modifications to the component so I wouldn't have to hack around it with navigates and submits. Ajax > Submit & Navigate (UX wise)

Attached is a modified version fo the component that fully supports Ajax
  • No problem with Ajax Refreshes, as long as you refresh the WebBlock along with the TextBox.
  • Can now support Buttons with Ajax method, instead of just Submit.
Hope it's useful to someone else :)
 Had to fix some other issues for my specific project, so attached is another modified version

Change list:
  • Supports AJAX methods
  • Supports multiple instances of CKEditor on the same page (New)
  • Supports OnChange events (New) 
wrote:
 
 I could not install your version. I received an error trying to upload the solution. Could you re-post it?

Unable to open Solution Pack for reading:    at ICSharpCode.SharpZipLib.Zip.ZipInputStream.GetNextEntry()
   at OutSystems.HubEdition.ServerCommon.Solutions.SolutionUtils.#h.#Kib.MoveNext()
   at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source, Func`2 predicate)
   at OutSystems.HubEdition.ServerCommon.Solutions.SolutionUtils.GetManifestFromFile(Byte[] file)
   at OutSystems.HubEdition.ServerCommon.Solutions.SolutionUtils.GetSolutionInfo(Byte[] file, DateTime& creation, Int32& schemaVersion, String& activationCode, String& productId, String& productName)
   at OutSystems.NssOMLProcessor.CssOMLProcessor.MssSolutionPackGetInfo(Byte[] ssFile, String& ssUID, DateTime& ssCreation, Int32& ssSchemaVersion, RCHEMessageRecord& ssMessage, String& ssActivationCode, String& ssProductId, String& ssProductName)
Hi Chinita,
 
I installed your version, but the options have stopped working when webblock is referenced for the second espace, no popups appears.
 
appear:
"NetworkError: 404 Not Found - http://MyIp/eSpace/Blocks/CKEditor/CKFlow/skins/kama/editor.css?t=B1GG4Z6"
"NetworkError: 404 Not Found - http://MyIp/eSpace/Blocks/CKEditor/CKFlow/contents.css"

can help?
Pedro Coelho wrote:
Hi Chinita,
 
I installed your version, but the options have stopped working when webblock is referenced for the second espace, no popups appears.
 
appear:
"NetworkError: 404 Not Found - http://MyIp/eSpace/Blocks/CKEditor/CKFlow/skins/kama/editor.css?t=B1GG4Z6"
"NetworkError: 404 Not Found - http://MyIp/eSpace/Blocks/CKEditor/CKFlow/contents.css"

can help?
 
 Hey Pedro. Thanks for the heads up.
I managed to find a workaround for that problem, but since nobody complained, I thought it was just me.

Attached is a modified version.
To make it work, just copy these resources from the CKEditor eSpace to your eSpace.



Actually, the first set (beginning with .\Blocks\) are just duplicates of the second set. Just get all four from CKEditor, then duplicate each of them :)
Thanks Chinita,
is already working well.
wrote:
 
 Hey Pedro. Thanks for the heads up.
I managed to find a workaround for that problem, but since nobody complained, I thought it was just me.

Attached is a modified version.
To make it work, just copy these resources from the CKEditor eSpace to your eSpace.



Actually, the first set (beginning with .\Blocks\) are just duplicates of the second set. Just get all four from CKEditor, then duplicate each of them :)
 
Hi Chinita,

I'm new with Outsystems and I'd like to request your help for an issue I'm facing regarding to the upload of your version of CKEditor. 
When trying to upload your new version I get an Intellectual Property Error. I read about it and didn't found a way to solve this. I have the new 7.0 version of both service studio and platform server.

Is there any way to upload your version in order to use the ajax capabilities you've implemented?


Thanks!
Go to www.outsystems.com/ipp and follow the wizard.

J.Ja
Justin James wrote:
Go to www.outsystems.com/ipp and follow the wizard.

J.Ja
 
 Thanks a lot Justin.

I had already visited that site, but since I wasn't the owner of the espace I didn't knew if I will be able to request a version valid for my license. Glad to know this has a simple resolution! :)
Hi!

Can I use this editor in mobile app's with PhoneGap?

Thanks
Hi,

Has anyone updated this to 3.6+? It would really help me if anyone did this and can share the component.

Best regrards,
Hermínio Mira
This has been updated to 3.6.6! Now it works with iPads. :D

J.Ja
Hi,

I am using CKEditor in my application, where I am repeating CkEditor in TableList so that user can update data for each record.

Issue #1: Data doesn't save in Internet explorer
Steps to generate issue:
1) Click on "Add New Record" to create new record.
2) Click on "Edit" link to open CKEditor and information.
3) Click on "Save" button. It will save the data.
4) Again open CkEditor by clicking "Edit" link and change information which doesn't save.

Please note that, it is working fine on Google Chrome and Firefox browsers.

Issue #2: Not able to add image using upload option
description: This option is not working when I was trying to upload image List. Same feature is working when I tried to upload the image by placing CK Editor outside of TableRecords.

Please advise

I have attached the sample for your reference.

Thanks in advance.


Regards,
Sagar Nannaware
Is the latets version of this component updated with the AJAX fix ?
And which version is it ?
Joop -

We updated it to 3.6.6 in March, I'm not sure what fix you mean but I guess you could look at the CKEditor history to find out.

Unfortunately, this component originally had a HUGE number of files in the resources, it takes a day to update them all, it's miserable. :(

J.Ja
It is miserable, Justin :) I totally agree with you.

I used the batch file approach because that was the only way I knew how to do it, still maintaining a target path in the javascript library. Unfortunately the Integration Studio approach (Add a Resource) would force me to do it one-by-one :(

Would you guys suggest any other approach? This could actually be a great improvement to the component (there's already new versions of CKEditor out there so we could upgrade our own). Hey, I just remembered a new approach: using the Zip extension...could it work?
Pedro -

Use Zip extension + 1 ZIP of the resources, and a "When Published" timer to expand the resource into the resources folder, perhaps?

J.Ja
Exactly! I'm just not sure if any file system permissions would be required on the server... Anyone to try it? Will do it as soon as I have the chance. Cheers!
Well, both solutions (ZIP or a "Resource Filled" extension) imply converting the component from single eSpace into a solution package. The ZIP method would need the FileSystem extension to deploy the unzipped files, the extension method would have to include that specific new extension.


Thanks António, I suggest that we publish the component with those references and outline the dependencies in the component page. That should put people aware of those extensions, at least. And we get the component properly maintained with the .zip approach. 
There's something else... (lol) Is there any out of the box action to return the physical path of an eSpace?
If not, there's another extension that needs to be created (.NET and Java) for the zip approach to work... :P


Edit: Nevermind, luckily FileSystem has that as well! :D
Can someone take it for a test drive please? (Attached)

Added the Zipped resources, and merged with my version from this thread (Ajax Refresh support & OnChange events).
(Don't forget it depends on the Extension FileSystem component)
Also added the Demo.aspx page, with many buttons, where I tested all that. :P

Releasing the solution once I get the OK from one of you guys.
I'm really jammed up at the moment, I'm knee deep in a data migration...

J.Ja
Thanks guys,

I've just tested your version António, but unfortunately I got an UnauthorizedAccessException while writing the very first CKEditor library directory into the server's filesystem. So I guess this may work well if you have complete control of the infrastructure, but may be impractical otherwise. Any suggestions to workaround this?

Complete error stack:
Timer Deploy error (inside action 'DeployCKEditor'). Timer duration = 0 secs:Access to the path 'C:\Program Files\OutSystems\Platform Server\running\CKEditor.763138052\ckeditor\' is denied. 

System.UnauthorizedAccessException: Access to the path 'C:\Program Files\OutSystems\Platform Server\running\CKEditor.763138052\ckeditor\' is denied.
   at ssCKEditor.RssExtensionFileSystem.MssDirectory_Create(HeContext heContext, String inParamPath)
   at ssCKEditor.Actions.ActionDeployCKEditor(HeContext heContext)
   at ssCKEditor.TimerDeploy.Execute(HeContext heContext, Int32 timeout)


I tested in a server where I don't have any kind of access (except for servicecenter), but apparently the runtime user has full permissions, that's why it worked. 

I don't see any simple way to get around it while keeping the process transparent for the developer... Maybe switch to the "resources in extension" approach? -.-
...the problem with the "resources in extension" approach is the Deploy Action. You'll have to set it manually one-by-one... Maybe we're okay with keeping with the .zip approach, António. We'll just need to provide a workaround (batch-file?) in case anyone gets the same problem I got, above. Please go ahead and publish your version to the component. And thank you so much! Any other ideas, folks?
Well, I think I have another option than the Batch.
What if we replace the FileSystem dependency for Network FileSystem?
The Network version provides impersonation, and would allow us to build a screen with a manual deploy action, where the developer could provide credentials. CKEditor's eSpace could be set with ServiceCenter user provider and it's own login screen.

The problem here is, with every publish, he'd have to manually deploy the files. (Think of solution deployments, etc.)
Maybe if we detect "undeployed" CKEditor, we could replace the editor with a screen block giving that information?
I use the CKEditor for public-facing stuff, anything that prompts the user for file system credentials is a no-no.

Maybe use NetworkFileSystem, which can do an authorization, and a site property for the credentials? The problem is when you have someone like me with a lot of servers, that means that for each server I need to configure the file system and add a user.

The real solution, is to keep "Like"-ing this idea until it gets implemented:

http://www.outsystems.com/ideas/750/manage-resource-folder/

It's a lot easier for the community to wrape the great jQuery, JavaScript, etc. widgets out there (and make the OS community beter in the process) if we can more easily manage the files in resources!

J.Ja
Justin, what if we set the CKFlow's "Internal Use Only" to "True"?
Would that solve your concern?

Also, the Site properties sound good, and could solve the issue with "republishes". :D
Antonio -

No, because we have a public facing application.

In a nutshell... this needs to work after every and each deployment with no configuration needed. If it cannot be done with a set-once site property and/or a "when published" timer, it will not be a good solution for people. :(

J.Ja
I believe that if you set a flow to Internal Use Only, it will only work if you access the pages from within the same LAN. That's why I gave the sugestion. It shouldn't matter that your application is public facing.
Besides, before asking for machine user credentials, it should ask for ServiceCenter credentials, to let you access that screen.
Edit: Like So.

The site properties and that screen can coexist.
The screen allows you to do it manually, and "OnSuccess" advises you to set the Site Properties correctly.

It might never work on the first deploy, because the Site Properties might not be set.
But as I said, they solve the next publications once the dev gets around to setting them up.
So that's definitely a way to go (Site Properties).
Ingenious, António! Except for the unencrypted ServiceCenter credentials in site properties I'd be fine with that. How would you work-it-around?

On the other hand, we might be running this into a very-big-footprint component... Still, if it works in an most-automated fashion, I'm not worried about it.
The credentials in site properties wouldn't be for ServiceCenter. The credentials stored in site properties would be for a system user, with privileges to write on the App Path.

ServiceCenter credentials would be needed in a login screen, to access "Manual Deploy" page. Once inside that page, the dev could manually deploy the files. If the operation is sucessful, the site properties could be dynamically set, and the "republish" issue would be solved.
Antonio -

Our application is on public cloud servers, we don't have the concept of "from within the LAN", at best we can access it from localhost.

The ZIP file approach is wrong, though. Because it doesn't work for someone (like us) with multiple servers, it will only deploy the files to ONE server, the one that is handling the timer or "deploy files" request or whatever. :(

What we need is a good way to add multiple files and their paths to the resources system, and for this particular project we just need to find out what the minimum number of files needed to make CKEditor work is.

J.Ja
I see where you're getting at Justin. It won't work for multiple front ends... You're right.
The extension method doesn't allow deploying to folders, I think, so we're back to the start.
Well guys,

I've created this small console program to create a batch file with all the command lines required to import a folder and all subfolders to an oml, with the corresponding subpath.

Attached the executable, but be aware the Service Studio location is hardcoded...
Attached is also an example of the .bat file produced after running it with a CKEditor zip (after expanded) downloaded form CKEditor's site.

To run the program do it like:
SSImportResources.exe OMLFILE FOLDER
e.g. SSImportResources.exe CKEditor.oml ckeditor_4.3_57acdb39622f

It will generate the batch file to import all files under the ckeditor_4.3_57acdb39622f folder to the CKEditor.oml

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Diagnostics;

namespace SSImportResources
{
    class Program
    {
        const string ssPath = @"C:\Program Files\OutSystems\Service Studio 8.0\ServiceStudio.exe";
        static string oml;
        const string output = "ImportResources.bat";

        static string cmd = " -importResource \"{0}\" \"{1}\" \"{2}\"";
        static StreamWriter file;
        static void Main(string[] args)
        {
            oml = args[0];
            if (File.Exists(output)) File.Delete(output);
            using (file = File.CreateText(output))
            {
                ImportFolder(args[1], args[1]);
            }
            Console.WriteLine("Output created at " + output);
        }

        private static void ImportFolder(string folder, string basef)
        {
            foreach (string f in Directory.GetFiles(folder))
            {
                string c = string.Format(cmd, oml,
                    f, Path.GetDirectoryName(f).Replace(basef, "."));
                file.WriteLine("\"" + ssPath + "\" " + c);
            }

            foreach(string d in Directory.GetDirectories(folder)) {
                ImportFolder(d, basef);
            }
        }
    }
}

Certainly makes it easier... I'll give it a try tomorrow and hopefully release the pending version on my laptop.
Kudos Gonçalo.
Gonçalo Borrêga wrote:
I've created this small console program to create a batch file with all the command lines required to import a folder and all subfolders to an oml, with the corresponding subpath.

To run the program do it like:
SSImportResources.exe OMLFILE FOLDER
e.g. SSImportResources.exe CKEditor.oml ckeditor_4.3_57acdb39622f
 
Beautiful !!
Would be nice to have the path to SS as input as well :-)
I added this to that code and replaced the const SS path. In case someone needs it. :)
(Not sure if it works outside my computer, as it uses the shell\open\command path and assumes all service studio versions are inside the same base folder)

        const string ssExe = @"\ServiceStudio.exe";       
        public static string getSSPath()
        {
            RegistryKey rk = Registry.ClassesRoot;
            RegistryKey sk = rk.OpenSubKey(@"ServiceStudio\shell\open\command");
            string ssPath = sk.GetValue("").ToString();
            ssPath = ssPath.Substring(0, ssPath.ToLower().IndexOf("servicestudio.exe"));
            string osPath = Directory.GetParent(Directory.GetParent(ssPath).ToString()).ToString();
            string[] osPaths = Directory.GetDirectories(osPath, "service studio*", SearchOption.AllDirectories);
            Console.WriteLine("Choose your Service Studio version:" + Environment.NewLine);
 
            if (osPaths.Length == 1) return osPaths[0] + ssExe;
 
            int counter = 0;
            foreach (string p in osPaths)
            {
                Console.WriteLine("    " + counter.ToString() + " " + p);
                counter++;
            }
            int osChosen = -1;
 
            while (osChosen < 0)
            {
                Console.Write(Environment.NewLine + "Enter the number of the version you wish to use [0-" + (osPaths.Length - 1).ToString() + "]:");
                string r = Console.ReadKey().KeyChar.ToString();
                if (int.TryParse(r, out osChosen))
                {
                    if (osChosen < 0 || osChosen >= osPaths.Length)
                    {
                        Console.WriteLine(Environment.NewLine + "You didn't press a valid number");
                        osChosen = -1;
                    }
                }
                else
                {
                    Console.WriteLine(Environment.NewLine + "You didn't press a valid number");
                    osChosen = -1;
                }
            }
 
            string osChosenPath = osPaths[osChosen];
            Console.WriteLine(Environment.NewLine + "Now adding resources with " + osChosenPath + ssExe + "...");
 
            return osChosenPath + ssExe;
        }

Wow guys, you did an awesome job to get CKEditor to support AJAX.
We're on our way to integrate our image uploader/cropper into CKEditor !
Inspired by Gonçalo Borrega's code, last night I decided to expand that.
Attached is the tool I used, might be useful for the rest of this component's dev team.

github: https://github.com/achinita/ImportResources/


Wow!!!! I'm baffled. This is simply A-M-A-Z-I-N-G. A full-standalone "plugin" to Service Studio... thanks a lot, Chinita!
Guys, there's a small glitch in one of the scripts ...  

<CKEditor instance> contains reference to the test txteditor instance ... this way it's using the instance created by the CKEditor ...
One thing I need to figure out is the use of destroy insted of delete.
Seems delete is leaking memory ...



"<script type='text/JavaScript'>
if (typeof CKEDITOR === 'undefined') {
        osjs('#"+InputId+"').after('<span style=""background: tomato; color: white; border: 1px solid red; padding: 3px;font-weight: bold;"">CKEditor not loaded. Please check for errors.</span>')
    }
    else {

        // Does it already exists, then destory it !!
        if(CKEDITOR.instances['" + InputId + "']) {
            //CKEDITOR.instances['" + InputId + "'].destroy();
            delete CKEDITOR.instances['" + InputId + "'];
        }

        // Update function, to trigger events
        osjs('#"+InputId+"')[0]['ckEditorUpdate'] = function () {
            setTimeout(function(){
                if (CKEDITOR.instances." + InputId +" && CKEDITOR.instances." +InputId + ".checkDirty()) {
                    var editor = CKEDITOR.instances." + InputId + ";
                    osjs('#" + InputId + "').val(osjs(editor.document.getBody().$).html());
                    editor.resetDirty();
                    osjs('#" + InputId + "').trigger('onchange');
                }
            },100);
        };
        CKEDITOR.replace( '" + InputId + "', {" + If( Config <> "", Config + ", ", "") +
    "language: 'en', filebrowserImageUploadUrl: '/CKEditor/Upload.aspx?command=QuickUpload&type=Images',
            on: {
                saveSnapshot: osjs('#"+InputId+"')[0].ckEditorUpdate,
                key: osjs('#"+InputId+"')[0].ckEditorUpdate,
                afterCommandExec: osjs('#"+InputId+"')[0].ckEditorUpdate,
                change: osjs('#"+InputId+"')[0].ckEditorUpdate
            }});
    }
</script>"
Hi Joop.
.destroy() wasn't working properly for some reason with Ajax requests.

What kind of problems is it causing? :o
Got that as well :-)
I read this http://dev.ckeditor.com/ticket/4555 but already seemed to be fixed.
And this one concerning destory() vs delete http://ckeditor.com/comment/39479, so delete it needs to be

Anyway, there is a reference to the demoscreen, in the code above I fixed that bit
Hi.

I want to conditionaly show CKEditor on the screen. If the user selects a option it shows the CKEditor if he selects another it hides CKEditor and show something else.
But this is not working, because if I hide the CKEditor and input widget I get this error: 

"An exception occurred in the client script.
Error: undefined "

This is what I get on the Chrome console:

  1. [CKEDITOR.editor] The instance "wt14_wtMainContent_wtInput_CK" already exists. _osjs.js?8_0_0_22:186


"Input_CK" is the name of the input widget.
 
Thanks!
Hi Carlos.
I think I've identified the problem, and came up with a temporary fix.

Also, have you updated to the latest version of the component?
What platform version are you using? (So I can share an eSpace with you)
I'm using Platform 8.0.0.22.
Are you using the latest version of the component? :)
Yes.
We've downloaded the latest version on January 8th.
Allright.

Attached is a modified eSpace. That might solve your problem.
The procedure is, put a CKEditor block in a section of your page that is always visible. Don't fill in the InputId Parameter for this instance of the block.

Your code, keep it as is, just make sure that your Ajax Refresh is affecting both the TextInput field and the CKEditor WebBlock that has it's Id.

In the espace's demo page, this procedure is implemented.

Explanation:
For some reason, the CKEDITOR page object isn't being loaded in time when you Ajax Refresh, so the library needs to be loaded before.
I've modified the InputId to Non mandatory, in order to make it possible to load the library only with the same webblock.

Tell me if it works for you. :)
Nop, I get the same error.

I attached an eSpace with the example I'm trying to run.

Thanks :)
Allright, thanks for the context eSpace.
Edit: Forget that webBlock instance without the Id, it is no longer needed. Actually, I made the Input parameter mandatory again. :)

I just switched from a temporary fix, to a full fix. Mostly because I've always meant to change some things on the editor but never had the need to, because everything seemed to work. :)

Attached is a new version of the editor, if it works for you, I'll convert to a 7.x version and publish the fixed version. I tested with your eSpace, worked fine.

Please tell me if it's ok now.

Changes:
  • Removed the loading of ckeditor.js from an injected <script> tag
  • Using jQuery's getScript to load the library now. No more <script src='xxx'> tag injection.
  • Using getScript's success parameter to load instances and do validations.
  • Centralized everything in the WebBlock's JavaScript section: easier to read and manage (we all like identation and coloring :P)
Bump.
Can anyone provide feedback about the version attached to the last post? :)

Edit: I uploaded anyway... New version available.

Added Features
  • Upgraded to CKEditor 4.3.1 (from 3.6.6.1) (see change log)
  • Reduced the number of <script> tags per instance
  • Now using jQuery's .ajax() (with cache) to load the editor library
  • Most of the code is now in the block's Javascript section
  • Restructured demo page

BugFixes
  • Fixed a bug that made the editor not load if the editor wasn't present on page load.
Hi António.

Thanks for the update!
Unfortunately, it's not working with my eSpace because I also have the jqTree plugin on the same screen as the CKEditor, and the CKeditor is not loading.

If I remove the jqTree from the screen it works.
They both worked with the previous version of the CKEditor component.

jqTree tree widget:
http://mbraak.github.io/jqTree/
Hi Carlos.
Do you see any errors in the console? :)
Hi António.

I fixed it on the jqTree widget.

Thanks for your help and for upgrading to CKEditor 4 :)
Good to know your problem is no more.

By the way, what was it?
Any chance we should worry about incompatibilities with other jQuery implementations?
The problem was caused by the jquery.mockjax.js.

It was copied from an example of the jqTree but it wans't needed for production, and was causing problems with CKEditor. I removed all the references to this library and know both jqTree and CKEditor work fine.
Ok. Thanks for the feedback once again Carlos. :)
Good morning!
I am using this component to obtain inputs from users and i need to write inside a docx template, but every single time i do that, i obtain "illegal xml charater", "unspecified error".
My question is if is possible to obtain the text from the input field and insert the same text  inside my document base and still keep the changes done in style eg:bold, size, etc

I read the forums about the subject and i am trying by two different ways but the result are the same.
In attachment I share with you what i am doing.
 
Anyone can help me?
 

Hello, 
 
We're having problems with this component in platform version 8
The usage is within a webblock which is then referenced in another eSpace. 
Also, we check that the HTML element ID generated by the platform is separated by ":" (colon)
 
ie: Layouts_wt1: wtMainContent: Notification_wt17: block: wtEmailTemplate_Body 
 
This behavior is generating the following JavaScript exception: 'Unexpected token : ' inside the CKEditorCreate (inputId, config) function.
 
As a temporary quickfix, after rendering the textarea (EmailTemplate_Body), we change his ID in order to not have colons. The replace was also necessary in all the places where this runtime ID is used. 
 
Someone with a better workaround or a more structural and definitive solution?

Version: CKEditor 4.3.1
Plataform Version: 8.0.0.24
Stack: JAVA / JBOSS / ORACLE
 
Best regards,
Mário Coelho
Hi Pedro, 

I have a concern regarding the CKEditor. My use case is as follows:

User views the post and edit it using CKEditor. Currently, the HTML content is already in the textarea but doesn't show up in the CKEditor. 

Based on this post...

Pedro Gonçalves wrote:
Hi again Alexandre,

I remember that happening when my field was set as mandatory. 
You probably need to use the CKEDITOR.instances.editor.updateElement() function. It forces CKEditor's dialog to transfer its contents to the text input.

Check out the details here: http://docs.cksource.com/ckeditor_api/symbols/CKEDITOR.editor.html#updateElement

Also, see the attached sample. Hope it helps.

Cheers!
I tried to follow this, but I can't due to the error that CKEDITOR is not defined. I've attached the OML for your reference. I need to make the contents of the textarea visible in the CKEditor. The content is directly from an advanced query. Any help would be appreciated. 

This screenshot might help you too...



Thanks, 

Julius