SugarCRM 7 - Add a new action to a record

Thu 07 August 2014

mobile_combined

Odds are if you're customising SugarCRM, you will at some point need to add functionality to the records page. This article shows you a framework for creating actions on the UI, the API entrypoints to run your code and how to link it all together using SugarCRM's sidecar functionality.

1. Add the button

In custom/modules/<YourModule>/clients/base/views/record/record.php, you'll need this to add the core button array.

In this file add in an entry at the bottom like:

$viewdefs[$module_name]['base']['view']['record']['buttons'] =
array (
  0 =>
  array (
    'type' => 'button',
    'name' => 'cancel_button',
    'label' => 'LBL_CANCEL_BUTTON_LABEL',
    'css_class' => 'btn-invisible btn-link',
    'showOn' => 'edit',
  ),
  1 =>
  array (
    'type' => 'rowaction',
    'event' => 'button:save_button:click',
    'name' => 'save_button',
    'label' => 'LBL_SAVE_BUTTON_LABEL',
    'css_class' => 'btn btn-primary',
    'showOn' => 'edit',
    'acl_action' => 'edit',
  ),
  2 =>
  array (
    'type' => 'actiondropdown',
    'name' => 'main_dropdown',
    'primary' => true,
    'showOn' => 'view',
    'buttons' =>
    array (
      0 =>
      array (
        'type' => 'rowaction',
        'event' => 'button:edit_button:click',
        'name' => 'edit_button',
        'label' => 'LBL_EDIT_BUTTON_LABEL',
        'acl_action' => 'edit',
      ),
      1 =>
      array (
        'type' => 'shareaction',
        'name' => 'share',
        'label' => 'LBL_RECORD_SHARE_BUTTON',
        'acl_action' => 'view',
      ),
      2 =>
      array (
        'type' => 'pdfaction',
        'name' => 'download-pdf',
        'label' => 'LBL_PDF_VIEW',
        'action' => 'download',
        'acl_action' => 'view',
      ),
      3 =>
      array (
        'type' => 'pdfaction',
        'name' => 'email-pdf',
        'label' => 'LBL_PDF_EMAIL',
        'action' => 'email',
        'acl_action' => 'view',
      ),
      4 =>
      array (
        'type' => 'divider',
      ),
      5 =>
      array (
        'type' => 'rowaction',
        'event' => 'button:do_some_task:click',
        'name' => 'do_some_task',
        'label' => 'LBL_DO_SOME_ACTION',
        'acl_action' => 'view',
      ),
      6 =>
      array (
        'type' => 'rowaction',
        'event' => 'button:find_duplicates_button:click',
        'name' => 'find_duplicates_button',
        'label' => 'LBL_DUP_MERGE',
        'acl_action' => 'edit',
      ),
      7 =>
      array (
        'type' => 'rowaction',
        'event' => 'button:duplicate_button:click',
        'name' => 'duplicate_button',
        'label' => 'LBL_DUPLICATE_BUTTON_LABEL',
        'acl_module' => '<Your_Module>',
        'acl_action' => 'create',
      ),
      8 =>
      array (
        'type' => 'rowaction',
        'event' => 'button:audit_button:click',
        'name' => 'audit_button',
        'label' => 'LNK_VIEW_CHANGE_LOG',
        'acl_action' => 'view',
      ),
      9 =>
      array (
        'type' => 'divider',
      ),
      10 =>
      array (
        'type' => 'rowaction',
        'event' => 'button:delete_button:click',
        'name' => 'delete_button',
        'label' => 'LBL_DELETE_BUTTON_LABEL',
        'acl_action' => 'delete',
      ),
    ),
  ),
  3 =>
  array (
    'name' => 'sidebar_toggle',
    'type' => 'sidebartoggle',
  ),
);

Note what I've stored at array key 5. This is the custom button that will be rendered and the event button do_some_task will be called in the javacript file we'll created. You can add this anywhere in the drop-down I just generally choose here.

2. Create the javascript hook to call the API

In custom/modules/<YourModule>/clients/base/views/record/record.js create a file like this.

({
    extendsFrom: 'RecordView',

    initialize: function (options) {
        app.view.invokeParent(this, {type: 'view', name: 'record', method: 'initialize', args:[options]});
        this.context.on('button:do_some_task:click', this.do_some_task, this);
    },
    do_some_task : function() {
        app.api.call('GET', app.api.buildURL('<YOUR_MODULE>/DoSomeTask/'+this.model.get('id')), null, {
            success: _.bind(function(response) {
                //response comes back from your api, maybe you want to set some value on your model or alter a response?
                this.model.set('some_field', response);
                //Or maybe you want to show an error or success
                app.alert.show('bad-task-response', {
                    level: 'error',
                    messages: response,
                    autoClose: false
                });
            }, this)
        });
    }
})

** 3. Build the API to act on the javascript file**

In custom/modules/<YourModule>/clients/base/api/doSomeTask.php create a file like so

<?php
if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');
require_once('custom/modules/<YourCustomModule>/SomeCustomClass.php');

class doSomeTask extends SugarApi
{
    public function registerApiRest()
    {
        return array(
            //GET
            'MyGetEndpoint' => array(
                //request type
                'reqType' => 'GET',

                //endpoint path
                'path' => array('<Your_Module>', 'DoSomeTask', '?'),

                //endpoint variables
                'pathVars' => array('', '', 'data'),

                //method to call
                'method' => 'DoSomeTask',

                //short help string to be displayed in the help documentation
                'shortHelp' => 'This does some custom task',
            ),
        );
    }

    /**
     * Method to be used for my MyEndpoint/GetExample endpoint
     */
    public function DoSomeTask($api, $args)
    {
        $id = $args['data'];

        $custom_bean = new SomeCustomClass();
        $custom_bean->retrieve($id);
        return $custom_bean->doSomething();
    }

}

Note: Make sure your DoSomeTask functon is uppercased not camel cased. I kept getting invalid argument count errors when it was camel-cased.

4. Language files for the button

Create a new language file at custom/Extension/modules/<Your_Module>/Ext/Language/en_us.doSomeTask.php with contents like

<?php
$mod_strings['LBL_DO_SOME_TASK'] = 'Do some task';

5. Quick Repair/Rebuild

This should hopefully merge your language files into your code and recompile your javascript into the front-end.

Category: SugarCRM Tagged: backbone javascript php

comments


Page 1 of 1