<!-- 
/*
Copyright 2017 apHarmony

This file is part of jsHarmony.

jsHarmony is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

jsHarmony is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with this package.  If not, see <http://www.gnu.org/licenses/>.
*/
-->
<script type="text/x-tutorial-info">
{
  "Title": "HTML Editor",
  "Menu": ["Models","Fields / Controls","Built-in Controls"],
  "Code": [
    "/models/FieldHTMLEditor_Basic.json",
    "/models/FieldHTMLEditor_Custom.json",
    "/models/FieldHTMLEditor_Custom.js"
  ],
  "Demo": [
    { "url": "jsHarmonyTutorials/FieldHTMLEditor_Basic?action=update&cust_id=1", "title": "HTML Editor" },
    { "url": "jsHarmonyTutorials/FieldHTMLEditor_Custom?action=update&cust_id=1", "title": "HTML Editor Custom Initialization" }
  ]
}
</script>

<h3>Overview</h3>

The "htmlarea" control provides an HTML Editor for input.  The "htmlarea" control is only available on models with the "form", "form-m", "exec", and "report" layouts.<br/>
<br/>
The "htmlarea" integrates CKEditor, and has support for uploading and pasting images.  Uploaded images are stored in a public folder at "/cmsfiles" for sharing, while pasted images are stored in the text as base64 images.<br/>
<br/>
The "htmlarea" control has the following field.controlparams parameters:
<pre>
{
  "control": "htmlarea",
  "controlparams": {
    "htmlarea_config": { /* Any CKEditor custom config options */ }
}
</pre>

<%-getScreenshot('jsHarmonyTutorials/FieldHTMLEditor_Basic?action=update&cust_id=1&popup=1','HTML Editor', { width: 1000, height: 1500 })%>
<pre>
{
  "table":"cust",
  "layout":"form",
  "onecolumn":true,
  "popup":[600,400],
  "caption":["Customer","Customers"],
  "fields":[
    {"name":"cust_id","caption": "ID"},
    {"name":"cust_name","caption":"Name"},
    {"name":"cust_portal_welcome_txt","caption":"Portal Welcome Content","control":"htmlarea"},
    {"name":"cust_desc","caption":"Description","control":"htmlarea",
      "controlparams":{
        "htmlarea_config": {
          "toolbar": [
            ["Styles", "Format", "Font", "FontSize"],
            ["Image", "Table", "HorizontalRule", "-", "Link", "Smiley", "TextColor", "BGColor", "Source", "Maximize"]
          ]
        } 
      }
    },
    {"name":"unbound_editor","caption":"Unbound Editor","control":"htmlarea","unbound":true,"default":"<b>Test</b> Sample",
      "controlstyle": "width:400px;height:100px;",
      "controlparams":{ 
        "htmlarea_config": { 
          "removePlugins": "toolbar,resize,elementspath",
          "allowedContent": "b i p h1 h2 strong em; a[!href]; img[!src,width,height]"
        } 
      }
    }
  ]
}
</pre>

The example above has three "htmlarea" controls.<br/>
<br/>
The first HTML Editor is a basic example of a default html editor linked to a database field.  It includes an embedded base64 image in the database data.<br/>
<br/>
The second HTML Editor has a customized menu using the field.controlparams.htmlarea_config property.<br/>
<br/>
The third HTML Editor links to an unbound field, and additionally has the menu, status bar, and resize controls removed.  The HTML Editor content can be get / set using JavaScript:
<pre>
//Getting the current HTML Editor value
var current_value = jshInstance.XModels["jsHarmonyTutorials/FieldHTMLEditor_Basic"].get('unbound_editor');

//Setting the current HTML Editor value
jshInstance.XModels["jsHarmonyTutorials/FieldHTMLEditor_Basic"].set('unbound_editor','<b>Test</b> Sample');
</pre>

<h3>Setting Width and Height</h3>
HTML Editor width and height can be set via the controlstyle attribute:
<pre>
{
  "control": "htmlarea",
  "controlstyle": "width:400px;height:100px;"
}
</pre>

<h3>Customizing the Toolbar</h3>
The toolbar can be customized using the field.controlparams.htmlarea_config property.  Any of the CKEditor Toolbar features can be used.
<pre>
{
  "control": "htmlarea",
  "controlparams": {
    "htmlarea_config": {
      "toolbar": [
        ['Styles', 'Format', 'Font', 'FontSize'],
        ['Bold', 'Italic', 'Underline', 'StrikeThrough', '-', 'Undo', 'Redo', '-', 'Cut', 'Copy', 'Paste', 'Find', 'Replace', '-', 'Outdent', 'Indent', '-', 'Print'],
        ['NumberedList', 'BulletedList', '-', 'JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyBlock'],
        ['Image', 'Table', 'HorizontalRule', '-', 'Link', 'Smiley', 'TextColor', 'BGColor', 'Source', 'Maximize']
      ]
    }
  }
</pre>

<h3>No Toolbar</h3>
The toolbar and status bar can be removed by extending the field.controlparams.htmlarea_config property:
<pre>
{
  "control": "htmlarea",
  "controlparams": {
    "htmlarea_config": {
      "removePlugins": "toolbar,elementspath",
      "allowedContent": "b i p h1 h2 strong em; a[!href]; img[!src,width,height]"
    }
  }
</pre>
The "removePlugins" and "allowedContent" properties are a CKEditor config properties.  In this example, "removePlugins" disables the toolbar and status bar, while "allowedContent" allows images to be pasted, and bold / italic tags to still be used via the CTRL+B and CTRL+I keys.

<h3>Custom HTML Editor Initialization</h3>
In cases where the HTML Editor should only be started in certain situations, the CKEditor can be connected to an existing HTML textarea using JavaScript. This can be useful in custom forms, and in situations where a drop-down might define whether the content should be HTML or raw text.<br/>
<br/>
In the following example, the editor can be switched between HTML and Plain Text via a dropdown:
<%-getScreenshot('jsHarmonyTutorials/FieldHTMLEditor_Custom?action=update&cust_id=1&popup=1','Custom HTML Editor Initialization')%>
<pre>
//model.json
//----------
{
  "table":"cust",
  "layout":"form",
  "onecolumn":true,
  "popup":[600,400],
  "caption":["Customer","Customers"],
  "onload":"_this.onload(xmodel,callback);",
  "fields":[
    {"name":"cust_id","caption": "ID"},
    {"name":"cust_name","caption":"Name"},
    {"name":"cust_desc_editor_type","unbound":true,"control":"dropdown","caption":"Editor Type",
      "lov": { "values": { "TEXT": "Text", "HTML": "HTML" } },"default":"TEXT",
      "onchange":"_this.cust_desc_editor_type_change(obj,newval,e);"},
    {"name":"cust_desc","caption":"Description","control":"textarea","controlstyle":"width:500px;height:500px;"}
  ]
}

//model.js
//--------
jsh.App[modelid] = new (function(){
  var _this = this;

  //On form load
  this.onload = function(xmodel,callback){
    _this.render_cust_desc_editor();
  }

  //On drop-down value change
  this.cust_desc_editor_type_change = function(obj,newval,e){
    _this.render_cust_desc_editor();
  }

  this.render_cust_desc_editor = function(){
    //Get the value of the dropdown
    var cust_desc_editor_type = xmodel.get('cust_desc_editor_type');

    if(cust_desc_editor_type=='HTML'){
      //If we should render an HTML editor
      //Add an "id" attribute to the cust_desc textarea, because it does not have one by default
      $('.cust_desc.xelem'+xmodel.class).attr('id',xmodel.class+'_cust_desc');
      //Initialize the editor on the cust_desc textarea
      XExt.CKEditor(xmodel.class+'_cust_desc');
    }
    else {
      //Otherwise, remove the CKEditor if it is currently displayed
      //Get the CKEditor object
      var editor_id = xmodel.class+'_cust_desc';
      var editor = (window.CKEDITOR?window.CKEDITOR.instances[editor_id]:undefined);
      if(editor){
        //Remove the editor
        editor.destroy();
      }
    }
  }

})();

</pre>

<h3>Saving Images / Files</h3>
Images and files are saved using the "/_ul/ckeditor" route.  Images and files are shared between all authenticated users.<br/>
<br/>
Uploaded files are temporarily stored in /data/public, before they are processed and saved to /data/cmsfiles.<br/>
<br/>
The root data folder ("/data") can be changed using the jsh.Config.datadir setting.