web-dev-qa-db-ja.com

HTML5入力タイプ=数値変更ステップの動作

Type = "number"の入力フィールドをstep = "100"で使用する場合。奇数を無効にしたくありません。増加または減少を1000の値にしたいだけです。

<input type="number" min="100" max="999999" step="100" />

ユーザーが値「199」を入力して送信すると、値が100で割り切れないため、エラーが発生します。ただし、step-valueで必要なのは、スピナーの動作を制御することだけです。ユーザーがクリックした場合は値199を200にし、ユーザーがクリックした場合は100にします。または理想的には値を100に増やしたり減らしたりします。

どうすればよいですか?私は次のように(jQuery 1.7.2で)無効なイベントを使用してみました:

$( "[type='number']" ).bind( 'invalid', function( e ) {
    var el = $( this ),
      val = el.val( ),
      min = el.attr( 'min' ),
      max = el.attr( 'max' );

    if ( val >= min && val <= max ) {
        return false;
    }
} );

ただし、これによりフォームが送信されなくなります。

PS:これはGoogle Chrome 20.0.1132.57 on Fedora16にあります。

30
mabs

できないと思いますが、stepと検証は 密接に結びついています です。将来的には、 stepUp()およびstepDown()関数 をオーバーライドして、説明した動作を取得できるようになる可能性がありますが、これが意図されているかどうかは調査していません。これらのユースケース。 WHATWGメーリングリスト に投稿して、これらの関数について具体的に質問し、ユースケースを説明することをお勧めします。

現在の実用的な目的で、step=1を設定し、clickイベントにバインドしてキャプチャしようとしましたか? 「上」クリックと「下」クリックの区別に問題がある可能性がありますが、それは克服できる可能性があります。ただし、text入力を使用し、pattern属性を適切に設定して、独自のスピナーを実装する方が、全体的に簡単な場合があります。

6
robertc

さて、まず第一に、この非常に興味深い質問に感謝します。私はあなたの問題の解決策を探すことによってHTML5検証について多くを学びました。

私の調査により、HTML5フォーム検証APIには読み取り専用である 興味深いプロパティのセット がありますが、やりたいことを行うのに非常に便利であることがわかりました。

あなたの問題に対する私のアプローチは、最初にnovalidate属性をフォーム要素に追加して、検証をトリガーするタイミングを制御できるようにし、次に入力に添付されたvalidityオブジェクトを読み取ることでした。どの検証エラーが存在するかを正確に知ることができ、唯一のエラーがstepMismatch(これが199などの数値の無効化をトリガーするもの)である場合、すべての検証プロセスをバイパスできます。それ以外の場合は、 reportValidity() メソッドを使用して通常のHTML検証動作を表示できます。

これが私が思いついたコードで、あなたが望むことをしてくれることを願っています:

var form = document.querySelector("form")       // Get the form
var input = document.querySelector("#myInput")  // Get the input to validate

form.addEventListener("submit", function(e) {
        e.preventDefault()  // Catch the submit
  // Do the magic
  if(onlyStepMatters(input.validity)){
        form.submit()
  }else {
        form.reportValidity()
  }
})

function onlyStepMatters(validityState) {
  return !(
    validityState.badInput || validityState.customError || validityState. patternMismatch || validityState.rangeOverflow || validityState.rangeUnderflow || validityState.tooLong || validityState.tooShort || validityState.typeMismatch || validityState.valueMissing
    )
    
  /* This is what the object looks like, notice I just skipped the stepMismatch */
  /*
  {
    badInput,
    customError,
    patternMismatch,
    rangeOverflow,
    rangeUnderflow,
    stepMismatch,
    tooLong,
    tooShort,
    typeMismatch,
    valid,
    valueMissing,
  }
  */
}
<form novalidate>
<input type="number" id="myInput" min="0" max="1000" step = "100" placeholder="Enter a number" required/>
<button type="submit">Send</button> 
</form>

このコードはリファクタリングされ、同じロジックに基づいてより簡潔になる可能性があると確信していますが、それについてさらに考える十分な時間がありません。

建設的なコメントをいただければ幸いです。

お役に立てれば。

4
Rafik Tighilt

ステップのみですが、範囲を使用してスライダーにマークを追加し、JavaScriptを使用して近い値を確認して設定できます

お気に入り

function updateTextInput(val) {
  if      (val > 36)  val = 50;
  else if (val > 26)  val = 36;
  else if (val > 20)  val = 26;
  else if (val > 15)  val = 20;
  else if (val >  1)  val = 15;
  document.getElementById('textInput').value = val;
}
<input type='range' min='0' max='50' step='1' name='slide' list="settings" onchange="updateTextInput(this.value);">
<datalist id="settings">
    <option>15</option>
    <option>20</option>
    <option>26</option>
    <option>36</option>
    <option>50</option>
</datalist>
<input type="text" id="textInput" />
1
Nuno Dias

これはあなたを助けることができる単純なjavascript関数です
ここで、prev_numはグローバル変数です
これはincrementdecrementの両方で機能します

var perv_num=0;
function ax(z)
{

     let def;
     let mul=10;
     let valu;
     let valucopy=parseInt(z.value);
     let  frst;
     valucopy=((valucopy+100)%100);


         if (parseInt( z.value)<100) 
         {
                  document.getElementById("myNumber").value="";
                  document.getElementById("myNumber").value=100;
         }
         else if(parseInt( z.value)<perv_num)
        {
                  def=parseInt( z.value.length);
                  mul=Math.pow(mul,def-1);
                  frst=(parseInt(z.value[0])*mul);
                  document.getElementById("myNumber").value="";
                  document.getElementById("myNumber").value=frst;
         }
         else if(valucopy  ==0)
         {
                  document.getElementById("myNumber").value="";
                 document.getElementById("myNumber").value=parseInt(z.value)+100;
          }
          else{
                  def=parseInt( z.value.length);
                  mul=Math.pow(mul,def-1);
                  frst=(parseInt(z.value[0])*mul);
                  valu=Math.abs( parseInt(z.value)-frst);
                  valu=100-valu;
                  var number=(parseInt(z.value)+valu);
                  document.getElementById("myNumber").value="";
                  document.getElementById("myNumber").value= number;
              }
              perv_num=parseInt( z.value);
}

そしてhtmlはのようなものです

    <input type="number" id="myNumber" onchange="ax(this)">

フィドルは https://jsfiddle.net/ecpy5gr0/1

0
Ricky

「変更」イベント内最も近い有効な値に丸める

$( "[type='number']" ).change(function () {
   var value = $(this).val());
   var newValue = Math.round(value/100)*100
   if (newValue < 100) {
      newValue = 100;
   }
   if (newValue > 999999) {
      newValue = 999999;
   }
   if (newValue === value ) {
      return;
   }
   $(this).val(newValue)
})
0
Sergey Gurin

これがあなたが求めたことを達成するために必要なコードです。再計算や標準の動作の変更を避けようとしたので、これは他の制約(必須、パターン、範囲など)に対して透過的である必要があります。

FirefoxとChromeでのみテストしましたが、最近のブラウザでも動作するはずです。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Disable validity constrains</title>
<!-- avoid highlight due to constrains -->
<style>#qty { box-shadow: unset; }</style>
</head>
<body>
<form>
        <input id="qty" name="num" type="number" min="100" max="1000" step="100">
        <input type="submit">
</form>
<script>
(function() {
        var el = document.getElementById('qty');
        el && el.addEventListener('invalid', function(event) {
                if ('validity' in el) {
                        for (var state in el.validity) {
                                if (state == 'stepMismatch') { continue; }
                                if (el.validity[state]) { return true; }
                        }
                        event.preventDefault();
                        el.form.submit();
                }
        }, true);
})();
</script>
</body>
</html>
0
Diego Perini

私はこれを達成しようとして、あなたのコードで少し遊んでいます:

理想的には、100の値で値を増減したいです

…そして、次のようなスクリプトで終わりました。

  • キーボードまたはマウスでステップの増減を検出し、
  • remainder変数を使用して、計算結果を格納します:value % 100
  • stepパラメータとvalueinputを変更します。
  • キーボードまたはマウスのイベントが終了したときにremainder変数を追加し直し、stepパラメーターを1にリセットします(送信できるようにする必要があります)。

この作業スニペットでは、100で割り切れない数値から始めて、矢印(キーボードまたはマウス)を使用して入力値を変更してみてください。

var remainder = false;
var stepbefore;

$("[type='number']").bind('keydown mousedown', function() {
  // If keyboard Up or Down arrow keys or mouse left button on the arrows
  if (event.keyCode == 38 || event.keyCode == 40 || event.button === 0) {
    // If there is already a change running, exit the function
    if (remainder !== false) return;

    var myStep = this.getAttribute("stepcustom"); // Get my "stepcustom" attribute
    remainder = this.value % myStep;
    this.value = Math.floor(this.value / myStep) * myStep;
    stepbefore = this.step;
    this.step = myStep;
  }
});

$("[type='number']").bind('keyup mouseup', function() {
  if (remainder !== false) {
    this.value = +(this.value) + remainder;
    this.step = stepbefore;
    remainder = false;
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<form>
  <input type="number" min="100" max="999999" step="1" stepcustom="100" />
  <input type="submit" />
</form>

それが役に立てば幸い。

0
Takit Isy

Change()関数を使用してみてください...

<form>
    <input type="number" id="number" min="100" max="999999" step="100" />
</form>

$(document).ready(function(){
    $("#number").change(function(a){
        if ($(this).val() % 100 === 0) {
            /* Do something when the number is even */ 
            console.log("EVEN");
        } else {
            /* Or when it's odd (isn't dividable by 100), do ... whatever */ 
            console.log("ODD");
        }
    })
});

そして、私はあなたが望む例のように、ブートストラップを使用してそれをテストしていました、ユーザーがクリックすると値は200になり(199から)、ユーザーがクリックすると値は100になります

分割可能を変更するには:

if ($(this).val() % 100 === 0) { //Change 100 with what ever you want
0

ステップ属性を動的に変更するスクリプトを作成します。

/*
  jQuery Optional Number Step

Version: 1.0.0
 Author: Arthur Shlain
   Repo: https://github.com/ArthurShlain/JQuery-Optional-Step
 Issues: https://github.com/ArthurShlain/JQuery-Optional-Step/issues
*/
(function ($) {

    $.fn.optionalNumberStep = function (step) {
        var $base = $(this);

        var $body = $('body');

        $body.on("mouseenter mousemove", '[data-optional-step]', function () {
            $(this).attr("step", $(this).attr('data-optional-step'));
        });

        $body.on("mouseleave blur", '[data-optional-step]', function () {
            $(this).removeAttr("step");
        });

        $body.on("keydown", '[data-optional-step]', function () {
            var key = event.which;
            switch (key) {
                case 38: // Key up.
                    $(this).attr("step", step);
                    break;

                case 40: // Key down.
                    $(this).attr("step", step);
                    break;
                default:
                    $(this).removeAttr("step");
                    break;
            }
        });

        if (step === 'unset') {
            $base.removeAttr('data-optional-step');
        }

        if ($.isNumeric(step)) {
            $base.attr('data-optional-step', step);
        }

    }

}(jQuery));

jQuery(function() {
  $('.optional-step-100').optionalNumberStep(100);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container mt-5">
  <h1>JQuery Optional Number Step</h1>
  <div class="form-group" style="max-width: 300px">
    <label>Example</label>
    <input type="number" class="form-control optional-step-100" value="0">
    <small id="emailHelp" class="form-text text-muted">Dynamic step for this field is 100
      <br>You can specify any numeric value on keyboard. 
      <br>HTML5 step validation will not be applied.</small>
  </div>
  <a class="btn btn-dark btn-sm" href="https://github.com/ArthurShlain/JQuery-Optional-Step" target="_blank">View on GitHub</a>
</div>

https://codepen.io/ArtZ91/pen/omePje

0
Arthur Shlain