javascripthtmldrop-down-menurangeslider

Value change of range slider when drop-down tab changed


I am trying to figure out how to change the value of a range slider when a drop-down unit menu is changed. For example, the slider is currently set to min -29, max 43, and step size 18 for "metric" drop-down. Thus, the range slider value is: -29, -11, 7, 25, 43. When the drop-down is changed to "imperial", I would like the range slider value to change to: -20, 12, 45, 77, 110. How can I program this in JavaScript? I would like to avoid using jQuery, since I have not been able to figure that out yet. Thank you in advance for your help.

<table style="margin-left: auto; margin-right: auto;width:75%;">
 <tr>
  <td style="text-align:right;width:40%;">
   <label for="unittype"><b>Units:</b></label>
  </td>
  <td style= "text-align:left;">
   <select id="unitselected" style="width:40%;" onChange="getunitType()">
    <option value="metric">Metric</option>
    <option value="imperial">Imperial</option>
   </select>
  </td>
</tr>
</table>

<label  id="tempunitresult" for"temp"><b>Temperature (&#8451;):</b></label>
 <br>
<input type="range" id="tempselected" class="slider" min="-29" step="18" max="43" oninput="rangeValueTemp.innerText=this.value">
<div style="text-align:center;" id="rangeValueTemp">7</div>

<script>
var unit_type = new Array();
  unit_type["metric"]=0;
  unit_type["imperial"]=1;

function getunitType(){
  var unitType = 0;
  var unitSelected = document.getElementById('unitselected');

  unitType = unit_type[unitSelected.value];

  if (unitType == 0){

    var tempValue = document.getElementById("tempselected");
    tempValue.setAttribute('min',-29);
    tempValue.setAttribute('max',43);
    tempValue.setAttribute('step',18);

  }else{

    var tempValue = document.getElementById("tempselected");
    tempValue.setAttribute('min',-20);
    tempValue.setAttribute('max',110);
}

</script>



Solution

  • Not sure ... but actually when changing units from metric (Celsius) to imperial (Fahrenheit) the range should stay the same.

    So min/max
    -29/43 °Celsius
    should have an exact (convertible) equivalent of:
    -20.2/109.4 °Fahrenheit

    Otherwise you'll encountering conversion issues when switching units.

    Example

    let unitSelected = document.getElementById('unitselected');
    let tempValue = document.getElementById("tempselected");
    let rangeValueTemp = document.getElementById("rangeValueTemp");
    let tempUnitString = document.getElementById("tempUnitString");
    let tempUnitStringCurrent = document.getElementById("tempUnitStringCurrent");
    
    // metric values
    let minCelsius = -29;
    let maxCelsius = 43;
    let stepsCelsius = 18;
    let initialValue = 7;
    
    // imperial values
    let minFahrenheit = minCelsius * 9 / 5 + 32;
    let maxFahrenheit = maxCelsius * 9 / 5 + 32;
    let stepsFahrenheit = 32.4;
    
    //default values
    let unitString = '°Celsius';
    tempUnitString.textContent = unitString;
    tempUnitStringCurrent.textContent = unitString;
    tempselected.setAttribute('min', minCelsius);
    tempselected.setAttribute('max', maxCelsius);
    tempselected.setAttribute('step', stepsCelsius);
    tempselected.value = initialValue;
    let unitType = +unitselected.value;
    let currentTemp = +tempselected.value;
    rangeValueTemp.textContent = currentTemp;
    
    
    //update temperature values
    tempValue.addEventListener('change', function(e) {
      currentTemp = +e.currentTarget.value;
      rangeValueTemp.textContent = currentTemp;
    })
    
    //update temperature units 
    unitSelected.addEventListener('change', function(e) {
      currentTemp = +tempselected.value;
      unitType = e.currentTarget.value;
      if (unitType == 'imperial') {
        unitString = '°Fahrenheit';
        currentTemp = currentTemp * 9 / 5 + 32;
        tempValue.setAttribute('step', stepsFahrenheit);
        tempValue.setAttribute('min', minFahrenheit);
        tempValue.setAttribute('max', maxFahrenheit);
      } else {
        unitString = '°Celsius';
        currentTemp = (currentTemp - 32) * 5 / 9;
        tempValue.setAttribute('min', minCelsius);
        tempValue.setAttribute('max', maxCelsius);
        tempValue.setAttribute('step', stepsCelsius);
      }
      currentTemp = +currentTemp.toFixed(3);
      rangeValueTemp.textContent = currentTemp;
      tempUnitString.textContent = unitString;
      tempUnitStringCurrent.textContent = unitString;
      tempselected.value = currentTemp;
    });
    input,
    select {
      display: block;
      width: 100%;
    }
    
    label {
      font-weight: bold;
      display: block;
    }
    <p>
      <label id="tempunitresult" for "temp">
            Temperature (<span id="tempUnitString"></span>):
        </label>
      <input type="range" id="tempselected" class="slider">
    </p>
    <p>
      <label for="unittype">Units:</label>
      <select id="unitselected">
        <option value="metric">Metric (Celsius)</option>
        <option value="imperial">Imperial (Fahrenheit)</option>
      </select>
    </p>
    <p><span id="rangeValueTemp">0</span>&thinsp;<span id="tempUnitStringCurrent"></span></p>