Demo(try the last one):
http://plnkr.co/edit/1yLmarsQFDzcLd0e8Afu?p=preview
How to get it to work?
Based on your plunkr, you should change
<div class="input-group" uib-dropdown auto-close="disabled">
<input type="text" class="form-control" placeholder="Click to start a visual query search..." autocomplete="off" uib-dropdown-toggle/>
<ul class="dropdown-menu" role="menu" ng-if="ctrl.dropdownReady" uib-dropdown-menu template-url="{{ctrl.dropdownTemplateFour}}">
</ul>
<span class="input-group-btn">
<button type="submit" name="search" id="search-btn" class="btn btn-flat"><i class="fa fa-search"></i>
</button>
</span>
</div>
to
<div class="input-group" uib-dropdown auto-close="disabled" ng-if="ctrl.dropdownReady">
<input type="text" class="form-control" placeholder="Click to start a visual query search..." autocomplete="off" uib-dropdown-toggle/>
<ul class="dropdown-menu" role="menu" uib-dropdown-menu template-url="{{ctrl.dropdownTemplateFour}}">
</ul>
<span class="input-group-btn">
<button type="submit" name="search" id="search-btn" class="btn btn-flat"><i class="fa fa-search"></i>
</button>
</span>
</div>
In which the ng-if="ctrl.dropdownReady"
is moved to the div.input-group
.
And change
vm.dropdownReady = false;
console.log('vm.dropdownReady =', vm.dropdownReady, ' partial = ', partial);
switch (template) {
case 'word':
partial ? vm.dropdownTemplateFour = 'word-dropdown-dom.template.html' : vm.dropdownTemplateThree = 'word-dropdown-dom.html';
break;
case 'main':
partial ? vm.dropdownTemplateFour = 'main-dropdown-dom.template.html' : vm.dropdownTemplateThree = 'main-dropdown-dom.html';
break;
}
vm.dropdownReady = true;
to
vm.dropdownReady = false;
console.log('vm.dropdownReady =', vm.dropdownReady, ' partial = ', partial);
switch (template) {
case 'word':
partial ? vm.dropdownTemplateFour = 'word-dropdown-dom.template.html' : vm.dropdownTemplateThree = 'word-dropdown-dom.html';
break;
case 'main':
partial ? vm.dropdownTemplateFour = 'main-dropdown-dom.template.html' : vm.dropdownTemplateThree = 'main-dropdown-dom.html';
break;
}
$timeout(function(){
vm.dropdownReady = true;
});
Which has a $timeout
wrap the vm.dropdownReady = true;
. And you should inject the $timeout
by hand;
Keep the menu open
According to the documentation, we can choose the initial state of drop menu with is-open
attr. And we can listen the toggle event with on-toggle
attr. So if we want to keep the menu open after user clicking the input, we should set the attributes of uib-dropdown
like this:
<div class="input-group" uib-dropdown auto-close="disabled" ng-if="ctrl.dropdownReady" is-open="ctrl.open" on-toggle="ctrl.toggled(open)">
And in controller:
vm.toggled = function (open) {
// the parameter `open` is maintained by *angular-ui/bootstrap*
vm.open=open;//we don't need to init the `open` attr, since it's undefined at beginning
}
With these things done, once the menu is open, it doesn't close without user clicking the input again.
Why?
Let's check this snippet:
$templateRequest(self.dropdownMenuTemplateUrl)
.then(function(tplContent) {
templateScope = scope.$new();
$compile(tplContent.trim())(templateScope, function(dropdownElement) {
var newEl = dropdownElement;
self.dropdownMenu.replaceWith(newEl);//important
self.dropdownMenu = newEl;
$document.on('keydown', uibDropdownService.keybindFilter);
});
});
The snippet above shows how does angular-ui/bootstrap use the template-url attr to retrive template and take it into effect. It replaces the original ul
element with a newly created element. That's why the uib-dropdown-menu
and template-url
is missing after clicking the ul
. Since they don't exist, you can't change the template-url with angular binding anymore.
The reason executing vm.dropdownReady = true;
immediately after the vm.dropdownReady = false;
doesn't work is that angular have no chance to dectect this change and execute the "ng-if" to actually remove the dom. You must make the toggling of vm.dropdownReady
asynchronous to give angular a chance to achieve this.