In my case, ng-view is a slider that has arrows to show the next template and the previous template. Currently it has one type of animation for the transition between templates.
<div data-ng-view data-ng-animate="{enter: 'slide-forward-enter', leave: 'slide-forward-leave'}"></div>
I want to extend the behaviour to do different animations depending on which arrow is clicked. Click on the "Next" arrow should perform slide-forward-enter & slider-forward-leave animation, while click on the "Previous" arrow should perform slide-reverse-enter & slider-reverse-leave.
How to achieve this?
You could add a class to your ng-view that changes based on the transition you want. From within your controller you could check whether the "Next" or "Previous" button was clicked, and setting the transition class accordingly. Let's assume you're defining 2 different transitions, 'forward' and 'back':
HTML
<div data-ng-view data-ng-animate="transitionClass"></div>
<button ng-click="slide('back')">Previous</button>
<button ng-click="slide('forward')">Next</button>
Controller
$scope.slide= function(myTransition) {
$rootScope.transitionClass = myTransition;
}
CSS
.forward-slide-enter {...}
.forward-slide-enter-active {...}
.forward-slide-leave{...}
.forward-slide-leave-active {...}
.back-slide-enter {...}
.back-slide-enter-active {...}
.back-slide-leave{...}
.back-slide-leave-active {...}
Further reading
See this question for details.
Related
I am trying to implement segmented control button instead of normal radio button in Angular
Although If i remove CSS class, normal radio button is working fine and remain selected on navigating to another page os clicking anywhere on the same page, but after adding CSS, radio button selection do not remain intact and deselects.
Please help with this
HTML Code :
<div class ="segmented-control">
<div ng-repeat="p in LP">
<a href="#" class="list-group-item">
<label> {{p.label}}
<input type ="radio" ng-model="test" name="test" value="{{p.value}}" ng-click="getElement($event)"></label>
</a>
</div>
</div>
CSS :
.segmented-control input[type="radio"] {
visibility:hidden;
}
.segmented-control .list-group-item {
display: inline-block;
}
In controller.js
calling below function to get the value of radio button
$scope.getElement= function(obj){
$scope.test = obj.target.value;
}
There are 2 issues with your code:
You have nested elements <div><a tag><label><radio></label> but the ng-model will be set only when you click exactly on the label. If you click little outside the label the ng-model will not be updated.
The gray color change that you see when you click on the segmented button does not mean that the radio button is selected. It is applying the following bootstrap class a.list-group-item:focus which means the button is in focus. That is why when you click outside the button the color changes back to white.
To solve this you have to add extra class to highlight the selected button and make sure your ng-model is updated no matter where the user clicks inside the div.
I have created a sample jsfiddle to demonstrate both the issues. Good luck and welcome to Stackoverflow!
I'm creating a reusable item picker component using Angular 1.5. The picker has a search field and a list of items to choose from. An example use case for the picker is a popup where the user selects some items and then has a "Continue" button to proceed.
Conceptually, the search field and the list of items belong to the component and the "Continue" button belongs to the surrounding dialog. However, I want to position the button next to the search field. In some cases there are no extra buttons, sometimes one extra button, sometimes two.
Something like this:
What is the best way to create such a component?
Options I've thought of:
Create a component / directive for the item picker, put the button before or after the directive in the HTML, and use CSS to position the button.
Here the positioning of the button is ugly and fragile, as it's not in the proper position within the HTML. It would probably need a wrapper div and absolute positioning on top of the picker component:
<div style="position: relative">
<item-picker></item-picker>
<button name="Continue" ng-click="submit()" style="position:absolute; top:5px; right: 5px"></button>
</div>
Somehow pass the buttons and callbacks as parameters to the item picker component. Here the ugliness is in the hard-coding of the buttons and styles and amount of buttons:
<item-picker btn1-text="Continue" btn1-style="primary" btn1-callback="submit()" btn2-text="Cancel" btn2-style="secondary" btn2-callback="cancel()"></item-picker>
I'm unsure whether the button configuration and callbacks could be passed as a single configuration object. I'm mainly concerned about the callback functions, whether they will work properly if passed through a configuration object instead of proper '&' callback binding.
Stop trying to make the picker into a component / directive and just use <ng-include> to include the picker code which reads the button configuration from the scope. Ugliness is in lack of scoping and not using components.
Is there some best practise for such cases?
One possible solution is to use ng-transclude, so your code could look something like:
Markup
<item-picker>
<button ng-click="parentScopeFn()">Btn 1</button>
...
</item-picker>
Directive
angular.module('myApp', [])
.directive('itemPicker', function() {
return {
restrict: 'E',
transclude: true,
scope: {
...
},
templateUrl: 'item-picker.html'
};
});
itemPicker template markup
<div class="item-picker">
<div class="item-picker-controls">
<div class="item-picker-search"><input type="search" ng-model="..."></div>
<div class="btn-group" ng-transclude></div>
</div>
<ul class="item-picker-list">
<li ng-repeat="item in items" ng-bind="item"></li>
</ul>
</div><!-- end item-picker template -->
Of course the above code is just an example and is making a lot of assumptions about your itemPicker component. Also, you'll still need to use CSS to position your buttons, but it might be easier to reason with b/c it'll be in the context of your component.
Note
You could also make use of "multi slot transclusion". This is probably useful in cases where the number and type of buttons you'll have is predictable and you want them arranged in a consistent way no matter how they are placed in the markup.
Hope this helps.
I'm attempting to learn AngularJS (background in BackboneJS). I have a div with some content inside, and I hope to render this div as a modal upon clicking inside of it:
<div class="stickynote"> Content here </div>
My thinking is to add a modal class that I can style in CSS. However, I'm not too sure how to add the modal class upon clicking (and conversely, removing the modal class upon clicking after the modal is rendered). Would I have to use ng-click and somehow set the class property from the JavaScript (myApp.js) file?
If you want to use your own modal styling and if you simply want to achieve adding an extra item to class attribute of your element, you can use a combination of ng-class and ng-click:
<div class="stickynote"
ng-class="{yourModalCSSClass: isModalOpen}"
ng-click="isModalOpen = true">
And somewhere else, you need another ng-click to turn it off:
<button ng-click="isModalOpen = false">Close modal</button>
Beware that both div and button must be in the same scope hierarchy to be able to use the same isModalOpen value. And by the way, I haven't tried this code but this should give you an idea. If you have a controller/directive, you can set isModalOpen from there by introducing functions in the scope:
// controller
$scope.toggleModal = function () {
$scope.isModalOpen = !$scope.isModalOpen;
}
<div ...
ng-click="toggleModal()">
<button ng-click="toggleModal()">...
If you're open to using a third-party solution, ng-dialog is an outstanding solution for modals+Angular.
https://github.com/likeastore/ngDialog
I have a problem getting the active slide in an Angular-UI Bootstrap carousel outside the carousel.
I have a panel, with the carousel inside, and want to put buttons in the footer of the panel that makes actions using the selected slide, but using jquery selectors is not an option.
I want to implement it using something in pure angular.
I think I can use the active attribute, but maybe there is something clever that can do the trick more smoothly.
Some code (Jade syntax):
.panel.panel-info
.panel-body
carousel.imgCarousel(interval='5000')
slide(ng-repeat='media in selCard.superviseTab.media')
img.img-responsive(preload-image ng-src='/api/cards/{{selCard.superviseTab.sID}}/media/{{$index}}')
.carousel-caption
multiSelect
h4 Slide {{$index+1}} of {{selCard.superviseTab.media.length}}
p {{media.originalFilename}}
.panel-footer
.navbar-collapse.collapse
ul.nav.navbar-nav.navbar-left
li
a.btn.btn-danger
i.fa.fa-unlink
If you look at the AngularUI documentation, you can see this is how the slides are integrated into the HTML:
<carousel interval="myInterval">
<slide ng-repeat="slide in slides" active="slide.active">
...
</slide>
</carousel>
We can see that the active slide is determined by the active property on each slide.
So, you should be able to iterate through the slides and return the first slide with the active property on it. As long as you haven't modified the slides array outside of this carousel, it should give you the index of the current slide.
For example, something like:
function isActive(slide) {
return slide.active;
};
$scope.getActiveSlide = function() {
var activeSlides = $scope.slides.filter(isActive)[0];
//return the first element, since the array should only return one item
};
Should do the job (or however you choose to implement your find functionality).
I am somewhat new to using Angular and AngularStrap directives. I need to use the tab directive with static markup like the example:
<div data-fade="1" bs-tabs>
<div data-title="'Home'"><p>Static tab content A</p></div>
<div data-title="'Profile'"><p>Static tab content B</p></div>
</div>
On another part of the page I would like to display a div only when the first tab is selected. The div is not part of the tabs, but is in the same overall controller. How can I show/hide this div based on the selected tab?
Something like this?
<div ng-show="???? active tab stuff here ????">Home tab is selected</div>
Thanks for any help.
As shown in the example on the AngularStrap page the active tap is stored in
tabs.activeTab
So you can use this property to conditionally show display something else like so
<div ng-show="tabs.activeTab == 0">The first tab is active</div>
UPDATE
Even with non object tabs you can just bind a model against the bs-tabs to store the active ID like so:
<div data-fade="1" ng-model="tabs.activeTab" bs-tabs>
Here is an updated plnkr. (Click on the 3rd tab and see the 'Test' text appear)
I found somewhat of a hack to resolve this issue for now. This does not seem like the best approach, so if someone has a better idea, please share.
I realized that the bsTabs directive is creating data-toggle attributes for each tab. By watching the data-toggle shown event, I am able to recognize the tab change and display the div. The controller code looks like this:
$scope.HomeTabSelected = true;
function watchTab() {
$('a[data-toggle="tab"]').on('shown', function (e) {
$scope.$apply($scope.HomeTabSelected = (e.target.innerHTML == "Home"));
})
}
setTimeout(watchTab, 2000); // setTimeout necessary to allow directive to render
and the HTML div uses ng-show.
<div ng-show="HomeTabSelected">Home tab is selected</div>