1

I want to change the behaviour of a Bootstrap dropdown based on a global state variable. If the uiState variable is 'normal' when it is clicked, it should display the dropdown, but if it's in another state it should do something else. I have the following code:

$(document).ready(function () {
    var uiState = 'normal';

    // Load HTML for word control from server
    var wordUiElement;
    $.get('/static/word_ui_element.html', function (data) {
        wordUiElement = data;
    });
   var nwords = 0;
   var testClickCounter = 0;

   // Make it so dropdowns are exclusively controlled via JavaScript
   $(document).off('.dropdown.data-api')

   $('#ui-add-word').click(function (event) {
       var control = wordUiElement.replace(/wx/g, 'w' + nwords.toString());
       $('#ui-spec').append(control);
       nwords++;
   });

   $('#ui-change-state').click(function (event) {
       if (uiState === 'word_select') {
           uiState = 'normal';
       } else {
           uiState = 'word_select';
       }
       console.log(uiState);
   });

    $('#ui-spec').on('click', '.dropdown .dropdown-toggle', function (event) {
        if (uiState === 'normal') {
            $(this).dropdown('toggle');
        }
        else {
            testClickCounter ++;
            console.log(testClickCounter);
        }
    });

});

However, when the dropdowns are dynamically created, their behaviour seems to be fixed based on what the uiState variable was when the dropdown was created.

This means that if a dropdown was created when the uiState variable was set to 'normal', no matter what uiState is when it's clicked, it will always show or hide the dropdown. On the other hand if the dropdown was created when uiState was 'word_select', it will always increment and log testClickCounter. It's as if the if statement in the handler is evaluated once when the dropdown is created and preserves whatever the value of uiState was when it was created.

I assume this is a scoping issue, and the event handler is executed when it's created. I want it to check at the time of the click what the value of uiState is, but I don't know how to fix it.

5
  • 1
    Maybe I don't get it, but I really don't get want you are trying to do there :) Commented Oct 28, 2015 at 11:05
  • They're based on the HTML data properties, post your HTML for the button. Commented Oct 28, 2015 at 11:09
  • 1
    Do you expect each dropdown to have its own state? Currently you have a global uiState variable for all of them! Commented Oct 28, 2015 at 11:19
  • Please show us where the value of uiState is changed. Commented Oct 28, 2015 at 11:20
  • No, they don't need their own state. I'll add the rest of the code Commented Oct 28, 2015 at 11:21

1 Answer 1

1

Instantiate the element with data-toggle="dropdown" and remove this property when it changes state, eg:

$('#wx').attr('data-toggle',''); // Dropdown no longer shows

or

$('#wx').attr('data-toggle','dropdown'); // Dropdown shows again

The rest of the trigger continue as usual:

$('#wx').on('click', '.dropdown .dropdown-toggle', function (event) {
    if (uiState !== 'normal') {
        testClickCounter ++;
        console.log(testClickCounter);
    }
});
Sign up to request clarification or add additional context in comments.

1 Comment

This does not address the problem. I've tried to explain it more clearly

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.