Enhanced Studio Samples

From dispage wiki

Jump to:navigation, search

Contents

Progressive Page ID Code

Scenario: add a progressive ID to the page screen of the List View of any module.


Procedure:

Step 1

Create a new Code field with the values below in the module where to add the counter :

Logic Hook: Default

DB Type: Non-DB

Code:

$GLOBALS['count_cc']++;
echo '<div align="right">'.$GLOBALS['count_cc'].'</div>';

Step 2

Add it to Layouts → ListView.


Opportunities warning on amount

Scenario: add a warning field that shows different images depending on the amount value. It shows “Thumb down” for less than 20,000 $ amount, “Thumb up” for more than 60,000 $.


Procedure :

Step 1

Create a new Code field in the Opportunities module with the values below

Logic Hook: Default

DB Type: Non-DB

Code:

if ($bean->amount_usdollar > 60000) 
echo "<image src='http://www.sugarcrm.com/forums/images/icons/icon14.gif'>";
elseif ($bean->amount_usdollar < 20000) 
echo "<image src='http://www.sugarcrm.com/forums/images/icons/icon13.gif'>";

Step 2

Add it to Layouts → ListView.

The List View should appear like shown in Figure 1


Opportunity warn.gif

Figure 1


Field with a List of Values

(Enhanced Studio FULL version is needed for this sample)

Scenario: create a field that allows to enter/change/delete multiple values.


Procedure :

Step 1

Create a new Code field in any module with the values below

Name: multi

Logic Hook: Default

DB Type: text

Code:

$isEdit = $GLOBALS['app']->controller->action == 'EditView';
echo '<table cellspacing="5" style="background-color:#FFFFFF">';
if (@$bean->multi_c || $isEdit) {
    $fields = unserialize(html_entity_decode($bean->multi_c, ENT_QUOTES));
    if ($isEdit) $fields[] = '';
    foreach ($fields as $f) {
        echo '<tr><td>';
        if ($isEdit) {
            echo '<input type="text" name="multi_c[]" value="'.$f.'" /></td>';
            echo '<td style="vertical-align:bottom;">';
            echo '<img src="themes/default/images/minus_inline.gif" onclick="$(this).parentsUntil(\'tbody\').last().remove()">';
            echo '&nbsp;<img src="themes/default/images/plus_inline.gif" onclick="var $e = $(this).parentsUntil(\'tbody\').last(), $f = $e.clone(); $f.find(\'input\').val(\'\');$e.after($f)">';
        }
        else {
            echo $f;
        }
        echo '</td></tr>';
    }
}
echo '</table>';


Step 2

Switch to the “before_save” Logic Hook:


Step 3

Enter the following value for “before_save”:

Code:

if (isset($_REQUEST['multi_c']) && is_array($_REQUEST['multi_c'])) {
    $multi_c = $_REQUEST['multi_c'];
    if (!@$multi_c[count($multi_c) -1]) {
        array_pop($multi_c);
    }
    $bean->multi_c = serialize($multi_c);
}


Step 4

Save the field


Step 5

Add it to Layouts → EditView and Layouts → DetailView.

Click the "plus" button to add a field after any item, the "minus" button to delete and item and change any field's value (Figure 2). The DetailView is shown in Figure 3.


From release 1.1 of ModuleSurfer it is possible to view this sample from ModuleSurfer grid with a little modification.

Take a look at the Field with a List of Values sample for ModuleSurfer to find out how.


Field with a Table of Values New-inline.png

(Enhanced Studio FULL version is needed for this sample)

Scenario: create a field that allows to enter/change/delete values in a table.


Procedure :

Step 1

Create a new Code field in any module with the values below

Name: es_subtable

Logic Hook: Default

DB Type: text

Code:

$isEdit = $GLOBALS['app']->controller->action == 'EditView';
echo '<style>.es-try-table {background-color:#FFFFFF; min-width: 200px !important} .es-try-table td, .es-try-table th {border:1px solid #CBDAE6 !important; padding: 0px 4px !important;}</style>';
echo '<table class="es-try-table" cellspacing="0">';
if (@$bean->es_subtable_c || $isEdit) {
    $fields = unserialize(html_entity_decode($bean->es_subtable_c, ENT_QUOTES));
    echo '<tr><th>Type</th><th>Price</th><th>Quantity</th>';
    if ($isEdit) {
        $fields[] = array('name' => '', 'price' => '', 'quantity' => '');
        echo '<th></th>';
    }
    echo '</tr>';
    foreach ($fields as $k => $f) {
        echo '<tr>';
        if ($isEdit) {
            echo '<td><input type="text" name="es_subtable_c['.$k.'][name]" value="'.$f['name'].'" /></td><td><input type="text" name="es_subtable_c['.$k.'][price]" value="'.$f['price'].'" /></td><td><input type="text" name="es_subtable_c['.$k.'][quantity]" value="'.$f['quantity'].'" /></td>';
            echo '<td style="vertical-align:bottom;">';
            echo '&nbsp;<img src="themes/default/images/minus_inline.gif" onclick="$(this).parentsUntil(\'tbody\').last().remove()">';
            echo '&nbsp;<img src="themes/default/images/plus_inline.gif" onclick="var $e = $(this).parentsUntil(\'tbody\').last(), $f = $e.clone(); $f.find(\'input\').val(\'\');$e.after($f);$e.siblings().andSelf().each(function () {var $this = $(this), i = $this.index(); $this.find(\'input\').each(function () {this.name = this.name.replace(/^([^\[]*\[)\d*/, \'$1\' + i)});});">&nbsp;</td>';
        }
        else {
            echo '<td>' . $f['name'] . '</td><td style="text-align:right">' . $f['price'] . '</td><td style="text-align:right">' . $f['quantity'] . '</td>';
        }
        echo '</tr>';
    }
}
echo '</table>';


Step 2

Switch to the “before_save” Logic Hook:


Step 3

Enter the following value for “before_save”:

Code:

if (isset($_REQUEST['es_subtable_c']) && is_array($_REQUEST['es_subtable_c'])) {
    $es_subtable_c = $_REQUEST['es_subtable_c'];
    $save_info = array();
    foreach ($es_subtable_c as $f) {
        if (@$f['name'] || @$f['price'] || @$f['quantity']) $save_info[] = $f;
    }
    $bean->es_subtable_c = serialize($save_info);
}


Step 4

Save the field


Step 5

Add it to Layouts → EditView, Layouts → DetailView and Layouts → ListView.

Click the "plus" button to add a field after any item, the "minus" button to delete and item and change any field's value (Figure 4). The DetailView and ListView are shown in the Figures 5 and 6.

Subtable Listview.png

Figure 6


Total Amount of listed Opportunities

(Enhanced Studio FULL version is needed for this sample)

Scenario: Add the total amount sum of the Opportunities shown in the List View.


Procedure :

Step 1

Create a new Code field in the Opportunities module with the values below

Name: any

Logic Hook: Default

DB Type: Non-DB

Code:

if (!isset($GLOBALS['ESCOppAmount'])) $GLOBALS['ESCOppAmount'] = 0;
$GLOBALS['ESCOppAmount'] += $bean->amount_usdollar;


Step 2

Switch to the “after_ui_frame” Logic Hook:


Step 3

Enter the following value in Code:

Code:

require_once('modules/Currencies/Currency.php');

echo '
<script language="javascript">

$(document).ready( function () {
    $(".list.view").after("<div style=\'float: right; font-size: 13px;\'>Total Amount: '.currency_format_number($GLOBALS['ESCOppAmount']).'</div>");
});

</script>';


Step 4

Save the field


Now the sum of the total amounts displayed in the Opportunities List View is shown under the records.

Total sample.png

Figure 7


Multiple File Upload

(Enhanced Studio FULL version is needed for this sample)

Scenario: create a field that allows to upload multiple files for each Contact.

The limitation that files could be uploaded only one at a time has been removed in the last version of this sample.

Procedure :

Step 1

Create a new Code field in the Contacts module with the values below

Name: file_upload

Logic Hook: Default

DB Type: text

Code:

$isEdit = $GLOBALS['app']->controller->action == 'EditView';
if (@$bean->file_upload_c) {
    echo '<table cellspacing="5" style="background-color:#FFFFFF">';
    foreach (explode(';', $bean->file_upload_c) as $n => $f) {
        $ext = strtolower(pathinfo($f, PATHINFO_EXTENSION));
        echo '<tr id="file_upload_div'.$n.'">';
        echo '<td><img src="http://www.dispage.com/resources/'.$ext.'.png" /> ';
        echo '<a href="cache/public_uploads/'.$f.'" target="_blank">'.$f.'</a><br/>';
        echo '<input type="hidden" name="file_upload_list[]" value="'.$f.'"></td>';
        if ($isEdit) {
            echo '<td style="vertical-align:bottom;"><img src="themes/default/images/minus_inline.gif" onclick="$(\'#file_upload_div'.$n.'\').remove();"></td>';
        }
        echo '</tr>';
    }
    echo '</table>';
}
if ($isEdit) {
    echo '
    <script language="javascript">
        $("#EditView").attr("enctype", "multipart/form-data").attr( "encoding", "multipart/form-data" );
    </script>
    <table  id="est-file-upload" cellspacing="5" style="background-color:#FFFFFF">
       <tr>
             <td><input name="file_upload_c[]" type="file"/></td>
             <td>
                    <img class="est-remove-file" style="display:none;" src="themes/default/images/minus_inline.gif" onclick="$(this).parentsUntil(\'tbody\').last().remove()">
                    <img src="themes/default/images/plus_inline.gif" onclick="var $e = $(this).parentsUntil(\'tbody\').last(), $f = $e.clone(); $f.find(\'input\').val(\'\'); $f.find(\'.est-remove-file\').show();$e.after($f)">
             </td>
       </tr>
    </table>
    ';
}


Step 2

Switch to the “before_save” Logic Hook:


Step 3

Enter the following value for “before_save”:

Code:

$uploaddir = 'cache/public_uploads/';
if (!file_exists($uploaddir)) {
    mkdir($uploaddir);
}
$file_up = array();

foreach($_FILES['file_upload_c']['name'] as $k => $name) {

       $basename = basename($name);
       $file_up[] = $basename;
       $uploadfile = $uploaddir . $basename;
       
       move_uploaded_file($_FILES['file_upload_c']['tmp_name'][$k], $uploadfile);
}
$bean->file_upload_c = join(';', array_filter(array_merge((array)@$_REQUEST['file_upload_list'], $file_up)));


Step 4

Save the field


Step 5

Add it to Layouts → EditView and Layouts → DetailView.

Now multiple files of any type can be uploaded into any Contact or deleted by clicking the trash icon, as shown in Figure 8. The DetailView is shown in Figure 9.

From release 1.1 of ModuleSurfer it is possible to view this sample from ModuleSurfer grid with a little modification.

Take a look at the Multiple File Upload sample for ModuleSurfer to find out how.



SugarCRM standard text field

Scenario: reproduce the standard SugarCRM text field.

The effect is the same of adding ad SugarCRM text field, but it can be used as a base to develop new features (such as AJAX spellcheck, Autocomplete or Javascript validation).


Procedure:

Step 1

Create a new Code field in any module with the values below

Logic Hook: Default

DB Type: text

Code:

if ($GLOBALS['app']->controller->action == 'EditView')
    echo '<input type="text" value="'.$bean-><field_name>.'" size="30" id="<field_name>" name="<field_name>"/>';
else
    echo $bean-><field_name>;

where the string “<field_name>” in the Code must be replaced with the Field Name (with the "_c" postfix if used in SugarCRM Studio).


Step 2

Add it to any Layout


The result is the same as a standard SugarCRM text field were used.


Google Map automatic link

Scenario: add a link to the Google Map of the customer address on Contacts / Accounts module.


Procedure for Accounts Module:

Accounts - Step 1

Create a new Code field in the Accounts module with the values below

Logic Hook: Default

DB Type: Non-DB

Code:

$search_string = urlencode("$bean->billing_address_street $bean->billing_address_city - $bean->billing_address_country");
echo '<a href="http://maps.google.it/maps?f=q&hl=en&geocode=&q=' . $search_string . '&ie=UTF8&z=12&iwloc=addr" style="color:#0000FF;text-align:left" target="_blank">Click here to view the map</a>';


Accounts - Step 2

Add it to Layouts → DetailView or EditView.


Procedure for Contacts Module:

Contacts - Step 1

Create a new Code field in the Contacts module with the values below

Logic Hook: Default

DB Type: Non-DB

Code:

$search_string = urlencode("$bean->primary_address_street $bean->primary_address_city - $bean->primary_address_country");
echo '<a href="http://maps.google.it/maps?f=q&hl=en&geocode=&q=' . $search_string . '&ie=UTF8&z=12&iwloc=addr" style="color:#0000FF;text-align:left" target="_blank">Click here to view the map</a>';


Contacts - Step 2

Add it to Layouts → DetailView or EditView.

The Detail View for a contact should appear like the one shown in Figure 10


Sample Google map.gif

Figure 10


Generic AJAX Call (using YUI libraries)

Scenario: perform any AJAX call and dump results on the screen without reloading the page using the YUI libraries integrated in SugarCRM.


Code:

echo '
<script>
function ajax_action () {

    var callback = {

            success: function(o) {

            … write here the js action …

        }
    }

    var connectionObject = YAHOO.util.Connect.asyncRequest ("GET", … write here your URI …, callback);
}

</script> 

<input type="button" value="ajax1" onclick="ajax_action();">';

The AJAX URI might call for instance a .php file written by the Administrator that performs any action, with GET parameters passed as input and the result echoed and returned by the “success” function. For example the result can be Javascript alerted through the following callback:

var callback = {

    success: function(o) {
        alert(o.responseText)
    }
}



Generic AJAX Call (using jQuery)

Scenario: perform any AJAX call and dump results on the screen without reloading the page using the jQuery functions integrated in Dispage Extension Manager.


Code:

echo '
<script>
function ajax_action2 () {
    $.ajax({url: "<your_uri>", 
        type: "<POST/GET>",
        data: <your_data>,
        success: function(data) {
            … write here the js action …
        }
    });
}
</script> 
<input type="button" value="ajax2" onclick="ajax_action2();">
';

To find out how the jQuery $.ajax call works, follow the link http://api.jquery.com/jQuery.ajax/


Autocomplete AJAX country field

(Enhanced Studio FULL version is needed for this sample)

Scenario: add the Autocomplete feature (natively included in dispage Extension Manager) to the “Country” field of the Billing Address in the Accounts Edit View. The autocomplete values are AJAX-loaded while typing.


Procedure:

Step 1

Create a Code field in the Accounts module with the values below

Logic Hook: after_ui_frame

DB Type: Non-DB

Code:

if ($GLOBALS['app']->controller->action == 'EditView')
    echo '
    <script language="javascript">
        $(document).ready(function () {
            $("#billing_address_country").autocomplete({
                "source" : "customAJAXCalls.php?call=Accounts_countries_cb"
            });
        });
    </script>
    ';

Step 2

Create an AJAXCallback field with

Field Name: countries_cb

Code:

global $app_list_strings;

if (!@$_REQUEST["term"]) die('[]');

require_once('include/utils.php');
require_once('include/SugarTheme/SugarTheme.php');
require_once('include/language/en_us.lang.php');

$found = array();

foreach ($app_list_strings['countries_dom'] as $c) {
    if (stripos($c, $_REQUEST["term"]) === 0) $found[] = '"'.$c.'"';
}
echo '[' . join(', ', $found) . ']';

No need to add any of the fields above to the EditView Layout.


Figure 11 is a screenshot taken while typing in Account’s Country field of Billing Address.


Autocomplete example.png

Figure 11


Generic SugarCRM DB / External DB Query

Scenario: connect to SugarCRM DB or any external DB, execute a query (possibly containing any data of the current field through the “$bean” variable) and echo the results. MySQL DB Engine is assumed to be used in this and the next sample.


Code:

global $connection_code_field;

if (!isset($connection_code_field)) {
    $connection_code_field = mysql_connect("<db_host>", "<db_user>", "<db_password>");
    mysql_select_db("<db_name>", $connection_code_field);
}
$sql = "<db_query>"; 

$res = mysql_query($sql, $connection_code_field);
if (mysql_num_rows($res))
$value = mysql_result($res, <id_field>);

echo $value;

where <db_host>, <db_user>, <db_password>, <db_name>, <db_query> and <id_field> must be properly set. When connecting to the SugarCRM DB, connection parameters can be retrieved automatically like in the following example.


Contact List in Account Module

Scenario: add a list of clickable related contacts for each account.


Procedure:

Step 1

Create a new Code field in the Accounts module with the values below

Logic Hook: Default

DB Type: Non-DB

Code:

global $db;

$sql = "SELECT ac.contact_id as id, CONCAT(c.first_name, ' ', c.last_name) as name FROM contacts c JOIN accounts_contacts ac ON c.id = ac.contact_id WHERE ac.account_id = '$bean->id'"; 

$res = $db->query($sql);
$values = array();
while($value = $db->fetchByAssoc($res))
    $values[] = "<a href='index.php?module=Contacts&return_module=Accounts&action=DetailView&record=".$value['id']."'>".$value['name']."</a>";

echo join($values, '<br/>'); 


Step 2

Add it to Layouts → DetailView or ListView.

A sample of List View for the field is shown in Figure 12


Sample Contacts account.gif

Figure 12

Navigation
dispage support
Toolbox