1

I have a <lightning:input> which I send to the server the value inside it when it changes to search and return the closest results.

I tried to do the following :

CMP - look at the lightning:input search

<lightning:layoutItem  padding="around-small">
                    <lightning:card variant="Narrow" class="slds-card_boundary" >
                    <aura:set attribute="title">
                    <lightning:icon iconName="action:filter" size="small"/>
                    Circles
                    </aura:set>

                    <aura:set attribute="footer">
                            <aura:iteration items="{!v.circleListAdded}" var="cla">
                                    <tr>
                                    <td>
                                            <output class="slds-text-heading_small slds-truncate" value="{!cla.value}"></output>  
                                    </td>

                                    <td>
                                            <button name="circle" style="background-color: transparent; border: none;" class="slds-button slds-button_neutral" onclick="{!c.removeElementHandler}" id="{!cla.key}"><lightning:icon style="padding: 0.01px;" class="my-icon-style" iconName="action:close" size="xx-small" /></button>
                                    </td>


                                    </tr>
                            </aura:iteration>    
                    </aura:set>

                    <lightning:input aura:id="circleSearchId" type="String" name="circle" onchange="{!c.handleSearchEvent}" />

                    <table class="slds-table slds-table_cell-buffer slds-table_bordered slds-table_striped" role="grid">
                            <aura:iteration items="{!v.circleListSearch}" var="cla">

                            <tr>


                                    <a id="{!cla.key}" name="circle" onclick="{!c.handleAddingClickEvent}"  style="padding: 4px;" class="slds-text-heading_small slds-truncate" > {!cla.value} </a>
                            </tr>
                    </aura:iteration>

                    </table>


            </lightning:card>
            </lightning:layoutItem>

Controller look at the bottom of the function (setTimeout)

handleSearchEvent : function(component,event,helper){
        let controllerMethod;
        let mapName;
        let listForSearchDisplay;
        let timeId;

    switch(event.getSource().get("v.name")){
        case "fac":
            mapName= "v.FacMaps";
            listForSearchDisplay="v.FacList";
            controllerMethod = "c.getFac";
            break;
        case "city":
            mapName= "v.cityMaps";
            listForSearchDisplay="v.cityListSearch";
            controllerMethod = "c.getCities";
            break;

        case "country":
            mapName= "v.CountryMaps";
            listForSearchDisplay="v.customers";
            controllerMethod= "c.countryListToAdd";
            break;


        case "circle":
            mapName= "v.circleMaps";
            listForSearchDisplay="v.circleListSearch";
            controllerMethod= "c.getCircles";
            break;
        default:
            console.log("default");

    }

    console.log('TimeId',timeId);
    if(timeId){
        clearTimeout(timeId);
    }
    timeId = setTimeout( helper.handleSearchEventClicking(component,mapName,listForSearchDisplay,controllerMethod,event.getSource().getLocalId(),timeId),500);


}

Helper

handleSearchEventClicking: function(component,mapName,listForDisplay,controllerMethod,rId,timeId){
    timeId=null;
     var action = component.get(controllerMethod);
    action.setParams({
         inputText : component.find(rId).get("v.value")
    });        


    action.setCallback(this,function(result){
        var state = result.getState();
        console.log("state",state);
        if(component.isValid() && state === "SUCCESS"){
            var resultArray = result.getReturnValue();
            component.set(mapName,resultArray);
            var generalArray = [];
            for(var key in resultArray){
                generalArray.push({value:resultArray[key], key:key})
            }


            component.set(listForDisplay, generalArray);

        }else if(state =="ERROR"){
            console.log("Error",result.getError());
        }
    });
    $A.enqueueAction(action);
}

The error I get from running this code and start to type in the lightning:input is :

Uncaught Action failed: c:SortingListsComponent$controller$handleSearchEvent [Bind must be called on a function]

But I don't sure that this is the right way...

I read about the

$A.getCallback

But I don't sure this is the solution and how to use it in this case...

any help will be much appreciate.

Thanks!

2
  • What happens with the current code? Please edit the question to add this detail.
    – Phil W
    Commented Nov 11, 2019 at 7:02
  • Just did @PhilW. Thanks
    – Salvation
    Commented Nov 11, 2019 at 7:07

2 Answers 2

0

If you look at the timer event handler, it is using "this". I assume you want this to reference the helper. In which case you need to change how you set the timer:

timeId = setTimeout(helper.handleSearchEventClicking(
             component,
             mapName,
             listForSearchDisplay,
             controllerMethod,
             event.getSource().getLocalId(),
             timeId).bind(helper),
         500);

Note the addition of the bind which ensures that the runtime calls the helper method with the helper as the "this", otherwise the "this" is not going to work.

1
  • Thanks ! let me test it :)
    – Salvation
    Commented Nov 12, 2019 at 10:10
0

You can create an attribute to store the latest search id with name searchId. Then you can use separate methods for keyup and keydown to search and then remove the previous search id.

CMP:

<aura:attribute name="searchId" type="Object" />

<span onkeyup="{!c.handleSearchEvent}" onkeydown="{!c.handleClearSearchEvent}">
    <lightning:input aura:id="circleSearchId"
                     type="String"
                     name="circle" />
</span>

JS:

handleSearchEvent: function (component, event, helper) {
    let searchId = setTimeout($A.getCallback(
        helper.handleSearchEventClicking.bind(helper, component, event, helper)
    ), 500);
    component.set("v.searchId", searchId);
},
handleClearSearchEvent: function (component) {
    clearTimeout(component.get("v.searchId"));
    component.set("v.searchId", null);
}
1
  • Thanks ! let me test it :)
    – Salvation
    Commented Nov 12, 2019 at 10:10

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .