我可以使dijit / form / FilteringSelect减少持久性吗?

时间:2015-04-30 13:38:32

标签: javascript regex dojo fuzzy-search dijit.form

我对Dijit's FilteringSelect小部件的工作方式已经有一段时间不满意了,并且一直在修改使用Dojo 1.10尝试为我的用例改进它。不幸的是,似乎没有任何设置组合是完全正确的,主要是因为它们不能一起工作。

  • 设置queryExpr: '*${0}*'很不错,但它会自动完成疯狂。
  • 设置autoComplete: true很好,只要您想从头开始输入整个文本,直到找到匹配为止。不幸的是,如果你想从中间的某个地方开始,它就会变成一个痛苦的屁股。当然你可以将searchDelay: N设置为足以捕获所有输入内容的东西,但只要你让它在菜单中返回增量结果,BAM就能保持输入并最终在其他地方找到匹配这个词出了窗外。

我真正想要的东西就像一个模糊查找器在shell或体面的文本编辑器中完成(例如fzf)。这样的查找器跳过中间字符,基本上按字符拆分输入并在它们之间添加隐式通配符。你继续输入,直到第一个匹配是你想要的,然后结束取景器,让它替换值。

我开始搞乱实现这个的方法,但没有走得太远。我考虑过劫持_patternToRegExp(),但很快发现我的商店(dojo/data/ItemFileReadStore的实例包含一些JSON数据)设置_oldAPI标志和that never gets executed。我很高兴更新商店,但对我而言,这并不容易让人更容易。黑客攻击我的商店,事情变得无法控制,我决定采用一种较少参与但更加狡猾的方法。

如果您关闭自动完成功能并将选项设置为在单词中间进行匹配,则会得到非常接近所需内容的结果列表。在输入足够的输入以获得匹配之后以及在 Tab 之前,用户要做的就是点击 Down 。那么问题就变成了如何避免需要这种人工干预并变得更加宽容。

define(["dijit/form/FilteringSelect"], function(FilteringSelect){
return declare("alerque.FuzzyFilter", [FilteringSelect], {
    autoComplete: false,
    highlightMatch: 'all',
    ignoreCase: true,
    queryExpr: '*${0}*',
    searchDelay: 0,

    _patternToRegExp: function(qs) {
        // If this ever actually got called, maybe we could
        // return qs split with wild cards between all characters
        return this.inherited(arguments);
    },

    onblur: function() {
        this._autoCompleteText(this.get('displayedValue'));
        // Pick first match from menu
        return this.inherited(arguments);
    }
})});

劫持onblur()函数似乎是制作一个默认为第一个匹配的小部件的正确位置,如果你选中或点击,但我无法弄清楚如何实际使用来自的第一个匹配菜单。

如何通过自动完成最佳匹配来进行更强大的模糊搜索?我不想要一个ComboBox,该值必须最终成为我的JSON数据集中的值之一。与此同时,我希望输入选项比从一开始键入值或者必须手动选择匹配更加笨拙。

1 个答案:

答案 0 :(得分:1)

可能是onBlur的解决方法/解决方案:

设置queryExpr =" \ $ {0} " 没有延迟和自动完成关闭

在过滤选择的onkeyup上你存储弹出匹配的第一个值,然后在onblur之后将filteringselect的displayedValue /值更改为第一个弹出窗口中的值(如果找到并且匹配...)< / p>

从弹出窗口中获取第一个值:

第一个显示的值可以在

  • 元素中找到,其中id = YOUR_FILTERING_SELECT_ID +&#34; _popup0&#34;

    所以如果你的id =&#34; mySearchData&#34;然后查找id&#34; mySearchData_popup0&#34;

    如果该元素存在,则将innerHTML存储在某处(隐藏元素或var ...)

    从innerHTML调整值以匹配商店中的值:

    根据您从innerHTML获得的值,从中删除span元素,使其与您的数据存储区中的某个值匹配

    如果您的过滤选择了我的ID =&#34; mySearchField&#34;如果你正在搜索&#34; 123&#34;弹出窗口中的第一个匹配显示&#34;测试123号码&#34; 那么第一个弹出窗口中的innerHTML值将如下所示

    <li id="mySearchField_popup0" class="dijitReset dijitMenuItem" role="option">
    test 
    <span class="dijitComboBoxHighlightMatch">123</span>
    number
    </li>
    

    所以,一点点String乱画(只需从innerHTML值中删除span标签),你就会得到一个与onblur之后的第一个结果相匹配的值。