2

I am trying to customize an HTML number input so that the step value increases after a certain number then increases more after another one. For example, this is the increment pattern I am trying to achieve:

1, 2, 4, 8, 12, 16, 20, 24, 32, 48, 64, 96, 128

1 is the first increment, 2 is the next, then 4, 8, 12, and so on. I have been doing research on this, but I cannot find any example that has been done already. Not even on this site. I tried using 1,2,4,8,12,16,20,24,32,48,64,96,128 as the step value, but it reverts to 1.

<input type="number" name="number1" min="1" max="128" step="1" value="1">

How do I write the step value so that this can happen, or must I use JavaScript for this instead?

Jon Kantner
  • 593
  • 2
  • 10
  • 29
  • 3
    Can't do it with HTML alone, the step can only be a single number. Would need to use JS. – j08691 Jan 12 '16 at 14:51
  • 3
    There's a fundamental flaw in your perception of how this works. You suppose that changing the step will allow you to have an incrementer that goes between standard images sizes (I assume), but let's say you're currently at 32. You might think step should be 16 so you can click the up button and go to 48, but step works both ways. Clicking down will also take you down by 16 to 16. That'll overshoot 24. You need another approach entirely. – Joseph Marikle Jan 12 '16 at 15:14

3 Answers3

2

Here are a couple of solutions. Please note that these are bleeding edge and not likely to work in a lot of browsers. Oh, and it goes without saying that this is not possible in HTML only. The following are javascript based answers.

You could use <dataset> to get a range of acceptable values and then use javascript to ensure that the result snaps to these values.

var el = document.querySelector('[name=number1]');
var valueSet = [1, 2, 4, 8, 12, 16, 20, 24, 32, 48, 64, 96, 128];

// event listener and initial trigger
el.addEventListener('change', function(e){
  // snippet to snap to a set value.
  // stolen from http://stackoverflow.com/a/19277804/854246
  el.value = valueSet.reduce(function (prev, curr) {
    return (Math.abs(curr - el.value) < Math.abs(prev - el.value) ? curr : prev);
  });
});
<input type="range" name="number1" value="1" list="sizes" min="1" max="128" />
<datalist id="sizes">
  <option>1</option>
  <option>2</option>
  <option>4</option>
  <option>8</option>
  <option>12</option>
  <option>16</option>
  <option>20</option>
  <option>24</option>
  <option>32</option>
  <option>48</option>
  <option>64</option>
  <option>96</option>
  <option>128</option>
</datalist>

Or you could use your number element to determine the index of an array that will serve as the display for your value.

// elements and set of values
var el = document.querySelector('[name=number1]');
var label = document.querySelector('#display');
var valueSet = [1, 2, 4, 8, 12, 16, 20, 24, 32, 48, 64, 96, 128];

// default values
el.setAttribute('min', 1);
el.setAttribute('max', valueSet.length);
el.setAttribute('step', 1);
el.value = 1;

// event listener and initial trigger
el.addEventListener('input', function(e){
  label.textContent = valueSet[this.value - 1];
});
el.dispatchEvent(new Event('input'));
<input type="number" id="number1" name="number1">
<label id="display"></label>

I haven't tested these in anything other than latest chrome on my mac.

Joseph Marikle
  • 76,418
  • 17
  • 112
  • 129
2

On the input change, event, you can change the value to your step.

var steps = [1, 2, 4, 8, 12, 16, 20, 24, 32, 48, 64, 96, 128];
var input = document.getElementById("inputSteps");
var inputVal = 1;
input.addEventListener("change", changeInputStep);

function changeInputStep() {
  var dir = 0;
  if (this.value > inputVal) {
    dir = 1;
  } else if (inputVal > 1) {
    dir = -1;
  }
  this.value = steps[steps.indexOf(inputVal) + dir];
  inputVal = parseInt(this.value);
}
<input type="number" name="number1" min="1" max="128" value="1" id="inputSteps">
Magicprog.fr
  • 4,072
  • 4
  • 26
  • 35
1

Try this

It might be not best but it will help you to figure out your problem.

     $( document ).ready(function() {
    
    $('.incBy2').val($( ".incBy2" ).attr( "min" ));
    var step_array = [1, 2, 4, 8, 12, 16, 20, 24, 32, 48, 64, 96, 128];
   $(document).on("click keyup", ".incBy2", function () {
        var prev_val= parseInt($(this).attr( "prev_val" ));
        var current_val = parseInt($(this).val());
        var new_val = 0;

        if ( ( step_array[prev_val-1] ==128 || step_array[prev_val-1] >=128 ) && current_val >=128 ){
            return;  
        }
               
        if ( current_val >= step_array[prev_val-1] && current_val >1 )
        {
            new_val = prev_val+1;
        } else {
            new_val = prev_val-1
        }

        if ( new_val < 1 ){
            $(this).attr("prev_val", "1");
            $(this).val(1);
        } else{
           $(this).attr("prev_val", new_val);
           $(this).val(step_array[new_val-1]); 
        }              
   });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<input class="incBy2" type="number" name="number1" min="1" max="128" prev_val="1"  value="1">
Uttam Kumar Roy
  • 2,060
  • 4
  • 23
  • 29