2009-06-24 4 views
4

제 양식에는 사용자가 값을 입력 할 수있는 입력란 세트가 있습니다. 이 상자 중 하나가 변경되면 양식이 자동으로 제출됩니다.비활성 키보드 x 밀리 초 후 자동 제출 양식

그러나 이제는 사용자가 마지막 필드에 머무르고 마우스를 가져 와서 텍스트 상자를 떠나지 않고 (다른 양식의) 확인 버튼을 누릅니다. 변경 이벤트가 트리거되지 않고 이전의 잘못된 값이 다음 페이지로 전달됩니다.

비활성 키보드가 몇 밀리 초 후에 onchange 이벤트를 트리거하려고합니다. 대부분의 자동 완성 플러그인처럼.
입력 필드를 입력하고 키 입력이 처리 될 때마다 재설정 된 시간을 시작하는 타이머를 구현할 수 있다고 생각합니다. 그런 다음 0이되면 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

좋은. 당신은 어떤 상황을 고려하지 않았다. –

+0

내가 바꿨다 $ element.trigger ("Keyboard.change"); ~ $ element.trigger ("change"); 순진한 구현이 훨씬 낫습니다. –

+0

아, 죄송합니다. 특정 애플리케이션의 네임 스페이스 이벤트였습니다. 당신은 그것을 바꿀 권리가 있었고 위의 코드를 바꿀 것입니다. –

0

나는 그런 해결책이 "다시 발명하는"것으로 간주 될지 모른다. 말했듯이, 페이지가로드되면 단순한 setTimeout 이상은 아닙니다. 약 3,000 밀리 초가 지나면 form.submit()을 실행합니다.

사용자가 입력하기에 충분한 시간을주기 위해 각 키 입력으로 카운트 다운을 다시 시작합니다.

+0

. 나는 keypress 이벤트에서 브라우저의 차이점에 대해서만 심사숙고하고있다. 지금까지 아무 문제도. –

0

onBlur가 작동하지 않으므로 사용자가 다음 필드로 이동하거나 다른 것을 클릭하면 값이 저장됩니까?

+0

사용자가 현재 값을 사용하여 다른 페이지로 이동하는 제출 단추를 클릭 할 때 문제가 발생합니다. 다음 페이지로가는 양식을 제출하기 전에 먼저 이전 양식을 다시 제출할 시간이 없습니다. –