1

jqueryを使用してカスタムオートコンプリートコンポーネントを作成しました。私の問題は、誰かがキーボードの上/下矢印キーを使ってオートコンプリートの提案とヒットリターンのいずれかを選択すると、event.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オブジェクトを返すサーバスクリプトへのAJAX呼び出しを行います。次のように getResultsの擬似コードは、次のように

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; 
} 

が最後にAJAX呼び出しの成功ハンドラがある:だから

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

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は単純な関数でありますオートコンプリート提案リストのli要素のすべてのハンドラとクリックもすべてfalseを返し、stopPropogationおよびpreventDefaultを呼び出します。ただし、依然としてフォーム提出が発生します。私は何が間違っているか、ここで行方不明です。長い投稿を申し訳ありません!

答えて

4

キーボードの上下キーを使用してオートコンプリート候補を選択してEnterキーを押すと、ブラウザのデフォルトイベントを停止する方法が見つかりました。 KeyDownイベントで、handleKey機能は、単にキーコード13をチェックし、その後のstopPropagationとのpreventDefaultを呼び出し

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

ここhandleKey機能は、このように私はKeyDownイベントのブラウザのデフォルトのアクションをキャンセル

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

です! keyupの場合、getResultsは選択があるかどうかをチェックして返します。

このトリックは、ブラウザのデフォルト動作を停止するために、キーアップではなくキーダウンに対処する必要があります。

特にこの点を指摘していただきありがとうございます。

0

キーアップイベントを処理する代わりに、サブミットイベントを処理します。そこにチェックを入れてすべてが完了したことを確認し、そうでなければfalseを返します。

+0

いいえ、オートコンプリート設定全体が、対応するテキストボックスのkeyupイベントにバインドされています。もう一つの問題は、私がこのオートコンプリートジェネリックを作りたいということです。だから私が達成しようとしているのは、それがバインドされているテキストボックスのリターンキーをトラップし、単に選択された値を使用するだけです。フォームは送信しません! – DeeTee

+0

@DeeTeeそれがポイントです。ブラウザがキーダウン時にフォームを送信している間、キーアップ時にブラウザのデフォルト動作を禁止します。 – CronosS

+0

@DeeTeeフォームを送信したくない場合は、すべての条件が満たされたときに送信するように送信イベントを処理するのが最も簡単です。さもなければ、あなたのhtmlのフォームを送信に使用せずに、Ajaxの投稿を送信ボタンのクリックで行ってください。 – evasilchenko

関連する問題