2012-12-06 176 views
15

我正在嘗試添加自定義自動完成功能,我想要在用戶輸入時觸發(當然可配置)。我發現自動完成的幾個例子爲codemirror:任何keyup後的codemirror自動完成?

http://codemirror.net/demo/complete.htmlhttp://codemirror.net/demo/xmlcomplete.html

但是這兩個觸發特定的鍵(控制-空間之一,「<」的除外),並都使用extraKeys功能來處理事件,但我想從任何鍵觸發。我試過以下幾種:

 var editor = CodeMirror.fromTextArea(document.getElementById("code"), 
     { 
      lineNumbers: true, 
      mode: "text/x-mysql", 
      fixedGutter: true, 
      gutter: true, 
//   extraKeys: {"'.'": "autocomplete"} 
      keyup: function(e) 
      { 
       console.log('testing'); 
      }, 
      onkeyup: function(e) 
      { 
       console.log('testing2'); 
      } 
     }); 

但是沒有運氣。任何關於如何從任何關鍵事件觸發的建議?

回答

2
onKeyEvent: function(e , s){ 
       if (s.type == "keyup") 
       { 
        console.log("test"); 
       } 
      } 
11

還顯示自動完成控件:

onKeyEvent: function (e, s) { 
    if (s.type == "keyup") { 
     CodeMirror.showHint(e); 
    } 
} 
3
editor.on('keyup', function(){ 
    CodeMirror.commands.autocomplete(editor); 
}); 

它可以工作

+0

這不提供問題的答案。要批評或要求作者澄清,在他們的帖子下留下評論 - 你總是可以評論你自己的帖子,一旦你有足夠的[聲譽](http://stackoverflow.com/help/whats-reputation),你會能夠[評論任何帖子](http://stackoverflow.com/help/privileges/comment)。 –

+3

這是這個問題的答案!在代碼下方添加此代碼,每次鍵入時,它都會觸發自動填充事件。 –

11
editor.on("inputRead",function(cm,changeObj){ 
    // hinting logic 
}) 

據我所看到的, 「inputRead」 是展現最好的事件「codemirror」中的「自動完成」。 唯一的缺點是你不能在退格或刪除時顯示提示。

+2

你能否詳細說明爲什麼它是最好的選擇?此外,如果您可以展示一些成功實施的示例提示邏輯,那將有助於其他人。 – shmim

+2

「keyup」/「keydown」事件捕獲上/下/右/左鍵。所以「inputRead」是捕捉提示邏輯的最佳方式。 就暗示邏輯而言,它取決於你想要實現它的語言。對於JavaScript,你可以看看「tern.js」。爲了構建提示邏輯,在繼續之前,需要查看目標語言的標記器,語法分析器和語義。 –

+0

謝謝,我甚至沒有意識到這件事。對於提示邏輯,我只是​​使用'cm.showHint({completeSingle:false})'。 – Nickkk

18

對於V5.7,以前提出的解決方案都不適用於我(我認爲它們甚至在早期版本中也有錯誤)。我解決方案

myCodeMirror.on("keyup", function (cm, event) { 
     if (!cm.state.completionActive && /*Enables keyboard navigation in autocomplete list*/ 
      event.keyCode != 13) {  /*Enter - do not open autocomplete list just after item has been selected in it*/ 
      CodeMirror.commands.autocomplete(cm, null, {completeSingle: false}); 
     } 
    }); 

它是如何工作的:

這將打開只有當它尚未打開自動完成彈出(否則鍵盤導航會造成重開與再次選擇的第一個項目的彈出) 。

當你點擊輸入你想要彈出關閉,所以這是一個特殊情況的字符,不應該觸發自動完成(你可能會考慮一個情況,當你想顯示antocompletion雖然空行)。

然後,最後一個修正是設置completeSingle: false,它可以防止您在輸入某個單詞時出現的情況,而在中間它會自動完成,並且您繼續通過反射進行輸入。所以用戶總是需要從彈出窗口中選擇想要的字符串(即使它是單個選項)。

+1

這個工作原理除了在評論結束時的雜散括號破壞了代碼:/ *輸入 - 剛剛選擇了項目後不要打開自動完成列表* /)<<<本支架 –

+0

@KB。,謝謝,修正了 –

+0

'null'是什麼? –

9

最類似IntelliSense的行爲可以通過實現這一目標:

var ExcludedIntelliSenseTriggerKeys = 
{ 
    "8": "backspace", 
    "9": "tab", 
    "13": "enter", 
    "16": "shift", 
    "17": "ctrl", 
    "18": "alt", 
    "19": "pause", 
    "20": "capslock", 
    "27": "escape", 
    "33": "pageup", 
    "34": "pagedown", 
    "35": "end", 
    "36": "home", 
    "37": "left", 
    "38": "up", 
    "39": "right", 
    "40": "down", 
    "45": "insert", 
    "46": "delete", 
    "91": "left window key", 
    "92": "right window key", 
    "93": "select", 
    "107": "add", 
    "109": "subtract", 
    "110": "decimal point", 
    "111": "divide", 
    "112": "f1", 
    "113": "f2", 
    "114": "f3", 
    "115": "f4", 
    "116": "f5", 
    "117": "f6", 
    "118": "f7", 
    "119": "f8", 
    "120": "f9", 
    "121": "f10", 
    "122": "f11", 
    "123": "f12", 
    "144": "numlock", 
    "145": "scrolllock", 
    "186": "semicolon", 
    "187": "equalsign", 
    "188": "comma", 
    "189": "dash", 
    "190": "period", 
    "191": "slash", 
    "192": "graveaccent", 
    "220": "backslash", 
    "222": "quote" 
} 

EditorInstance.on("keyup", function(editor, event) 
{ 
    var __Cursor = editor.getDoc().getCursor(); 
    var __Token = editor.getTokenAt(__Cursor); 

    if (!editor.state.completionActive && 
     !ExcludedIntelliSenseTriggerKeys[(event.keyCode || event.which).toString()] && 
     (__Token.type == "tag" || __Token.string == " " || __Token.string == "<" || __Token.string == "/")) 
    { 
     CodeMirror.commands.autocomplete(editor, null, { completeSingle: false }); 
    } 
}); 
+0

你能解釋一點點嗎?特別是'__Token'條件,它似乎適用於xml(?) – Christian

+0

這個數組包含鍵碼,它不應該觸發智能感知下拉,即。功能鍵,移位或控制。如果引發CodeMirror中的事件,將按照此數組檢查按下的鍵,並且僅當處理程序不在該處時,該處理程序纔會繼續。這只是爲了避免不必要的彈出菜單(我覺得非常煩人)。 –

+0

我添加了「32」:「空格」並刪除了「190」:「句點」更像是Visual Studio IntelliSense之類的。 – Jan

1

讓我分享任何包含KEYUP後自動完成(對蜂巢SQL)一個完整的例子:

包括腳本和樣式:

<link rel="stylesheet" href="/static/codemirror/lib/codemirror.css"> 
<link rel="stylesheet" href="/static/codemirror/theme/material.css"> 
<link rel="stylesheet" href="/static/codemirror/addon/hint/show-hint.css" /> 

<script type="text/javascript" src="/static/codemirror/lib/CodeMirror.js"></script> 
<script type="text/javascript" src="/static/codemirror/mode/sql/sql.js"></script> 
<script type="text/javascript" src="/static/codemirror/addon/hint/show-hint.js"></script> 
<script type="text/javascript" src="/static/codemirror/addon/hint/sql-hint.js"></script> 

HTML:

<textarea id="code" name="code" rows="4" placeholder="" value=""></textarea> 

腳本:

<script> 

    $(function() { 
     initSqlEditor(); 
     initAutoComplete(); 
    }); 

    // init sql editor 
    function initSqlEditor() { 

     var editor = CodeMirror.fromTextArea(document.getElementById('code'), { 
      autofocus: true, 
      extraKeys: { 
       "Tab": "autocomplete" 
      }, 
      hint: CodeMirror.hint.sql, 
      lineNumbers: true, 
      mode: 'text/x-hive', 
      lineWrapping: true, 
      theme: 'material', 
     }); 

     editor.on('keyup', function(editor, event){ 
      // type code and show autocomplete hint in the meanwhile 
      CodeMirror.commands.autocomplete(editor); 
     }); 
    } 

    /** 
    * Init autocomplete for table name and column names in table. 
    */ 
    function initAutoComplete() { 

     CodeMirror.commands.autocomplete = function (cmeditor) { 

      CodeMirror.showHint(cmeditor, CodeMirror.hint.sql, { 

       // "completeSingle: false" prevents case when you are typing some word 
       // and in the middle it is automatically completed and you continue typing by reflex. 
       // So user will always need to select the intended string 
       // from popup (even if it's single option). (copy from @Oleksandr Pshenychnyy) 
       completeSingle: false, 

       // there are 2 ways to autocomplete field name: 
       // (1) table_name.field_name (2) field_name 
       // Put field name in table names to autocomplete directly 
       // no need to type table name first. 
       tables: { 
        "table1": ["col_A", "col_B", "col_C"], 
        "table2": ["other_columns1", "other_columns2"], 
        "col_A": [], 
        "col_B": [], 
        "col_C": [], 
        "other_columns1": [], 
        "other_columns2": [], 
       } 
      }); 
     } 
    } 

</script> 
1

改變阿列克Pshenychnyy的回答有點(見here),回答,因爲我不能添加評論

下面的代碼也從不必要的情況下

即將停止自動完成
editor.on("keyup", function (cm, event) { 
if (!cm.state.completionActive && /*Enables keyboard navigation in autocomplete list*/ 
    event.keyCode != 13 &&   /*Enter - do not open autocomplete list just after item has been selected in it*/ 
    event.keyCode != 16 &&  //not for shift 
    event.keyCode != 17 &&  //not for ctrl 
    event.keyCode != 18 &&  //not for alt 
    event.keyCode != 60 &&  //not for <or> 
    event.keyCode != 32 &&  //not for the space key 
    event.keyCode != 8 &&  //not for the backspace key 
    event.keyCode != 9){  //not for the tab key 
     CodeMirror.commands.autocomplete(cm, null, {completeSingle: false}); 
    } 
}); 

如果這個列表令人討厭打字給你,或者你認爲這個列表還有更多的東西,那麼創建一個 函數可能是一個好主意,取決於哪個鍵被按下,將事件作爲參數然後使用它來變爲真或假。