EditLive! for Java JavaScript API CustomPropertiesDialog Example

Introduction

The EditLive! for Java JavaScript API includes functionality to allow developers to create custom dialogs for use with specific tags.  Custom dialogs can be used to edit the attributes of a specific tag.  This example demonstrates how to create a general dialog which may be used with any tag.  In the case of this example, the functionality is tied to adjusting the properties of the <TD> tag.

This functionality of EditLive! for Java is accessed by creating a custom menu item or toolbar button which makes a call to an external JavaScript function.  After the relevant attributes are edited externally to EditLive! for Java the relevant information is sent back to EditLive! for Java via the SetProperties function.

Getting Started

System Requirements

This example requires a JavaScript capable browser and a Web server.  

Note: This example is not compatible with Netscape 4.x.

Required Skills

The following skills are required prior to working with this sample:

Overview

This example consists of a single page with EditLive! for Java embedded in it and an XML configuration file for EditLive! for Java.  The Web page with EditLive! for Java also contains the JavaScript functions required to make use of the custom properties dialog functionality of EditLive! for Java.  

The XML configuration file for this example contains XML specifying a custom menu item.  The custom menu item (within the Custom menu) makes use of the customPropertiesDialog functionality of EditLive! for Java.  In this example the custom properties dialog functionality operates on <TD> tags.  It allows users to edit the attributes of a <TD> tag, this is assigned via the enableintag attribute of the <customMenuItem> element.

When using the custom properties dialog functionality there are several things which must be taken into account.  In particular, care should be taken to ensure that the ephoxTagID attribute is preserved during the course of the external operations.  For more information on the usage of custom properties dialogs please see the article on Custom Properties Dialogs for EditLive! for Java.

This sample demonstrates how to perform the following with EditLive! for Java and JavaScript:

Examination of customprop_eljconfig.xml

The customprop_eljconfig.xml file contains the configuration information for the example.  This file configures the custom menu item to use the customPropertiesDialog functionality of EditLive! for Java.  

Note: The examination here is only of those XML tags which pertain to the configuration of the custom menu item and custom toolbar button.  For more information on how to create a complete EditLive! for Java XML configuration file and other XML elements please see the EditLive! for Java XML Reference.

  1. Create a menu bar for use with EditLive! for Java.

    <editLiveForJava>
        ...
        <menuBar>
        </menuBar>
        ...
    </editLiveForJava>
  2. Create a menu for the custom menu item to be placed in.  In this case the menu is called the Custom menu.

    <editLiveForJava>
        ...
        <menuBar>
            ...
            <menu name="&amp;Custom">
            </menu>
            ...
        </menuBar>
        ...
    </editLiveForJava>
  3. Create the custom menu item which uses the customPropertiesDialog functionality of EditLive! for Java.  The value corresponding to the customPropertiesDialog function is the name of the JavaScript event from the custompropsample.htm page which will be used.  In this case the function's name is customPropDemo.  The custom menu item will appear in the Custom menu as the TD Properties item.  This menu item will only be available while the cursor is placed in a <TD> tag.  This is specified in the enableintag element.

    <editLiveForJava>
        ...
        <menuBar>
            ...
            <menu name="&amp;Custom">
                ...
                <!--
                This button provides an interface point between EditLive! for Java
                and the Web browser for use with a custom properties dialog
        
                This menu item makes a call to the JavaScript function called
                "customPropertiesDialog"
                -->
                <customMenuItem
                    name="customPropertiesDemo"
                    text="TD Properties"
                    action="customPropertiesDialog"
                    value="customPropDemo"
                    enableintag="TD"
                />
                ...
            </menu>
            ...
        </menuBar>
        ...
    </editLiveForJava>

Examination of custompropsample.htm

The custompropsample.htm file contains the main page for this example.  An instance of EditLive! for Java is embedded within this page.  Also contained with this page are two JavaScript functions which launch the gallery.htm page in a new browser window and insert the selected image into the instance of EditLive! for Java in this page.

  1. Include the EditLive! for Java JavaScript function library.

    <html>
        <head>
            <!--Include the EditLive! for Java JavaScript library file-->
            <script src = "../../../../redistributables/editlivejava/editlivejava.js" language="JavaScript" ></script> 
  2. Create the JavaScript function which EditLive! for Java uses as a callout for the custom properties dialog functionality.  In this case the function is called customPropDemo as specified in the XML configuration file.  

    In this example this function parses the data received from EditLive! for Java and places it into an array.  This array is then passed to another function which creates the custom dialog (the showPropertiesDialog function).

    The properties string provided by EditLive! for Java is a list of name-value pairs.  These pairs are separated by the new line character ("\n").  The name and value in each pairing is then separated by an equals character ("=").  This is used by the function to parse the properties string.

    /**
    * This function is the call out function accessed by EditLive! for Java.
    * EditLive! for Java provides a string containing the relevant attributes,
    * this function then parses the string and constructs an array with the data
    * from the string. The array constructed by this string is passed to the
    * showPropertiesDialog function for rendering as a dialog.
    */
    function customPropDemo(properties){
        var posIndex=0;
        var propArray = new Array();
        //parse the string
        while(posIndex < properties.length){
            var lineEnd;
            //get the position of the "\n" delimiting characters
            if(properties.indexOf("\n",posIndex) >=0){
                lineEnd = properties.indexOf("\n",posIndex);
            }else{
                lineEnd = properties.length;
            }
            //parse the name/value pair
            var valuePair = properties.substring(posIndex,lineEnd);
            posIndex = lineEnd + 1;
            //get the position of the "=" character
            var name = valuePair.substring(0,valuePair.indexOf("="));
            var value = valuePair.substring(valuePair.indexOf("=")+1,valuePair.length);
            var arrayPosition = propArray.length;
            //store the name/value pair in the array
            propArray[arrayPosition] = new Array();
            propArray[arrayPosition][0] = name;
            propArray[arrayPosition][1] = value;
        }
        showPropertiesDialog(propArray);
    }
  3. The showPropertiesDialog function shown below is used to create the custom properties dialog window.  It constructs, in JavaScript, the HTML for the custom properties dialog.

    This function includes a JavaScript function, addAttribute, which is used to add additional attributes.  This function is accessed when the Add button is pressed in the custom properties dialog. 

    /**
    * This function constructs the dialog used to display the properties to the user.
    * The user can edit and add properties via this dialog. Note that this function
    * includes an escaped JavaScript function which allows for the addition of
    * properties.
    */

    function showPropertiesDialog(propertiesArray){
        //create a new window
        var dialog = window.open("","ListProperties","width=500,height=300,status=no,resizeable=no,scrollbars=no,location=no,toolbar=no");
        //populate the <head> of the window
        var content = "<html><head><title>Custom Properties Dialog</title><script language='javascript'>";
        //Construct the JavaScript function which will add a property
        content += "function addAttribute(attrName, attrValue){\n";
        //check the names of the form fields
        content += "if(attrName==''|attrValue==''){\n";
        content += "alert('Please supply a name and value');\n";
        content += "return;\n";
        content += "}else{\n";
        //get the table to append the information to
        content += "var propTable = document.getElementById('propTable');\n";
        content += "var tbody = propTable.tBodies[0];\n";
        //construct the new row
        content += "var propHeading = document.createTextNode(attrName);\n";
        content += "var propRow = document.createElement('TR');\n";
        content += "var propHeader = document.createElement('TH');\n";
        content += "var propCell = document.createElement('TD');\n";
        content += "var propInput = document.createElement('INPUT');\n";
        content += "propHeader.setAttribute('width','25%');\n";
        content += "propInput.setAttribute('name', attrName);\n";
        content += "propInput.setAttribute('type','text');\n";
        content += "propInput.setAttribute('value',attrValue);\n";
        //add the new row
        content += "tbody.appendChild(propRow);\n";
        content += "propRow.appendChild(propHeader);\n";
        content += "propRow.appendChild(propCell);\n";
        content += "propHeader.appendChild(propHeading);\n";
        content += "propCell.appendChild(propInput);\n";
        //clear the relevant form field values
        content += "properties.addName.value='';\n";
        content += "properties.addValue.value='';\n";
        content += "}\n";
        content += "}\n";
        //finish constructing the document <head> and the start of the <body> and <form>
        content += "</script></head><body><form name='properties' align='center'><table width='50%' align='center' ID='propTable'>";
        posIndex = 0;
        //construct the table containing values
        for(posIndex = 0; posIndex < propertiesArray.length; posIndex++){
            if(!(propertiesArray[posIndex][0]=="ephoxTagID")){
                content += "<tr><th width='25%'>"+propertiesArray[posIndex][0]+"</th>";
                content += "<td><input type='text' name='"+propertiesArray[posIndex][0]+"' value='"+propertiesArray[posIndex][1]+"'></td></tr>";
            }else{
                //the ephoxTagID is stored in a hidden form field to ensure that it is
                //not edited while still being present as a form element.
                content += "<input type='hidden' name='ephoxTagID' value='"+propertiesArray[posIndex][1]+"'>";
            }
        }
        content += "</table>";
        //put the fields to add a value
        content += "<table align='center' width='100%'>";
        content += "<tr><td><b>Name:<input type='text' name='addName'></b></td><td><b>Value:</b><input type='text' name='addValue'></td></tr>";
        content += "<tr><td><input type='button' name='add' onclick='javascript:addAttribute(properties.addName.value,properties.addValue.value);' value='Add Attribute'></td></tr>";
        content += "</table>";
        content += "<p align='center'>";
        content += "<input type='button' name='ok' value='OK' onclick='javascript:window.opener.returnProperties(window)'>";
        content += "<input type='button' name='cancel' value='Cancel' onclick='javascript:window.close()'>";
        content += "</p>";
        content += "</form></body></html>";
        dialog.document.write(content);
        dialog.document.close();
    }

    When writing the attributes retrieved from EditLive! for Java to the custom properties dialog document this function uses the name attribute of form fields to store the corresponding name of the attribute from EditLive! for Java.  It also uses the value attribute of form fields to store the value of the attribute from EditLive! for Java.  

    It can also be seen that this function writes the ephoxTagID attribute as a hidden form field.  This ensures that the attribute is persisted within the custom properties dialog and is uneditable.
  4. Create a function to set the new properties back in EditLive! for Java.  This function is provided a reference to the custom properties dialog as a parameter.  It then iterates over the form fields within the custom dialog and captures the relevant information.  The function creates name-value pairs which are placed in a string of a format accepted by EditLive! for Java and sent back to EditLive! for Java with the SetProperties function of the EditLive! for Java JavaScript Runtime API.

    Note the use of the JavaScript escape method to encode the properties string prior to it being sent to EditLive! for Java.  

    /**
    * This function returns the properties to EditLive! for Java.
    * The function iterates over the fields in the custom properties
    * dialog and places them back in the string form required
    * by EditLive! for Java
    */
    function returnProperties(propertiesWindow){
        var elements = propertiesWindow.document.properties.elements;
        var returnString = "";
        var posIndex;
        //iterate over the form elements
        for(posIndex = 0;posIndex < elements.length;posIndex++){
            //ignore the add, cancel and ok buttons
            //also ignore the addName and addValue fields
            if(elements[posIndex].name != "ok" && elements[posIndex].name != "cancel" &&
                elements[posIndex].name != "add" && elements[posIndex].name != "addName"
                && elements[posIndex].name != "addValue"){
                returnString += elements[posIndex].name + "=" + elements[posIndex].value + "\n";
            }
        }
        propertiesWindow.close();
        //return the string to EditLive! for Java
        editlivejava1.SetProperties(escape(returnString));
    }
  5. Create a form to place an instance of EditLive! for Java in.

            <form name = exampleForm>
  6. Create an instance of EditLive! for Java inside the form.

                <SCRIPT language="JavaScript">
                <!--
                    var editlivejava1;
                    editlivejava1 = new EditLiveJava("ELJApplet1",700 , 400);
                    editlivejava1.setDownloadDirectory("../../../../redistributables/editlivejava");
                    editlivejava1.setLocalDeployment(false);
                    editlivejava1.setXMLURL("customprop_eljconfig.xml");
                    editlivejava1.setBody(escape("<table width='100%'><tr><td width='50%' align='center'></td><td width='50%' align='center'></td></tr><tr><td width='50%' align='center'></td><td width='50%' align='center'></td></tr></table>"));
                    editlivejava1.show();
                -->
                </SCRIPT>

            </form>
        </body>
    </html>

Partial XML Configuration

The following is a partial XML configuration file.  The configuration listed here would facilitate the creation of a custom menu item for this example.  However, the following XML listing would not be sufficient to correctly configure an instance of EditLive! for Java.   For more information on how to create a complete EditLive! for Java XML configuration file and other XML elements please see the EditLive! for Java XML Reference.

<editLiveForJava>
    ...
    <menuBar>
        ...
        <menu name="&amp;Custom">
            ...
            <!--
            This button provides an interface point between EditLive! for Java
            and the Web browser for use with a custom properties dialog
    
            This menu item makes a call to the JavaScript function called
            "customPropertiesDialog"
            -->
            <customMenuItem
                name="customPropertiesDemo"
                text="TD Properties"
                action="customPropertiesDialog"
                value="customPropDemo"
                enableintag="TD"
            />
            ...
        </menu>
        ...
    </menuBar>
    ...
</editLiveForJava>

Complete HTML and JavaScript

The following is the completed code for the pages listed above.  Note, some changes have been made from the steps listed above.  The changes only effect the page formatting not the functionality.

custompropsample.htm

<HTML>
    <HEAD>
        <TITLE>EditLive! for Java Custom Properties Example</TITLE>
        <link rel="stylesheet" href="../raiseevent/stylesheet.css">
        <!--Include the EditLive! for Java JavaScript Library-->
        <SCRIPT src="../../../../redistributables/editlivejava/editlivejava.js" language="JavaScript"></SCRIPT>
        <script language="javascript">
        <!--
        /**
          * This function is the call out function accessed by EditLive! for Java.
          * EditLive! for Java provides a string containing the relevant attributes,
          * this function then parses the string and constructs an array with the data
          * from the string. The array constructed by this string is passed to the
          * showPropertiesDialog function for rendering as a dialog.
          */
        function customPropDemo(properties){
            var posIndex=0;
            var propArray = new Array();
            //parse the string
            while(posIndex < properties.length){
                var lineEnd;
                //get the position of the "\n" delimiting characters
                if(properties.indexOf("\n",posIndex) >=0){
                    lineEnd = properties.indexOf("\n",posIndex);
                }else{
                    lineEnd = properties.length;
                }
                //parse the name/value pair
                var valuePair = properties.substring(posIndex,lineEnd);
                posIndex = lineEnd + 1;
                var name = valuePair.substring(0,valuePair.indexOf("="));
                var value = valuePair.substring(valuePair.indexOf("=")+1,valuePair.length);
                var arrayPosition = propArray.length;
                //store the name/value pair in the array
                propArray[arrayPosition] = new Array();
                propArray[arrayPosition][0] = name;
                propArray[arrayPosition][1] = value;
            }
            showPropertiesDialog(propArray);
        }

        /**
          * This function constructs the dialog used to display the properties to the user.
          * The user can edit and add properties via this dialog. Note that this function
          * includes an escaped JavaScript function which allows for the addition of
          * properties.
          */

        function showPropertiesDialog(propertiesArray){
            //create a new window
            var dialog = window.open("","ListProperties", "width=500,height=300,status=no,resizeable=no,scrollbars=no,location=no,toolbar=no");
            //populate the <head> of the window
            var content = "<html><head><title>Custom Properties Dialog</title><script               language='javascript'>";
            //Construct the JavaScript function which will add a property
            content += "function addAttribute(attrName, attrValue){\n";
            //check the names of the form fields
            content += "if(attrName==''|attrValue==''){\n";
            content += "alert('Please supply a name and value');\n";
            content += "return;\n";
            content += "}else{\n";
            //get the table to append the information to
            content += "var propTable = document.getElementById('propTable');\n";
            content += "var tbody = propTable.tBodies[0];\n";
            //construct the new row
            content += "var propHeading = document.createTextNode(attrName);\n";
            content += "var propRow = document.createElement('TR');\n";
            content += "var propHeader = document.createElement('TH');\n";
            content += "var propCell = document.createElement('TD');\n";
            content += "var propInput = document.createElement('INPUT');\n";
            content += "propHeader.setAttribute('width','25%');\n";
            content += "propInput.setAttribute('name', attrName);\n";
            content += "propInput.setAttribute('type','text');\n";
            content += "propInput.setAttribute('value',attrValue);\n";
            //add the new row
            content += "tbody.appendChild(propRow);\n";
            content += "propRow.appendChild(propHeader);\n";
            content += "propRow.appendChild(propCell);\n";
            content += "propHeader.appendChild(propHeading);\n";
            content += "propCell.appendChild(propInput);\n";
            //clear the relevant form field values
            content += "properties.addName.value='';\n";
            content += "properties.addValue.value='';\n";
            content += "}\n";
            content += "}\n";
            //finish constructing the document <head> and the start of the <body> and <form>
            content += "</script></head><body><form name='properties' align='center'><table width='50%' align='center' ID='propTable'>";
            posIndex = 0;
            //construct the table containing values
            for(posIndex = 0; posIndex < propertiesArray.length; posIndex++){
                if(!(propertiesArray[posIndex][0]=="ephoxTagID")){
                    content += "<tr><th width='25%'>"+propertiesArray[posIndex][0]+"</th>";
                    content += "<td><input type='text' name='"+propertiesArray[posIndex][0]+"' value='"+propertiesArray[posIndex][1]+"'></td></tr>";
                }else{
                    //the ephoxTagID is stored in a hidden form field to ensure that it is
                    //not edited while still being present as a form element.
                    content += "<input type='hidden' name='ephoxTagID' value='"+propertiesArray[posIndex][1]+"'>";
                }
            }
            content += "</table>";
            //put the fields to add a value
            content += "<table align='center' width='100%'>";
            content += "<tr><td><b>Name:<input type='text' name='addName'></b></td><td><b>Value:</b><input type='text' name='addValue'></td></tr>";
            content += "<tr><td><input type='button' name='add' onclick='javascript:addAttribute(properties.addName.value,properties.addValue.value);' value='Add Attribute'></td></tr>";
            content += "</table>";
            content += "<p align='center'>";
            content += "<input type='button' name='ok' value='OK' onclick='javascript:window.opener.returnProperties(window)'>";
            content += "<input type='button' name='cancel' value='Cancel' onclick='javascript:window.close()'>";
            content += "</p>";
            content += "</form></body></html>";
            dialog.document.write(content);
            dialog.document.close();
        }


        /**
         * This function returns the properties to EditLive! for Java.
         * The function iterates over the fields in the custom properties
         * dialog and places them back in the string form required
         * by EditLive! for Java
         */
        function returnProperties(propertiesWindow){
            var elements = propertiesWindow.document.properties.elements;
            var returnString = "";
            var posIndex;
            //iterate over the form elements
            for(posIndex = 0;posIndex < elements.length;posIndex++){
                //ignore the add, cancel and ok buttons
                //also ignore the addName and addValue fields
                if(elements[posIndex].name != "ok" && elements[posIndex].name != "cancel" &&
                    elements[posIndex].name != "add" && elements[posIndex].name != "addName"
                    && elements[posIndex].name != "addValue"){
                    returnString += elements[posIndex].name + "=" + elements[posIndex].value + "\n";
                }
            }
            propertiesWindow.close();
            //return the string to EditLive! for Java
            editlivejava1.SetProperties(escape(returnString));
        }
        -->
    </script>
    </HEAD>
    <BODY>
        <FORM name = exampleForm>
            <h1>EditLive! for Java Custom Properties Dialog Example</h1>
            <p>To access the custom properties dialog place the cursor in a table cell and
            use the <b>Custom &gt; TD Properties</b> menu item</p>
            <!--Create an instance of EditLive! for Java-->
            <SCRIPT language="JavaScript">
            <!--
                var editlivejava1;
                editlivejava1 = new EditLiveJava("ELJApplet1",700 , 400);
                editlivejava1.setDownloadDirectory("../../../../redistributables/editlivejava");
                editlivejava1.setLocalDeployment(false);
                editlivejava1.setXMLURL("customprop_eljconfig.xml");
                editlivejava1.setBody(escape("<table width='100%'><tr><td width='50%' align='center'></td><td width='50%' align='center'></td></tr><tr><td width='50%' align='center'></td><td width='50%' align='center'></td></tr></table>"));
                editlivejava1.show();
            -->
            </SCRIPT>
        </FORM>
    </BODY>
</HTML>

Summary

The customPropertiesDialog functionality of EditLive! for Java may be used in differing situations to complement the existing functionality of the EditLive! for Java applet.  Custom toolbar buttons and menu items can call JavaScript functions which can open developer defined dialogs.  The changes made in such dialogs can be placed back into EditLive! for Java using the SetProperties function provided by the EditLive! for Java JavaScript API as demonstrated in this example.

See Also