Add additional field to the Selection List in a Related Field

Dear Sugar Users, 

Within our Cases module, we have a related field to the Contacts, in this case it is used to select the Primary Contact of a Case. 

In the "Select Contact..." box that appears (See below). We can type a name component of the contact and a list of selectable contacts will appear. However, there may be contacts of the same name. We can always click the "Search and Select" option to do a more detailed search, however it would be convenient to be able to extend this control to also show the Account for the contact. 

Does anyone know how this can be done? Or what files I need to check to see if it is extendable?


BTW This is Sugar Ent 12.0.2 On Prem. 

Many thanks for your help. 

  • Hi  ,

    There are various way of achieving this. I will give you a very generic example, I'm hopping that will inspire you for your own solutions. 

    You can do this via generic relate customisations. You would create `custom/clients/base/fields/relate/relate.js` with following content:

    ({
        extendsFrom: "RelateField",
    
        getSearchFields(){
            // get the fields from super;
            const fields = this._super("getSearchFields");
            if (this.getSearchModule() == "Contacts"){
                // append the contact fields for search results
                fields.push("account_name");
            }
            // return
            return fields;
        },
    
        /**
         * Searches for related field.
         * @param event
         */
        search: _.debounce(function(query) {
            var term = query.term || '',
                self = this,
                searchModule = this.getSearchModule(),
                params = {},
                limit = self.def.limit || 5,
                relatedModuleField = this.getRelatedModuleField();
    
            if (query.context) {
                params.offset = this.searchCollection.next_offset;
            }
            params.filter = this.buildFilterDefinition(term);
            
            this.searchCollection.fetch({
                //Don't show alerts for this request
                showAlerts: false,
                update: true,
                remove: _.isUndefined(params.offset),
                reset: _.isUndefined(params.offset),
                fields: this.getSearchFields(),
                context: self,
                params: params,
                limit: limit,
                success: function(data) {
                    var fetch = {results: [], more: data.next_offset > 0, context: data};
                    if (fetch.more) {
                        var fieldEl = self.$(self.fieldTag),
                            //For teamset widget, we should specify which index element to be filled in
                            plugin = (fieldEl.length > 1) ? $(fieldEl.get(self._currentIndex)).data("select2") : fieldEl.data("select2"),
                            height = plugin.searchmore.children("li:first").children(":first").outerHeight(),
                            //0.2 makes scroll not to touch the bottom line which avoid fetching next record set
                            maxHeight = height * (limit - .2);
                        plugin.results.css("max-height", maxHeight);
                    }
                    _.each(data.models, function (model, index) {
                        if (params.offset && index < params.offset) {
                            return;
                        }
                        // set empty additional text
                        let additionalText = ""
                        // append the additional data if the searchModuleContacts
                        if (self.getSearchModule() == "Contacts"){
                            const acc_name = model.get("account_name"); // get the account_name here
                            additionalText = ( acc_name ? ' (' + acc_name + ')' : ''); //set here
                        }
                        fetch.results.push({
                            id: model.id,
                            text: model.get(relatedModuleField) + additionalText //use the account_name here if its set
                        });
                    });
                    if (query.callback && _.isFunction(query.callback)) {
                        query.callback(fetch);
                    }
                },
                error: function() {
                    if (query.callback && _.isFunction(query.callback)) {
                        query.callback({results: []});
                    }
                    app.logger.error("Unable to fetch the bean collection.");
                }
            });
        }, app.config.requiredElapsed || 500),
    })
    

    Anytime a contact relation field being used this will application wide adds the account_name to end of the contact names. 

    Hope this helps. Slight smile

    Tevfik Tümer
    Sr. Developer Support Engineer

  • Hi  Wow, fantastic reply, this works as expected and I can see how I can use this to extend other controls. 

    I have noticed that the To field on an Email works differently (See below), Could we use the same process to extend this field to show the Contacts Account name too?

    Thanks again. 

  • Hi  ,

    I'm glad it worked as you expected. To do similar changes in emails reciepients much trickier than contacts field. 
    To field works with collections,To be able to show accounts and contacts the users must have a relationship and modify in the collection before pass to select2 (Dropdown).

    You can review: render function in modules/Emails/clients/base/fields/email-recipients/email-recipients.js 

    Tevfik Tümer
    Sr. Developer Support Engineer