0

I created a custom lightning component that has a text area(plain HTML and not lightning/UI component for a reason. Refer to comments sections if you need to know why) and a submit button. Ignoring unwanted complexities, the functionality is for the submit button to save the text area content in a backend table on click of the button. The lightning component is on a custom lightning page.

Problem: When the lightning page loads for the first time and the Submit button is clicked with some data in the text area, the javascript controller gets the content of the text area as empty. However, when I refresh the page and enter some data in the text area, the submit button captures the text as expected.

My understanding: I believe the text area is probably not available in the DOM yet during the first load. I found this by placing breakpoint in the JS code using chrome dev tools. On first load the jquery selector on the text area(I have highlighted this line of code with //***) returned empty string though the text area had value. On refreshing the page I got back the value as expected. This is a basic use case and I believe there should be a simpler answer to my problem which I am not able to figure out. Any help is much appreciated!

Here is my code;

Component Code(Removed some irrelevant code here):

<aura:component controller="MeetingNotesApexController" implements="force:appHostable,flexipage:availableForAllPageTypes,force:hasRecordId,force:lightningQuickAction" access="global" >

<ltng:require styles="{!join(',', $Resource.At_Css)}"  
                scripts="{!join(',', $Resource.jquery, $Resource.Caret_Js, $Resource.At_Js)}" afterScriptsLoaded="{!c.doInit}" />

    <aura:attribute name="commentText" type="String" />
    <aura:attribute name="submitBtnLabel" type="String" default="Submit Comment"/>


    <div style="margin-top: 0.25cm; margin-bottom: 0.50cm">
        <textarea id="commentsTextArea" style="margin-bottom: 0.25cm" required = "true" value="{!v.commentText}" class="slds-textarea" rows="4" cols="50" placeholder="Enter your comments" onkeyup = "{!c.displayTypeAheadMenu}"></textarea>
        <lightning:button variant="brand" aura:id="commentEditorSubmitBtn" label="{!v.submitBtnLabel}" title="" onclick="{!c.handleSaveMeetingComment}" />
        <aura:if isTrue="{!v.isUpdate}">
            <lightning:button variant="brand" aura:id="commentEditorCancelBtn" label="Cancel" title="" onclick="{!c.handleCancelEditBtn}" />
        </aura:if>
    </div>

</aura:component>

Controller code(Just the method that handles Save):

({
handleSaveMeetingComment: function(component, event, helper){
    var isUpdate = component.get('v.isUpdate');
    //*********************************************************************
    var textAreaValue = jQuery('#commentsTextArea').val();
    //*********************************************************************
    var meetingCommentListComp = component.find("meetingCommentsComp");
    var meetingProductFamiliesComp = component.find("meetingProductFamiliesComp");
        var meetingRecord = component.get("v.meetingRecord");
        console.log("Meeting Record in Esle = " + meetingRecord);
        var meetingDetailsId = meetingRecord.MeetingDetails__c;
        console.log("Meeting details Id = " + meetingDetailsId);
        component.set("v.simpleNewMeetingComment.Comment_Text__c", textAreaValue);
        component.set("v.simpleNewMeetingComment.Meeting_Id__c", component.get("v.recordId"));
        component.set("v.simpleNewMeetingComment.MeetingDetails__c", meetingDetailsId);

component.find("meetingCommentRecordCreator").saveRecord(function(saveResult){
            if (saveResult.state === "SUCCESS" || saveResult.state === "DRAFT") {
                    // record is saved successfully
                    var resultsToast = $A.get("e.force:showToast");
                    resultsToast.setParams({
                        "title": "Save Complete",
                        "message": "Comment saved!"
                    });
                    resultsToast.fire();
                    //Clear text area contents
                    jQuery('#commentsTextArea').val('')
                    //reloads the view
                    $A.get('e.force:refreshView').fire();
                    //creates new template for LDS component, or it overwrites the previous save.
                    helper.createTemplateForMeetingRecordCreator(component);
                    meetingCommentListComp.doInit();
                    meetingProductFamiliesComp.doInit();
                    console.log('Save successful');

                } else if (saveResult.state === "INCOMPLETE") {
                    // handle the incomplete state
                    console.log("User is offline, device doesn't support drafts.");
                } else if (saveResult.state === "ERROR") {
                    // handle the error state
                    console.log('Problem saving comment, error: ' + JSON.stringify(saveResult));
                } else {
                    console.log('Unknown problem, state: ' + saveResult.state + ', error: ' + JSON.stringify(saveResult.error));
                }
        });
    }
})

If I have missed any information that is needed for figure out the issue, please let me know and I will provide them.

Thanks!

  • Is there any specific reason you're using jQuery` to read textarea` value? Ideally, you should be reading the v.commentText attribute to read the value in controller function and using ui:inputTextArea standard framework Component. – VarunC Dec 8 '17 at 14:14
  • @VarunC, I am having an external JS library that adds events to the text area for auto-complete. If I use ui:inputTextArea I am not able to add these custom events to the text area. This is the custom event; jQuery("#commentsTextArea").atwho({ ..... }); I get an error stating unknown function called "atwho" if I use ui:inputTextArea. This is what I tried; 1.) Get the ui:inputTextArea by aura:id 2.) From the result of above statement I called the .atwho method. If there is something I missed in the ui:inputTextArea approach, please let me know. – GdnMaximus Dec 8 '17 at 15:13
  • @VarunC, If I directly use the v.commentText instead of the jQuery selector, the save might work(haven't tested this), however, the auto-complete on the text area wouldn't which is a requirement for me, unfortunately. P.S. Continuing my prev comment here since there is a word count limit per comment. – GdnMaximus Dec 8 '17 at 15:22
  • There may be some issues with how the autocomplete works. The DOM is not fully built when a component is initialized and may or may not be fully built when your scripts load. Without knowing the details of the third party libraries, it is tough to say for sure that this is causing the problem. However, can you try debugging the value of your textarea (as returned by jQuery) in the afterRender? developer.salesforce.com/docs/atlas.en-us.lightning.meta/… – dsharrison Dec 8 '17 at 16:26
  • Yes using afterRender should be helpful for you in that case. I'm pasting few lines of code so moving that bit of code into an answer below, since can't paste the code properly in comments here. – VarunC Dec 8 '17 at 18:25
0

Using an afterRender along with a custom poll function that will retry calling your code until your JS libraries have been loaded properly. Sometimes 3rd party libraries take some time injecting into framework.

({
    afterRender: function(component, helper) {
        /* globals $ */

        var timesToCheck = 20;
        var poll = function () {
            setTimeout(function () {
                console.log('timesToCheck: '+timesToCheck);
                timesToCheck -= 1;
                if (typeof $ !== 'undefined' && component.isValid()) {
                    //perform your custom intialization code for auto complete textarea hook here

                } else if (timesToCheck > 0) {
                    poll();
                } else {
                    console.log('giving up')
                }
            }, 500);
        };

        poll();

    }
})

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.