2009-06-24 13 views
4

私のフォームには、ユーザーが値を入力できる入力ボックスのセットがあります。 これらのボックスのいずれかが変更されると、フォームは自動的に送信されます。非アクティブなキーボードのxミリ秒後に自動的にフォームを送信

しかし、問題は、ユーザーが最後のフィールドにとどまり、テキストボックスを最初に残さずにマウスを押して(別のフォームの)[OK]ボタンを押すという問題です。変更イベントがトリガーされず、古い、正しくない値が次のページに渡されます。

数ミリ秒のアクティブでないキーボードの後に​​onchangeイベントをトリガーしたいと思います。ほとんどのオートコンプリートプラグインのように。
私は、入力フィールドを入力してキーストロークが処理されるたびにリセットされるタイミングを開始するタイマーを実装できると思います。そして、ゼロに達するとonchangeイベントがトリガーされます。

私は車輪を再発明していないし、そのような機能がどこかで利用可能かどうか疑問に思っていた。
提案?

答えて

6

私は同様の問題があり、現在内部アプリケーションで使用中のjQueryプラグインを作成しました。ユーザーが入力を終えた後、変更イベントがトリガーされます。

jQueryを使用していない場合でも、コードは引き続き他のものに適用できます。

jQuery.fn.handleKeyboardChange = function(nDelay) 
{ 
    // Utility function to test if a keyboard event should be ignored 
    function shouldIgnore(event) 
    { 
     var mapIgnoredKeys = { 
      9:true, // Tab 
      16:true, 17:true, 18:true, // Shift, Alt, Ctrl 
      37:true, 38:true, 39:true, 40:true, // Arrows 
      91:true, 92:true, 93:true // Windows keys 
     }; 
     return mapIgnoredKeys[event.which]; 
    } 

    // Utility function to fire OUR change event if the value was actually changed 
    function fireChange($element) 
    { 
     if($element.val() != jQuery.data($element[0], "valueLast")) 
     { 
      jQuery.data($element[0], "valueLast", $element.val()) 
      $element.trigger("change"); 
     } 
    } 

    // The currently running timeout, 
    // will be accessed with closures 
    var timeout = 0; 

    // Utility function to cancel a previously set timeout 
    function clearPreviousTimeout() 
    { 
     if(timeout) 
     { 
      clearTimeout(timeout); 
     } 
    } 

    return this 
    .keydown(function(event) 
    { 
     if(shouldIgnore(event)) return; 
     // User pressed a key, stop the timeout for now 
     clearPreviousTimeout(); 
     return null; 
    }) 
    .keyup(function(event) 
    { 
     if(shouldIgnore(event)) return; 
     // Start a timeout to fire our event after some time of inactivity 
     // Eventually cancel a previously running timeout 
     clearPreviousTimeout(); 
     var $self = $(this); 
     timeout = setTimeout(function(){ fireChange($self) }, nDelay); 
    }) 
    .change(function() 
    { 
     // Fire a change 
     // Use our function instead of just firing the event 
     // Because we want to check if value really changed since 
     // our previous event. 
     // This is for when the browser fires the change event 
     // though we already fired the event because of the timeout 
     fireChange($(this)); 
    }) 
    ; 
} 

使用法:あなたは正しかった

$("#my_input").handleKeyboardChange(300).change(function() 
{ 
    // value has changed! 
}); 
+0

nice。あなたは私がしなかったいくつかの状況を考慮に入れました –

+0

私は変更しました $ element.trigger( "Keyboard.change"); 〜 $ element.trigger( "change"); 私の素朴な実装よりはるかに良くなりました。 –

+0

ああ申し訳ありませんが、この特定のアプリケーションの名前空間イベントでした。あなたはそれを変更する権利があり、私はそれを上のコードに変更します。 –

0

私は、このような解決策が何かを「再発明する」と考えられるかどうかはわかりません。あなたが言ったように、ページが読み込まれると、単純なsetTimeout以外の何ものでもないように思えます。約3,000ミリ秒後に、form.submit()を実行します。

私はたぶん各キーストロークでカウントダウンを再開して、ユーザーが入力するのに十分な時間を与えるでしょう。

+0

、私でした。私はちょうどkeypressのイベントのブラウザの違いの穴あき者です。これまでのところ問題はありません。 –

0

ユーザーが次のフィールドに移動したり、何か他のものをクリックしたときの両方で、値が保存されますか?

+0

問題は、ユーザーが現在の値を使用して別のページに移動する送信ボタンをクリックしたときに発生します。次のページに行くフォームを提出する前に、前のフォームを最初に再提出する時間はありません。 –

関連する問題