1

jquery를 사용하여 사용자 정의 자동 완성 구성 요소를 구축했습니다. 내 문제는 누군가가 키보드 up/down 화살표 키를 사용하여 autocomplete 제안 및 히트 리턴 중 하나를 선택하면 form.stopPropogation() 및 event.preventDefault()를 호출하고 false를 반환하더라도 양식 제출이 발생한다는 것입니다. 내가 KeyUp 이벤트에 핵심 기능을 결합했다jQuery가 event.stopPropogation, event.preventDefault 및 return false를 사용하여 반환 키에서 양식 제출을 중단 할 수 없음

:

$('#'+id).keyup(function(event){ getResults(event,this,url,method,data,setEl,makeLink,cssClass); event.preventDefault(); event.stopPropagation(); return false;}); 

getResults는 JSON 객체를 반환하는 서버 스크립트에 아약스 호출합니다.

function resultHandler(result, id, setEl, makeLink, event) { 
    $("#ac_"+id).remove(); 
if (result && result.length>0) { 
    var $ul = $("<ul id='ac_"+id+"' class='autocomplete'></ul>"); 
    var $li; 
    for (var i=0; i<result.length; i++) { 
     if (result[i]) { 
      if (makeLink) { 
       $li = $("<li onclick=\"location.href='/"+result[i].type+"/"+result[i].id+"'\">"+result[i].type+" '"+result[i].title+"'</li>"); 
      } else { 
       if (!setEl) { 
        $li = $("<li onclick=\"$('#"+id+"').val('"+result[i].id+"'); return killEvent(event);\">"+result[i].type+" '"+result[i].title+"'</li>"); 
       } else { 
        $li = $("<li onclick=\"$('#"+setEl+"').val('"+result[i].id+"'); $('#"+id+"').val('"+result[i].title+"');return killEvent(event);\">"+result[i].type+" '"+result[i].title+"'</li>"); 
       } 
      } 
      //$li.click(function(){ location.href="/"+result[i].type+"/"+result[i].id; }); 
      // doesn't work as the click function has no access to result[i] object 
      $ul.append($li); 
     } 
    } 
    var left = $('#'+id).offset().left; 
    var top = $('#'+id).offset().top+$('#'+id).outerHeight(); 
    $ul.css("width",$("#"+id).css("width")).css("left",left+"px").css("top",top+"px"); 
    $ul.insertAfter('#'+id); 
} 
    return false; 
} 

을 그리고 마지막으로, killEvent 간단한 함수 : 그래서

function killEvent(event) { 
    var keyCode = event.keyCode ? event.keyCode : event.which; 
if (keyCode == 13) { 
    event.stopPropogation(); 
    event.preventDefault(); 
    return false; 
    } 
} 

다음과 같이

function getResults(event,element,url,method,data,setEl,makeLink,cssClass) { 
    $(element).css("position","inherit"); 
var keyCode = event.keyCode ? event.keyCode : event.which; 
if (keyCode == 40){ //down arrow key 
    if ($("#ac_"+element.id+" .hover").is("li")) { // some li is already on hover! 
     if ($("#ac_"+element.id+" .hover").is($("#ac_"+element.id+" li").last())) { 
      $("#ac_"+element.id+" .hover").removeClass("hover"); 
      $("#ac_"+element.id+" li").first().addClass("hover"); 
     } else { 
      $("#ac_"+element.id+" .hover").removeClass("hover").next().addClass("hover"); 
     } 
    } else { 
     $("#ac_"+element.id+" li").first().addClass("hover"); 
    } 
    event.stopPropagation(); 
    event.preventDefault(); 
    return false; 
} else if (keyCode == 38){ //up arrow key 
    if ($("#ac_"+element.id+" .hover").is("li")) { // some li is already on hover! 
     if ($("#ac_"+element.id+" .hover").is($("#ac_"+element.id+" li").first())) { 
      $("#ac_"+element.id+" .hover").removeClass("hover"); 
      $("#ac_"+element.id+" li").last().addClass("hover"); 
     } else { 
      $("#ac_"+element.id+" .hover").removeClass("hover").prev().addClass("hover"); 
     } 
    } else { 
     $("#ac_"+element.id+" li").last().addClass("hover"); 
    } 
    event.stopPropagation(); 
    event.preventDefault(); 
    return false; 
} else if (keyCode == 13){ //return key 
    if ($("#ac_"+element.id+" .hover").is("li")) { // some li is already on hover! 
     $("#ac_"+element.id+" .hover").removeClass("hover").trigger("click"); 

    } 
    event.stopPropagation(); 
    event.preventDefault(); 
    return false; 
} 

if (setEl) { if (!$(element).val() || $(element).val()=="") { $("#"+setEl).val('');} } 
if ($(element).val() != autocomplete_prev_search[element.id]) { 
    $("#ac_"+element.id).remove(); 
} 
autocomplete_prev_search[element.id] = $(element).val(); 
if ($(element).val().length>=3) { 
    if (!url){return;} 
    if (!data) { 
     data = {match:$(element).val()}; 
    } else { 
     data.match = $(element).val(); 
    } 
    if (!method) { method = "POST"; } 
    $.ajax({ 
     type: method, 
     url: url, 
     data: data, 
     success: function(result){ return resultHandler(result,element.id,setEl,makeLink,event); }, 
     beforeSend: function(){ $(element).css("background-image","url('/kit/icons/indeterminate.gif')").css("background-repeat","no-repeat").css("background-position","right center"); }, 
     complete:function(){ $(element).css("background-image","none"); }, 
     error: errorHandler, 
     timeout: 1000, 
     dataType: "json" 
    }); 
} 
    return false; 
} 

마지막으로 아약스 호출의 성공 핸들러는 다음과 같이 getResults의 의사입니다 , 모든 핸들러와 autocomplete 제안 목록의 li 요소에 대한 클릭까지 모두 false를 반환하고 stopPropogation 및 preventDefault를 호출합니다. 그러나 양식 제출은 여전히 ​​발생합니다! 내가 여기서 잘못하거나 잘못하고있는 것은 무엇인가. 긴 게시물을 위해 유감스럽게 생각합니다!

답변

4

키보드의 위/아래 키를 사용하여 자동 완성 제안을 선택하고 Enter 키를 누를 때 브라우저의 기본 이벤트를 중지하는 방법을 발견했습니다!

$('#'+id).keydown(function(event){ return handleKey(event); }); 
$('#'+id).keyup(function(event){ return getResults(event,this,url,method,data,setEl,makeLink,cssClass); }); 

여기서 keydown의 경우 handleKey 함수는 키 코드 13을 확인한 다음 stopPropagation 및 preventDefault!

여기

function handleKey(event) { 
    var keyCode = event.keyCode ? event.keyCode : event.which; 
    if (keyCode == 13) { 
     event.preventDefault(); 
     event.stopPropagation(); 
     return false; 
    } else { 
     return true; 
    } 
} 

은 따라서 나는를 keyDown의 브라우저의 기본 동작을 취소 handleKey 기능을입니다! keyup에서 getResults는 선택 항목이 있는지 확인하고 반환합니다.

트릭은 브라우저의 기본 동작을 중지하기 위해 키 업이 아니라 keydown에 대한 조치를 취해야한다는 것입니다.

감사합니다. 특히 이것을 지적 해 주신 CronosS에게 감사드립니다!

0

키 업 이벤트를 처리하는 대신 제출 이벤트를 처리하십시오. 거기에 수표를 추가하여 모든 것이 완료되었는지 확인한 후 반환하지 않은 경우 false를 반환합니다.

+0

아니요, 전체 자동 완성 설정은 작동해야하는 입력란의 keyup 이벤트에 바인딩됩니다. 또 다른 문제는이 자동 완성을 일반으로 만들고 싶다는 것입니다. 그래서 내가 달성하고자하는 모든 것은 그것이 바인딩 된 텍스트 상자에 반환 키를 함정하지만 단순히 값을 사용하지만, 양식 제출을 허용하지 않는다는 것입니다! – DeeTee

+0

@DeeTee 그게 핵심입니다. 브라우저가 키를 눌렀을 때 전에 양식을 보내는 동안 키 업시 브라우저의 기본 동작을 금지합니다. – CronosS

+0

@DeeTee 양식 제출을 원하지 않는 경우 가장 간단한 방법은 제출 기준을 처리하여 모든 기준이 충족 될 때 제출하는 것입니다. 그렇지 않으면 제출을 위해 html에 양식을 사용하지 말고 제출 단추를 클릭하여 Ajax 게시자에게 물어보십시오. – evasilchenko