javascriptjqueryasp.netwebforms

EventListener not being removed


I've got some Javascript that works fine on the first load, but isn't working on Postback. After doing some reading, it seems like I need to remove the EventListeners and rebind them. So I've got the following code. On first load, the alerts triggered are:

I type in my textbox and the counters count down as expected. I click a button which triggers a postback. After that, my alerts are:

And the counters stop functioning completely. This is not inside an Update Panel. My assumption is that I remove the EventListeners and then add them back by running the PageLoadStuff function again, but I'm not even sure if that's right.

EDIT: In the "isPostback" block of code, if I comment out everything but PageLoadStuff(), the "PageLoadStuff Complete" alert never appears, so I'm assuming it's dying on the addEventListener.

Here's my script:

<script type="text/javascript">

    function PageLoadStuff() {
        alert("PageLoadStuff Start");
        const textArea2 = document.getElementById('TextBox_Follow_Up_Answer2');
        const label1 = document.getElementById('Label_Answer_Char_Count');
        const label2 = document.getElementById('Label_Answer_Char_Count2');
        const labelRemaining1 = document.getElementById('Label_Answer_Char_Remaining');
        const labelRemaining2 = document.getElementById('Label_Answer_Char_Remaining2');
        alert("PageLoadStuff Vars");

        // Add input event listener for text area
        textArea2.addEventListener('input', IncrementCounters);

        function IncrementCounters() {
            textCounter(textArea2, 3000, label1, labelRemaining1);
            textCounter2(textArea2, 865, label2, labelRemaining2);
            //        alert("Event Listener - DOMContentLoaded");
        }
        alert("PageLoadStuff Complete");
    }

    var isPostBack = '<%= this.IsPostBack%>' == 'True';
    if (isPostBack) {
        alert("It's a PostBack!");
        const textArea2 = document.getElementById('TextBox_Follow_Up_Answer2');
        alert(textArea2);
        document.removeEventListener('DOMContentLoaded', PageLoadStuff);
        textArea2.removeEventListener('input', IncrementCounters);
        alert("EventListeners Removed");
        PageLoadStuff();

    }

    if (document.readyState == 'loading') {
        // still loading, wait for the event
        document.addEventListener('DOMContentLoaded', PageLoadStuff);
    } else {
        PageLoadStuff();
    }

    Sys.Application.add_load(function () {
        alert("Add_Load");
        PageLoadStuff();
    });

    function textCounter(field, maxlimit, label, label2) {
        if (field.value.length > maxlimit)
            field.value = field.value.substring(0, maxlimit);
        else {

            label.innerHTML = maxlimit - field.value.length;
        }
        if (field.value.length > maxlimit - 500) {
            label.style.color = "#FF0000";
            label2.style.color = "#FF0000";
        }
        else {
            label.style.color = "#000000";
            label2.style.color = "#000000";
        }
    //    alert("textCounter Fired");
    }

    function textCounter2(field, maxlimit, label, label2) {
        if (field.value.length > maxlimit)
        field.value = field.value;
        else {

            label.innerHTML = maxlimit - field.value.length;
        }
        if (field.value.length > maxlimit - 200) {
            label.style.color = "#FF0000";
            label2.style.color = "#FF0000";
        }
        else {
            label.style.color = "#000000";
            label2.style.color = "#000000";
        }
    //    alert("textCounter2 Fired");
    }

</script>

<body>
  <table>
     <tr>
        <td></td>
        <td>
           <textarea id="TextBox_Follow_Up_Answer2" style="width: 600px; height: 120px;" maxlength="3000" runat="server"></textarea>
           <br />
           <span id="Label_Answer_Char_Count">3000</span>
           <span id="Label_Answer_Char_Remaining">characters remaining</span> :
           <span id="Label_Answer_Char_Count2">865</span>
           <span id="Label_Answer_Char_Remaining2">characters remaining for email</span>
           <br />
         </td>
     </tr>
     <tr style="background-color: lightgray; color: black; border-spacing: 0; padding: 0; border-collapse: collapse;">
        <td>
           <asp:Label ID="Label44" runat="server" Text="Article Number:"></asp:Label>
        </td>
        <td>
           <asp:TextBox ID="TextBox_Answer_Article_Number" runat="server" Width="300px" MaxLength="100"></asp:TextBox>
        </td>
     </tr>
     <tr>
        <td>
           <asp:Label ID="Label45" runat="server" Text="Section Number:"></asp:Label>
        </td>
        <td>
           <asp:TextBox ID="TextBox_Answer_Section_Number" runat="server" MaxLength="50" Width="300px"></asp:TextBox>
        </td>
     </tr>
     <tr style="background-color: lightgray; color: black; border-spacing: 0; padding: 0; border-collapse: collapse;">
        <td>
           <asp:Label ID="Label46" runat="server" Text="Actual Response Method:"></asp:Label>
           <asp:Label ID="Label65" runat="server" Text="*" ForeColor="Red" Font-Size="Large"></asp:Label>
        </td>
        <td>
           <asp:Button ID="Button_Create_Email" runat="server" Text="Create Email" CssClass="action_button" Height="22px" Width="200px" OnClick="Button_Create_Email_Click" />
        </td>
     </tr>
  </table
</body>

And the code-behind for the button:

protected void Button_Create_Email_Click(object sender, EventArgs e)
{
    string question;
    string article;
    string section;

    string answer = WebUtility.HtmlDecode(TextBox_Follow_Up_Answer2.Value);
    string answer_article = TextBox_Answer_Article_Number.Text;
    string answer_section = TextBox_Answer_Section_Number.Text;

    Page.ClientScript.RegisterStartupScript(this.GetType(), "email", "parent.location='mailto:Nobody@Noone.com?Subject=Coach Response for Answer

        "%0D%0A %0D%0AAnswer:  " + answer +
        "%0D%0AAnswer Article:  " + answer_article +
        "%0D%0AAnswer Section:  " + answer_section +

        "%0D%0A %0D%0AREMINDER: If this answers your question, please accept the answer in the Question Response Page." +

        "'", true);

}

Solution

  • Your

    const textArea2 = document.getElementById('TextBox_Follow_Up_Answer2');
    

    will only be executed if it's a postback and it's outside of any functions, before the HTML below is loaded and therefore at this point the element for which you are searching for by id does not exist yet. You will need to move your postback code into another <script> tag at the very end of your file, just before you close the </body>.