如何将已经工作的 jquery ajax 发布请求重用于自动完成功能?

Posted

技术标签:

【中文标题】如何将已经工作的 jquery ajax 发布请求重用于自动完成功能?【英文标题】:How to reuse the jquery ajax post request, that is already working, to the autocomplete functionality? 【发布时间】:2018-10-30 09:51:02 【问题描述】:

我有一个“显示城市”链接,当点击它时,它会显示一些城市的模式:

<a class="city" id="showCities" 
 data-toggle="modal" data-target="#modal2" href=""> Show cities</a>

当用户在模态框内单击一个城市时,模态框会关闭,并在“#conferences”div 中显示会议表中“城市”列等于单击的城市的会议。这适用于 ajax 请求。

怀疑:

我的怀疑是因为我想重用这部分代码,即 ajax 请求,用于自动完成搜索 输入 ID 为“#search”。例如,当用户在此自动完成输入中写入“Ne”时,它会显示为 Newcastle。 这工作正常。

但是当用户在 Newcastle 中点击时,它应该出现在会议的 div“#conferences”中 城市栏为“纽卡斯尔”。对于这部分,我对如何重用 ajax 发布请求的代码有疑问 模态框内的城市被点击。你知道如何实现吗?

就像用户点击“纽卡斯尔”时一样 他被重定向到“http://proj.test/conferences/where/city/Newcastle”,并且显示城市是纽卡斯尔的会议(在这种情况下只有 1 个):

["id":2,"name":"conf test","city":"Newcastle",...]

但是应该发生的是城市专栏的会议 是纽卡斯尔出现在#conferences div中。

自动完成控制器:

class AutocompleteController extends Controller

    public function index()
    return view('autocomplete.index');
    

    public function search(Request $request)
        $search = $request->term;
        $conferences = Conference::where('name', 'LIKE', '%'.$search.'%')->get();

        $cities = Conference::where('city', 'LIKE', '%'.$search.'%')->get();

        $data= [];
        foreach ($conferences as $key => $value)
            $data[] = ['category'=> 'Conferences', 'value' => $value->name, 'url' => 'conference/'.$value->id.'/'.$value->slug];
        

        foreach ($cities as $key => $value)
            $data[] = ['category'=> 'Cities', 'value' => $value->city, 'url' => 'conferences/where/city/'.$value->city];
        
        return response($data);
    

自动完成 Jquery:

$.widget( "custom.catcomplete", $.ui.autocomplete, 
_create: function() 
    this._super();
    this.widget().menu( "option", "items", "> :not(.ui-autocomplete-category)" );
    ,
    _renderMenu: function( ul, items ) 
    var that = this,
    currentCategory = "";
    $.each( items, function( index, item ) 
        var li;
        if ( item.category != currentCategory ) 
            ul.append( "<li class='ui-autocomplete-category bg bg-light-gray2 h6 font-weight-bold text-heading-blue'>"
            + item.category + "</li>" );
            currentCategory = item.category;
        
        li = that._renderItemData( ul, item );
        if ( item.category ) 
        li.attr( "aria-label", item.category + " : " + item.label );
        
    );
    
);

$("#search").catcomplete(
    source: " URL::to('autocomplete-search') ",
    select: function(event, ui) 
    window.location.href = ui.item.url;

点击 Show citis 时出现的模态:

<div class="modal fade bd-example-modal-lg" id="modal2" tabindex="-1" role="dialog" aria-labelledby="myLargeModalLabel" aria-hidden="true">
    <div class="modal-dialog modal-lg">
        <div class="modal-content">
            <div class="modal-body">
                <ul class="modal-list row">
                    @foreach($cities as $city)
                    <li class="col-lg-4 col-md-6 col-sm-12">
                        <a  class="" name="city" id="$city">$city</a>
                    </li>
                    @endforeach
                </ul>
            </div>
        </div>
    </div>
</div>

显示会议、结果的 div #conferences":

<div class="row" id="conferences">
    @foreach(conferences as $conference)
    <div class="col-12 col-sm-6 col-lg-4 col-xl-3 mb-4">
        <img class="card-img-top" src="$conference->image" >
        <div class="card-body">
            <h5 class="card-title h6 font-weight-bold text-heading-blue">$conference->name</h5>
            <p class="card-text font-size-sm"><i class="fa fa-map-marker" aria-hidden="true"></i> $conference->place,
                $conference->city</p>
        </div>
    </div>
    @endforeach
</div>

jQuery ajax 请求:

$("a[name='city']").on('click', function()

    $('#showCities').html($(this).text()+' <i class="fa fa-caret-down" aria-hidden="true"></i>');

        var city = $(this).attr("id");

        $.ajax(

        url: ' route('city.conferences',null) /' + city,
        type: 'GET',
        success:function(result)
        console.log(result)

        $('#conferences').empty();
        var newConferences='';
        var placeholder = "route('conferences.show', ['id' => '1', 'slug' => 'demo-slug'])";
        $.each(result, function(index, conference) 
        $('#modal2').modal('hide');
        var url = placeholder.replace(1, conference.id).replace('demo-slug', conference.slug);

        newConferences += '<div class="col-12 col-sm-6 col-lg-4 col-xl-3 mb-4">\n' +
            '    <div class="card-body">\n' +
                '      <h5 class="card-title h6 font-weight-bold text-heading-blue">'+conference.name+'</h5>\n' +
                '      <p class="card-text font-size-sm"><i class="fa fa-map-marker" aria-hidden="true"></i> '+conference.city+'</p>\n' +
                '     </div>\n' +
            '   </div>\n';
        );
        $('#conferences').html(newConferences);

        ,
        error: function(error) 

        console.log(error.status)
        
    );
);

【问题讨论】:

【参考方案1】:

一种选择是使用数据属性。作为额外的批评,根据您的 AJAX 请求的工作方式,您可能不想使用城市名称作为 ID;特别是如果请求中可能返回多个同名城市(ID 将发生冲突并产生意外结果)。

<div class="modal fade bd-example-modal-lg" id="modal2" tabindex="-1" role="dialog" aria-labelledby="myLargeModalLabel" aria-hidden="true">
    <div class="modal-dialog modal-lg">
        <div class="modal-content">
            <div class="modal-body">
                <ul class="modal-list row" id="cities-list>
                    @foreach($cities as $city)
                    <li class="col-lg-4 col-md-6 col-sm-12">
                        <a class="" data-city-name="city" name="city" id="$city">$city</a>
                    </li>
                    @endforeach
                </ul>
            </div>
        </div>
    </div>
</div>

例如,我在上面的代码中添加了一些 ID。然后,您只需在链接的点击事件中访问这些值,如下所示:

$('#cities-list li a').on('click', function() 
    // push city name to #conferences div
    $('#conferences').append($('<p />').text($(this).attr('data-city-name')));
);

【讨论】:

谢谢,但这部分已经在使用问题代码“jQuery ajax request”。我的疑问是如何将该代码重用于自动完成功能。因为在点击城市时的自动完成中,用户被重定向到“proj.test/conferences/where/city/Newcastle”,并且会出现城市等于点击城市的会议,而不是结果出现在会议 div 中。 问题应该是因为这里 "$("#search").catcomplete( source: " URL::to('autocomplete-search') ", select: function( event, ui) window.location.href = ui.item.url; );"" 当点击城市“Newcastle”时,用户被重定向到“proj.test/conferences/where/city/Newcastle”,但是用户不应该被重定向到那个页面,应该对那个 url 进行 ajax 请求。只有在自动完成输入中单击会议名称时,用户应该被重定向到会议详细信息页面,这工作正常,问题仅在于单击城市时。 that._renderItemData( ul, item ); 在哪里?你能显示那个代码吗? 基本上,绘制您遇到问题的链接的代码在哪里?它显然不在模态中,对吗? renderItemData 来自 jquery ui 插件。并且它在链接被渲染的那部分。

以上是关于如何将已经工作的 jquery ajax 发布请求重用于自动完成功能?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Symfony 和 Jquery 发出 POST Ajax 请求

如何在 jQuery 中使用 Ajax 请求发送 FormData 对象? [复制]

如何在 jQuery 中使用 Ajax 请求发送 FormData 对象? [复制]

如何在 jQuery 中使用 Ajax 请求发送 FormData 对象? [复制]

如何将 JQuery AJAX 请求中的字符串值传递给 Spring Boot 控制器?

如何将请求数据传递到 JQuery.ajax 中的 Complete 事件中