How to stop Angular UI (Bootstrap) accordion from flashing - javascript

I've created an accordion based on ngResource (for live/ajax data). All works fine, however the accordion flashes (twice) on loading. How can I stop this?
This is my code (service):
AdminMenu.factory('myServices', ['$resource', function($resource) {
return $resource('/api/categories?sort=createdAt asc');
}]);
And this is my template:
accordion(class="admin-accordion", close-others="accordion", ng-cloak)
accordion-group(ng-repeat="category in categories", is-open="category.active", heading="{{category.name}}")
tabset
tab(ng-repeat="subcat in category.subcategories", heading="{{subcat.name}}", active="subcat.active", select="alertMe(category.subcategories)") {{subcat.content}}
PS: I don't know whether it could be related but within my accordion, I also have a tab using the same data as the accordion (as you can see from example above)
Any ideas?

Related

Call multiple directive on load and on click through one directive

I have a index.html page and this page is working as a single directive.
angular.module('app').directive('index', function() {
return {
templateUrl: 'html/index.html'
}
}).controller('index', ['$scope', '$http', function($scope, $http) {}])
Inside index.html, I have three tabs gallery, list and summary. I have put all these three tabs in different directive like this.
/*Gallery directive*/
angular.module('app').directive('gallery', function() {
return {
templateUrl: 'html/gallery.html'
}
})
/*List directive*/
angular.module('app').directive('list', function() {
return {
templateUrl: 'html/list.html'
}
})
angular.module('app').directive('summary', function() {
return {
templateUrl: 'html/summary.html'
}
})
I want that when I load the index.html page the gallery and the summary directive should also get loaded and visible in index.html. Also I am fetching some data in index.html on load, I also want to pass that data to summary,gallery and list directives. Also I have a gallery tab and list tab. When I click on the gallery tab I want the gallery directive to be loaded and when I click on the list tab I want the list directive to be loaded with the data. Initially the gallery and the summary directive should be there by default. The switching will only happen in gallery and the list view. The summary directive should be fixed there.
Initially I developed it all in a single directive. But now I am trying to make all these in a different directive.
Image below explain about my scenario
I am not sure, can we call multiple directive through single directive ? If yes then how can I achieve this ?
Regards
Create a factory holding the data that gets injected to the directive
Here its shown Sharing data between directives

Angular 1 directive component has different behavior in modal and out of the modal

I am really struggling with the issue with custom directive component. I have created TreeView dropdown component based on Angular ivh-treeview angular-ivh-treeview. Becasue ivh-treeview by default does not have recommended functionality and stylig I have extend it. But now I am facing an issue I haven't seen before and I would be really thankful for your help. The component works absolutelly OK in the modal. When you click on the checkboxes it reacts pretty fast and everything looks great. But when I use the same component on any other page (not in the modal) it has really strange behavior. When you select any checkbox, it does not update immediatelly, you have to click somewhere else on the page, or close and open dropdown to see changes. I have no clue what is going on there and why the same component works in the modal. Maybe it's because modalInstance has different scope but I am done.
Here you can see and play with an example (Page 1 - modal, Page 2 - no modal): DEMO
This is just a fragment of the code I had to include to be able to link here DEMO on Plunkr
<ivh-dropdown ivh-model="treeStructureFinal" selected-array="formData.casinos" is-disabled="inReadMode" placeholder="Select casinos"></ivh-dropdown>
Thank you everyone!
When this kind of thing happens I always think about $scope.$apply().
So I did a minor modification and now the directive works fine, just by adding a scope.$apply at the end of the click handler:
$document.bind('click', function (event) {
var isClickedElementChildOfPopup = element.find(
event.target).length > 0;
if (!isClickedElementChildOfPopup
&& element[0].children[1].classList.contains("show")) {
element[0].children[1].classList.toggle("show");
}
scope.$apply();
});
Take a look at it working:
https://plnkr.co/edit/s1UNCXNCZ46zXjte9lpZ?p=preview
Hope that helps.

How to show alert in UI bootstrap when user is at different point in page

I'm using Angular for a web app. I used Angular UI bootstrap to show an alert in my page as response to some action, say a button click. However, I placed this alert div at beginning of the page. My page is long. So when I'm some where at the middle of the page and an alert happens, the user will not know the alert happened because it is at beginning of the page. I want to scroll page automatically to alert area when it happens. How to do this ?
Some what related to this https://stackoverflow.com/a/24203856/2182674, but its not looking quite good to show at fixed place in the page. That is overlaying page content and not good for my case.
Alert content is set by a controller in angular. So using href anchor for button won't work.
When triggering the action you can scroll to the alert element using something like this:
$("#button").click(function() {
/* trigger UI bootstrap alert */
/* ... */
$('html, body').animate({
scrollTop: $("#alertElementtoScrollToID").offset().top
}, 2000);
});
Angular can $anchorScroll to an element:
angular.module('anchorScrollExample', [])
.controller('ScrollController', ['$scope', '$location', '$anchorScroll',
function ($scope, $location, $anchorScroll) {
$scope.gotoBottom = function() {
// set the location.hash to the id of
// the element you wish to scroll to.
$location.hash('bottom');
// call $anchorScroll()
$anchorScroll();
};
}]);
You can do this with a simple anchor html element :
<a id="myalert">Alerte</a>
...
Go to the alert

Don't destroy an Angular Bootstrap modal on close

I am using Angular Bootstrap to display a Modal (the one presented here), which works perfectly. However, default behavior of this Angular extension is that the modal is reconstructed (and a new instance of its controller will be creatred) whenever it is closed and then opened again.
Since I have some pretty advanced stuff going on inside the Modal, I would like the modal to just be hidden when it is closed, so that its state remains. I have searched around a bit, but unfortunately could not find a simple and effective answer.
Just hiding it would be an option, but this then has to happen whenever the modal is closed, so also when it closes because the backdrop is clicked. And I want the same animation as when the modal is opened in the normal way.
Why don't you abstract the modal state into its own service? That way, whenever the modal controller is created, it uses the service to setup the view state on initialisation.
Eg. create a service
.factory('ModalStateService', function(){
var state = {
someValue: 'something'
};
return {
getState: function() { return state; }
};
});
Then in your controller:
.controller('ModalCtrl', function($scope, ModalStateService){
$scope.viewState = ModalStateService.getState();
});
Then in your modal content view for example:
<span>{{viewState.someValue}}</span>
If you were then to set someValue inside your modal, say through an input, the service state would be updated. Then when you create and destroy your modal, the state will persist.
As you might already know Angular initializes a controller when the associated view is added to the DOM. So the plugin author might have decided to add and remove the view element so that he does not have to worry about clearing the 'scope'each time user opens and closes the modal.
For example, we have a login box in the modal and if the scope is not cleared, it will keep the filled in details even the next time we show it.
An easy hack to solve your problem will be to wrap the originl modal in a custom directive, reneder it. And just change the display property of your custom modal to show and hide the modal ;)

Call function every time ng-show is true?

I'm currently using AngularStrap tabs in a project, and I want the content for one of the tabs to be refreshed every time the tab is shown. I have the tabs set up with
%div(ng-model="tabs.index" bs-tabs="tabs")
%div(ng-repeat="tab in tabs" data-title="{{tab}}")
and the tab is shown using
%div(ng-show="tabs.active().title == 'Previous Requests'")
%div(class="outer-tab-content")
However, since ng-show just displays the tab, and doesn't load it every time it's shown, I can't seem to use ng-load to solve this problem. And, since I'm using AngularStrap tabs, I can't figure out how to add an ng-onclick to the tab in question.
Advice?
You can add a watch for your active tab title in your controller code:
$scope.$watch('tabs.active.active().title', function(newValue, oldValue) {
if(newValue === 'Previous Requests')
$scope.tabs.refresh();
});

Categories