最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Bootstrap dropdown not working after initial ajax form submission - Stack Overflow

programmeradmin3浏览0评论

I have a dropdown on my page, manager.php, here. Sorry for the formatting - bootstrap.:

  <!-- Bootstrap -->
  <script type="text/javascript" src=".3.2/js/bootstrap.min.js"></script>
  <link rel="stylesheet" href="../../css/bootstrapstyle.css">
  <!-- Bootstrap Dropdown Enhancements-->
  <script type="text/javascript" src="../../js/dropdowns-enhancement.js"></script>
  <link rel="stylesheet" href="../../css/dropdowns-enhancement.css">

<div class="row">
  <div class="col-lg-6">
    <div class="input-group">
      <div class="input-group-btn">
        <button type="button" class="btn dropdown-toggle btn-primary" data-toggle="dropdown" aria-expanded="false">Search By <span class="caret"></span></button>
        <ul id="searchBy" class="dropdown-menu" role="menu">
          <li class="disabled"><a href="#">Search By...</a></li>
          <li><a href="#">cost</a></li>
          <li><a href="#">name</a></li>              
        </ul>
      </div>               
    </div>
  </div>
</div>

<div id="everything">
</div>

This code works fine when I load manager.php directly and the dropdown initializes, but this is not how I need the code to work.

The user begins on return.php; this page collects a bunch of data from the user and returns it to manager.php.

Once the user selects to do so on return.php, this code is run:

$.ajax({
      type: 'POST',
      url: 'manager.php',      
      data: {number:number, location:location, project:project, comments:comments},        
        success:function(data){
        $('#everything').html(data);                                                            
        }
  });

The ajax call works correctly, and it loads the data returned from manager.php into the everything div. It passes along the data as expected. The only thing that DOESN'T work upon loading manager.php into the DIV is the drop-down. I need to understand what I'm doing wrong to cause this functionality so I can prevent doing it in the future.

I have a dropdown on my page, manager.php, here. Sorry for the formatting - bootstrap.:

  <!-- Bootstrap -->
  <script type="text/javascript" src="https://netdna.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"></script>
  <link rel="stylesheet" href="../../css/bootstrapstyle.css">
  <!-- Bootstrap Dropdown Enhancements-->
  <script type="text/javascript" src="../../js/dropdowns-enhancement.js"></script>
  <link rel="stylesheet" href="../../css/dropdowns-enhancement.css">

<div class="row">
  <div class="col-lg-6">
    <div class="input-group">
      <div class="input-group-btn">
        <button type="button" class="btn dropdown-toggle btn-primary" data-toggle="dropdown" aria-expanded="false">Search By <span class="caret"></span></button>
        <ul id="searchBy" class="dropdown-menu" role="menu">
          <li class="disabled"><a href="#">Search By...</a></li>
          <li><a href="#">cost</a></li>
          <li><a href="#">name</a></li>              
        </ul>
      </div>               
    </div>
  </div>
</div>

<div id="everything">
</div>

This code works fine when I load manager.php directly and the dropdown initializes, but this is not how I need the code to work.

The user begins on return.php; this page collects a bunch of data from the user and returns it to manager.php.

Once the user selects to do so on return.php, this code is run:

$.ajax({
      type: 'POST',
      url: 'manager.php',      
      data: {number:number, location:location, project:project, comments:comments},        
        success:function(data){
        $('#everything').html(data);                                                            
        }
  });

The ajax call works correctly, and it loads the data returned from manager.php into the everything div. It passes along the data as expected. The only thing that DOESN'T work upon loading manager.php into the DIV is the drop-down. I need to understand what I'm doing wrong to cause this functionality so I can prevent doing it in the future.

Share Improve this question edited Jun 4, 2015 at 17:24 Brian Powell asked Jun 1, 2015 at 16:52 Brian PowellBrian Powell 3,4114 gold badges37 silver badges64 bronze badges 6
  • 3 because you are probably replacing the html and the events do not magically get hooked back up. You need to rerun the code or learn about event delegation. – epascarello Commented Jun 1, 2015 at 17:49
  • can you provide plunker that reproduced problem? – Grundy Commented Jun 4, 2015 at 17:21
  • Can you post the code that you call to create the dropdown? And have you tried simply recalling $("#searchBy").dropdown(); in the AJAX callback? – tymeJV Commented Jun 4, 2015 at 17:28
  • @tymeJV, the dropdown is the first section of code in my original question. It operates through bootstrap's dropdown enhancements .css and .js files (behigh.github.io/bootstrap_dropdowns_enhancement) – Brian Powell Commented Jun 4, 2015 at 17:32
  • @JohnWu -- So have you tried recalling it? – tymeJV Commented Jun 4, 2015 at 17:32
 |  Show 1 more comment

5 Answers 5

Reset to default 7

You can't initialize the bootstrap component after page load by adding bootstrap classes. To do this, you have to initialize it yourself

To initialize a dropdown, write this code:

$('.dropdown-toggle').dropdown();

after

$('#everything').html(data);

for more details: http://getbootstrap.com/javascript/#dropdowns

You need to manually reset the dropdown after you've loaded the data into the everything div. I've modified your AJAX call to show you where to put the call.

$.ajax({
      type: 'POST',
      url: 'manager.php',      
      data: {number:number, location:location, project:project, comments:comments},        
        success:function(data){
          $('#everything').html(data);
          $('#searchBy').dropdown();
        }
  });

The dynamic loading you're doing doesn't cause the DOM to reload forcing the drop down to be reinitialized. After you're AJAX call has completed, you can then reset the bootstrap drop down manually by calling .dropdown();.

EDIT

Generally functions in bootstrap for features are setup using a $( document ).ready() call. This function executes once, after the DOM has been loaded and only after the DOM has has been fully loaded. Since your manipulating the DOM, you are not causing the function to be triggered again, and you need to manually trigger the feature you need.

You also want to load your includes only once on each page. They need to on manager.php in order for the function be available when you go into your success method. I'd suggest using a template for your project so you manage all your includes in one place. Also, if your using manager.php as a page to be included in another page, it's okay if you don't have the reference to the JavaScript pieces won't work since you don't want users accessing that component on it's own.

The reload you are doing appears to be forcing the content to be re-added to the page, thus forcing the $( document ).ready() call in the included file to be re-executed. You can do this, but it's very inefficient.

So I'm not sure why this works, but it has so far:

I've modified my ajax call to reload bootstrap's .js file prior to executing the return.

function reload_js(src) {
    $('script[src="' + src + '"]').remove();
    $('<script>').attr('src', src + '?cachebuster='+ new Date().getTime()).appendTo('head');
}

$.ajax({
      ...      
        success:function(data){
        reload_js('https://netdna.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js');                
        $('#everything').html(data);                                                            
        }
  });

For the bounty, can someone explain to me:

a.) Why do I need to force the reload of bootstrap.min.js?

b.) Why is this even necessary if I have a link to this file in BOTH files' <head> sections?

  <!-- Bootstrap -->
  <script type="text/javascript" src="https://netdna.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"></script>
  <link rel="stylesheet" href="../../css/bootstrapstyle.css">

I've also tried loading it in one, but not the other (so I don't load it twice,) and that doesn't do anything.

c.) Why does this work? What is it doing?

page will load DOM 1st time. ajax just update a part of page, so new elements you add wont have prop you defined. you need to reinit as you did or make something like this

http://hussain.io/2012/01/reinitializing-jquery-event-on-ajax-response/

I want to share my experience: I am doing dynamical multi layer dropdown menu, meaning that user can customize how many parents and children this menu has. So, after ajax submission, I empty the navbar where the menu is $(document).find('.navbar-nav').empty();

And fill it with the new html like:
html.push("<li class="nav-item dropdown"> <a class="nav-link" href="#">" + val.PageName + ""); // It is OnTop

and append it to my navbar: $(".navbar-nav").append(html.join(''));

and the dropdown item is there but it was not working. The reason is that you have to load all the js and css for that new html items again.

Here is the good example os static multilayer menu: https://github.com/kmlpandey77/bootnavbar

So, the main point is after you append new html to the DOM item, you need to reload the page so it to work, or load resources that is that new html items are using;

Here how to load after ajax and append process :

        jQuery.ajaxSetup({ async: false });
        $.get("wwwroot/bootnavbar/bootnavbar.css")
            .done(function () {
                // exists code 

                jQuery.ajaxSetup({
                    async: true

                });

            }).fail(function () {
                // not exists code

                jQuery.ajaxSetup({ async: true });

            });
发布评论

评论列表(0)

  1. 暂无评论