This manual is deprecated. Please visit https://groupoffice.readthedocs.io for the latest documentation.

Difference between revisions of "Custom Fields"

From Group-Office Groupware and CRM Documentation
Jump to: navigation, search
(Subclass of default_customfield_type)
(Replaced content with "TODO")
 
Line 1: Line 1:
Group-Office provides the possibility to add user-defined Custom Fields. These are data entries like the built-in data entries, much like the contacts in the Addressbook module, that admins can add to the existing data entries. For example, as admin, you can create the possibility for users to select an employer associated with a contact. Group-Office has predefined Custom Field types that you can use for your modules. You can add these to your modules with the Custom Fields module.
+
TODO
 
+
You can also create new Custom Field types. For this, you need to work with at least four files:
+
#One PHP-file containing a subclass of default_customfield_type, which specifies how your Custom Field should be displayed.
+
#One JS file of which the purpose is to allow selection of the Custom Field's actual data entry.
+
#Connected to the previous file, is one CustomField.js that specifies the information needed for Custom Field type selection in the Custom Field module.
+
#The file containing your modules's main class for registering your Custom Field in an event listener.
+
 
+
Here, we will show you how to make your own Custom Field type with an example of adding a contact Custom Field to a contact record.
+
 
+
== Subclass of default_customfield_type ==
+
 
+
The default_customfield_type class contains public functions for displaying your Custom Field data in, for example, HTML tags. It also contains a public function that allows transformation of the data before storing it in the database. The class is defined in customfields.class.inc.php, though you only need to write your own extension of the class. In our example, we wrote the following subclass:
+
 
+
<pre>
+
class contact_customfield_type extends default_customfield_type {
+
 
+
  function format_for_display($field, &$record, $fields) {
+
 
+
    if(!empty($record[$field['dataname']])) {
+
      $record[$field['dataname']]='<a href="#" onclick=\'GO.linkHandlers[2].call(this,'.$this->get_id($record[$field['dataname']]).');\' title="'.$this->get_name($record[$field['dataname']]).'">'.
+
                                                                                                                                                            $this->get_name($record[$field['dataname']]).'</a>';
+
    }
+
  }
+
 
+
  private function get_id($cf) {
+
    $pos = strpos($cf,':');
+
    return substr($cf,0,$pos);
+
  }
+
 
+
  private function get_name($cf) {
+
    $pos = strpos($cf,':');
+
    return substr($cf,$pos+1);
+
  }
+
 
+
}
+
</pre>
+
 
+
The format_for_display function is called when the entry should be displayed on the detail panels you see on the right-hand side of most Group-Office modules. As you can see, a record field is initialized to a string, which represents a html anchor with a link to a Group-Office JavaScript event handler. In this case, our event handler GO.linkHandlers[2] summons a panel filled with data of your Custom Field's entry.
+
 
+
To initialize the custom field we need to add an event.
+
 
+
In you main module class ( in this case addressbook.class.inc.php) add:
+
<pre>
+
public function __on_load_listeners($events) {
+
...
+
$events->add_listener('init_customfields_types', __FILE__, 'addressbook', 'init_customfields_types');
+
...
+
}
+
 
+
function init_customfields_types(){
+
global $GO_MODULES, $customfield_types;
+
require_once($GO_MODULES->modules['addressbook']['class_path'].'contact_customfield_type.class.inc.php');
+
$customfield_types['contact']=new contact_customfield_type(array());
+
}
+
</pre>
+
 
+
== Enabling selection of data entry ==
+
 
+
The following JavaScript allows selection of the actual contact Custom Field data entry, but note that it is also used for other contact selection purposes elsewhere.
+
 
+
<pre>
+
GO.addressbook.SelectContact = function(config){
+
 
+
if(!config.displayField)
+
config.displayField='name';
+
+
if(!config.valueField)
+
config.valueField='id';
+
+
config.store = new GO.data.JsonStore({
+
    url: GO.settings.modules.addressbook.url+ 'json.php',
+
    baseParams: {
+
    task: 'contacts',
+
'addressbook_id' : config.addressbook_id
+
},
+
    root: 'results',
+
    id: 'id',
+
    totalProperty:'total',    
+
        fields: ['id', 'cf', 'name', 'salutation', 'email', 'first_name', 'middle_name','last_name', 'home_phone', 'work_phone', 'cellular'],
+
    remoteSort: true
+
});
+
+
config.store.setDefaultSort('name', 'asc');
+
 
+
config.triggerAction='all';
+
config.selectOnFocus=true;
+
config.pageSize=parseInt(GO.settings['max_rows_list']);
+
 
+
GO.addressbook.SelectContact.superclass.constructor.call(this,config);
+
+
}
+
Ext.extend(GO.addressbook.SelectContact, GO.form.ComboBoxReset);
+
 
+
Ext.ComponentMgr.registerType('selectcontact', GO.addressbook.SelectContact);
+
</pre>
+
 
+
The store contains a 'cf' field, which in our case has the form "<id>:<fullname>", so for example "113:John Doe". In Custom Fields, only one value is handled, instead of a displayField and a valueField, so we joined both pieces of information into the single, parsable variable cf. When creating a SelectContact object for the contact Custom Field, a valueField config parameter is sent to the constructor which is set to 'cf'.
+
 
+
Another important thing to note is the final line, which registers the type 'selectcontact' for later use in CustomField.js.
+
 
+
== CustomField.js ==
+
 
+
A Custom Field dataType called contact is defined here. The getFormField function returns a SelectContact object, which we defined previously. The most important things here are the config parameters hiddenName and valueField. The valueField is the cf part of the contact record which is the actual data entry value of this Custom Field.
+
 
+
<pre>
+
GO.moduleManager.onModuleReady('customfields', function(){
+
  GO.customfields.nonGridTypes.push('contact');
+
  GO.customfields.dataTypes.contact={
+
    label : GO.addressbook.lang.contact,
+
    getFormField : function(customfield, config){
+
      return {
+
        xtype: 'selectcontact',
+
      fieldLabel: customfield.name,
+
        hiddenName:customfield.dataname,
+
forceSelect:true,
+
        anchor:'-20',
+
valueField:'cf'
+
      }
+
    }
+
  }
+
}, this);
+
</pre>
+
 
+
== Functions that display the Custom Field value ==
+
 
+
Did you notice the JavaScript part GO.linkHandlers[2].call in the first PHP file? We shouldn't forget to declare this. In our Addressbook module's MainPanel script, we declared what this function actually does. Basically, it opens a new window containing information on the contact with the specified id.
+
 
+
<pre>
+
GO.linkHandlers[2]=GO.mailFunctions.showContact=function(id){
+
//GO.addressbook.contactDialog.show(id);
+
+
var contactPanel = new GO.addressbook.ContactReadPanel();
+
var linkWindow = new GO.LinkViewWindow({
+
title: GO.addressbook.lang.contact,
+
items: contactPanel
+
});
+
contactPanel.load(id);
+
linkWindow.show();
+
}
+
</pre>
+
 
+
And there you have it! Your very own Custom Field. Don't forget to add your own files to the scripts.txt file of your particular module.
+

Latest revision as of 15:28, 6 July 2012

TODO