Updating a record from a list view using the action dropdown

I'm still on the learning curve as a SugarCRM developer. I've done significant amounts of development on the back end (logic hooks, database work, scheduled jobs) but am still learning the ropes on the front end. I could really use some help understanding how to make this happen.

We have a custom module that includes a status dropdown. A set of our users spend much of their day in the list view of this module. One of their key actions is to update this status field. I've been asked to enable updating this status directly from the list view, which would simplify their workflow a lot.

I modified the modules recordlist.php file to add the status options in the dropdown (see the attached image). So if they select "Mark Complete", the status field should be updated to "Complete." The column in the listview should update to refresh the new value as well.

How do I make it so Sugar is "listening" for this action and makes the appropriate update?

Does the update of the record itself happen in Javascript on the front end? Or does the action trigger a process/call on the backend, with PHP code ultimately updating the field and saving it?

Thanks for any help you can provide.

Parents
  • I am not sure you are approaching this in the most efficient way.

    The user can use the Edit on the list view to update each line one by one but the easiest would be to add the status to the mass-update, that way they can check the boxes on the left for all the lines to be updated to a given value and then just select the status to assign.

    See if these links help:

    Adding a field to Mass Update:

    http://support.sugarcrm.com/Knowledge_Base/Studio_and_Module_Builder/Adding_a_Field_to_Mass_Update/ 

    Alternatively, you could add a List View Action (not Row Action) to mass update the status to the value you want on a whole set of selected list-view records, effectively doing a one-click mass update.

    For example, in my Cases module I added an action to close as spam in

    custom/modules/Cases/clients/base/views/recordlist/recordlist.php

    in the actions array:

     

    array (
            'name' => 'close_as_spam',
            'type'=>'button',
            'label' => 'LBL_CLOSE_AS_SPAM_ACTION',
            'acl_action' => 'edit',
            'events' => array(
              'click' => 'list:closeasspam:fire',
            ),
          ),

    I then extended the controller and defined the code to execute when the event fires:

    custom/modules/Cases/clients/base/views/recordlist/recordlist.js

    ({
       extendsFrom: 'RecordlistView',

       initialize: function(options){
          this._super('initialize', [options]);
          //define the event for the close as spam action
          this.context.on('list:closeasspam:fire', this.closeAsSpamClicked, this);

       },
       //execute the update
       updateRecords: function(params){
         var self = this,
             url = app.api.buildURL('Cases/MassUpdate');
         app.api.call('update',url,params,{
           success: function(o){
             self.layout.context.reloadData({showAlerts: false});
             var massCollection = self.context.get('mass_collection');
             massCollection.reset();
           },
           error: function(e){
             app.alert.show('error_while_mass_update', {
               level:'error',
               title: app.lang.getAppString('ERR_INTERNAL_ERR_MSG'),
               messages: app.lang.getAppString('ERR_HTTP_500_TEXT')
             });
           },
         });
       },
       //set the values to update
       closeAsSpamClicked : function() {
         var ids = _.map(this.context.get('mass_collection').models, function(selected_model){return selected_model.id}),
             params = {
               'massupdate_params':{
                 'uid':ids,
                 'status':'Closed',
                 'resolution':'Closed as Spam',
                 'case_closed_reason_c':'Spam'
               }
             };
         this.updateRecords(params);
       },
    })

    Note that all this does is leverage the MassUpdate to set the status, resolution and case_closed_reason_c (custom field) without the users having to set those themselves.

     

    If you wish to go down the path of custom rowaction events

    in custom/modules/<yourModule>/clients/base/views/recordlist/recordlist.php

    you will have added an item in the rowactions array.

    You now need an event handler for your custom event in the controller

    in custom/modules/<yourModule>/clients/base/views/recordlist/recordlist.js

    and define what to do when the event is fired

    Hope this helps,
    FrancescaS

Reply
  • I am not sure you are approaching this in the most efficient way.

    The user can use the Edit on the list view to update each line one by one but the easiest would be to add the status to the mass-update, that way they can check the boxes on the left for all the lines to be updated to a given value and then just select the status to assign.

    See if these links help:

    Adding a field to Mass Update:

    http://support.sugarcrm.com/Knowledge_Base/Studio_and_Module_Builder/Adding_a_Field_to_Mass_Update/ 

    Alternatively, you could add a List View Action (not Row Action) to mass update the status to the value you want on a whole set of selected list-view records, effectively doing a one-click mass update.

    For example, in my Cases module I added an action to close as spam in

    custom/modules/Cases/clients/base/views/recordlist/recordlist.php

    in the actions array:

     

    array (
            'name' => 'close_as_spam',
            'type'=>'button',
            'label' => 'LBL_CLOSE_AS_SPAM_ACTION',
            'acl_action' => 'edit',
            'events' => array(
              'click' => 'list:closeasspam:fire',
            ),
          ),

    I then extended the controller and defined the code to execute when the event fires:

    custom/modules/Cases/clients/base/views/recordlist/recordlist.js

    ({
       extendsFrom: 'RecordlistView',

       initialize: function(options){
          this._super('initialize', [options]);
          //define the event for the close as spam action
          this.context.on('list:closeasspam:fire', this.closeAsSpamClicked, this);

       },
       //execute the update
       updateRecords: function(params){
         var self = this,
             url = app.api.buildURL('Cases/MassUpdate');
         app.api.call('update',url,params,{
           success: function(o){
             self.layout.context.reloadData({showAlerts: false});
             var massCollection = self.context.get('mass_collection');
             massCollection.reset();
           },
           error: function(e){
             app.alert.show('error_while_mass_update', {
               level:'error',
               title: app.lang.getAppString('ERR_INTERNAL_ERR_MSG'),
               messages: app.lang.getAppString('ERR_HTTP_500_TEXT')
             });
           },
         });
       },
       //set the values to update
       closeAsSpamClicked : function() {
         var ids = _.map(this.context.get('mass_collection').models, function(selected_model){return selected_model.id}),
             params = {
               'massupdate_params':{
                 'uid':ids,
                 'status':'Closed',
                 'resolution':'Closed as Spam',
                 'case_closed_reason_c':'Spam'
               }
             };
         this.updateRecords(params);
       },
    })

    Note that all this does is leverage the MassUpdate to set the status, resolution and case_closed_reason_c (custom field) without the users having to set those themselves.

     

    If you wish to go down the path of custom rowaction events

    in custom/modules/<yourModule>/clients/base/views/recordlist/recordlist.php

    you will have added an item in the rowactions array.

    You now need an event handler for your custom event in the controller

    in custom/modules/<yourModule>/clients/base/views/recordlist/recordlist.js

    and define what to do when the event is fired

    Hope this helps,
    FrancescaS

Children
  • Thank you very much for your reply. 

    I know they could use Mass Update, but in this use case, they are only updated one at a time as a user completes another action outside of Sugar.

    Editing the record in the list view via the "edit" option does work correctly. However it requires 5 clicks to update a single record (click the action arrow, click edit, click the dropdown, click the value, click save). If I can get this working as I hope, it is only 2 clicks (click the action arrow, click the desired value). In a process which might be completed hundreds of times each day, saving the extra clicks will save a lot of time.

    I did manage to add the item in the rowactions array, and my event handler is now firing the javascript function. But the record isn't updating. Here is my recordlist.js so far:

    ({

        extendsFrom:'RecordListView',

        initialize:function(options){
            this._super("initialize",[options]);
            this.context.on('list:editcompleterow:fire',this.markItineraryComplete,this);
        },
       
        markItineraryComplete:function(){
            this.model.set("status_c", 'Complete');
            console.log("Save was attempted.");
        } 
    })
  • I went through your code a bit. It looks like I need to use app.api.call to make a call to the API and update the status for this specific record. I will play with that a bit and see if I can get it working. Thanks again.