angular bootstrap accordion is-open scope - angularjs

I am trying to figure out how to close an accordion group from a button within the group.. seems like it should be easy.. but looks to be something with the scope being defined only within the group and not available in the controller? in the code snippet below the first button is how I would like to close the accordion group. The second button works.
Here is a simple plunkr on what I'm working on https://plnkr.co/edit/bghRaioszH3SZmiWxcoH?p=preview
<uib-accordion close-others="true" ng-controller="testCtrl">
<uib-accordion-group panel-class="panel-primary" is-open="status.isOpen">
<uib-accordion-heading>
Open: {{ status.isOpen }}
<i class="pull-right glyphicon" ng-class="{'glyphicon-chevron-down': status.isOpen, 'glyphicon-chevron-right': !status.isOpen}"></i>
</uib-accordion-heading>
<button class="btn btn-warning" ng-click="close()">Cancel</button>
<button class="btn btn-warning" ng-click="status.isOpen=!status.isOpen">Cancel</button>
</uib-accordion-group>
</uib-accordion>

To access the status of an accordion group through your controller's scope, you need to do something like this:
Move ng-controller="testCtrl" to the <body> element
Define status explicitly in your controller's scope:
.controller('testCtrl', function($scope) {
$scope.status = {
isOpen: true
}
$scope.close = function(){
$scope.status.isOpen = false;
};
});

Related

How can I add uib-tooltip from within an attribute directive?

Instead of adding uib-tooltip="tooltip text" to the element I want to add only a tooltip attribute.
In the tooltip directive I want to do something along the lines of "on mouseenter if a condition is met then show my full text content in uib-tooltip"
You can use tooltip-enable.
JS
.controller("ctrl", function($scope){
$scope.isToolTipEnabled = false;
$scope.toggleToolTip = function(){
$scope.isToolTipEnabled = !$scope.isToolTipEnabled;
}
});
HTML
<div ng-controller="ctrl">
<div class="label label-info" class="btn btn-default"
tooltip-enable="isToolTipEnabled"
uib-tooltip="This is a conditional tooltip">Conditional Tooltip here</div>
<button type="button" class="btn btn-default" ng-click="toggleToolTip()" ng-class="{'btn-success': isToolTipEnabled, 'btn-danger': !isToolTipEnabled}">Tooltip is {{isToolTipEnabled ? 'enabled' : 'disabled'}}</button>
</div>

Angular Modal: add template from another html

I have a modal template in another html file but after the page was loaded first time modal window opens without a content, second time it's all ok. How can this be fixed?
Here's the plunker http://plnkr.co/edit/lw056nAaU7BfqIVZSddb?p=preview
//Open modal on main page with:
<div ng-controller="ModalDemoCtrl">
<button type="button" class="btn btn-default" ng-click="open()">Open me!</button>
<button type="button" class="btn btn-default" ng-click="open('lg')">Large modal</button>
<button type="button" class="btn btn-default" ng-click="open('sm')">Small modal</button>
<button type="button" class="btn btn-default" ng-click="toggleAnimation()">Toggle Animation ({{ animationsEnabled }})</button>
<div ng-show="selected">Selection from a modal: {{ selected }}</div>
You should not wrap your template with <script type="text/ng-template" id="myModalContent.html"></script>.
Ui-modal expects direct HTML here.
If you need to use ng-template, you should insert the ng-template script tag in your index.html (or anywhere else but it should be loaded in your page) and open your modal with template instead of templateUrl this way :
var modalInstance = $uibModal.open({
animation: $scope.animationsEnabled,
template: "<div ng-include src=\"'myModalContent.html'\"></div>",
controller: 'ModalInstanceCtrl',
size: size,
resolve: {
items: function () {
return $scope.items;
}
}
});
Maybe you can use $templateCache in this case instead to load the template from another file. I don't know why you have this issue but this solved the problem for me.
Maybe you are not looking for something like that, since this increase the JS file size and sometimes this template will never be used.
angular.module('ui.bootstrap.demo').run(['$templateCache', function ($templateCache) {
$templateCache.put('myModalContent.html',
'Hello World'
);
}]);
What do you think?
EDIT: #Pierre Maoui answer seems more adequate for me based on the question.

angular js - ng-hide/ng-show API not working properly

Here i trying to implement application in angular js. I have an minimize/maximize button for all child element and seprate minimize/maximize button to inside child element.
But when i click toggle minimize its minimize all all child element.
Problem is when i click toggleonce it also minimize all child element.
var dashboard = angular.module("dashboard",['ui.bootstrap']);
dashboard.controller('dash-control', ['$scope', function($scope) {
$scope.isHidden = false;
$scope.toggle = function(){
$scope.isHidden = !$scope.isHidden;
};
$scope.toggleonce= function()
{
if( this.isHidden === true)
this.isHidden = false;
else
this.isHidden = true;
};
}]);
VIEW:
<div class="contentpanel" ng-app="dashboard" ng-controller="dash-control as ctrl">
<button class="btn btn-white" type="button" ng-click="toggle()">
<i class="fa fa-minus-square"></i>
</button>
<div>
<a href="" class="tooltips" ng-click="toggleonce()" title="Minimize Panel">
<i class="fa fa-minus"></i>
</a>
<div class="row tinychart" ng-show="isHidden">Contenr Heading 1</div>
<div class="row tinychart" ng-hide="isHidden">Content Description 1</div>
</div>
<div>
<a href="" class="tooltips" ng-click="toggleonce()" title="Minimize Panel">
<i class="fa fa-minus"></i>
</a>
<div class="row tinychart" ng-show="isHidden">Contenr Heading 2</div>
<div class="row tinychart" ng-hide="isHidden">Content Description 1</div>
</div>
......
.....
.....
</div>
The variable $scope.isHidden is a controller level variable and by clicking toggleonce() you are changing the variable to true through out the page(since both the 'minimize panels' are in the scope of the controller. Thereby any ng-hide for isHidden will be hidden and thereby it is causing the global 'minimise'.
You have two options:
1) use separate variables for each Minimize panel and toggle the values of that variable when you click on the corresponding function. Also write the Panel level 'ng-hide's for its own variable.
2) write a isolated scope directive for all Minizable panels. And isolate its scope from the Controller. Now write a toggleonce function in the directive which changes the value of the Hidden variable within the directive's scope. You must use the following syntax while writing the directive:
.directive('minimizePanel', function() {
return {
scope: true,
};
You can watch this video for more inputs.

Angular directive two way databinding fails

I have a dropdown directive with a function which sets the active item in the dropdown:
angular.module('clientApp')
.directive('customDropDown', function ($filter, calculationsFactory) {
return {
templateUrl: 'template/custom-drop-down/custom-drop-down.html',
restrict: 'E',
scope: {
resources: '=',
activeResource: '=',
},
link: function postLink(scope) {
scope.setActiveResource = function(resource){
scope.activeResource = resource;
};
}
};
});
Markup:
<custom-drop-down resources="medias" active-resource="activeMedia"></custom-drop-down>
DirectiveTemplate:
<div class="btn-group" dropdown>
<button type="button" class="btn btn-default dropdown-toggle" dropdown-toggle style="width:100%;" ng-click="$event.stopPropagation()">
{{activeResource.title}} <span class="caret pull-right" style="margin-top:8px;"></span>
</button>
<ul class="dropdown-menu" role="menu">
<li ng-repeat="resource in filtredResources"
ng-click="setActiveResource(resource)"
ng-class="{active: resource === activeResource}">
<a href>{{resource.title}}</a>
</li>
</ul>
</div>
Problem is that the function don't two way bind "activeMedia" in this case. It does not get updated.
I tried to replicate the case in jsfiddle but there it works. Anything I could have missed?
Update
I have identified the issue.
My directive is placed within the accordion directive from ui-bootstrap:
<accordion>
<accordion-group heading="Resources" is-open="true">
<custom-drop-down resources="medias" active-resource="activeMedia"></custom-drop-down>
</accordion-group>
</accordion>
If I move my directive outside the accordion directive, it works. So somehow the accordion directive is interfering with my directive. Possible to solve without modifying the code for ui-bootstrap?
In your case it is a scoping issue, as discussed here.
For elements inside angular-bootstrap controls you need to use $parent. as a prefix on scope variables.
<accordion>
<accordion-group heading="Resources" is-open="true">
<custom-drop-down resources="$parent.medias" active-resource="$parent.activeMedia"></custom-drop-down>
</accordion-group>
</accordion>

Invoking modal window in AngularJS Bootstrap UI using JavaScript

Using the example mentioned here, how can I invoke the modal window using JavaScript instead of clicking a button?
I am new to AngularJS and tried searching the documentation here and here without luck.
Thanks
OK, so first of all the http://angular-ui.github.io/bootstrap/ has a <modal> directive and the $dialog service and both of those can be used to open modal windows.
The difference is that with the <modal> directive content of a modal is embedded in a hosting template (one that triggers modal window opening). The $dialog service is far more flexible and allow you to load modal's content from a separate file as well as trigger modal windows from any place in AngularJS code (this being a controller, a service or another directive).
Not sure what you mean exactly by "using JavaScript code" but assuming that you mean any place in AngularJS code the $dialog service is probably a way to go.
It is very easy to use and in its simplest form you could just write:
$dialog.dialog({}).open('modalContent.html');
To illustrate that it can be really triggered by any JavaScript code here is a version that triggers modal with a timer, 3 seconds after a controller was instantiated:
function DialogDemoCtrl($scope, $timeout, $dialog){
$timeout(function(){
$dialog.dialog({}).open('modalContent.html');
}, 3000);
}
This can be seen in action in this plunk: http://plnkr.co/edit/u9HHaRlHnko492WDtmRU?p=preview
Finally, here is the full reference documentation to the $dialog service described here:
https://github.com/angular-ui/bootstrap/blob/master/src/dialog/README.md
To make angular ui $modal work with bootstrap 3 you need to overwrite the styles
.modal {
display: block;
}
.modal-body:before,
.modal-body:after {
display: table;
content: " ";
}
.modal-header:before,
.modal-header:after {
display: table;
content: " ";
}
(The last ones are necessary if you use custom directives) and encapsulate the html with
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title">Modal title</h4>
</div>
<div class="modal-body">
...
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
Open modal windows with passing data to dialog
In case if someone interests to pass data to dialog:
app.controller('ModalCtrl', function($scope, $modal) {
$scope.name = 'theNameHasBeenPassed';
$scope.showModal = function() {
$scope.opts = {
backdrop: true,
backdropClick: true,
dialogFade: false,
keyboard: true,
templateUrl : 'modalContent.html',
controller : ModalInstanceCtrl,
resolve: {} // empty storage
};
$scope.opts.resolve.item = function() {
return angular.copy(
{name: $scope.name}
); // pass name to resolve storage
}
var modalInstance = $modal.open($scope.opts);
modalInstance.result.then(function(){
//on ok button press
},function(){
//on cancel button press
console.log("Modal Closed");
});
};
})
var ModalInstanceCtrl = function($scope, $modalInstance, $modal, item) {
$scope.item = item;
$scope.ok = function () {
$modalInstance.close();
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
}
Demo Plunker
The AngularJS Bootstrap website hasn't been updated with the latest documentation. About 3 months ago pkozlowski-opensource authored a change to separate out $modal from $dialog commit is below:
https://github.com/angular-ui/bootstrap/commit/d7a48523e437b0a94615350a59be1588dbdd86bd
In that commit he added new documentation for $modal, which can be found below:
https://github.com/angular-ui/bootstrap/blob/d7a48523e437b0a94615350a59be1588dbdd86bd/src/modal/docs/readme.md.
Hope this helps!
Quick and Dirty Way!
It's not a good way, but for me it seems the most simplest.
Add an anchor tag which contains the modal data-target and data-toggle, have an id associated with it. (Can be added mostly anywhere in the html view)
Now,
Inside the angular controller, from where you want to trigger the modal just use
angular.element('#myModalShower').trigger('click');
This will mimic a click to the button based on the angular code and the modal will appear.
Different version similar to the one offered by Maxim Shoustin
I liked the answer but the part that bothered me was the use of <script id="..."> as a container for the modal's template.
I wanted to place the modal's template in a hidden <div> and bind the inner html with a scope variable called modal_html_template
mainly because i think it more correct (and more comfortable to process in WebStorm/PyCharm) to place the template's html inside a <div> instead of <script id="...">
this variable will be used when calling $modal({... 'template': $scope.modal_html_template, ...})
in order to bind the inner html, i created inner-html-bind which is a simple directive
check out the example plunker
<div ng-controller="ModalDemoCtrl">
<div inner-html-bind inner-html="modal_html_template" class="hidden">
<div class="modal-header">
<h3>I'm a modal!</h3>
</div>
<div class="modal-body">
<ul>
<li ng-repeat="item in items">
<a ng-click="selected.item = item">{{ item }}</a>
</li>
</ul>
Selected: <b>{{ selected.item }}</b>
</div>
<div class="modal-footer">
<button class="btn btn-primary" ng-click="ok()">OK</button>
<button class="btn btn-warning" ng-click="cancel()">Cancel</button>
</div>
</div>
<button class="btn" ng-click="open()">Open me!</button>
<div ng-show="selected">Selection from a modal: {{ selected }}</div>
</div>
inner-html-bind directive:
app.directive('innerHtmlBind', function() {
return {
restrict: 'A',
scope: {
inner_html: '=innerHtml'
},
link: function(scope, element, attrs) {
scope.inner_html = element.html();
}
}
});

Resources