Lookup Component

initializeContactLookupField : function(component) {
        var self = this;
        var soLine = _.cloneDeep(component.get('v.line'));
        if(!$A.util.isEmpty(soLine.assignments) && soLine.assignments.length === 1) {
            soLine.contactId = soLine.assignments[0].contactId;
        }
        var event = component.get('v.eventObj');
        var filter = 'Id ';
        if (event.enableContactSearch) {
            filter += '!= null AND OrderApi__Privacy_Settings__c ';
            if (component.get('v.isAuthenticated') && !component.get('v.isGuest')) {
                filter += '!= \'unlisted\' ';
            } else {
                filter += '= \'public\' ';
            }
            if (!event.searchAllContacts && !$A.util.isEmpty(component.get('v.accountId'))) {
                filter += ' AND accountId = \'' + component.get('v.accountId') + '\' ';
            }
            if (component.get('v.eventObj.enableContactRestriction') &&
                !$A.util.isEmpty(component.get('v.eventObj.existingAttendeeContactIds'))) {
                filter += ' AND Id NOT IN (\''+component.get('v.eventObj.existingAttendeeContactIds').join('\',\'')+'\')';
            }
        } else {
            filter += '= null';
        }
        var fields = event.contactSearchFields;
        var fieldList = ['Name'];
        if (!$A.util.isEmpty(fields)) {
            var fldList = fields.split(',');
            fldList.forEach(function(element) {
                if (element.trim().toLowerCase() !== 'name') {
                    fieldList.push(element.trim());
                }
            });
        }

        var otherAttributes = {
            advanced: true,
            enforceSharingRules : false,
            concatenateLabel : true,
            types : {
                Contact : {
                    fieldNames : fieldList,
                    filter : filter,
                    initialLoadFilter : filter + ' Order By LastModifiedDate ASC LIMIT 100'
                },
                OrderApi__Assignment__c : {
                    fieldNames : ['OrderApi__Full_Name__c', 'OrderApi__email__c'],
                    filter : 'Id = null',
                    initialLoadFilter : 'Id = null'
                },
                EventApi__Waitlist_Entry__c : {
                    fieldNames : ['EventApi__Full_Name__c', 'EventApi__Email__c'],
                    filter : 'Id = null',
                    initialLoadFilter : 'Id = null'
                }
            },
            otherMethods: {
                searchField : ['sObjectLabel', 'Name', 'Email', 'OrderApi__Preferred_Email__c'],
                render: {
                    option: function (item, escape) {
                        if (item.type === 'OrderApi__Assignment__c') {
                            return '';
                        }
                        if (item.type === 'EventApi_Waitlist_Entry__c') {
                            return '';
                        }
                        var lowerText = '';
                        if (!$A.util.isEmpty(fields)) {
                            fieldList.forEach(function(element) {
                                if (item.sObj.hasOwnProperty(element)
                                    && !$A.util.isEmpty(item.sObj[element])
                                    && element.toLowerCase() !== 'name') {
                                    var elementToDisplay = item.sObj[element];
                                    if (lowerText === '') {
                                        if ($A.util.isObject(elementToDisplay)) {
                                            lowerText = Object.values(elementToDisplay).join(', ');
                                        }
                                        else {
                                            lowerText = elementToDisplay;
                                        }
                                    } else {
                                        if ($A.util.isObject(elementToDisplay)) {
                                            lowerText += '  ' + '•' + '  ' + escape(Object.values(elementToDisplay).join(', '));
                                        }
                                        else {
                                            lowerText += '  ' + '•' + '  ' + escape(elementToDisplay);
                                        }
                                    }
                                }
                            });
                        }
                        return '<div class="slds-grid">' +
                            '<div class="slds-p-right--xx-small slds-shrink-none" style="height: 0;">' +
                            '<img src="' + $A.get('$Resource.Framework__SLDS_Icons') +
                            '/icons/utility/user_60.png" width="12"/>' +
                            '</div>'+
                            '<div class="slds-grid slds-wrap slds-size--1-of-1">' +
                            '<div class="slds-col slds-size--1-of-1 slds-align-middle">' +
                            '<strong style="line-height: 1.4;">' + escape(item.sObj.Name) + '</strong>' +
                            '</div>'+
                            '<div class="slds-col slds-size--1-of-1 slds-text-body--small">' +
                            lowerText +
                            '</div>' +
                            '</div>' +
                            '</div>';
                    },
                    item: function (item, escape) {
                        var returnHTML = '<div class="slds-position--absolute">'+
                            '<img src="' + $A.get('$Resource.Framework__SLDS_Icons') +
                            '/icons/utility/user_60.png" width="12" class="slds-m-right--xx-small"/>' +
                            '<span class="slds-align-middle">';
                        if (item.type === 'OrderApi__Assignment__c') {
                            returnHTML += escape(item.sObj.OrderApi__Full_Name__c);
                        }
                        else if (item.type === 'EventApi__Waitlist_Entry__c') {
                            returnHTML += escape(item.sObj.EventApi__Full_Name__c);
                        }
                        else {
                            returnHTML += escape(item.sObj.Name);
                        }
                        returnHTML += '</span>' +
                            '</div>' ;
                        return returnHTML;
                    },
                    option_create : function (data, escape) {
                        return '<div class="slds-grid slds-grid_vertical create" data-selectable="true">'+
                               '<div class="slds-m-bottom_xx-small">'+ escape(data.input) +' is not in our system.</div>' +
                               '<div><a href="javascript:void(0)">+ Add ' + escape(data.input) + '</a></div>' +
                               '</div>';
                    }
                },
                create : function(input) {
                    var firstName = input.substr(0, input.indexOf(' '));
                    var lastName = input.substr(input.indexOf(' ') + 1);
                    component.find('firstName').updateValue(firstName);
                    component.find('lastName').updateValue(lastName);
                    component.find('preferredEmail').updateValue('Personal');
                    component.find('email').updateValue(null);
                    if (!$A.util.isEmpty(component.find('matchingField'))) {
                        component.find('matchingField').updateValue(null);
                    }
                    if (!$A.util.isEmpty(component.get('v.guestRegistrationFieldsGlobals'))) {
                        component.get('v.guestRegistrationFieldsGlobals').forEach(function(element){
                            $A.getComponent(element).updateValue(null);
                        });
                    }
                    component.find('addAttendeeBtn').set('v.disable',component.get('v.eventObj.createContactForAttendees'));
                    self.updateTicketModalBody(component);
                    self.showPopover(component);
                    return {
                        id: component.getLocalId(),
                        text: function() {
                            input = firstName + ' ' + lastName;
                            return input;
                        }
                    }
                }
            }
        };

        if (component.get('v.isTransfer') && !component.get('v.eventObj.createContactForAttendees')) {
            otherAttributes.otherMethods.create = false;
        }

        if (!$A.util.isEmpty(soLine) && !$A.util.isEmpty(soLine.contactId) && !$A.util.isEmpty(soLine.contactName) &&
            soLine.contactName.toLowerCase() !== 'undefined') {
            otherAttributes.preloadObj = {
                sObj : {
                    Name : soLine.contactName
                },
                sObjectId : soLine.contactId,
                sObjectLabel : soLine.contactName
            }
        }
        var disableInput = false;
        if (component.get('v.eventObj.isInvitationOnly') && component.get('v.index') === 0 && component.get('v.isSalesOrderLine')) {
            component.set('v.primaryRegistrationInvitation',true);
            disableInput = true;
        }

        $A.createComponent(
            'markup://Framework:InputFields',{
                'value' : soLine,
                'fieldType' : 'lookup',
                'aura:id' : 'contactId',
                'labelStyleClasses' : component.get('v.labelStyleClasses'),
                'label' : component.get('v.label'),
                'isRequired' : true,
                'fireChangeEvent' : true,
                disabled : disableInput,
                'group' : soLine.id,
                otherAttributes : otherAttributes
            }, function(cmp) {
                cmp.set('v.value', soLine);
                component.set('v.contactGlobalId', cmp.getGlobalId());
                var divComponent = component.find("lookupDiv");
                var divBody = divComponent.get("v.body");
                divBody.push(cmp);
                divComponent.set("v.body",divBody);
            }
        );
    }
JS