[SalesForce] jQuery not reloading properly after switching to new tab in Lightning Component

I have used jQuery to detect changes in a textbox in a lightning component.I am able to detect the change first time it loads the library.But when I switch to a different tab and comes back in, it doesn't detect the change.Could anyone please advise why it is happening like that

        <!--Component-->
<aura:component>        
    <ltng:require scripts="/resource/jQuery/jquery-1.11.3.min.js" afterScriptsLoaded="{!c.setListener}"/>           
    <input type="text" style="width:90%"  placeholder="Username" id="searchBox"/>   
</aura:component>

    <!--Client Side Controller-->
({
    setListener: function(component, event, helper) {
        console.log('before');
        $("#searchBox").keyup(function (e) {
            console.log('Key is pressed');
        });
    }
})

Best Answer

It's a timing issue where the first call to setListener happens to run late enough (after your component has rendered to the dom) - the first time only - the second (nth really) time ltng:require has already loaded jquery (remember you are running in a single page app architecture) and your afterScriptsLoaded action fires immediately but before #searchbox exists in the dom.

I've run into this myself (I'm also the author of ltng:require) and am looking at changing ltng:require to have it insure the same lifecycle timing so this will not happen.

With that said using jquery for this is overkill. Also the use of dom ID based locators is not only not required it's going to break when you have more than one instance of your component anywhere in the dom. You can easily let lightning wire up the event handler and it will take care of all of the lifecycle stuff automatically and not have the dom ID collision issue either.

<input type="text" style="width:90%" placeholder="Username" onkeyup="{!c.onkeyup}"/> 

and in your controller.js:

({
    onkeyup: function(component, event, helper) {
        console.log('Key is pressed');
    }
})

You can even do better than this by using the higher level ui:inputText component and get free placeholder and bidirectional data binding support for free:

https://developer.salesforce.com/docs/atlas.en-us.lightning.meta/lightning/ui_input.htm

<ui:inputText placeholder="Username" updateOn="keyup" keyup="{!c.onkeyup}" aura:id="search"/>   

onkeyup: function(component, event, helper) {
    console.log("Key is pressed: " + component.find("search").get("v.value"));
}
Related Topic