简体   繁体   中英

Trying to change one select box based on the value of another

I have a small javascript program that looks at the value in one select box (id_Decade for the decade) and adjusts the range of values in two other select (range of years for that decade). The html for the page is created by a Django 2.0 application. I am running jQuery as well.

One of the range of years select boxes (id_Date_year) works correctly - the decade is read from id_Decade, the range of years is created, the id_Date_year select boxes are populated correctly, and if there is a pre-selected year in id_date_year, that is preserved.

The problem the other select box, id_Approximate Date_year, does not preserve the pre-selected year value. The years for the decade are loaded correctly, but the pre-selected year is not selected again.

In this picture, it shows the page after loading. The initial decade is 1890, and the pre-selected year is 1894. Note how the Date select boxes have the year 1984 selected, but the Approximate Date boxes have Choose a year selected. Both select boxes have the correct range of years - 1890-1899. 在此输入图像描述

If I change the decade to 1950, then the Date and Approximate Date selects are correct, since the selected year is 1894, and that is not in the decade of the 1950s. Both select boxes have the same range of years - 1950 to 1959. 在此输入图像描述

Both select boxes use the same code. I know that a space is verboten in the id name of an element, but Django is creating that id value, and I have not found a way to change it.

Here is the code:

  (function($) {
      $(document).ready(function(){
        console.log("Made it into update years from decade");
        // Get the selected year if there is a Date field
        var Date_years = $('#id_Date_year');
        var selectedDateYear = Date_years.find(':selected').val();
        console.log("selectedDateYear="+selectedDateYear);
        // Get the decade selected
        var decade1 = $('#id_Decade option:selected').text();
        console.log("decade1="+decade1);
        // get the years for that decade
        newOptions = years_from_decade(decade1);
        // update the date select box
        update_options(newOptions, Date_years, selectedDateYear);

        // Get the selected year if there is an Approximate Date field
        var Approximate_years = $("[id='id_Approximate Date_year']");
        var selectedApproximateYear = Approximate_years.find(':selected').val();
        console.log("selectedApproximateYear="+selectedApproximateYear);
        // update the date select box
        update_options(newOptions, Approximate_years, selectedApproximateYear);

        $('#id_Decade').change(function(){
          // chang the years if the decade changes
          var decade2 = $('#id_Decade option:selected').text();
          console.log("decade2="+decade2);
          newOptions = years_from_decade(decade2);
          console.log("we have newOptions=");
          console.log(newOptions);
          update_options(newOptions, Date_years, selectedDateYear);
          update_options(newOptions, Approximate_years, selectedApproximateYear);
        })

        // calculate the years for the decade
        function years_from_decade(decade) {
          console.log("we have a decade="+decade);
          var newOptions = {};
          base_year = parseInt(decade, 10);
          for (i = 0; i < 10; i++) {
            year = base_year + i;
            key = year.toString();
            newOptions[key] = key;
          }
          return newOptions;
        }

        // replace the options with new ones
        function update_options(newOptions, target, selectedYear) {
          console.log("update_options selectedYear="+selectedYear);
          target.find('option:gt(0)').remove(); // remove all options, but not the first
          $.each(newOptions, function(key, value) {
            target.append($("<option></option>").attr("value", value).text(key));
            console.log("value="+value+" selectedYear="+selectedYear);
            if (value == selectedYear) {
              console.log("got a match! value="+value);
              target.val(value).change();
            }
          })
        }
      });
    })(jQuery);

The console messages for both select boxes are the same. The matching of the pre-selected year works in both cases, but the id_Approximate Date_year select box does not get the pre-selected year selected, whereas the id_Date_year does.

Is this behavior related to the space in the id value? As you can see from my code, I am not an experienced js coder. I am sure there are much better ways to do what I want to do!

Thanks!

Mark

You are correct that you can not use a space in a jQuery selector. If this is what's causing your problem, you can get around it multiple ways:

  • Using plain JS and wrapping it with $() to convert it to jQuery object $(document.getElementById('id_Approximate Date_year'))
  • Using attribute selector $("[id='content Module']")
  • Escaping the space $('id_Approximate\\\\ Date_year')

Demo examples:

 $('#div one') .html('$(\\'#div one\\') Successful') $(document.getElementById('div two')) .html('$(document.getElementById(\\'div two\\')) Successful') $("[id='div three']") .html('$("[id=\\'div three\\']") Successful') $('#div\\\\ four') .html('$(\\'#div\\\\\\\\ four\\') Successful') 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div id="div one">Unchanged</div> <div id="div two">Unchanged</div> <div id="div three">Unchanged</div> <div id="div four">Unchanged</div> 

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