Friday, August 27, 2010

Subpanel save and continue in quick create form

This hack is for the Sugarcrm official release 5.5.1

Inline quick create form in a sub panel is supported by sugar (it is not the default way of creating new sub panel entries). We can add an inline quick create form to a subpanel by adding the widget class SubPanelTopButtonQuickCreate to the subpanel definition.
Now when we press the Create button just above the subpanel in question the form will load just under the subpanel without a full page load. In this quick create form there is a save button which will close the form and show subpanel records. So to add another record the user needs to press the create button again.

This posting describes how to add a new "Save & continue" button that will save the new record & open a new blank form again.



This customization is not upgrade safe.

The following files need to be modified:

1. include/EditView/SubpanelQuickCreate.php
a. function SubpanelQuickCreate modified to support new 'SUBPANELSAVEANDCONTINUE' button.
// HACK : New Widget - Save and Continus Button for inline (subpanel) forms
$this->ev->defs['templateMeta']['form']['buttons'] = array('SUBPANELSAVE', 'SUBPANELCANCEL', 'SUBPANELFULLFORM', 'SUBPANELSAVEANDCONTINUE');
// HACK : New Widget - Save and Continus Button for inline (subpanel) forms


2. include/generic/SugarWidgets/SugarWidgetSubPanelTopButtonQuickCreate.php
a. In function &_get_form code block added to create some hidden variable in quick create form.
// HACK : Inline problem with one-to-many relations
switch ( strtolower( $currentModule ) )
{
 case 'prospects' :
  $name = $defines['focus']->account_name ;
  break ;
 case 'documents' :
  $name = $defines['focus']->document_name ;
  break ;
 case 'kbdocuments' :
  $name = $defines['focus']->kbdocument_name ;
  break ;
 case 'leads' :
 case 'contacts' : 
  $name = $defines['focus']->first_name . " " .$defines['focus']->last_name ;
  break ;
 default :
    $name = (isset($defines['focus']->name)) ? $defines['focus']->name : "";
}
$button .= '<input type="hidden" name="return_name" value="' . $name . "\" />\n";

$relationship_name = $this->get_subpanel_relationship_name($defines);
$button .= '<input type="hidden" name="return_relationship" value="' . $relationship_name . "\" />\n"; 
// HACK : Inline problem with one-to-many relations


3. include/language/en_us.lang.php
// HACK : New Widget - Save and Continus Button for inline (subpanel) forms
$app_strings['LBL_SUBPANEL_SAVE_AND_CONTINUE_KEY'] = '';
$app_strings['LBL_SUBPANEL_SAVE_AND_CONTINUE_LABEL'] = 'Save and Continue';
$app_strings['LBL_SUBPANEL_SAVE_AND_CONTINUE_TITLE'] = 'Save and Continue';
// HACK : New Widget - Save and Continus Button for inline (subpanel) forms


4. include/Smarty/plugins/function.sugar_button.php
a. In function smarty_function_sugar_button new case added for save and continue button.
// HACK : New Widget - Save and Continus Button for inline (subpanel) forms    
case "SUBPANELSAVEANDCONTINUE":
 return '{if $bean->aclAccess("save")}<input title="{$APP.LBL_SUBPANEL_SAVE_AND_CONTINUE_TITLE}" accessKey="{$APP.LBL_SUBPANEL_SAVE_AND_CONTINUE_KEY}" class="button" onclick="this.form.action.value=\'Save\';if(check_form(\''.$view.'\'))return SUGAR.subpanelUtils.inlineSaveAndContinue(this.form.id, \''.$params['module'] . '_subpanel_save_continue_button\');return false;" type="submit" name="' . $params['module'] . '_subpanel_save_continue_button" id="' . $params['module'] . '_subpanel_save_continue_button" value="{$APP.LBL_SUBPANEL_SAVE_AND_CONTINUE_LABEL}">{/if} ';
// HACK : New Widget - Save and Continus Button for inline (subpanel) forms

b. New funcation added to generate subpanel id.
function buttonGetSubanelId($module){
 $subpanel = strtolower($module);
 $activities = array('Calls', 'Meetings', 'Tasks', 'Emails');
 if($module == 'Notes'){
  $subpanel = 'history';
 }
 if(in_array($module, $activities)){
  $subpanel = 'activities';
 }  
 return $subpanel;
}



5. include/SubPanel/SubPanelTiles.js
a. Following 3 function modified to support save and continue code.
// HACK : New Widget - Save and Continus Button for inline (subpanel) forms
inlineSaveAndContinue: function (theForm, buttonName) {
 ajaxStatus.showStatus(SUGAR.language.get('app_strings', 'LBL_SAVING'));
 var success = function (data) {
  
  var element = document.getElementById(buttonName);
  do {
   element = element.parentNode;
  } while (element.className != 'quickcreate' && element.parentNode);
      
  if (element.className == 'quickcreate') {
   var subpanel = element.id.slice(9, -7);
   SUGAR.subpanelUtils.cancelCreate(buttonName);
        
   var module = get_module_name();
   var id = get_record_id();
   var layout_def_key = get_layout_def_key();
   try {
    eval('result = ' + data.responseText);
   } catch (err) {}
   if (typeof(result) != 'undefined' && result != null && typeof(result['status']) != 'undefined' && result['status'] != null && result['status'] == 'dupe') {
    document.location.href = "index.php?" + result['get'].replace(/&amp;/gi, '&').replace(/&lt;/gi, '<').replace(/&gt;/gi, '>').replace(/&#039;/gi, '\'').replace(/&quot;/gi, '"').replace(/\r\n/gi, '\n');
    return;
   } else {

    ajaxStatus.showStatus(SUGAR.language.get('app_strings', 'LBL_SAVED'));
    ajaxStatus.hideStatus();
    document.getElementById(createFormName).onsubmit();
     showSubPanel(subpanel, null, true);
    if (reloadpage) window.location.reload(false);
   }
  }
 }
 var reloadpage = false;
 var createFormName = 'formform' + document.getElementById(theForm).module.value;
 if ((buttonName == 'Meetings_subpanel_save_button' || buttonName == 'Calls_subpanel_save_button') && document.getElementById(theForm).status[document.getElementById(theForm).status.selectedIndex].value == 'Held') {
  reloadpage = true;
 }
 YAHOO.util.Connect.setForm(theForm, true, true);
 var cObj = YAHOO.util.Connect.asyncRequest('POST', 'index.php', {
  success: success,
  failure: success,
  upload: success
 });
 return false;
}, 
// HACK : New Widget - Save and Continus Button for inline (subpanel) forms

sendAndRetrieve:function(theForm,theDiv,loadingStr, subpanel){

function redoTabs(formid) {
 var k = window.topIndex || 0;
 var form = document.getElementById("whole_" + formid);
 form = form.getElementsByTagName("form")[0];
 var elements = form.getElementsByTagName("*");

 // Main script cycle:
 for (var i = 0; i < elements.length; i++) {
  var element = elements[i];
  var tag = element.tagName.toLowerCase();
  var type = "";

  if (tag == "input") {
   try {
    type = element.getAttribute("type");
    if (type) type = type.toLowerCase();
   }
   catch (e) {
    type = "";
   };
  }

  if (((tag == "input") && (type != "hidden")) || (tag == "select") || (tag == "textarea") || (tag == "iframe") || (tag == "button")) {
   try {
    element.setAttribute("tabindex", k);
    element.tabIndex = k;
   }
   catch (e) {}

   ++k;
  }
  else {
   var tindex = false;

   try {
    tindex = element.hasAttribute("tabIndex");
   }
   catch (e) {
    tindex = false;
   };

   try {
    if (tindex) element.setAttribute("tabindex", 999);
   }
   catch (e) {}
  }
 }

 window.topIndex = k;
}

function success(data) {
 theDivObj = document.getElementById(theDiv);
 subpanelContents[theDiv] = new Array();
 subpanelContents[theDiv]['list'] = theDivObj;
 subpanelContents[theDiv]['newDiv'] = document.createElement('div');
 dataToDOMAvail = false;
 subpanelContents[theDiv]['newDiv'].innerHTML = '<script type="text/javascript">dataToDOMAvail=true;</script>' + data.responseText;
 subpanelContents[theDiv]['newDiv'].id = theDiv + '_newDiv';
 subpanelContents[theDiv]['newDiv'].className = 'quickcreate';
 // HACK: Upgrade sugarbase to SugarCRM 5.5
 //theDivObj.style.display = 'none';
 // HACK: Upgrade sugarbase to SugarCRM 5.5
 theDivObj.parentNode.insertBefore(subpanelContents[theDiv]['newDiv'], theDivObj);
 if (!dataToDOMAvail) {
  SUGAR.util.evalScript(data.responseText);
 }
 subpanelLocked[theDiv] = false;
 setTimeout("enableQS(false)", 500);
 ajaxStatus.hideStatus();

 redoTabs(theDiv);
}


6. modules/ModuleBuilder/parsers/relationships/AbstractRelationship.php
a. Following function is modified to add quick create button in subpanel. As SubPanelTopCreateButton already exist as subpanel widget, subpanel will show 2 create button. Remove undesired create button from following code.
protected function getSubpanelDefinition ($relationshipName , $sourceModule , $subpanelName, $titleKeyName = '')
{
 $subpanelDefinition = array ( ) ;
 $subpanelDefinition [ 'order' ] = 100 ;
 $subpanelDefinition [ 'module' ] = $sourceModule ;
 $subpanelDefinition [ 'subpanel_name' ] = $subpanelName ;
 // following two lines are required for the subpanel pagination code in ListView.php->processUnionBeans() to correctly determine the relevant field for sorting
 $subpanelDefinition [ 'sort_order' ] = 'asc' ;
 $subpanelDefinition [ 'sort_by' ] = 'id' ;
 if(!empty($titleKeyName)){
  $subpanelDefinition [ 'title_key' ] = 'LBL_' . strtoupper ( $relationshipName . '_FROM_' . $titleKeyName ) . '_TITLE' ;
 }else{
  $subpanelDefinition [ 'title_key' ] = 'LBL_' . strtoupper ( $relationshipName . '_FROM_' . $sourceModule ) . '_TITLE' ;
 }
 $subpanelDefinition [ 'get_subpanel_data' ] = $relationshipName ;
 $subpanelDefinition [ 'top_buttons' ] = array(
  array('widget_class' => "SubPanelTopCreateButton"),
  array('widget_class' => 'SubPanelTopButtonQuickCreate'),
  array('widget_class' => 'SubPanelTopSelectButton', 'mode'=>'MultiSelect')
 );
 
 return array ( $subpanelDefinition );
}

1 comment:

Unknown said...

I implemented the code, in my instance and the Save and Continue button appear in the subpanel, but when I create a new record and click the Save and Continue button the record is being saved but there is no blank record are appearing to fill another record. I don't know why this thing is happened.