简体   繁体   中英

How to interact with an added id after dom loaded

I have a page that will either have a selectbox or a link depending on data from the server side. If the select box is available then I can get the id (in this case town_id) However if there is no select box then I will create one but I set the selects id and name using the value from input classed otf_form_field_id

<div class="otf_form_field">
    <input type="hidden" class="otf_form_field_name" value="town">
    <input type="hidden" class="otf_form_field_id" value="town_id">

    <!-- select will be hidden with templating -->
    <!-- <select class="form-control chosen" name="town_id" id="town_id" data-rule-required="true" data-placeholder="Choose a town">
        <option value=""></option>

        <option value="1">1</option>
        <option value="2">2</option>

        {foreach $towns as $town}
        <option value="{$town.id}" {if $town.id eq $form_data.town_id}selected="selected"{/if}>{$town.town_name}{if $town.region_name}, {$town.region_name}{/if}</option>
        {/foreach}

        <option value="ADD_NEW">Add new town...</option>
    </select> -->

    <p class="mt5">You have no towns configured.</p>
    <p class="mt5"><a href="#modal-1" role="button" class="showhouse-text" data-toggle="modal">Add new town</a></p>

</div>

The code below in the if($('#' + select_id).length === 0){ line checks if there is a select box. If there is none I need to create one. I can create it ok but when I go to select add new from the drop down the modal does not display. I change the select_id to (in this case) town_id with town_id = make_select_id and I thought using the .on event would catch items added after the dom is loaded $('.otf_form_field').on('change', '#'+select_id, function(){

It will display alright if there is a select box populated with options and i have the add new option.

// get the field name, will be set in hidden input
var otf_form_field_name = $('.otf_form_field_name').val();

// get the id of the select box
var select_id = $('.otf_form_field select').prop('id');

// if there is no select box get value to assign it later
if(select_id === undefined){
  var make_select_id = $('.otf_form_field_id').val();
}

// set the option text to show on the chosen search box if there 
// are no results being returned
$("#" + select_id).chosen({no_results_text: '<a href="#modal-1" role="button" class="showhouse-text" data-toggle="modal">Add new ' + otf_form_field_name + '...</a> - No results match', disable_search_threshold: 15});

// hide the modal notificaiton and checking gif
$('#saving_otf_gif, .modal_notification').hide();

// when the chosen (which will use on the fly) is changed
$('.otf_form_field').on('change', '#'+select_id, function(){

   // check if the value is equal to 'ADD_NEW'
  if($(this).val() == "ADD_NEW"){

    // show the modal

  }

});

// when the save button on the modal is clicked
$('#save_otf_btn').click(function(e){

  // if the form is valid
  if($('#validation-form-two').valid()){

    // e.preventDefault() stops the server side redirecting
    e.preventDefault();

    // hide the save button so cannot multiple click
    // show the buffer gif
    $('#save_otf_btn').hide();
    $('#saving_otf_gif').show();

    // check to see if there was an id, if there there were no items available 
    // then there would be no select box and we need none
    if($('#' + select_id).length === 0){

      // build the select box with item_id and item_name
      $('.otf_form_field').html('<select class="form-control chosen" name="' + make_select_id + '" id="' + make_select_id + '" data-rule-required="true" data-placeholder="Choose ' + otf_form_field_name + '..."></select');

      // make it chosen with css hack 
      $("#" + make_select_id).chosen({disable_search_threshold: 15});
      $("#" + make_select_id).css('width', '100%');

      // append new option into select box
      $('#' + make_select_id).append('<option value="TEST" selected>TEST</option>');

      // move the ADD_NEW option to bottom of list and update all
      $('#' + make_select_id).append('<option value="ADD_NEW">Add new ' + otf_form_field_name + '...</option>');
      $('#' + make_select_id).trigger('chosen:updated');

      select_id = $('.otf_form_field select').prop('id');

    } else {

      // just append option, no need to create select

    }

    // hide the modal and reset button incase user

  }

});

When the DOM loads and the select isn't present, your code attaches the onchange event but there are no select elements that it can attach it to.

Once you create the select and add it to the DOM, reattach the onchange event to the selects again.

$('.otf_form_field').html('<select class="form-control chosen" name="' + make_select_id + '" id="' + make_select_id + '" data-rule-required="true" data-placeholder="Choose ' + otf_form_field_name + '..."></select');

$('.otf_form_field').on('change', '#'+select_id, function(){

   // check if the value is equal to 'ADD_NEW'
  if($(this).val() == "ADD_NEW"){

    // show the modal    
  }    
});

I would put this in a function though and call it since you're calling it on load and when you add the select to the DOM manually:

function addOnChangeHandler(){
   $('.otf_form_field').on('change', '#'+select_id, function(){        
       // check if the value is equal to 'ADD_NEW'
      if($(this).val() == "ADD_NEW"){        
        // show the modal        
      }        
    });
}

And then

$('.otf_form_field').html('<select class="form-control chosen" name="' + make_select_id + '" id="' + make_select_id + '" data-rule-required="true" data-placeholder="Choose ' + otf_form_field_name + '..."></select');

addOnChangeHandler();

And just call the same function on page load.

(this is an fyi more than an answer)

one of the really great features of jQuery's on , is that is listens for new elements which match the selector you pass it. This doesn't help much when you have to wait until you know the id of an element, but if you know these new <select> 's will have a particular class, you could rewrite as $('.otf_form_field').on('change', '.select-classname', function(){ ... }); and never worry about timing.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM