OX6:Gui Plugin Development: Difference between revisions

From Open-Xchange
Line 279: Line 279:
== Customized/new buttons in the panel ==
== Customized/new buttons in the panel ==


This example adds new buttons to the pannel in the contact view. A click on one
This example adds new buttons to the pannel in the contact view.
of that buttons opens a pop up.


  /**
  /**
   *  
   *
   * All content on this website (including text, images, source
   * This program is free software; you can redistribute it and/or modify it
  * code and any other original works), unless otherwise noted,
   * under the terms of the GNU General Public License, Version 2 as published
   * is licensed under a Creative Commons License.
   * by the Free Software Foundation.
  *
   *
   * http://creativecommons.org/licenses/by-nc-sa/2.5/
   * Copyright (C) 2004-2007 Open-Xchange, Inc.
   *  
   * Copyright (C) 2004-2008 Open-Xchange, Inc.
   * Mail: info@open-xchange.com  
   * Mail: info@open-xchange.com  
   *  
   *  
   * @author Viktor
   * @author: Viktor
   *  
   *
   */
   */
   
   
Line 303: Line 300:
   * Add menu Entries to the new generated panel object and define the icons
   * Add menu Entries to the new generated panel object and define the icons
   * as well as the to be called functions. The identifiers must be unique  
   * as well as the to be called functions. The identifiers must be unique  
   * all over the complete js code (button1 and button2 in this example
   * all over the complete js code (button1 and button2) in this example
   */
   */
  MenuNodes.createSmallButton(contextmenu,"button1", "Display",
  MenuNodes.createSmallButton(contextmenu,"button1", "Display",
Line 314: Line 311:
     click2);
     click2);
  /* The pannel object gets the id 20 and gets displayed in the fixed area
  /* The pannel object gets the id 20 and gets displayed in the fixed area
   * possible areas are FIXED and DYNAMIC
   * possible areas are FIXED and DYNAMIC the id controls the order in the areas
   */  
   */  
  addMenuNode(contextmenu.node, MenuNodes.FIXED, 20);
  addMenuNode(contextmenu.node, MenuNodes.FIXED, 20);
//Following makes the new pannel options dynamic active/inactive
  changeDisplay("contacts", "id1");
  changeDisplay("contacts", "id1");
  menuarrows["contacts"] = {};
  menuarrows["contacts"] = {};
Line 322: Line 321:
     menuglobalzaehler = 0;
     menuglobalzaehler = 0;
     menuarrows["contacts"]["id1"] = new Array();
     menuarrows["contacts"]["id1"] = new Array();
//menucountselected here holds the amount of select items
     menu_display_contents("contacts","id1", menucountselected >= 1,
     menu_display_contents("contacts","id1", menucountselected >= 1,
  "button1");
  "button1");
// following an example how to get data out of the GUI internal cache. button2
// is only active when a contact which as a business tel number is selected.
  if (activemodule == "contacts") {
     OXCache.newRequest(null, "contacts", {
     OXCache.newRequest(null, "contacts", {
         objects: menuselectedobjects,
         objects: menuselectedobjects,
Line 333: Line 336:
                 "button2");
                 "button2");
         });
         });
    }
  }
  }
  register("OX_SELECTED_ITEMS_CHANGED", changeplugin);  
  register("OX_SELECTED_ITEMS_CHANGED", changeplugin);  
   
   
//now the called functions for the buttons follow
  function click1() {
  function click1() {
     OXCache.newRequest(null, "contacts", {
     OXCache.newRequest(null, "contacts", {

Revision as of 07:35, 5 September 2008

Introduction

With Open-Xchange SP4 you will be able to add you own JavaScript Code for existing events. The follwoing examples show how you can add your own About page, your own Window Title, and your own message for not activated/bought components of OX (Upsell Message).

Setup and file description

Two things have to be done to register your own JavaScript Code within the server:

1. You have to create the property file in /opt/open-xchange/etc/groupware/settings/, for example myjscode.properties. The file should have the following value:

modules/$NAME/enabled=true

$NAME is equal to the filename of the property file, in our case it would be:

modules/myjscode/enabled=true

This will enable the JS Code located in $WEBSRV/ox6/plugins/$NAME (for example /var/www/ox6/plugins/myjscode/).

2. Next we have to create the folder that we had configured, in our example we would have to create:

mkdir /var/www/ox6/plugins/myjscode/

The server now will have a look at this directory and searches for the file register.js in this directory. All your JS enhancements should be written to that file.

3. Afterwards you have to restart the groupware server with:

/etc/init.d/open-xchange-groupware restart

Examples

Customized About page

/opt/open-xchange/etc/groupware/settings/productinfo.properties:

# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License, Version 2 as published
# by the Free Software Foundation.
#
# Copyright (C) 2004-2007 Open-Xchange, Inc.
# Mail: info@open-xchange.com 
# 
# @author: Stefan Preuss <stefan.preuss@open-xchange.com>

modules/productinfo/enabled=true

/var/www/ox6/plugins/productinfo/register.js:

/**
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License, Version 2 as published
 * by the Free Software Foundation.
 *
 * Copyright (C) 2004-2007 Open-Xchange, Inc.
 * Mail: info@open-xchange.com 
 * 
 * @author: Stefan Preuss <stefan.preuss@open-xchange.com>
 *
 */

oxProductInfo.vendor_address = "Open-Xchange GmbH\nMartinstrasse 41\n57462 Olpe\nE-Mail: info@open-xchange.com\n<a href=\"http://www.open-xchange.com\" target=\"_blank\">www.open-xchange.com</a>"

Customized Window Title

/opt/open-xchange/etc/groupware/settings/windowtitle.properties:

# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License, Version 2 as published
# by the Free Software Foundation.
#
# Copyright (C) 2004-2007 Open-Xchange, Inc.
# Mail: info@open-xchange.com 
# 
# @author: Stefan Preuss <stefan.preuss@open-xchange.com>

modules/windowtitle/enabled=true

/var/www/ox6/plugins/windowtitle/register.js:

/**
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License, Version 2 as published
 * by the Free Software Foundation.
 *
 * Copyright (C) 2004-2007 Open-Xchange, Inc.
 * Mail: info@open-xchange.com 
 * 
 * @author: Stefan Preuss <stefan.preuss@open-xchange.com>
 *
 */

oxProductInfo.product_name = "This is the fabulous Open-Xchange Server"; 

try {
    window.document.title = oxProductInfo.product_name;
} catch (e) { }

Customized Upsell Message

/opt/open-xchange/etc/groupware/settings/upsell.properties:

# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License, Version 2 as published
# by the Free Software Foundation.
#
# Copyright (C) 2004-2007 Open-Xchange, Inc.
# Mail: info@open-xchange.com
# 
# Author: Stefan Preuss <stefan.preuss@open-xchange.com>

# The following property enables the Upsell-Layer Plugin for the OX6 AJAX GUI
modules/upsell/enabled=true

/var/www/ox6/plugins/upsell/register.js:

/**
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License, Version 2 as published
 * by the Free Software Foundation.
 *
 * Copyright (C) 2004-2007 Open-Xchange, Inc.
 * Mail: info@open-xchange.com 
 * 
 * @author: Stefan Preuss <stefan.preuss@open-xchange.com>
 *
 */

/*
 * Example for an Upsell-Layer
 * The OX GUI triggers a special event if a user clicks on disabled features.
 */

 /*
  * Register to Upsell-Event
  */
 register("Feature_Not_Available", showUpsellLayer);

 /**
  * Function to display an Upsell-Alert dialog
  * @param feature String (optional) - Module description
  * @param win Window (optional) - Only needed/given if we trigger the event from the new object windows 
  */
 function showUpsellLayer(feature, win) {
    // setting corewindow to default if win is not defined
    win = win || corewindow; 
    
    /*
     * Build up the dialog content
     * Note: You can also use myDiv.innerHTML!
     */
    var myDiv = newnode("div",{ textAlign: "center", padding: "10px" }, 0, [ 
            newnode("div", 0, { background: "url(http://www.example.com/img/header/logo.gif)" }, 0,
                win.document),
            newnode("span", 0, 0, [ 
                document.createTextNode("Diese Funktion ist nur in Open-Xchange Premium verfügbar!") ],
                win.document),
            newnode("input", { marginTop: "10px"}, 
                { type: "button", onclick: function() { window.open("http://www.open-xchange.com") },
                  value: "Weitere Information zu Open-Xchange Premium!" }, 0, 
                win.document),
            newnode("input", { marginTop: "10px"}, 
                { type: "button", onclick: function() { window.open("http://www.open-xchange.com") },
                  value: "Paket-Upgrade auf Open-Xchange Premium!" }, 0, 
                win.document) 
        ], win.document);
    
    // calling the newAlert function to open the dialog at the given window
    win.newAlert("Hinweis " + feature, null, AlertPopup.close, myDiv);
 }
 
 /*
  * Comment this out to change the grayed out module images in the upper left corner!
  */
 /*
 if (!document.getElementById("sp_c_portal").src.match(/mod_portal_sel.gif$/)) {
    document.getElementById("sp_c_portal").src = getFullImgSrc("img/portal/mod_portal.gif");
 }
 document.getElementById("sp_c_calendar").src = getFullImgSrc("img/calendar/mod_calendar.gif");
 document.getElementById("sp_c_tasks").src = getFullImgSrc("img/tasks/mod_tasks.gif");
 document.getElementById("sp_c_infostore").src = getFullImgSrc("img/infostore/mod_infostore.gif");
 */

Customized / Extended configuration tree

In order to extend your configuration frontend you will have to make more changes then overwrite existing JS methods. You have to implement your own configuration site. Below, you will find the JS API Doc that will show you how to build external contents into the configuration frontend:

JavaScript API for extending the configuration frontend

/opt/open-xchange/etc/groupware/settings/extendconfiguration.properties:

modules/extendconfiguration/enabled=true

/var/www/ox6/plugins/extendconfiguration/register.js:

// Extending the configuration tree.

// Add a new folder-like node called "Example", and inside it another node
// called "Page". The position of a node is specified by a path string.
// Each tree level is separated by slashes. There should be only two levels
// below the standard "configuration" root element: configuration/x for inner
// nodes and configuration/x/y for leaf nodes.

new ox.Configuration.InnerNode("configuration/example", "Example");
var node = new ox.Configuration.LeafNode("configuration/example/page", "Page");


// Connect the node to a new page. 

var page = new ox.Configuration.Page(node, "Example Configuration Page");


// All data on the page is collected in a single data object. This object is
// transmitted to and from the server in the methods load() and save() using
// static methods of ox.JSON.
// For save(), the parameter cont is a continuation function which must be
// called after the data was saved successfully.

page.save = function(data, cont) {
    ox.JSON.put(AjaxRoot + "/serverplugin?action=set&session=" + session,
        data, cont);
}


// The continuation function of load() expects the data object as parameter.
// To extract the data object from the server reply, a new continuation function
// is used.

page.load = function(cont) {
    ox.JSON.get(AjaxRoot + "/serverplugin?action=get&session=" + session,
        function(reply) { cont(reply.data); });
};


// Content is added to the page with the method addWidget().
// Here, a static text is added at the top of the page.

page.addWidget(new ox.UI.Text("Long explanation text"));


// Individual input widgets can be connected to fields in the data object by
// specifying the field name as the second parameter to addWidget().

page.addWidget(new ox.UI.CheckBox("CheckBox Label"), "fieldname");


// Layout can be controlled by using container widgets.
// Configuration pages currently support only the Group container, which adds
// a header over its children.
// Every group has its own data object, which becomes nested in the page's
// data object.

var group = new ox.Configuration.Group("Group title");
page.addWidget(group, "subobject");


// Adding widgets to a goup happens exactly like for a page, since both are
// descendants of ox.UI.Container.

var input = new ox.UI.Input("Detail field");
group.addWidget(input, "input");


// All input widgets have a default value which is used when the data object
// does not contain the widget's field (e. g. on first login).

input.default_value = "default";


// ox.UI.Selection has many descendants which implement the same thing:
// A field which must contain one of several possible values.
// The possible values are set with the method setEntries().

var choice = new ox.UI.ComboBox("Choice");
group.addWidget(choice, "choice");
choice.setEntries([0, 1, Infinity], ["Zero", "One", "Infinity"]);

Customized/new buttons in the panel

This example adds new buttons to the pannel in the contact view.

/**
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License, Version 2 as published
 * by the Free Software Foundation.
 *
 * Copyright (C) 2004-2007 Open-Xchange, Inc.
 * Mail: info@open-xchange.com 
 * 
 * @author: Viktor
 *
 */

//create a new menu Object for the panel and define the unique id (id1 here)
var contextmenu = MenuNodes.createSmallButtonContext("id1", "SMS");

/**
 * Add menu Entries to the new generated panel object and define the icons
 * as well as the to be called functions. The identifiers must be unique 
 * all over the complete js code (button1 and button2) in this example
 */
MenuNodes.createSmallButton(contextmenu,"button1", "Display",
    "themes/default/img/menu/edit.gif",
"themes/default/img/menu/edit_d.gif",
    click1);
MenuNodes.createSmallButton(contextmenu,"button2", "Send",
    "themes/default/img/menu/edit.gif",
"themes/default/img/menu/edit_d.gif",
    click2);
/* The pannel object gets the id 20 and gets displayed in the fixed area
 * possible areas are FIXED and DYNAMIC the id controls the order in the areas
 */ 
addMenuNode(contextmenu.node, MenuNodes.FIXED, 20);

//Following makes the new pannel options dynamic active/inactive

changeDisplay("contacts", "id1");
menuarrows["contacts"] = {};
function changeplugin() {
    menuglobalzaehler = 0;
    menuarrows["contacts"]["id1"] = new Array();

//menucountselected here holds the amount of select items

    menu_display_contents("contacts","id1", menucountselected >= 1,
"button1");

// following an example how to get data out of the GUI internal cache. button2 // is only active when a contact which as a business tel number is selected.

  if (activemodule == "contacts") {
    OXCache.newRequest(null, "contacts", {
        objects: menuselectedobjects,
        columns: ["telephone_business1"]
    }, null, function(data) {
            menu_display_contents("contacts","id1",
                menucountselected == 1 &&
data.objects[0].telephone_business1,
                "button2");
        });
   }
}
register("OX_SELECTED_ITEMS_CHANGED", changeplugin); 

//now the called functions for the buttons follow

function click1() {
    OXCache.newRequest(null, "contacts", {
        objects: menuselectedobjects,
        columns: ["id", "folder_id", "last_name"]
    }, null, display);
}

function click2() {
    OXCache.newRequest(null, "contacts", {
        objects: menuselectedobjects,
        columns: ["telephone_business1"]
    }, null, call);
}

function display(data) {
    for (var i = 0; i < menucountselected; i++)
        alert(data.objects[i].last_name);
}

function call(data) {
    alert("Calling " + data.objects[0].telephone_business1);
}

Help Menu

It is possible to add entries to the pop-up menu of the help button in the top right corner. Following is a simple example which opens a language-specific help page:

var label = { de_DE: "Hilfe", en_US: "Help", fr_FR: "Aide" };
HelpMenu.addText(label[config.language || "en_US"], displayLink);

function displayLink() {
        open("/help/" + config.language);
}

The manual handling of the label is required until proper support for plug-in internationalization is implemented.