How to show preloader inside button instead text Angular JS? - angularjs

I use Angular JS library ngActivityIndicator.
I tried to show preloader inside element div instead text when button is pushed:
<div ng-activity-indicator="CircledDark">
<div ng-click="Add();" class="btn shareBtn">
<div ng-view></div>
<span>Text</span>
</div>
</div>
I posted <div ng-view></div> inside and have added directive ng-activity-indicator="CircledDark" to parent element.
When I click button, I call function that display preloader:
$activityIndicator.startAnimating();
But preloader is created outside of button:
<div ng-show="AILoading" class="ai-circled ai-indicator ai-dark-spin"></div>
This is official documantation, from here I have taken example:
https://github.com/voronianski/ngActivityIndicator#directive
How to show preloader inside button instead text Angular JS?

I think the only solution is to separate your ng-view and button, at least they do something similar in their sample page. So, in your markup you could do something like this:
<div ng-click="add()" class="btn btn-default" ng-activity-indicator="CircledDark">
<span ng-show="!AILoading">Add</span>
</div>
<div ng-view ng-show="!AILoading">{{ delayedText }}</div>
And in your controller:
$scope.delayedText = "";
$scope.add = function() {
$activityIndicator.startAnimating();
$timeout(function() {
$scope.delayedText = "Here we are!";
$activityIndicator.stopAnimating();
}, 3000);
};
Here is full Demo, you can play with CSS a little so the size of the button won't change when text is replaced by icon.

Related

Angularjs ng-show is not working inside the modal

Im opening modal popup on click of one button. The modal popup is opening and i want to show one progress bar inside the modal popup. After getting the response i want to hide it.
The progress bar is not showing for the fisrt time if im closing and opening the popup again then it's showing.
Below is my controller code :
$scope.clickUpload = function(){
$('#import_poi_modal').modal('show');
setTimeout(function(){
$scope.fileChangeProgress = true;
console.log($scope.fileChangeProgress)
},1000);
}
HTML:
<div class="modal fade" id="import_poi_modal">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-body">
<div class="center-content" ng-show="fileChangeProgress"> //here im using the variable to show and hide
<div class="col-6">
<div class="progress m-t-30 m-b-30" >
<div class="progress-bar progress-bar-orange active progress-bar-striped" style="width: 100%; height:14px;" role="progressbar"> </div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
I have tried with setTimeout. Still it's not working.
Since setTimeout is a javascript function(not an Angular one), you will need to use $apply to notify Angular for the changes.
setTimeout(function(){
$scope.$apply(
function() {
$scope.fileChangeProgress = true;
console.log($scope.fileChangeProgress);
}
);
},1000);
Another solution is to use the Angular native $timeout support:
$timeout(function(){
$scope.fileChangeProgress = true;
console.log($scope.fileChangeProgress)
},1000);
Should serve you the same purpose without $apply.
You can also refer to this $apply in setTimeout

AngularJS: ng-class not refreshing when Bootstrap modal re-opens

I have a Bootstrap modal with a form inside a div set with ng-class:
<div id="modalNewOrder" class="modal fade" data-modalName="order" role="dialog" ng-controller="NewOrderController as NewOrderCtrl">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close pull-left" data-dismiss="modal">X</button>
<h4 class="modal-title">
New order
</h4>
</div>
<div class="modal-body">
<div ng-class="NewOrderCtrl.position">
<form>
// input text here
</form>
When the modal is loaded, its NewOrder.position sets its css to center. When the form is processed, NewOrder.position is updated to top, and the results of are shown below it.
Now the problem: I want NewOrder.position to be reset to center when the modal is re-opened. However, even if I reset NewOrder.position, it seems the ng-class is not being updated. How do I do that?
I'm using this on my controller, but its not working to update ng-class:
$("#modalNewOrder").on("hidden.bs.modal", function () {
$(this).find('form')[0].reset();
self.clearQuery();
self.position = "mycss-position-center";
});
***** UPDATE *****
Following Naren's suggestion and experimenting a little, I've updated my code. In my html I have:
<div ng-class="{'mycss-position-top' : NewOrderCtrl.top, 'mycss-position-center' : !NewOrderCtrl.top}">
and
<form ng-submit="processing()">
And in my controller, I have:
var self = this;
self.top = false;
$("#modalNewOrder").on('shown.bs.modal', function() {
self.top = false;
});
$("#modalNewOrder").on("hidden.bs.modal", function () {
self.top = false;
});
self.processing = function(){
self.top = true;
};
The problem now is that in the first re-opening of the modal, self.top is evaluated as "true", even if the "on show" function is processed and show "false" in console.log. Only if I close the modal again and re-open it once more, then it goes do false.
* UPDATE *
The proposed solution was working. I've found a syntax error in another place which was causing this last wrong behavior.
Final Answer:
Please don't use JQuery plugins in angular, angular does not detect the functions or variable changes. If you google the plugin name with angular (angular bootstrap) you will run into a library that enables you to use Bootstraps functionality with angular itself (angular UI Bootstrap). This is the proper way of writing code, If you use JQuery function, even if you solve and issue like this, you will run into another issue (because angular cannot detected the changes completely), Please do some research for a angular plugin before going with the Pure JQuery plugin approach.
JSFiddle Demo
Old Answer:
Why not always center the form as default and on form submit update the corresponding class.
HTML:
<div id="modalNewOrder" class="modal fade" data-modalName="order" role="dialog" ng-controller="NewOrderController as NewOrderCtrl">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close pull-left" data-dismiss="modal">X</button>
<h4 class="modal-title">
New order
</h4>
</div>
<div class="modal-body">
<div class="mycss-position-center" ng-class="{'mycss-position-top' : process}">
<form ng-submit="processing()">
// input text here
</form>
JS:
app.controller('NewOrderController', function($scope) {
$scope.process = false;
$scope.processing = function(){
$scope.process = true;
};
});
I thinks your ng-class is not initialisation when you call boostrap modal.
You can use watch syntax like that:
$scope.$watch(' NewOrder.position', function () {
$scope.NewOrder.position = "mycss-position-center";
}, true);
Some thing like that..

Override ng-hide on ng-click

On the process of trying to learn angularjs, I am creating a set of divs using ng-repeat. I have five divs in all. I am only displaying the first div using $firstdirective component.
<div class="container" ng-app="demoApp" ng-controller="demoController">
<div class="row" ng-repeat="job in jobs" ng-hide="!$first">
<div class="col-md-4">
{{job}}
</div>
<div class="col-md-4">
<button class="btn-primary btn-xs add" ng-click="showNext($event)" ng-hide="$last">Add</button>
<button class="btn-primary btn-xs delete" style="display: none;">Delete</button>
</div>
</div>
</div>
That works.
Now, each div has two buttons, Add and Delete. When I click add I want to hide the add button and delete button of the current row and open the next row. So I wrote,
$scope.showNext = function(evt) {
var elm = evt.target;
$(elm).hide();
$(elm).next().hide();
$(elm).closest("div.row").next().slideDown();
};
This is not working as ng-hide is overriding my slideDown. What is the angularjs way of doing it?
Also I would like the delete button only on the $last visible row && !first. How to find last visible row in ng-repeat?
Fiddle: https://jsfiddle.net/codeandcloud/u4penpxw/
You shouldn't manipulate the DOM with things like $(elm).hide();, you should use ng-class= to let Angular add classes that hide or show the elements. If you switch your ng-repeat to ng-repeat="job in jobs track by $index", you could write something like that in your showNext()-function:
$scope.showNext = function(index) {
$scope.currentJob = $scope.jobs[index]
}
and call it like ng-click="showNext($index) - of course you'd need to do some refactoring as well. But then you could write something like ng-class="{hidden: (job == currentJob}" to hide all buttons except in the current row.
There's a lot of good thoughts in this q&a: "Thinking in AngularJS" if I have a jQuery background?

Get value from ng-repeat outside of ng-repeat

I got a header bar outside of ng-repeat:
<ion-header-bar class="headerView" ng-show="!hideAll">
<button id="shareImage" class="button button-icon icon ion-share" style="color:#fff" ng-click="shareImageTo({{originalImageSource}})"></button>
<button class="button button-outline button-light close-btn" ng-click="closeModal()">{{::actionLabel}}</button>
</ion-header-bar>
And a slidebox where images are shown:
<ion-slide ng-repeat="single in slides track by $index">
<div class="item item-image gallery-slide-view">
<img ng-src="{{single.original}}">
<input type="text" ng-model="originalImageSource" value="{{single.original}}">
</div>
</ion-slide>
{{single.original}} is an URL to an image. But this URL is not placed in the input field. It is shown when I´m deleting this ng-model statement.
If a user clicks the button #shareImage the ShareImageTo(URL) function is executed. But with an undefined value for {{originalImageSource}}.
Any thoughts on how i could pass the URL in {{single.original}} to this ShareImageTo() function?
With $ionicSlideBoxDelegate you can get the current slide index via currentIndex(). That enables you to get the URL by $scope.slides[$ionicSlideBoxDelegate.currentIndex()].original in your ShareImageTo()-method like that:
$scope.ShareImageTo = function() {
var URL = $scope.slides[$ionicSlideBoxDelegate.currentIndex()].original;
//your logic
};
Another approach would be to use ion-slide-box's directive on-slide-changed.
Template:
<ion-slide-box on-slide-changed="slideHasChanged($index)">
...
</ion-slide-box>
Controller:
$scope.slideHasChanged = function(index) {
$scope.originalImageSource = $scope.slides[index].original;
//.. some more logic
}
Just create a div that wrap around both your navbar and your slidebox, and place your ng-repeat in that div :)

Call a method on a nested controller

I have an Angular app that displays a ui.bootstrap.modal dialog when I click on a certain element. I want to make the modal logic reusable so have separated it into a separate controller. The result (simplified) looks like this:
<div ng-controller="MyController">
<button class="btn" ng-click="open()">Open me!</button>
<div ng-controller="ModalController" modal="shouldBeOpen" close="close()" options="opts">
...
</div>
</div>
The visibility of the modal is controlled by a property on ModalController:
$scope.shouldBeOpen = true;
How can I set that property from the open() method on MyController?

Resources