Search code examples
javascriptflaskjquery-eventshtml-input

Why is my jQuery event listener not running upon app startup?


I'm working on making a script that detects if a checkbox with id "chapterex" is checked, and updates the page accordingly if it is: if it is not checked, add the multiple attribute to the file upload. Otherwise, do NOT include the multiple attribute. The script runs, but seemingly does not perform its intended action.

=====js file=====

function check() {
  let checked = $("#chapterex").is(':checked');
  console.log("checked", checked);
  let inner_html = "<span><strong>Step 2:</strong></span>" +
  "<label for='myfile'>Select a file</label>" +
  "<input type='file' id='letter' name='letter'>" +
  "</div>";
  let inner_html_multiple = "<span><strong>Step 2:</strong></span>" +
  "<label for='myfile'>Select a file</label>" +
  "<input type='file' 'id='letter' name='letter' multiple>" +
  "</div>";
  if (checked) {
    console.log("checked in if");
    $('#file_field').replaceWith(inner_html);
  } else {
    console.log("not checked, in else");
    $('#file_field').replaceWith(inner_html_multiple);
  }
}
check();
console.log("hi successfully attached");
$('#chapterex').on('change', check);

=======html file=====

<div class="form-group col-sm-12" style="padding-left:0px">
            <span><strong>Step 1:</strong></span>
            <label for="chapter">Text</label>
            <span><input type="checkbox" id="chapterex" name="chapterex"><span>&nbsp;Yes</span></span>
          </div>
          <div class="form-group col-sm-12" style="padding-left:0px" id="file_field">
            <!-- <span><strong>Step 2:</strong></span>
            <label for="myfile">Select a file</label>
            <input type="file" id="letter" name="letter"> -->
          </div>
          <div class="form-group col-sm-12" style="padding-left:0px">
            <span><strong>Step 3:</strong></span>

console info:

-checked false
-not checked, in else
-hi successfully attached

When I add the event listener in console, it works. Based on the console output it is running everything, but seemingly not attaching the HTML. I'm not sure if this matters, but I am using Python's Flask library and this is a script hosted in a different directory. It's obviously running though, so I doubt that's the source of any issue.

Another problem I'm having is that even when it attaches correctly, it seems I'm unable to attach multiple files. I would appreciate any help!


Solution

  • The issue in your code is, that you're removing #file_field element when you're calling check for the first time. Then, when change event calls check, the element is not found, and seemingly nothing happens.

    It's notable, that $('#file_field') returns a jQuery object even when no elements was found, and calling replaceWith of the "empty" jQuery object doesn't trigger any errors.

    Wrap your code into $(document).ready(function () {your code here}); to make sure all the elements exist at the time the code runs, and use .html() instead of .replaceWith().

    function check() {
      let checked = $("#chapterex").is(':checked');
      let inner_html = "<span><strong>Step 2:</strong></span>" +
        "<label for='letter'>Select a file </label>" +
        "<input type='file' id='letter' name='letter'>" +
        "</div>";
      let inner_html_multiple = "<span><strong>Step 2:</strong></span>" +
        "<label for='letter'>Select multiple files </label>" +
        "<input type='file' id='letter' name='letter' multiple>" +
        "</div>";
      if (checked) {
        $('#file_field').html(inner_html);
      } else {
        $('#file_field').html(inner_html_multiple);
      }
    }
    check();
    $('#chapterex').on('change', check);
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <div class="form-group col-sm-12" style="padding-left:0px">
      <span><strong>Step 1:</strong></span>
      <label for="chapter">Text</label>
      <span><input type="checkbox" id="chapterex" name="chapterex"><span>&nbsp;Yes</span></span>
    </div>
    <div class="form-group col-sm-12" style="padding-left:0px" id="file_field"></div>
    <div class="form-group col-sm-12" style="padding-left:0px">
      <span><strong>Step 3:</strong></span>
    </div>

    There was also a typo in inner_html_multiple, id attribute of label tag was preceded by an extra single quote, that caused the dead label.