Laravel 5 - 预先搜索:如何查找带重音或没有重音的单词

时间:2018-03-13 16:56:57

标签: search diacritics bootstrap-typeahead

我已经实现了bootstrap-typeahead,并且当搜索例如“vision”(没有重音)这个词时,我希望typeahead找到同时存在“visión”的巧合(带重音)和“愿景”。

我已经看过几个例子,比如:accent insensitive regex,但我不明白在typeahaead中实现它的形式。我也看到了这一点:Typeahead insensitive accent我创建了一个新文件bootstrap3-typeahead-ci.min.js,如此答案所示,但这不起作用。一些帮助?感谢。

EDITED 补充问题

这是我的 typeahead.js (简化)

$(document).ready(function(){

function buscar(texto){
    $('#texto').val(texto);
    $('#buscar').submit();
}

if ($('.typetitulo').length) {

    var lang = $("#lang_js").data('value');

    var json_location = 'storage/json/';
    var noticia_location = 'actualidad/';

    var noticias = new Bloodhound({
        prefetch: {
            url: json_location + lang + '/' + 'noticia.json',
            cache: false
        },
        datumTokenizer: Bloodhound.tokenizers.obj.whitespace('title', 'lead'),
        queryTokenizer: Bloodhound.tokenizers.whitespace
    });

    var documentos = new Bloodhound({
        prefetch: {
            url: json_location + '/' + 'documento.json',
            cache: false
        },
        datumTokenizer: Bloodhound.tokenizers.obj.whitespace('name', 'description'),
        queryTokenizer: Bloodhound.tokenizers.whitespace
    });

    $('.typetitulo').typeahead(

        {
            name: 'noticias',
            display: 'title',
            source: noticias,
            templates: {
                header: "<h3>"+ tit_actualidad +"</h3>",
                suggestion: function (item) {
                    var enlace = noticia_location + item.id + '/' + item.slug;
                    return "<div><a href='"+enlace+"'>" + item.title + "</a></div>";
                }
            }
        },

        {
            name: 'documentos',
            display: 'name',
            source: documentos,
            templates: {
                header: "<h3>"+ tit_documentos +"</h3>",
                suggestion: function (item) {
                    var enlace = item.path;
                    return "<div><a href='"+enlace+"'>" + item.name + "</a></div>";
                }
            }
        }).on('typeahead:selected', function(e){
        e.target.form.submit();
    });
  }
});

视图

{!! Form::open([
'route' => 'buscar',
'id' => 'buscar',
'name' => 'buscar',
'class' => 'buscador col-xs-12',
'method' => 'POST',
'accept-charset' => 'utf-8'
]) !!}

<input name="texto" class="input_buscador typetitulo" autocomplete="off" type="text"/>
<input name="lang" type="hidden" value="{{$lang}}"/>

{!! HTML::image('images/web/icons/lupa.svg', '',  array('height' => '30', 'class' => 'boton_buscador', 'onclick' => 'document.buscar.submit()') ) !!}

{!! Form::close() !!}

// .... //

             @if(isset($data['noticias']) && $data['noticias']->count() !== 0)
                    <div class="col-xs-12 pad_inf_2">
                        <h3>@lang('header.actualidad')</h3>

                        @foreach($data['noticias'] as $value)
                            <span class="item">
                                <a href="{{ route('noticia', [$value['id'], $value['slug']]) }}">{{$value['title']}}</a>
                            </span>
                        @endforeach
                    </div>
            @endif

            @if(isset($data['docs']) && $data['docs']->count() !== 0)
                    <div class="col-xs-12 pad_inf_2">
                        <h3>@lang('header.biblioteca')</h3>

                        @foreach($data['docs'] as $value)
                            <span class="item">
                                <a href="{{ asset(($value['type'] == 'url')? $value['url'] : $value['path']) }}" target="_blank">{{$value['name']}}</a>
                            </span>
                        @endforeach
                    </div>
            @endif

这是 typeahead-insensitive.js ,如下所示:[{3}}

// function for making a string accent insensitive
    $.fn.typeahead.Constructor.prototype.normalize = function (str) {
        // escape chars
        var normalized = str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");

        // map equivalent chars
        normalized = normalized.replace(/[aãáàâ]/gi, '[aãáàâ]');
        normalized = normalized.replace(/[eẽéèê]/gi, '[eẽéèê]');
        normalized = normalized.replace(/[iĩíìî]/gi, '[iĩíìî]');
        normalized = normalized.replace(/[oõóòô]/gi, '[oõóòô]');
        normalized = normalized.replace(/[uũúùû]/gi, '[uũúùû]');
        normalized = normalized.replace(/[cç]/gi, '[cç]');

        // convert string to a regular expression
        // with case insensitive mode
        normalized = new RegExp(normalized, 'gi');

        // return regular expresion
        return normalized;
    }

    // change 'matcher' method so it became accent insensitive
    $.fn.typeahead.Constructor.prototype.matcher = function (item) {

        // get item to be evaluated
        var source = this.displayText(item);

        // make search value case insensitive
        var normalized = this.normalize(this.query);

        // search for normalized value
        return source.match(normalized);
    }

    // change 'highlighter' method so it became accent insensitive
    $.fn.typeahead.Constructor.prototype.highlighter = function (item) {

        // get html output
        var source = this.displayText(item);

        // make search value case insensitive
        var normalized = this.normalize(this.query);

        // highlight normalized value in bold
        return source.replace(normalized, '<strong>$&</strong>');
    }

布局中我添加了:

{{--  Typeahead --}}
    {!! HTML::script('https://cdnjs.cloudflare.com/ajax/libs/typeahead.js/0.11.1/typeahead.bundle.min.js') !!}
    {!! HTML::script('js/web/typeahead-insensitive.js') !!}
    {!! HTML::script('js/web/typeahead.js') !!}

0 个答案:

没有答案