Bootstrap dropdown not working after initial ajax form submission

18,251

Solution 1

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.

Solution 2

you can't initialize the bootstrap component after page load by adding bootstrap clasaes. To do this you have to initialize it by your self

To initialize a dropdown write this code

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

after

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

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

Solution 3

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?

Share:
18,251

Related videos on Youtube

Brian Powell
Author by

Brian Powell

Updated on June 19, 2022

Comments

  • Brian Powell
    Brian Powell almost 2 years

    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.

    • epascarello
      epascarello almost 9 years
      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.
  • Brian Powell
    Brian Powell almost 9 years
    Yup, tried to delete :). Unfortunately though, your answer does not cause the dropdown on manager.php to function for me. My answer (below) does work, but I don't understand WHY.
  • Brian Powell
    Brian Powell almost 9 years
    This works as well - adding dropdown() to the .dropdown-toggle class, instead of the <ul id="searchBy". That's interesting that I can either do this, or force the reload of bootstrap.js. Either way, I appreciate this! I like having more than one way to accomplish something.
  • Brian Powell
    Brian Powell almost 9 years
    It seems your logic was indeed correct - we were just focusing on the wrong element. Adding $('.dropdown-toggle').dropdown(); after the success call works, but I don't see any difference in the Chrome console (speed-wise) between this solution, and my solution. But it's really nice having two methods to solve this now; it's been bugging me for months! Either way, I appreciate the time you've put into this to help me understand this.
  • Brian Powell
    Brian Powell almost 9 years
    When you say doesn't cause the DOM to reload, does that mean the <head> section of manager.php doesn't get loaded? I'm not sure what this signifies entirely...
  • ICodeForCoffee
    ICodeForCoffee almost 9 years
    The head section is part of it, but the entire html document is in the DOM (Document Object Model). Every webpage has it's own DOM that the browser works with and you can manipulate with JavaScript. en.wikipedia.org/wiki/Document_Object_Model
  • PHP Worm...
    PHP Worm... almost 9 years
    Yes you can do this but it will re-initialize all the drop-downs on that page having class .dropdown-toggle
  • Niranjan
    Niranjan over 8 years
    perfect!!. Until today , I was defering the loading of bootstrap.js until all my ajax calls complete, with some crappy code. But now I replaced it with $('....').dropdown(); Thank you!!

Related