First I define an array:
$scope.workspaces = [{name: "Traffic Permits", state: "traffic-permits", classname: "tab_table ng-isolate-scope"}];
then I call it:
<a class="{{workspace.classname}}" ng-repeat="workspace in workspaces"
ui-sref="{{workspace.state}}" ui-sref-active="active">{{workspace.name}}
</a>
Seens pretty straightforward. I am just declaring a menu basically. However I am getting a strange error:
TypeError: a.hashPrefix is not a function
at Object.href (http://localhost:51188/Scripts/angular-ui-router.min.js:7:11776)
at Object.y.href (http://localhost:51188/Scripts/angular-ui-router.min.js:7:19457)
at link.t (http://localhost:51188/Scripts/angular-ui-router.min.js:7:24512)
at link (http://localhost:51188/Scripts/angular-ui-router.min.js:7:24721)
at nodeLinkFn (http://localhost:51188/Scripts/angular.js:6711:13)
at compositeLinkFn (http://localhost:51188/Scripts/angular.js:6105:13)
at publicLinkFn (http://localhost:51188/Scripts/angular.js:6001:30)
at $get.boundTranscludeFn (http://localhost:51188/Scripts/angular.js:6125:21)
at controllersBoundTransclude (http://localhost:51188/Scripts/angular.js:6732:18)
at ngRepeatAction (http://localhost:51188/Scripts/angular.js:20624:15) <a class="{{workspace.classname}} ng-binding ng-scope" ng-repeat="workspace in workspaces" ui-sref="{{workspace.state}}" ui-sref-active="active">
All help is appreciated thanks.
angular.module('myModule').config(function ($stateProvider, $urlRouterProvider) {
//
// For any unmatched url, redirect to /state1
$urlRouterProvider.otherwise("/traffic-permits");
//
// Now set up the states
$stateProvider
.state('traffic-permits', {
url: "/traffic-permits",
templateUrl: "/admin/permittable"
});
});
Ok, so I am now using the unminified version of the router. The error is being thrown at:
url = "#" + $locationProvider.hashPrefix() + url;
The error is $locationProvider.hashPrefix() is not a function, what could this be???
I put a break point there. hashPrefix is an empty string.
Hash prefix is not a property - you use it to set the hash prefix.
https://docs.angularjs.org/guide/$location#-location-service-configuration
Figured it out:
apparently somebody thought it was a good idea to add this in the module config:
$locationProvider.hashPrefix = '';
ridiculous....
Related
I am not very good with angular, but i know some basics. Now, I have access points and want to assign them to a building. I can select this building with a <select>. I have written a simple controller, but it wont work. What am I making wrong, i cant find a solution.
Edit 1:
I can see the option fields (they are 3). But after I select one of these, my browser console throws the exception
Edit 2: Plunkr -> https://plnkr.co/edit/EIPs8yVlTSaYQ0EuZLTb (i hope, this url works) .. When you click on "Neuer Access-Point" the error will occur, after you select something on "Gebäude"
Select field
<select ng-model="$ctrl.input.building">
<option ng-repeat="building in $ctrl.buildings" ng-value="building.id" ng-bind="building.name"></option>
</select>
Controller
(function () {
function createController(Building) {
var ctrl = this;
ctrl.buildings = null;
ctrl.input = {
host: '',
desc: '',
web: '',
building: ''
};
ctrl.$onInit = function () {
Building.getAll().then(function (res) {
if (res.status >= 200 && res.status < 300) {
ctrl.buildings = res.data;
}
});
};
}
angular.module('app').controller('CreateController', createController)
})();
Error
angular.js:14791 Error: [$rootScope:inprog] http://errors.angularjs.org/1.6.8/$rootScope/inprog?p0=%24apply
at angular.js:88
at p (angular.js:18897)
at m.$digest (angular.js:18319)
at m.$apply (angular.js:18640)
at Object.$$debounceViewValueCommit (angular.js:29394)
at Object.$setViewValue (angular.js:29372)
at angular.js:33596
at m.$eval (angular.js:18533)
at m.$apply (angular.js:18632)
at HTMLSelectElement.<anonymous> (angular.js:33595)
Here is the issue with your code.
<div id="wrapper" ng-app="accessPoints" ng-controller="RootController **as $root**">
Change it to simply
ng-controller="RootController as anythingButNot$root"
or even just ng-controller="RootController"
Declaring any controller as $root is creating mess for you. $root is the root level controller of your application. Inside your html if you declare any controller as $root, it tries to overwrite $root, creating trouble with digest cycle, hence you are getting the error.
Link to updated plunk => https://plnkr.co/edit/UcJHVmekMqWMXJBnv2Cu?p=preview
I'm trying to use angular js ui router to route my page.
Here's the code that I've written:
<a ui-sref="transporterEditDetails({companyId: '{{d.companyId}}' )" style="cursor: pointer">{{d.companyName}}</a>
Here's the js code :
var routerApp = angular.module('routerApp', ['ui.router','ui.bootstrap','xeditable','google.places','angular-loading-bar','ui.select','angularUtils.directives.dirPagination','notificationsTruckway','ui.tinymce'])
routerApp.config(function($stateProvider, $urlRouterProvider,cfpLoadingBarProvider) {
$stateProvider
.state('transporterEditDetails', {
url: '/transporterEditDetails/:companyId',
controller:'TransporterEditDetailsController',
templateUrl: 'Transporter-editDetails.html'
})
routerApp.controller('TransporterEditDetailsController', function($scope,$location,$http,usersFactory,$stateParams) {
$scope.companyId = $stateParams.companyId;
}
I don't know what's wrong in my code, I'm unable to get the href attribute which should be generated automatically.
Did you try without quotes and parentheses
<a ui-sref="transporterEditDetails({companyId: d.companyId})" style="cursor: pointer">{{d.companyName}}</a>
You don't need to use {{}}(interpolation) inside ui-sref. Also remove '(wrapped single quote)
ui-sref="transporterEditDetails({companyId: d.companyId })"
I have an URL http://sitename.com/#/products/manage-options/31?form_id=32&type=create-template
Here above my URL I want to remove type but below my code not working properly. Please Check
My Current page URL - http://sitename.com/#/products/manage-options/31?type=create-template
Click Here
$scope.clickMe = function(){
$location.search('type', null);
$state.go('products.manage_options', ({form_id: $stateParams.form_id}));
};
After page redirecting I saw type QueryString not removed.
My output is - http://sitename.com/#/products/manage-options/31?form_id=32&type=create-template I want http://sitename.com/#/products/manage-options/31?form_id=32
please help me.
EDIT:
Router
.state('products.manage_options', {
url: '/manage-options/:product_id?form_id=&type',
templateUrl: "views/product/manage_options.html",
controller: "manageAttributeCtrl",
data: {pageTitle: 'Manage Options'},
})
Remove
$location.search('type', null);
Change following line :
$state.go('products.manage_options', ({form_id: $stateParams.form_id, type:null}));
see documentation https://docs.angularjs.org/api/ng/service/$location#search
$state.go('products.manage_options', ({form_id: $stateParams.form_id, type:null}));
I need to bind status message to variable. If it's empty I need to hide div. If it's not empty show div and message. At the moment when I update $scope.statusMessage.msgin controller the {{statusMessage.msg}} is not being updated. How to fix it?
<div class="alert alert-info"
ng-class="{'alert-danger': statusMessage.status == -1, 'alert-success': statusMessage.status == 1, 'alert-warning': statusMessage.status == 0}"
role="alert" ng-hide="(statusMessage.msg).length == 0">{{statusMessage.msg}}</div>
$scope.statusButtonAction = function(action){
$scope.statusMessage.msg = 'Validation Error';
}
UPDATE 1
<form role="form" class="form-inline" id="status-buttons">
<button type="button" class="btn btn-warning btn-lg" ng-click="statusButtonAction('Validation Error')">Validation Error</button>
</form>
UPDATE 2
declaration of :
$scope.statusMessage = {
msg: '',
status: null
};
UPDATE 3
http://jsbin.com/jaquc/2/
UPDATE 4
I use https://github.com/angular-ui/ui-router . and my config is :
prototypeApplication.config(function ($stateProvider, $urlRouterProvider) {
$stateProvider.state('welcome', {
url: '/',
views: {
'': {
templateUrl: 'views/prototype/welcome.html',
controller: 'welcomeController'
},
'header#welcome': {
templateUrl: 'views/components/header.html'
},
'check-in#welcome': {
templateUrl: 'views/prototype/welcome/check-in.html',
controller: 'checkInController'
},
'status-buttons#welcome': {
templateUrl: 'views/prototype/welcome/status-buttons.html',
controller: 'checkInController'
}
}
})
UPDATE 5
Strange enough, but when I switch from object oriented representation to plain variables all works:
$scope.statusMessage = '123';
$scope.statusState = null;
Does it mean I have to use some trick to make AngularJS read object's property's values?
Make sure that you defined $scope.statusMessage ie:
$scope.statusMessage = {};
before you try set $scope.statusMessage.msg in your statusButtonAction function.
and use
ng-hide="!statusMessage.msg" or ng-show="statusMessage.msg"
instead
ng-hide="(statusMessage.msg).length == 0"
Please see working demo here http://jsbin.com/vavahi/1/edit
I think the issue is use of '==' instead of '==='. The former does type coercion and results are a bit 'unreliable' especially with strings/arrays... At least I use ng-hide="myArray.length === 0" as the way to control and works always as it should.
(However, I am not sure what you are trying to do in your ng-class with "... == -1" etc. - at least I don't see statusMessage.status being declared nor used in your code...)
I found that editing ui-router configuration like this solves the problem
...
check-in#welcome': {
templateUrl: 'views/prototype/welcome/check-in.html'
/*,
controller: 'checkInController' */ // should be removed to work!
...
I have been continuing learning angular and have now used the angular ui bootstrap pagination successfully. I am able to display the list of items together with the correct number of pages. And also switch to the correct page whenever I click on the pagination.
Now my question is if a user wanted to bookmark a certain page, or to make sure the user stays on the same page whenever he refreshes the browser, how do I go about it. There are no links (href) being generated on the address bar of the browser. Do I also need to set routes? Can you please post some examples, as it would greatly help me. Thanks.
You need to set up routes, you can do it using routeProvider or ui router
In this example, I use route provider to demonstrate, but the idea is the same.
Here I set up a route with currentPage as parameter:
app.config(function($routeProvider) {
$routeProvider
.when('/page/:currentPage', {
templateUrl: "template.html",
controller: PaginationDemoCtrl
})
});
In your controller, you can retrieve the current page from $routeParam:
$scope.currentPage = $routeParams.currentPage || 1; //default to 1 if the parameter is missing
//load your paged data from server here.
You could just $watch current page for changes and update the location accordingly:
$scope.$watch("currentPage",function(value){
if (value){
$location.path("/page/" + value);
}
})
Source code
DEMO link
With routing, you also need to update your code to load paged data from server. We don't load data immediately when the currentPage changes (in this case is the $watch function). We load our paged data when we retrieve the $routeParam.currentPage parameter.
As requested by #Harry, here is another solution to generate href links by overwriting bootstrap html template:
app.config(function($routeProvider) {
$routeProvider
.when('/page/:currentPage?', {
templateUrl: "template.html",
controller: PaginationDemoCtrl
})
})
.run(["$templateCache","$rootScope","$location", function($templateCache,$rootScope,$location) {
$rootScope.createPagingLink = function(pageNumber){
return "#" + $location.path().replace(/([0-9])+/,pageNumber);
//Here is a sample function to build href paths. In your real app, you may need to improve this to deal with more case.
}
$templateCache.put("template/pagination/pagination.html",
"<ul class=\"pagination\">\n" +
" <li ng-if=\"boundaryLinks\" ng-class=\"{disabled: noPrevious()}\"><a ng-href=\"{{$root.createPagingLink(1)}}\">{{getText('first')}}</a></li>\n" +
" <li ng-if=\"directionLinks\" ng-class=\"{disabled: noPrevious()}\"><a ng-href=\"{{$root.createPagingLink(page - 1)}}\">{{getText('previous')}}</a></li>\n" +
" <li ng-repeat=\"page in pages track by $index\" ng-class=\"{active: page.active}\"><a ng-href=\"{{$root.createPagingLink(page.number)}}\">{{page.text}}</a></li>\n" +
" <li ng-if=\"directionLinks\" ng-class=\"{disabled: noNext()}\"><a ng-href=\"{{$root.createPagingLink(page + 1)}}\">{{getText('next')}}</a></li>\n" +
" <li ng-if=\"boundaryLinks\" ng-class=\"{disabled: noNext()}\"><a ng-href=\"{{$root.createPagingLink(totalPages)}}\">{{getText('last')}}</a></li>\n" +
"</ul>");
}]);
Source code
DEMO link
We can do this with the $location, without needing $route.
Here is an example of how to call the pagination from Angular UI Bootstrap:
<pagination ng-model="Controls.currentPage"
total-items="Controls.totalItems"
items-per-page="Controls.videosPerPage"
max-size="5"
rotate="false"
boundary-links="true"
ng-change="pageChanged()">
</pagination>
Inside the pageChanged() function, use the following to create a unique URL for your results page:
** My code is on Coffeescript, but the logic is simple and the code easy to adapt **
$location.search('page', $scope.Controls.currentPage)
And on your controller, use the following to check, when starting, if the URL parameter is there:
urlParams = $location.search()
if urlParams.page?
$scope.Controls.currentPage = urlParams.page
else
$scope.Controls.currentPage = 1
Yes, if you want your app to allow linking into certain states then you will have to have your app leverage the routeProvider.
The official docs don't have a great deal of information on routes but the tutorial has this page:
http://docs.angularjs.org/tutorial/step_07
Also John Lindquist's excellent short video tutorials are a must watch. One dealing with routes is:
http://www.egghead.io/video/gNtnxRzXj8s
Here the generic solution - the uibPagination directive decorator and the updated template:
angular.module('ui.bootstrap.pagination')
.config(function($provide) {
$provide.decorator('uibPaginationDirective', function($delegate, $templateCache) {
var directive = $delegate[0];
directive.scope.getPageHref = "&";
$templateCache.put("uib/template/pagination/pagination.html",
"<li ng-if=\"::boundaryLinks\" ng-class=\"{disabled: noPrevious()||ngDisabled}\" class=\"pagination-first\"><a ng-href=\"{{noPrevious() ? '' : getPageHref()(1)}}\" ng-disabled=\"noPrevious()||ngDisabled\" uib-tabindex-toggle>{{::getText('first')}}</a></li>\n" +
"<li ng-if=\"::directionLinks\" ng-class=\"{disabled: noPrevious()||ngDisabled}\" class=\"pagination-prev\"><a ng-href=\"{{noPrevious() ? '' : getPageHref()(page - 1)}}\" ng-disabled=\"noPrevious()||ngDisabled\" uib-tabindex-toggle>{{::getText('previous')}}</a></li>\n" +
"<li ng-repeat=\"page in pages track by $index\" ng-class=\"{active: page.active,disabled: ngDisabled&&!page.active}\" class=\"pagination-page\"><a ng-href=\"{{getPageHref()(page.number)}}\" ng-disabled=\"ngDisabled&&!page.active\" uib-tabindex-toggle>{{page.text}}</a></li>\n" +
"<li ng-if=\"::directionLinks\" ng-class=\"{disabled: noNext()||ngDisabled}\" class=\"pagination-next\"><a ng-href=\"{{noNext() ? '' : getPageHref()(page + 1)}}\" ng-disabled=\"noNext()||ngDisabled\" uib-tabindex-toggle>{{::getText('next')}}</a></li>\n" +
"<li ng-if=\"::boundaryLinks\" ng-class=\"{disabled: noNext()||ngDisabled}\" class=\"pagination-last\"><a ng-href=\"{{noNext() ? '' : getPageHref()(totalPages)}}\" ng-disabled=\"noNext()||ngDisabled\" uib-tabindex-toggle>{{::getText('last')}}</a></li>\n" +
"");
return $delegate;
});
});
We decorate the directive with the getPageHref function passed from the outer scope which is used to construct the page links.
Usage:
<div ng-controller="ProductController">
...
<ul uib-pagination
total-items="totalItems"
ng-model="page"
get-page-href="getPageHref">
</ul>
</div>
Now you have to define the getPageHref function in your outer scope:
angular.module('app')
.controller('ProductController', function($scope) {
...
$scope.getPageHref = function(page) {
return '#/products?page=' + page;
};
});
Just to make code look better you can use template-url attribute on uib-pagination element
to specify your new template url
I whould use ui-sref instead of using a function to generate the link .
and instead of reloading the controller for each page click pass a function for ng-click with $eventso you could prevent the href from been executed
with e.preventDefault() and calling your ajax before
<li ng-repeat="page in pages track by $index" ng-class="{active: page.active}"><a ui-sref="list({page: page.text})" ng-click="$root.paginationClick(page.number,$event)">{{page.text}}</a></li>