Kauri Documentation
 PreviousHomeNext 
3.6 Adding data via a formBook Index3.8 Adding form validation and formatters

3.7 Creating a module to add a HTML editor

We have created a form to add some blog items. It is of course not very user friendly to let users input HTML via a simple textarea. For that, we will use an existing HTML editor. We choose for TinyMCE here, because it has a jQuery plugin and is simple to plugin. We will create this as a separate module in our application and in this section, we'll show how to do that.

Creating the module structure

When creating our application by using the archetype, we have already added one module as default 'module1'. Beside this folder, we'll create a new module 'tinymce' with this folder structure:

-- myblog
   |-- pom.xml
   |-- conf
       |-- wiring.xml
   |-- module1
   |      ...
   |-- tinymce
       |-- src
       |   |-- main
       |       |-- kauri
       |       |   |-- spring
       |       |       |-- services.xml
       |       |-- tiny_mce
       |       |   |-- jquery.tinymce.js
       |       |   |-- tiny_mce.js
       |       |   |-- .... rest of tinyMCE code 
       |       |-- router.groovy
       |-- pom.xml

Configure the tinymce module

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0,http://maven.apache.org/maven-v4_0_0.xsd">

  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>org.kauriproject</groupId>
    <artifactId>myblog</artifactId>
    <version>1.0-SNAPSHOT</version>
    <relativePath>../..</relativePath>
  </parent>

  <artifactId>kauri-tinymce</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>
  <name>MYBLOG ::: TINYMCE</name>

  <build>
  </build>
</project>
<?xml version="1.0"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:kauri="http://kauriproject.org/runtime/1.0#springext"
  xmlns:context="http://www.springframework.org/schema/context"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
                    http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
                    http://www.springframework.org/schema/context
                    http://www.springframework.org/schema/context/spring-context-2.5.xsd
                    http://kauriproject.org/runtime/1.0#springext
                    http://www.kauriproject.org/schemas/runtime/springext.xsd">

  <context:annotation-config />

  <kauri:module restletContext="context" classLoader="classloader" handle="module"/>

  <kauri:import-service id="routing" service="org.kauriproject.routing.RoutingService"/>

  <kauri:export-restservice ref="main"/>

  <bean id="main" factory-bean="routing" factory-method="createRouter">
    <constructor-arg ref="context"/>
    <constructor-arg ref="module"/>
  </bean>

</beans>
builder.router {

    directory(
            uri: "/",
            listingAllowed: true,
            root: "module:/tiny_mce/"
            
    )
}

Wire it in the myblog application

To wire the new module inside the blog application, we add the tinymce artifact to the wiring.xml and mount the rest service on the correct path:

    <artifact id="tinymce" groupId="org.kauriproject" artifactId="kauri-tinymce" version="1.0-SNAPSHOT">
      <inject-restservice name="jquery" ref="jquery:main"/>

      <mount name="main" path="/tinymce"/>
    </artifact>

Because the other artifact 'module1' depends on this one, make sure to define 'tinymce' before 'module1'

In the root pom.xml, add the module:

  <modules>
    <module>module1</module>
    <module>tinymce</module>
  </modules>

Use it in the form

TinyMCE is now available via the service protocol, so we can load the tiny mce jquery script via this URI:

    <script type="text/javascript" src="${publicUri('service:/tinymce/jquery.tinymce.js')}"></script>

When the script is loaded we can call tinymce on the textarea of the form:

        $('form textarea').tinymce({
          script_url : '${publicUri('service:/tinymce/tiny_mce.js')}',
          theme : "simple"
        });

Note that this will call tinymce for all textarea controls in your form. If you use this elsewhere, be more specific in the jQuery selector

To make sure the tinymce module copies its content to the textarea before submission of the form, we have to call the triggerSave method.

        itemForm.prevalidation( function () {
           tinyMCE.triggerSave(true, true);
           $('form textarea').change();
        });

Result

Page template {id}-edit.html now looks like this:

<?xml version="1.0"?>
<html t:inherit="module:/templates/layout.xml"
      xmlns:t="http://kauriproject.org/template">

  <t:init>
    <t:variable name="id" value="${request.attributes.id}" />
    <t:if test="${id != 'new'}">
      <t:variable name="item" src="service:/data/items/${id}" overwrite="false" accept="application/json"/>
    </t:if>
  </t:init>

  <t:block name="title">${item.title}</t:block>

  <t:block name="extraHeaders">
      <t:superBlock/>

      <script type="text/javascript" src="${publicUri('service:/tinymce/jquery.tinymce.js')}"></script>
   
      <script type="text/javascript">
      jQuery(document).ready(function() {
      
        var fconf = {
          "createURI": "${publicUri('service:/data/items/')}",
        
          type: {
            members: {
              'id' : {
                'base' : 'integer',
                'control' : {
                  'initial' : {
                    'enable' : false
                  }
                }
              },
              'title': 'string',
     
              'content': {
                'base': 'string',
                'control' : 'textarea-control'
               },
               'date' : 'date'
            }
          }
        }; / *end fconf */

        /* create form */
        if(${id == 'new'})
            fconf.createURI = "${publicUri('service:/data/items/')}";   
        else
            fconf.dataURI = "${publicUri('service:/data/items/')}${id}";
        var itemForm = new jQuery.org.kauriproject.forms.Form("item-form", fconf);


        itemForm.setCreateMode(${id == 'new'});
        if(${id != 'new'})
            itemForm.setWireValue(${item});
        
        
        $('form textarea').tinymce({
          script_url : '${publicUri('service:/tinymce/tiny_mce.js')}',
          theme : "simple",
        });



        itemForm.prevalidation( function () {
           tinyMCE.triggerSave(true, true);
           $('form textarea').change();
        });

     
        itemForm.submitSuccess = function (data, success) {
            window.location = "${publicUri('service:/main/items/all.html')}";
        };       

      });
    </script>

  </t:block>

  <t:block name="content">
     <form id="item-form">
     
     </form>
  </t:block>

</html>

Which results in:

You'll see at this point a date parse error when you load one of your entities, in the validation section we'll show how to solve this

 PreviousHomeNext 
3.6 Adding data via a form3.8 Adding form validation and formatters