2

I'm trying to learn pure native JavaScript, so please, don't suggest using frameworks to solve the task. I know the're awesome and learning them will be the first thing I'm going to do when I'm done with pure JS :)

Now, the question. Fiddle

As you can see, I have two custom dropdowns there. Each of them can be opened and controlled both with mouse and keyboard. The last thing I need to do to solve this task is to implement the following functionality: opening one dropdown should close the other one, and clicking outside the dropdown should close any of the opened dropdowns (assuming only one can be opened at a time).

I've tried adding an onclick listener to the document, which would close the dropdowns if any of them were open but not used before, but after I've clicked the document once, the dropdowns are not showing any more. But that's not even a solution for half of the problem. since I allocate flags bIsOpen to the objects, I can't access them from another object to see if it's triggered.

Give me a hint, please :)

JonH
  • 32,732
  • 12
  • 87
  • 145
Anton Matyulkov
  • 722
  • 1
  • 7
  • 15
  • 1
    Are you using Hungarian notation? Please don't. – Waleed Khan Feb 11 '13 at 14:52
  • 3
    Because people [use Hungarian notation wrong](http://stackoverflow.com/questions/111933/why-shouldnt-i-use-hungarian-notation). You don't need to qualify `isOpen` with a `b` to know that it's a boolean, and it's fairly obvious from the plural 'dropdown objects' that it's a variable-size container of some sort. Adding prefixes isn't helping with the clarity of the code; if it did, then it would be okay. – Waleed Khan Feb 11 '13 at 14:58

1 Answers1

1

Move the opening and closing logic into their own functions:

DropDown.prototype.open = function (e) {
    ...
}

DropDown.prototype.close = function (e) {
    ...
}

And

this.htmlDropDown.onclick = function (e) {
    if (this.bIsOpen) {
        this.open(e);
    } else {
        this.close(e);
    }
}

(Make sure that the open and close functions adjust bIsOpen, not the onclick handler.)

Then, add a list of all the current dropdowns that exist:

function DropDown(htmlObject) {
    DropDown.dropdowns.push(this);
    ...
}

DropDown.dropdowns = []; // no 'prototype'

And finally, in the open-er, close all the other dropdowns:

DropDown.prototype.open = function (e) {
    var dropdown;
    for (var i = 0; i < DropDown.dropdowns.length; i++) {
        dropdown = DropDown.dropdowns[i];
        if (dropdown !== this) {
            dropdown.close();
        }
    }
    ...
}
Waleed Khan
  • 11,426
  • 6
  • 39
  • 70