Alex
Alex

Reputation: 53

jquery change() not working within hidden div

I've been wondering and can't find a solution why the operation $("#locationid3").change (line 85) is not working even though it's the same as $("#locationid").change and $("#locationid2").change (the lines above it). The main difference is : - #locationid and #locationid2 is placed directly within the html-form and is always visible - #locationid3 is placed in a hidden div outside the html-form and will only be shown if "prod2" in product-dropdown is selected

the reason for creating a hidden div outside the form is so the fieldsets inside the form can be reloaded by changing the product-dropdown. By changing the product, all fieldset will be hidden with method "hideFieldsets()" and the corresponding fieldset (using account, product, data-id and data-position) will be shown with method "showFieldset()".

I've put the code in jsfiddle

$(document).ready(function(){
      $("#accountid").change(function() {
            var $dropdown = $(this);
            var accounts = {
               "id_1":{"products":[{"id":"1","val":"prod1"},{"id":"2","val":"prod2"}],"locations":[{"id":"4","val":"loc1"},{"id":"1","val":"loc2"}],}

               };


            var key = $dropdown.val();
            var products = {};
            var locations = {};
            var locations2 = {};
            var locations3 = {};
            switch(key) {
                case 'id_1' :products = accounts.id_1.products;locations = accounts.id_1.locations;locations2 = locations;locations3 = locations;break;


            }


            var $productid = $("#productid");
            $productid.empty();
            $.each(products, function(index, value) {
            var option = $('<option></option>').val(value.id).text(value.val);
            $productid.append(option);

            });

            $('#productid').val();
            $productid.trigger("change");

            var $locationid = $("#locationid");
            $locationid.empty();
            $.each(locations, function(index, value) {
            var option = $('<option></option>').val(value.id).text(value.val);
            $locationid.append(option);

            });


            var $locationid2 = $("#locationid2");
            $locationid2.empty();
            $.each(locations2, function(index, value) {
            var option = $('<option></option>').val(value.id).text(value.val);
            $locationid2.append(option);

            });


            var $locationid3 = $("#locationid3");
            $locationid3.empty();
            $.each(locations3, function(index, value) {
            var option = $('<option></option>').val(value.id).text(value.val);
            $locationid3.append(option);

            });


        });



    $("#productid").change(function() {
        var possibleFieldsets = {

        "id_1_1" : ["id_1_1__ test ","id_1_1__ test2 "],
        "id_1_2" : ["id_1_2__ test ","id_1_2__ test2 "],
        };

        hideFieldsets();
        var selectedAccProd = $("#accountid option:selected").val()+"_"+$("#productid option:selected").val();
        showFieldsets(possibleFieldsets[selectedAccProd]);

    });

        $("#locationid").change(function() {
            readLocationData(this.value);
        });

        $("#locationid2").change(function() {
            readLocationData(this.value);
        });

        $("#locationid3").change(function() {
            readLocationData(this.value);
        });

        var allFieldset = {};
        $('#allFieldsets').children().each(function(index,fieldsetElement){
            var $fieldsetElement = $(fieldsetElement);
            allFieldset[$fieldsetElement.attr("data-id")] = $fieldsetElement;
        });
        $('#allFieldsets').remove();


        function hideFieldsets(){

            for(var key in allFieldset){
                var $div = $('fieldset[data-id="'+key+'"]').parent();
                if($div.children().length > 0){
                    allFieldset[key] = $div.children();
                    $div.empty();
                }
                $div.hide();
            }
        }

        function showFieldsets(fieldsetArray){
            $.each(fieldsetArray, function(index, element){
                var $div = $('div[data-position="'+element.split('__')[1]+'"]');
                $div.append(allFieldset[element]);
                $div.show();

            });

        } 
         function readOrderData(orderId){
            window.alert("reading data");
        }



        function readLocationData(locationId){
            window.alert("location changed");
        }

        $("#accountid").trigger("change");
      });

      $isUnread = false;

I would really appreciate any lead / advice on how to make #locationsid3 change() works. Thanx!

Upvotes: 4

Views: 1512

Answers (3)

Sandeep Nayak
Sandeep Nayak

Reputation: 4757

You should delegate the change event to the parent element. This is needed since when the event is bound on document.ready, dropdown 3 would be hidden in DOM and is shown only later.

$(document).ready(function() {
  $("#accountid").change(function() {
    var $dropdown = $(this);
    var accounts = {
      "id_1": {
        "products": [{
          "id": "1",
          "val": "prod1"
        }, {
          "id": "2",
          "val": "prod2"
        }],
        "locations": [{
          "id": "4",
          "val": "loc1"
        }, {
          "id": "1",
          "val": "loc2"
        }],
      }

    };


    var key = $dropdown.val();
    var products = {};
    var locations = {};
    var locations2 = {};
    var locations3 = {};
    switch (key) {
      case 'id_1':
        products = accounts.id_1.products;
        locations = accounts.id_1.locations;
        locations2 = locations;
        locations3 = locations;
        break;


    }


    var $productid = $("#productid");
    $productid.empty();
    $.each(products, function(index, value) {
      var option = $('<option></option>').val(value.id).text(value.val);
      $productid.append(option);

    });

    $('#productid').val();
    $productid.trigger("change");

    var $locationid = $("#locationid");
    $locationid.empty();
    $.each(locations, function(index, value) {
      var option = $('<option></option>').val(value.id).text(value.val);
      $locationid.append(option);

    });


    var $locationid2 = $("#locationid2");
    $locationid2.empty();
    $.each(locations2, function(index, value) {
      var option = $('<option></option>').val(value.id).text(value.val);
      $locationid2.append(option);

    });


    var $locationid3 = $("#locationid3");
    $locationid3.empty();
    $.each(locations3, function(index, value) {
      var option = $('<option></option>').val(value.id).text(value.val);
      $locationid3.append(option);

    });


  });



  $("#productid").change(function() {
    var possibleFieldsets = {

      "id_1_1": ["id_1_1__ test ", "id_1_1__ test2 "],
      "id_1_2": ["id_1_2__ test ", "id_1_2__ test2 "],
    };

    hideFieldsets();
    var selectedAccProd = $("#accountid option:selected").val() + "_" + $("#productid option:selected").val();
    showFieldsets(possibleFieldsets[selectedAccProd]);

  });

  $("#locationid").change(function() {

    readLocationData(this.value);
  });

  $("#locationid2").change(function() {

    readLocationData(this.value);
  });

  $(document).on("change", "#locationid3", function() {
    console.log("here");
    readLocationData(this.value);
  });

  var allFieldset = {};
  $('#allFieldsets').children().each(function(index, fieldsetElement) {
    var $fieldsetElement = $(fieldsetElement);
    allFieldset[$fieldsetElement.attr("data-id")] = $fieldsetElement;
  });
  $('#allFieldsets').remove();


  function hideFieldsets() {

    for (var key in allFieldset) {
      var $div = $('fieldset[data-id="' + key + '"]').parent();
      if ($div.children().length > 0) {
        allFieldset[key] = $div.children();
        $div.empty();
      }
      $div.hide();
    }
  }

  function showFieldsets(fieldsetArray) {
    $.each(fieldsetArray, function(index, element) {
      var $div = $('div[data-position="' + element.split('__')[1] + '"]');
      $div.append(allFieldset[element]);
      $div.show();

    });

  }

  function readOrderData(orderId) {
    window.alert("reading data");
  }



  function readLocationData(locationId) {
    window.alert("location changed");
  }

  $("#accountid").trigger("change");
});

$isUnread = false;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form action="" id="orderForm" method="POST" enctype="multipart/form-data">
  <fieldset data-id="admin">
    <legend>Admin</legend>
    <table>
      <tr>
        <td>
          <label for="accountid">Kunde:</label>
        </td>
        <td>
          <select id="accountid" name="accountid">
            <option value="id_1">acc1</option>
        </td>
        <td></td>
        <td></td>
        <td>
          <label for="productid">Produkt:</label>
        </td>
        <td>
          <select id="productid" name="productid">
            <option value="1">prod1</option>
            <option value="2">prod2</option>
          </select>
        </td>

      </tr>
      <tr>
        <td>
          <label for="locationid">Standort:</label>
        </td>
        <td>
          <select id="locationid" name="locationid">
            <option value="4">loc1</option>
            <option value="1">loc2</option>
          </select>
        </td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>

      </tr>
      <tr>
        <td>
          <label for="locationid2">Standort2:</label>
        </td>
        <td>
          <select id="locationid2" name="locationid2">
            <option value="4">loc1</option>
            <option value="1">loc2</option>
          </select>
        </td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>

      </tr>
    </table>
  </fieldset>
  <div data-position=" test "></div>
  <div data-position=" test2 "></div>


  <hr>
</form>
<div style="display:none; width:0px; height:0px; position:absolute; top:-1px; left:-1px" id="allFieldsets">
  <fieldset data-id="id_1_1__ test " data-position=" test ">
    <legend>test</legend>
    <div>
      <table>
        <tr>
          <td>
            <label for="registrationnumber">test111</label>
          </td>

        </tr>

      </table>
    </div>
  </fieldset>
  <fieldset data-id="id_1_1__ test2 " data-position=" test2 ">
    <legend>test2</legend>
    <div>
      <table>
        <tr>
          <td>
            <label for="appointmentdate">test112</label>
          </td>

        </tr>

      </table>
    </div>
  </fieldset>
  <fieldset data-id="id_1_2__ test " data-position=" test ">
    <legend>test</legend>
    <div>
      <table>
        <tr>
          <td>
            <label for="registrationnumber">test121</label>
          </td>

        </tr>

      </table>
    </div>
  </fieldset>
  <fieldset data-id="id_1_2__ test2 " data-position=" test2 ">
    <legend>test2</legend>
    <div>
      <table>
        <tr>
          <td>
            <label for="appointmentdate">test122</label>
          </td>

        </tr>
        <tr>
          <td>
            <label for="locationid3">Standort3:</label>
          </td>
          <td>
            <select id="locationid3" name="locationid3">
              <option value="4">loc1</option>
              <option value="1">loc2</option>
            </select>
          </td>
          <td></td>
          <td></td>
          <td></td>
          <td></td>

        </tr>
      </table>
    </div>
  </fieldset>

</div>

Upvotes: 0

Randhir Singh
Randhir Singh

Reputation: 245

You are not simply doing show/hide on the #location3 select box. You are removing the html from the page and appending it again when prod2 is selected. You need to use .on method of jquery. Because it will fire the events bind with html loaded after dom creation.

$('body').on('change','#locationid3',function(){
   readLocationData(this.value);
});

Check this demo: Demo

Upvotes: 3

Daniel Cheung
Daniel Cheung

Reputation: 4819

Because your #locationid3 is dynamically changed, the normal selection won't work. You need to use the following format:

$("#parent-element").on("change", "#find-this-element", function(){})

The #parent-element has to be static, so if you only has a static body, you can do $("body").on("change", "#find-this-element", function(){}). However, you should use the closest static element to improve performance.

Upvotes: 1

Related Questions