Angularjs ng-show is not working inside the modal - angularjs

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

Related

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..

Is ng-if not evaluated or I do not understand about ng-view clearly

Go straight to the code and I will explain more along the question
I have the index.html file like this:
<body class="horizontal-menu">
<!-- Preloader -->
<div id="preloader">
<div id="status"><i class="fa fa-spinner fa-spin"></i></div>
</div>
<div ng-if="isLoading">
<div id="status"><i class="fa fa-spinner fa-spin"></i></div>
</div>
<section>
<div class="contentpanel">
<!-- content goes here... -->
<error-page ng-if="error"></error-page>
<div ng-view ng-if="!isLoading && !error"></div>
</div>
</div><!-- mainpanel -->
</section>
</body>
I want to implement the indicator for my page, you can see the <div id="status"><i class="fa fa-spinner fa-spin"></i></div> as well as ng-if="isLoading" line.
In the login component I have these line of code to change from login view to register view.
$scope.onRegister = function () {
$rootScope.isLoading = true;
$location.path(routes.REGISTER);
}
What I want is when changing the view from login view to register view, the indicator (spinner) is up. After that, in the register component code I have these lines to force the spinner off.
function registerController($scope, $rootScope, $location, $http) {
$rootScope.isLoading = false;
}
But the spinner rounds endlessly.
I tried to read about $viewContentLoaded, and I put these line of code in my application (parent application) as well as the register controller.
$rootScope.$on('$viewContentLoaded', function (event) {
$rootScope.isLoading = false;
})
It still does not help.
Many thanks in advance for helping me solving that issue.
I think this answer might answer your question that explains how ng-if works:
https://stackoverflow.com/a/19177773/5018962
In short:
The ngIf directive removes or recreates a portion of the DOM tree based on an expression. If the expression assigned to ngIf evaluates to a false value then the element is removed from the DOM, otherwise a clone of the element is reinserted into the DOM.

AngularJS: Infinite Scroll in a container

I'm using ngInfiniteScroll in AngularJS for a specific container.
Simple example
html
<div id="containerInfiniteScroll" class="container">
<div infinite-scroll="next()" infinite-scroll-disabled="disabled" infinite-scroll-distance="1" infinite-scroll-container='"#containerInfiniteScroll"'>
<div class="row">
<div class="col-xs-12 col-sm-12 col-lg-12">
<span data-ng-repeat="el in elements | limitTo:limit">
{{el}}
</span>
</div>
</div>
</div>
</div>
css
.container{overflow-y:scroll;}
js
//Varibles...
$scope.elements = ['element1','element2','element3','...','elementn'];
$scope.limit=50;
$scope.disabled = false;
//Function that infinte-scroll calls:
$scope.next = function(){
$scope.limit=$scope.limit+50;
$scope.disabled = $scope.limit>=elements.length;
};
The ngInfiniteScroll works as expected for contentInfiniteScroll content. Except this case...
Don't charge more elements if the scroll-y of the page (not the
scroll of the container) is on bottom.
And only don't work in this case...
What am I doing wrong? It's me, or maybe I need to retouch the library ngInfiniteScroll.js ?
Thank you.

How to show preloader inside button instead text Angular JS?

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.

Type error : Cannot read property 'childNodes' of undefined

I am trying to display a modal when the view is loaded.
Code :
//View
<div id="showCom" ng-controller="showmodalCtrl" ng-init="init()">
<div class="modal fade" id="companyModal" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title">Please Select Company</h4>
</div>
<div class="modal-body">
<form>
<div class="form-group">
<label class="control-label">Recipient:</label>
<input type="text" class="form-control">
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary">Submit</button>
</div>
</div>
</div>
</div>
//Controller
.controller('showmodalCtrl', ['$scope', function($scope){
$scope.init = function(){
$('#companyModal').modal("show");
}
}])
Everything works fine and the modal is displayed but I get this error on the console :
Type error : Cannot read property 'childNodes' of undefined
I have no idea why this is happening.
Also if I remove the "form" from the modal , i don't get any error. So I guess the problem is with the form but I am not able to resolve it.
Thanks in advance.
I had the same problem and I managed to resolve it by wrapping the modal open function inside a $timeout() or a normal setTimeout() function.
setTimeout(function(){
jQuery('#messageModal').modal('show');
}, 0);
I had the same error message when trying to use a JQuery plugin. Running it after document ready resolved the issue for me. The plugin was running fine but the angular code that followed in the current scope was not.
It was the "Set timeout"-answer in this thread that led me to try this solution.
Solution for me:
angular.element(document).ready(function () {
//Angular breaks if this is done earlier than document ready.
setupSliderPlugin();
});
As another solution in AngularJS context I'm using this approach:
Include $timeout module in your JS controller
Run init() function with all initializers like this:
$timeout(init, 0);
Works good.
Sorry for edit. Is your HTML well formed? Check that all the tags match.
In your code snippet, it looks like you're missing a closing div. check that - the one that closes the controller div.
I had a similar problem. It would throw an exception when i tried to add some html to dom and compile it using $compile in angularJs.
Inside of the html was another directive that tried to add some dom element from the page to somewhere else in the page.
I just had to call .clone of that element before i moved it to the new location.
And the exception was gone.
$popupContent = $(attrs.popupSelector).clone();
$container = $('<div class="popup-container"></div>');
$container.append($popupContent);
$container.hide();
$('body').append($container);

Resources