Angular Bootstrap Tabs, initialize a tab through controller - angularjs

I am unable to get an angular tab other than the first one to be active on load. I am passing a url parameter such as ?location=Tucson to make that decision. I would like the second tab to display as active on load. Oddly enough the first tab is being set to active automatically, perhaps this is by default.
I am using
* angular-strap
* #version v2.1.4 - 2014-11-26
How can I set the second tab to active through the controller?
This is my setup
<section class="mainbar" data-ng-controller="contactus as vm">
<div>
<tabset>
<tab class="tab-pane" id="Tampa" heading="Tampa">
<tab-heading>Tampa</tab-heading>
<div class="actionBtn">
<a id="tpabtn" class="btn btn-default ldbtn request" data-ng-click="vm.getcontactformF()">
<div><span class="glyphicon glyphicon-envelope"></span></div>
<div>
<div class="title">Have Questions?</div>
<div>Send us a message</div>
</div>
</a>
</div>
</tab>
<tab class="tab-pane" id="Tucson" active="active">
<tab-heading>Tucson</tab-heading>
<div class="actionBtn">
<a href="tel:8885210206" class="btn btn-default ldbtn">
<div><span class="glyphicon glyphicon-earphone"></span></div>
<div>
<div class="title">RV Service</div>
<div class="phone">888.521.0206</div>
</div>
</a>
</div>
</tab>
</tabset>
</div>
<script type="text/ng-template" id="_contactfservice.html">
<div data-ng-include data-src="'/app/form/contactusform.html'"></div>
</script>
</section>
JS
(function () {
'use strict';
var controllerId = "contactus";
angular
.module('app')
.controller(controllerId, ['$location', '$window', '$rootScope', '$scope', '$sce', '$q', 'common', 'config', 'bootstrap.dialog', 'datacontext', contactus]);
function contactus($location, $window, $rootScope, $scope, $sce, $q, common, config, bsDialog, datacontext) {
/* jshint validthis:true */
var vm = this;
vm.highlightLocation = highlightLocation;
activate();
function activate() {
common.activateController([getLocationHours()], controllerId).then(function () {
common.postLoad();
log('Activated contact us View test test');
$window.ga('send', 'event', $location.path(), 'form-viewed');
highlightLocation();
});
}
function highlightLocation() {
var location = common.getQueryStringParameter('location', document.location.href);
console.log(location);
if (location == "Tucson") {
$scope.tabs = [{active: false}, {active: true}];
}
}
}
})();

some weird issue with bootstrap ui, this works.
$scope.data = {};
$timeout(function () {
$scope.vm.data.static2 = true;
}, 0)

Related

AngularJS call AngularStrap Modal from service

I am trying to create a service to display Angular-Strap modals since I have many different parts of code that will need to trigger a modal and I don't want to run into a situation where I would have a circular reference.
This is code that works where you have access to $scope. For instance, in the applications controller.
function MyModalController($scope) {
$scope.title = 'Draw Object Properties';
$scope.content = 'Hello Modal<br />This is place holder test';
};
MyModalController.$inject = ['$scope'];
// Pre-fetch an external template populated with a custom scope
var myOtherModal = $modal({ controller: MyModalController, templateUrl: 'webmapapi/modal/toolproperties.html', show: false });
// Show when some event occurs (use $promise property to ensure the template has been loaded)
$scope.showModal = function () {
myOtherModal.$promise.then(myOtherModal.show);
};
Like I said I need to call this from a service though.
(function (angular, undefined) {
'use strict';
angular.module('ModalService', ['service', 'webValues', 'msObjects', 'mgcrea.ngStrap',])
.config(function ($modalProvider) {
angular.extend($modalProvider.defaults, {
html: true
});
})
.factory("ModalService", function (MapApiService, webValues, VectorObjs,$modal) {
var modalSVC = {
};
modalSVC.showModal = function (modalType) {
var scope = angular.element(document.getElementById('mainContainer')).scope();
function MyModalController(scope) {
scope.title = 'Draw Object Properties';
scope.content = 'Hello Modal<br />This is place holder test';
};
MyModalController.$inject = ['scope'];
// Pre-fetch an external template populated with a custom scope
var myOtherModal = $modal({ controller: MyModalController, templateUrl: 'myURL.html', show: true });
// Show when some event occurs (use $promise property to ensure the template has been loaded)
myOtherModal.show;
};
return modalSVC;
})
}(angular));
The above does not like the scope I'm getting.
Okay, It's amazing how easy something can be once you know what you are doing!!
Essentially you will want to set up a service...
(function (angular, undefined) {
'use strict';
angular.module('ModalService', ['mgcrea.ngStrap'])
.controller('ModalServiceController', modalServiceController)
.factory("ModalService", function ($animate, $document, $compile, $controller, $http, $rootScope, $q, $templateRequest, $timeout, $modal) {
function ModalService() {
var self = this;
self.showModal = function (title,templateUrl) {
var modal = $modal({
title: title,
templateUrl: templateUrl,
show: true,
backdrop: 'static',
controller: 'ModalServiceController'
});
modal.show;
};
}
return new ModalService();
})
modalServiceController.$inject = ['$scope', '$modal'];
function modalServiceController($scope,$modal) {
//title and content need to be populated so I just left the default values
$scope.title = 'Draw Object Properties';
$scope.content = 'Hello Modal<br />This is place holder test';
};
}(angular));
Now that you have your controller set up and injecting $modal, all you have to do from anywhere you have your service reference injected is...
ModalService.showModal("Your Title",
"Your URL");
I have a template(must be formatted as ) set up as Template.html and the contents are...
<div class="modal" tabindex="-1" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header" ng-show="title">
<button type="button" class="close" ng-click="$hide()">×</button>
<h4 class="modal-title" ng-bind-html="title"></h4>
</div>
<div class="modal-body" ng-show="content">
<h4>Text in a modal</h4>
<p ng-bind-html="content"></p>
<pre>2 + 3 = {{ 2 + 3 }}</pre>
<h4>Popover in a modal</h4>
<p>This <a href="#" role="button" class="btn btn-default popover-test" data-title="A Title" data-content="And here's some amazing content. It's very engaging. right?" bs-popover>button</a> should trigger a popover on click.</p>
<h4>Tooltips in a modal</h4>
<p><a href="#" class="tooltip-test" data-title="Tooltip" bs-tooltip>This link</a> and <a href="#" class="tooltip-test" data-title="Tooltip" bs-tooltip>that link</a> should have tooltips on hover.</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" ng-click="$hide()">Close</button>
<button type="button" class="btn btn-primary" ng-click="$hide()">Save changes</button>
</div>
</div>
</div>
I hope this helps you!!

Trying to show a modal popup but getting this error [$injector:unpr] in angularjs

Hi I am a newbie and I am learning angularjs. I am implementing a modal popup on click. But seems like there is an issue in dependency.
My index file
<body>
<div class="global-wrap">
<div class="container">
<div class="col-md-offset-3 col-md-6 col-md-offset-3 login">
<h1 class="align-cent">ShopOber</h1>
<div ng-controller="PosController">
<button ng-click="open()" class="btn btn-warning">Simple Popup</button>
</div>
</div>
</div>
</div>
</body>
</html>
my controller file
var posControllers = angular.module('posControllers', ['ui.bootstrap']);
posControllers.controller('PosController', ['$scope', '$http', '$routeParams', '$modal', function ($scope, $http, $routeParams, $modal) {
$scope.open = function () {
console.log('opening pop up');
var modalInstance = $modal.open({
templateUrl: 'popup.html',
});
};
}]);
and my app.js file
var myApp = angular.module('myApp', [
'ngRoute', // we are telling angular that we are using ngRouting feature that enables deeplinking first
'posControllers',
// we specify the JS that will handle this module
//'caControllers'
]);
Full error in console
"Error: [$injector:unpr] http://errors.angularjs.org/1.4.4/$injector/unpr?p0=%24uimodalProvider%20%3C-%20%24uimodal%20%3C-%20PosController
L/<#https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular.min.js:6:416
eb/q.$injector<#https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular.min.js:40:307
d#https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular.min.js:38:308
eb/u.$injector<#https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular.min.js:40:379
d#https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular.min.js:38:308
e#https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular.min.js:39:64
Xe/this.$get</</<#https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular.min.js:80:149
K#https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular.min.js:61:140
g#https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular.min.js:54:326
g#https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular.min.js:54:349
g#https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular.min.js:54:349
g#https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular.min.js:54:349
g#https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular.min.js:54:349
g#https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular.min.js:54:349
V/<#https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular.min.js:53:388
yc/d/</<#https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular.min.js:20:4
kf/this.$get</n.prototype.$eval#https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular.min.js:133:35
kf/this.$get</n.prototype.$apply#https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular.min.js:133:264
yc/d/<#https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular.min.js:19:477
e#https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular.min.js:39:94
yc/d#https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular.min.js:19:398
yc#https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular.min.js:20:179
Zd#https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular.min.js:19:1
#https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular.min.js:292:238
a#https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular.min.js:174:283
Hf/c#https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular.min.js:35:124
"
I am following this tutorial https://www.formget.com/angularjs-popup/.The pop up does not show up although it code does and when i write display:block in console the pop up does come
My popup.html
<div class="modal-header">
<h3 class="modal-title">Header</h3>
</div>
<div class="modal-body">
Popup example with close button
</div>
<div class="modal-footer">
<button class="btn btn-warning" type="button"
ng-click="close()">Close</button>
</div>
Since angular-bootstrap 1.0.0 newer version all the directive & services are prefixed with uib. Specifically service are prefixed with uib such as $modal=> $uibModal & directives are prefixed with uib- such as popover => uib-popover .Here you can see the changelog
So you should be injecting $uibModal instead of $modal
var posControllers = angular.module('posControllers', ['ui.bootstrap']);
posControllers.controller('PosController',
['$scope', '$http', '$routeParams', '$uibModal',
function($scope, $http, $routeParams, $uibModal) {
$scope.open = function() {
console.log('opening pop up');
var modalInstance = $uibModal.open({
templateUrl: 'popup.html',
});
};
}
]
);
Make sure you have referenced the library for angular-bootstrap
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.js"></script>
<script src="http://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.6.0.js"></script>
also module should be like this,
var myApp = angular.module('myApp', [
'ngRoute',
'posControllers',
'caControllers',
'ui.bootstrap'
]);
DEMO

Ng-Click not firing Button is Clicked

So have a modal with a two buttons on it. One to close the modal, and one that should fire a function when clicked. I've attached a controller to the modal, and the controller itself works, as it does a successful console.log(). The ng-click doesn't seem to fire the function though. I think I just need another set of eyes on this, and it is greatly appreciated.
HTML:
<div id="forwardCall" class="modal fade" ng-controller="CallCtrl as call">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4>Transfer Call</h4>
</div>
<!-- dialog body -->
<div class="modal-body">
<p>Select Person below</p>
<div id="transferSelection">
<?php echo $transferCallSelect; ?>
</div>
</div>
<!-- dialog buttons -->
<div class="modal-footer">
<button class="btn btn-warning" data-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-primary" data-dismiss="modal" ng-click="call.hideControls()">Transfer Call</button></div>
</div>
</div>
</div>
Controller:
app.controller('CallCtrl', ['$scope', '$http', function($scope, $http){
console.log("Call Controller");
function hideControls(){
console.log("Controls Hidden");
var well = document.getElementById('callControls');
well.style.display = 'none';
}
}]);
If you are using controller as syntax, you are binding to this variable instead of $scope. Here is a good post talked about Controller As Syntax.
tymejv gave you a good suggestion. You have to binding the function to this when you are using controller as syntax. So that you can access the function or variable for this particular controller.
this.hideControls = function() { ... };
You can binding to function to the $scope as well:
$scope.hideControls = function() { ... };
controller.js
(function () {
'use strict';
angular
.module('app')
.controller('CallCtrl', CallCtrl);
CallCtrl.$inject = ['$scope', '$http'];
function CallCtrl($scope, $http) {
var vm = this;
console.log("Call Controller");
vm.well = true;
vm.hideControls = function () {
console.log("Controls Hidden");
//Do not to this! This is not jQuery
//var well = document.getElementById('callControls');
//well.style.display = 'none';
vm.well = false;
};
}
}());
index.html
<div id="forwardCall" class="modal fade" ng-controller="CallCtrl as call">
<div ng-show={{ call.well }}>Some content</div>
</div>

Can I stop the transition to the next state in an onExit?

I have two states, A and B.
When I exit state A by clicking on a close button I do a transition to screen A using $state.go to state B (screen B)
When I exit state A by clicking on the back browser button on screen A I do a transition to state B (screen B) as the browser URL changes
In the onExit of screen A I do a check and if this fails an Error Dialog opens, clicking Close on the error dialog returns a failed promise to the onExit
However the onExit still goes ahead and I go to screen B
Is it possible to stop the transition from State A (Screen A) to State B (Screen B) if something fails in the onExit?
You can achieve your goal implementing a $stateChangeStart event handler in which you can cancel the state transition (event.preventDefault();) when needed.
Here below is an example where a checkBox simulate a condition of transition disabled. In this case on state change (both state.go and navigation) it opens a modal asking the user to accept/reject the transition blocked (another simulation of some validation check):
var myApp = angular.module('myApp', ['ui.router','ui.bootstrap']);
myApp.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/state_a');
$stateProvider
.state('state_a', {
url: '/state_a',
templateUrl: 'stateA.html',
onEnter: function() {
console.log("onEnter stateA");
},
onExit: function($rootScope, $state) {
console.log("onExit stateA: "+$rootScope.chk.transitionEnable);
},
controller: function($scope, $state) {
$scope.goToStateB = function() {
$state.go("state_b");
}
}
})
.state('state_b', {
url: '/state_b',
templateUrl: 'stateB.html',
onEnter: function() {
console.log("onEnter stateB");
},
onExit: function() {
console.log("onExit stateB");
},
controller: function($scope) {
}
});
});
myApp.controller('mainCtrl', function($rootScope, $scope, $uibModal, $state) {
$rootScope.chk = {};
$rootScope.chk.transitionEnable = true;
$rootScope.$on('$stateChangeStart',
function(event, toState, toParams, fromState, fromParams, options) {
if (!$rootScope.chk.transitionEnable) {
event.preventDefault();
$scope.toState = toState;
$scope.open();
} else {
console.log("$stateChangeStart: "+toState.name);
}
})
$scope.open = function () {
var modalInstance = $uibModal.open({
animation: $scope.animationsEnabled,
templateUrl: 'myModal.html',
scope: $scope,
controller: function($uibModalInstance, $scope) {
$scope.ok = function () {
$uibModalInstance.close('ok');
};
$scope.cancel = function () {
$uibModalInstance.dismiss('cancel');
};
},
size: 'sm'
});
modalInstance.result.then(function (value) {
console.info('Modal closed: ' + value);
}, function () {
console.info('Modal dismissed');
$rootScope.chk.transitionEnable = true;
$state.go($scope.toState.name);
});
};
});
<!DOCTYPE html>
<html>
<head>
<link href="//netdna.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet">
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular-animate.js"></script>
<script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-1.1.1.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.17/angular-ui-router.min.js"></script>
<script src="app.js"></script>
</head>
<body ng-app="myApp" ng-controller="mainCtrl">
<nav class="navbar navbar-inverse" role="navigation">
<div class="navbar-header">
<a class="navbar-brand" ui-sref="#">AngularUI Router</a>
</div>
<ul class="nav navbar-nav">
<li><a ui-sref="state_a">State A</a></li>
<li><a ui-sref="state_b">State B</a></li>
</ul>
</nav>
<div class="container">
<div ui-view></div>
</div>
<script type="text/ng-template" id="myModal.html">
<div class="modal-header">
<h3 class="modal-title">Title</h3>
</div>
<div class="modal-body">
Transition to <b>{{toState.name}}</b> is disabled, accept or ignore?
</div>
<div class="modal-footer">
<button class="btn btn-primary" type="button" ng-click="ok()">Accept</button>
<button class="btn btn-warning" type="button" ng-click="cancel()">Ignore</button>
</div>
</script>
<script type="text/ng-template" id="stateA.html">
<div class="jumbotron text-center">
<h1>state A</h1>
<p>Example</p>
<a class="btn btn-primary" ng-click="goToStateB()">Goto State B</a>
<a class="btn btn-danger">Do nothing...</a>
</div>
<div class="checkbox">
<label>
<input type="checkbox" ng-model="chk.transitionEnable"> Enable transition
</label>
<pre>chk.transitionEnable = {{chk.transitionEnable}}</pre>
</div>
</script>
<script type="text/ng-template" id="stateB.html">
<div class="jumbotron text-center">
<h1>state B</h1>
<p>The page... </p>
</div>
<div class="container">
Bla bla
<div class="checkbox">
<label>
<input type="checkbox" ng-model="chk.transitionEnable"> Enable transition
</label>
<pre>chk.transitionEnable = {{chk.transitionEnable}}</pre>
</div>
</div>
</script>
</body>
</html>
I answered a similar question where you can prevent the state transition, you might find it useful
$scope.$on('$stateChangeStart') and $modal dialog
#beaver approach definitely works well if the logic decides on the transition to the state B resides in the state A controller.
However if is the case that the state transition to state B requires a pre-condition to be true (regardless of the current state), then using ui-router Resolve could be a cleaner solution.
The business logic for the pre-condition could live in a separate service.
This setup also allows the state B controller to receive the resolved value, if required. And since the resolve function uses promises, the process can be asynchronous as well.
angular.module("yourAppModule")
.service('StateB_helperService', [
'$q',
function($q) {
this.allowTransition = function() {
var deferred = $q.defer();
//
// ... state transition logic ...
//
// resolves the promise to allow the state transition
// rejects otherwise
//
return deferred.promise;
}
}
])
...
angular.module("yourAppModule")
.config([
'$stateProvider',
function($stateProvider) {
$stateProvider.state('state_b', {
templateUrl: "...",
resolve: {
stateB_PreCondition: [
'StateB_helperService',
function(StateB_helperService) {
return StateB_helperService.allowTransition();
}
]
}
})
}
])

AngularJS $scope.$parent strange hierarchy

I'm trying to access the $parent in my child controller but for some reason I have to access the Fifth $parent in order to get the actual $scope from the Parent controller, Any Ideas?
Parent Controller
angular.module('App')
.controller('HomeController', ['$scope', '$rootScope', 'user',
function($scope, $rootScope, user) {
$rootScope.currentNav = 'home';
$rootScope.currentUser = user.data;
$scope.tabs = [
{
heading : 'Empresas',
template : 'home_companies_tab.html'
},
{
heading : 'Tickets',
template : 'home_tickets_tab.html'
}
];
$scope.companies = []
$scope.selectedCompanyIndex = undefined;
$scope.selectedCompany = undefined;
$scope.selectedTicketIndex = undefined;
$scope.selectedTicket = undefined;
}]);
Child Controller
angular.module('App')
.controller('HomeCompaniesTabController', ['$scope', 'Companies',
function($scope, Companies) {
$scope.loadCompanies = function () {
$scope.companies = Companies.query();
}
/**
* Init
*/
$scope.selectCompany = function (company, index) {
$scope.$parent.selectedCompanyIndex = index; //this doesnt work
$scope.$parent.$parent.$parent.$parent.$parent.selectedCompany = company; //this does, why?
console.log($scope);
}
if($scope.currentUser.security < 3) {
$scope.loadCompanies();
}
}]);
Home template
<div ng-include="'dist/templates/header.html'"></div>
<div class="container-fluid">
<div class="row">
<div class="col-xs-12">
company : {{selectedCompany}}
</div>
</div>
<tabset>
<tab ng-repeat="tab in tabs" heading="{{tab.heading}}">
<div ng-include="'dist/templates/' + tab.template" ></div>
</tab>
</tabset>
</div>
Child template
<div class="row-fluid" ng-controller="HomeCompaniesTabController">
<div class="col-md-3">
<h4>Lista de Empresas</h4>
<hr/>
<div class="list-group">
<a
href=""
class="list-group-item"
ng-repeat="company in companies"
ng-click="selectCompany(company, $index)">
<h4 class="list-group-item-heading">
{{company.name}}
</h4>
</a>
</div>
</div>
<div class="col-xs-9">
<div ng-show="selectedCompany">
<h4><b>{{selectedCompany.name}}</b></h4>
</div>
</div>
Based on the comments of charlietfl I came up with this simple service for sharing data
angular.module('App')
.factory('SharedData', [function () {
return {
}
}]);
Then I simply inject it in the controllers
angular.module('App')
.controller('HomeController', ['$scope', '$rootScope', 'user', 'SharedData',
function($scope, $rootScope, user, SharedData) {
$rootScope.currentNav = 'home';
$rootScope.currentUser = user.data;
$scope.sharedData = SharedData;
$scope.tabs = [
{
heading : 'Empresas',
template : 'home_companies_tab.html'
},
{
heading : 'Tickets',
template : 'home_tickets_tab.html'
}
];
$scope.companies = [];
}]);

Resources