2

I have created search functionality in the lightning component using this link Custom Account Searching Lightning Component In Salesforce

enter image description here

Now I need to query and display the table of data with multiple field's data what we enter like below

enter image description here

So here I need to add more fields in component and query in apex with the data we enter we enter in fields.

I am facing the problem with how to query in apex with multiple fields data and How to handle search button in a lightning component with multiple fields

Component:

<!-- CREATE ATTRIBUTE/VARIABLE-->
<aura:attribute name="searchResult" type="List" description="use for store and display account list return from server"/>
<aura:attribute name="searchKeyword" type="String" description="use for store user search input"/>
<aura:attribute name="Message" type="boolean" default="false" description="use for display no record found message"/>
<aura:attribute name="TotalNumberOfRecord" type="integer" default="0" description="use for display Number of records"/>

<!-- SHOW LOADING SPINNER--> 
<lightning:spinner variant="brand" size="large" aura:id="Id_spinner" class="slds-hide" />

<div class="slds-m-around_medium">
   <!-- SEARCH INPUT AND SEARCH BUTTON--> 
    <lightning:layout>
        <lightning:layoutItem size="3" padding="around-small">
            <lightning:input value="{!v.searchKeyword}"
                             required="true"
                             placeholder="search Accounts.."
                             aura:id="searchField"
                             label="Account Name"/>
        </lightning:layoutItem>
        <lightning:layoutItem size="2" padding="around-small">
            <lightning:button onclick="{!c.Search}"
                              variant="brand"
                              label="Search"
                              iconName="utility:search"/> 
        </lightning:layoutItem>
    </lightning:layout>

    <!-- TOTAL RECORDS BADGES--> 
    <div class="slds-m-around_x-small">
        <lightning:badge label="{!v.TotalNumberOfRecord}" />
    </div>

    <!-- ERROR MESSAGE IF NOT RECORDS FOUND--> 
    <aura:if isTrue="{!v.Message}">
        <div class="slds-notify_container slds-is-relative">
            <div class="slds-notify slds-notify_toast slds-theme_error" role="alert">
                <div class="slds-notify__content">
                    <h2 class="slds-text-heading_small">No Records Found...</h2>
                </div>
            </div>
        </div>
    </aura:if>

    <!-- TABLE CONTENT--> 
    <table class="slds-table slds-table_bordered slds-table_cell-buffer">
        <thead>
            <tr class="slds-text-title_caps">
                <th scope="col">
                    <div class="slds-truncate" title="S.no">S.no</div>
                </th>
                <th scope="col">
                    <div class="slds-truncate" title="Account Name">Account Name</div>
                </th>
                <th scope="col">
                    <div class="slds-truncate" title="Type">Type</div>
                </th>
                <th scope="col">
                    <div class="slds-truncate" title="Industry">Industry</div>
                </th>
                <th scope="col">
                    <div class="slds-truncate" title="Phone">Phone</div>
                </th>
                <th scope="col">
                    <div class="slds-truncate" title="Fax">Fax</div>
                </th>
            </tr>
        </thead>
        <tbody> 
            <!--### display all records of searchResult attribute by aura:iteration ###-->
            <aura:iteration items="{!v.searchResult}" var="acc" indexVar="count">
                <tr>
                    <td>
                        <div class="slds-truncate">{!count + 1}</div>
                    </td>
                    <td>
                        <div class="slds-truncate">{!acc.Name}</div>
                    </td>
                    <td>
                        <div class="slds-truncate">{!acc.Type}</div>
                    </td>
                    <td>
                        <div class="slds-truncate">{!acc.Industry}</div>
                    </td>
                    <td>
                        <div class="slds-truncate">{!acc.Phone}</div>
                    </td>
                    <td>
                        <div class="slds-truncate">{!acc.Fax}</div>
                    </td>
                </tr>
            </aura:iteration>
        </tbody>
    </table>
</div>

Controller:

({
Search: function(component, event, helper) {
    var searchField = component.find('searchField');
    var isValueMissing = searchField.get('v.validity').valueMissing;
    // if value is missing show error message and focus on field
    if(isValueMissing) {
        searchField.showHelpMessageIfInvalid();
        searchField.focus();
    }else{
      // else call helper function 
        helper.SearchHelper(component, event);
    }
},

})

Helper:

     ({
     SearchHelper: function(component, event) {
    // show spinner message
     component.find("Id_spinner").set("v.class" , 'slds-show');
    var action = component.get("c.fetchAccount");
    action.setParams({
        'searchKeyWord': component.get("v.searchKeyword")
    });
    action.setCallback(this, function(response) {
       // hide spinner when response coming from server 
        component.find("Id_spinner").set("v.class" , 'slds-hide');
        var state = response.getState();
        if (state === "SUCCESS") {
            var storeResponse = response.getReturnValue();

            // if storeResponse size is 0 ,display no record found message on screen.
            if (storeResponse.length == 0) {
                component.set("v.Message", true);
            } else {
                component.set("v.Message", false);
            }

            // set numberOfRecord attribute value with length of return value from server
            component.set("v.TotalNumberOfRecord", storeResponse.length);

            // set searchResult list with return value from server.
            component.set("v.searchResult", storeResponse); 

        }else if (state === "INCOMPLETE") {
            alert('Response is Incompleted');
        }else if (state === "ERROR") {
            var errors = response.getError();
            if (errors) {
                if (errors[0] && errors[0].message) {
                    alert("Error message: " + 
                                errors[0].message);
                }
            } else {
                alert("Unknown error");
            }
        }
    });
    $A.enqueueAction(action);
},

})

Apex Class:

public with sharing class searchAccountController {

@AuraEnabled
public static List < account > fetchAccount(String searchKeyWord) {
 String searchKey = searchKeyWord + '%';
 List < Account > returnList = new List < Account > ();
  List < Account > lstOfAccount = [select id, Name, Type, Industry, Phone, 
Fax 
from account
                               where Name LIKE: searchKey LIMIT 500];

  for (Account acc: lstOfAccount) {
   returnList.add(acc);
  }
 return returnList;
}

}

  • SOQL is not very pratcical for your use case, you will most likely want to switch to SOSL – glls Mar 19 '19 at 18:58
  • @glls You probably should have posted that as an answer. ☺ – sfdcfox Mar 19 '19 at 19:00
  • thats fine, as long as the OP is served =) – glls Mar 19 '19 at 19:01
2

You'll probably want to use SOSL (Salesforce Object Search Language) instead:

@AuraEnabled
public static Account[] fetchAccount(String searchKeyWord) {
 return [FIND :searchKeyWord IN ALL FIELDS RETURNING Account(Id,Name,Type,Industry,Phone,Fax)][0];
}
| improve this answer | |
0

I have created a Generic lightning Component You can use this component. It's very fast and search for any keyword in any field in the data table.

GenericTable.cmp

<aura:component >
    <!-- Attrubutes Definations Start here -->
    <aura:attribute type="boolean"
                    name="enableSearchonRow"
                    description="This attribute is used to show hide search option in tabel"/>
    <aura:attribute type="Integer"
                    name="maxRowSelection"
                    default="1"
                    description="This attribute is used to define number of row can be selected"/>
    <aura:attribute type="string"
                    name="tableHeaderTitle"
                    default=""
                    description="This attribute is used to define title for table"/>
    <aura:attribute type="List"
                    name="selectedRows"
                    description="This attribute is used to store preselected record Ids"
                    />
    <aura:attribute type="string"
                    name="panelHeightinPx"
                    default="170px"
                    description="This attribute is used to define container Height"
                    />
    <aura:attribute type="string"
                    name="headerIcon"
                    default="standard:empty"
                    description="This attribute is used to define icon in Header"
                    />
    <aura:attribute type="boolean"
                    name="showRowNumber"
                    default="false"
                    description="This attribute is used to show hide row number"
                    />
    <aura:attribute type="boolean"
                    name="showHeaderButton"
                    default="false"
                    description="This attribute is used to show hide button in Header"
                    />
    <aura:attribute type="string"
                    name="buttonLabel"
                    default="New"
                    description="This attribute is used to show label on Button"
                    />
    <aura:attribute type="string"
                    name="searchString"
                    default="false"
                    description="This attribute store search fields for row filter. Fields must be comma saperated."
                    />
    <aura:attribute name="recordSearchKey" 
                    type="string" 
                    default=""
                    description="this attribute store search string for row in table"
                    access="Private"/>
    <aura:attribute name="unFilteredData"
                    type="List"
                    description="this attribute store all data for table without filter"
                    access="Private"
                    /> 
    <aura:attribute name="lstDataRows"
                    type="List"
                    Description="attribute store Data Rows list of sobject"/>
    <aura:attribute name="lstColumns"
                    type="List"
                    Description="store Header columns property list"/> 
    <aura:attribute name="defaultSelectedRow"
                    type="string"
                    Description="store default selected row id in table"/> 
    <aura:attribute name="showSpinner"
                    type="Boolean" 
                    default ="false" 
                    access="private"/>
    <aura:attribute name="sortDirection"
                    type="String"
                    default="desc" />
    <aura:attribute name="sortedBy"
                    type="String" />
    <!-- Attrubutes Definations ends here -->
    <!-- Aura Handeler Section -->
    <aura:handler name="init" value="{!this}" action="{!c.doinit}"/>
    <aura:method name="setPredefinedValues" action="{!c.setPredefinedValues}" access="public"/>
    <!--<aura:handler name="change" value="{!v.lstDataRows}" action="{!c.setPredefinedValues}"/>-->
    <!-- Aura Handeler Section Ends here -->
    <!-- Events Regstration Sections Defiend here -->
    <aura:registerEvent name="onclickActionEvent" type="c:CmAp_LightningDataTableActionEvent"/>
    <aura:registerEvent name="onRowChangeEvent" type="c:CmAp_LightningDataTableSelectionEvent"/>
    <aura:registerEvent name="onClickRowActionEvent" type="c:CmAp_LightningDataTableRowActionEvent"/>
    <!-- Events Regstration Sections Ends here -->
    <lightning:card title="{!v.tableHeaderTitle+' ('+if(not(empty(v.lstDataRows)),v.lstDataRows.length,0)+')'}" iconName="{!v.headerIcon}" variant="base">
        <aura:set attribute="actions">
            <aura:if isTrue="{!v.enableSearchonRow}">
                <lightning:input type="search" variant=" label-hidden" class="slds-m-left_small slds-m-right_small" placeholder="{!'Search '+v.tableHeaderTitle}" value="{!v.recordSearchKey}" onchange="{!c.searchInRows}" />
            </aura:if>
            <aura:if isTrue="{!v.showHeaderButton}">
                <lightning:button class="slds-theme_neutral" variant="brand" label="{!v.buttonLabel}" onclick="{!c.handelBttonClickAction}"></lightning:button>
            </aura:if>
        </aura:set>
        <aura:set attribute="footer">&nbsp;</aura:set>
        <div style="{!if(not(empty(v.lstDataRows)),'','display:none')}">
            <div style="{!if((v.lstDataRows.length> $Label.c.CmAp_AutoHeightMaxRowLimit),'height:'+v.panelHeightinPx,'')}">
                <!-- Spinner Section -->
                <aura:if isTrue="{!v.showSpinner}">
                    <div class="slds-is-relative">
                        <lightning:spinner variant="brand" alternativeText="Loading..." />
                    </div>
                </aura:if>
                <!-- Spinner Ends Here -->
                <lightning:datatable aura:id="recordTabel"
                                     columns="{!v.lstColumns}"
                                     data="{!v.lstDataRows}"
                                     keyField="Id"
                                     selectedRows="{!v.selectedRows}"
                                     maxRowSelection="{! v.maxRowSelection }"
                                     onrowselection="{!c.updateSelectedText}"
                                     showRowNumberColumn="{!v.showRowNumber}"
                                     sortedDirection="{!v.sortDirection}"
                                     sortedBy="{!v.sortedBy}"
                                     onsort="{!c.handleSort}"
                                     wrapTextMaxLines="2"
                                     hideCheckboxColumn="{!if(v.maxRowSelection>0,false,true)}"
                                     onrowaction="{!c.rowOnClickActions}"
                                     />
            </div>
        </div>

        <div class="slds-box slds-theme_default slds-align_absolute-center" style="{!if(not(empty(v.lstDataRows)),'display:none','')}">
            <p><b>No data to display.</b></p>
        </div>

    </lightning:card>
</aura:component>

GenericTableCOntroller.Js

({
    doinit: function(component, event, helper){
        component.set("v.showSpinner",true);

    },
    setPredefinedValues : function(component, event, helper) {
        helper.setPredefinedValues(component, event, helper);
    },
    updateSelectedText: function (component, event, helper) {
        helper.handleSelect(component, event, helper);
    },
    searchInRows: function (component, event, helper) {
        helper.searchInRows(component, event, helper);
    },
    handleSort: function(component, event, helper) {
        helper.handleSort(component, event);
    } ,
    handelBttonClickAction: function (component, event, helper) {
        helper.handelBttonClickAction(component, event, helper)
    },
    rowOnClickActions: function (component, event, helper) {
        helper.rowOnClickActions(component, event, helper)
    }
})

GenericTableHelper.js

({
    setPredefinedValues : function(component, helper) {
        let lstData =component.get("v.lstDataRows");
        let lstUnFilteredData = component.get("v.unFilteredData");
       // if($A.util.isUndefined(lstUnFilteredData) || $A.util.isEmpty(lstUnFilteredData)){
            component.set("v.unFilteredData",lstData);
        //}
        this.handelDefaultRowSelection(component, helper);
        component.set("v.showSpinner",false);
    },
    handelDefaultRowSelection: function(component, helper){
        let defaultSelectedRow = component.get("v.defaultSelectedRow");
        if(!$A.util.isUndefined(defaultSelectedRow) && !$A.util.isEmpty(defaultSelectedRow)){
            let temp =[];
            temp.push(defaultSelectedRow);
            let recordTabel = component.find("recordTabel");
            if(recordTabel){
                recordTabel.set("v.selectedRows", temp);            
            }
        }
    },
    searchInRows: function (component, event, helper) {
        let data = component.get("v.lstDataRows"); 
        let allData = component.get("v.unFilteredData"); 
        let strfieldlist = component.get('v.searchString');
        if(!$A.util.isUndefined(strfieldlist) && !$A.util.isEmpty(strfieldlist)){
            let fieldlList = strfieldlist.split(',');
            let searchKey = component.get("v.recordSearchKey");
            if(!$A.util.isUndefined(data) || !$A.util.isEmpty(data)){  
                let filtereddata = allData.filter(checkFieldsValidity);  
                function checkFieldsValidity(word){
                    let isValid=false;
                    for(let fieldname of fieldlList) {
                        if(word.hasOwnProperty(fieldname) && 
                           (!searchKey || word[fieldname].toLowerCase().indexOf(searchKey.toLowerCase()) > -1)){
                            isValid= true;
                            break;
                        }
                    }
                    return isValid;
                }
               component.set("v.lstDataRows", filtereddata); 
                this.handelDefaultRowSelection(component, helper);
            } 
            if(searchKey==''){  
                component.set("v.lstDataRows",component.get("v.unFilteredData"));  
            }
        }

    },
    sortBy: function(field, reverse, primer) {
        var key = primer
        ? function(x) {
            return primer(x[field]);
        }
        : function(x) {
            return x[field];
        };

        return function(a, b) {
            a = key(a);
            b = key(b);
            return reverse * ((a > b) - (b > a));
        };
    },
    handleSort: function(component, event) {debugger;
        var sortedBy = event.getParam('fieldName');
        var sortDirection = event.getParam('sortDirection');
        let data = component.get('v.lstDataRows');
        var cloneData = data.slice(0);
        cloneData.sort((this.sortBy(sortedBy, sortDirection === 'asc' ? 1 : -1)));        
        component.set('v.lstDataRows', cloneData);
        component.set('v.sortDirection', sortDirection);
        component.set('v.sortedBy', sortedBy);
    },
    handelBttonClickAction: function(component, event, helper){
        let compEvent = component.getEvent("onclickActionEvent");
        let tableUniqueName = component.get("v.tableDataType"); 
        compEvent.setParams({"tableUniqueName" : tableUniqueName });
        compEvent.fire();
    },
    handleSelect: function(component, event, helper){
        let compEvent = component.getEvent("onRowChangeEvent");
        let tableUniqueName = component.get("v.tableHeaderTitle"); 
        let selectedRows = event.getParam('selectedRows');
        compEvent.setParams({"tableUniqueName" : tableUniqueName,
                             "selectedRows":selectedRows});
        compEvent.fire();
    },
     rowOnClickActions: function (component, event, helper) {debugger;
        let compEvent = component.getEvent("onClickRowActionEvent");
        let tableUniqueName = component.get("v.tableHeaderTitle"); 
        let objRecord = event.getParam('row');
        let actionName = event.getParam('action').name;
        compEvent.setParams({"tableUniqueName" : tableUniqueName,
                             "selectedRowActionName":actionName,
                             "selectedRowData":objRecord});
        compEvent.fire();
    }
})

Ho to Use

<c:CmAp_LightningDataTable aura:id="genericTable"
                               tableHeaderTitle ="{!$Label.c.CmAp_DevicesHeader}"
                               panelHeightinPx="350px"
                               headerIcon="standard:planogram"
                               maxRowSelection="1"
                               showRowNumber="{!v.objWrapDevice.showRowNumber}"
                               showHeaderButton="false"
                               enableSearchonRow="{!v.objWrapDevice.enableSearchonRow}"
                               searchString="{!$Label.c.CmAp_DeviceSearchString}"
                               lstDataRows="{!v.objWrapDevice.dataForTable}"
                               lstColumns ="{!v.objWrapDevice.columnForTable}"
                               defaultSelectedRow="{!v.SelectedDeviceId}"/>

Here you can see UI:

https://drive.google.com/file/d/13o9JLaz_UafbDWnnhhzo1m1oCMSgXwrR/view

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.