I have this bootstrap and Angular JS app. I am using the following directive to show active navigation links:
mainControl.directive("myDataToggle", function(){
function link(scope, element, attrs) {
var e = angular.element(element);
e.on('click', function(){
e.parent().parent().children().removeClass('active');
e.parent().addClass("active");
})
}
return {
restrict: 'A',
link: link
};
});
Problem is this works fine in the nav, but if I have a button link that links to the separate sections of the app, the main nav at the top does not get updated To reflect which view I am in?
Any ideas?
The problem is that you're setting the class when you're clicking the link, not when you are navigating.
I presume you're using the ngRoute. If so you can try this approach:
Provide a name for your routes
$routeProvider.
when('/', {
templateUrl: 'views/home.html',
name: 'home'
}).
when('/about', {
templateUrl: 'views/about.html',
name: 'about'
});
Than add $route to your main controller, and pass it on to $scope
function MainCtrl($scope, $route) {
$scope.$route = $route;
}
Now you can add the active class using ng-class
<a ng-class="{active: $route.current.name == 'home'}"> Home </a>
<a ng-class="{active: $route.current.name == 'about'}"> About </a>
demo: https://jsfiddle.net/jkrielaars/mao8kx0L/2/
Related
I'm currently using a Bootstrap theme using Angular JS.
I have three menu buttons located at the top, all of which are going straight to the same page (users), But I would like them to redirect to other associated tabs. In my app.js I have the following routeProvider which should direct the buttons to other html/js files I have:
app.config(['$routeProvider', '$httpProvider',
function ($routeProvider, $httpProvider) {
$routeProvider.
when('/users', {
template: '<svn-userlist></svn-userlist>'
}).
when('/groups', {
// templateUrl: 'grouplist.html'
template: '<svn-grouplist></svn-grouplist>'
}).
when('/repos', {
template: '<svn-repolist></svn-repolist>'
}).
when('/users/:uid', {
template: '<svn-userform></svn-userform>'
}).
when('/groups/:gid', {
template: '<svn-groupform></svn-groupform>'
}).
otherwise({
redirectTo: '/users'
});
delete $httpProvider.defaults.headers.common['X-Requested-With'];
}
]);
How can I setup this routeProvider so that it functions properly?
I'm trying to setup one of my first angular projects and am having trouble getting to grips with the routing.
On page load I see the initial template that has been set by the preferencesDirective, which is great.
When I click the "Change Template" button I want it to change to another template but nothing happens. If I set the template url's in the $routeProvider to something invalid then I see a 404 error in the debugger which tells me something must be working but nothing happens when the template url is valid.. How do I get it to change correctly?
Thanks.
<div id="PreferencesApp" class="" ng-app="clientPreferencesModule">
<preferences-directive factory-settings="clientPreferences"></preferences-directive>
Change Template
</div>
<script>
var app = angular.module("clientPreferencesModule", ["ngResource", "ngRoute"]);
//var app = angular.module("clientPreferencesModule", ["ngRoute"]);
app.config(function ($routeProvider) {
$routeProvider.when("/", { controller: "clientPreferencesController", templateUrl: '/AngularTemplates/ClientPreferences/PreferencesTemplate.html' });
$routeProvider.when("/Preferences/:id", { controller: "clientPreferencesController", templateUrl: '/AngularTemplates/ClientPreferences/PreferencesTemplate.html' });
$routeProvider.when("/Preferences", { controller: "clientPreferencesController", templateUrl: '/AngularTemplates/ClientPreferences/PreferencesTemplate.html' });
$routeProvider.when("/Details", { controller: "clientPreferencesController", templateUrl: '/AngularTemplates/ClientPreferences/DetailsTemplate.html' });
});
app.controller('clientPreferencesController', clientPreferencesController);
clientPreferencesController.$inject = ["$scope", "$resource", "$rootScope", "$http", "$route", "$location"];
function clientPreferencesController($scope, $resource, $rootScope, $http, $route, $location) {
this.model = #Html.Raw(JsonConvert.SerializeObject(Model));
$scope.location = $location.path();
}
app.directive('preferencesDirective', preferencesDirective);
function preferencesDirective() {
return {
restrict: 'EA',
scope:
{
factorySettings: '='
},
controller: 'clientPreferencesController',
controllerAs: 'pc',
bindToController: true,
templateUrl: '/AngularTemplates/ClientPreferences/PreferencesTemplate.html'
}
}
</script>
For routing to work you've to create different views along with its associated controller & then have directive inside that view. And also you'll need ng-view directive in index.html in which all the routes view going to be loaded. And also preferencesDirective should only contain the reusable unique functionality, & the complete app view, so that you can have it different views with different data sets alongside different view components.
So, your template can be:
<div id="PreferencesApp" class="" ng-app="clientPreferencesModule">
Change Template
<div ng-view></div>
</div>
Now for different routes you can have each different controllers or if you want to handle it in one controller the have only one, but different from directive's controller, so it can be,
app.config(function ($routeProvider) {
$routeProvider.when("/", { controller: "viewController", templateUrl: '/AngularTemplates/ClientPreferences/PreferencesTemplate.html' });
$routeProvider.when("/Preferences/:id", { controller: "viewController", templateUrl: '/AngularTemplates/ClientPreferences/PreferencesTemplate.html' });
$routeProvider.when("/Preferences", { controller: "viewController", templateUrl: '/AngularTemplates/ClientPreferences/PreferencesTemplate.html' });
$routeProvider.when("/Details", { controller: "viewController", templateUrl: '/AngularTemplates/ClientPreferences/DetailsTemplate.html' });
});
Have preferencesDirective in all these templates. (This will now potentially change the directive's template but you can have changing dom of each view in views's templates & keep directive's template constant)
Now in viewController by making use of $routeParams you can check the current route & send different data to preferencesDirective's controller.
Now if you must want to change directives template conditionally then make use of ng-include inside directive's template.
function preferencesDirective() {
return {
restrict: 'EA',
scope:
{
factorySettings: '=',
templateSrc: '='
},
controller: 'clientPreferencesController',
controllerAs: 'pc',
bindToController: true,
templateUrl: '<ng-include src="pc.template()"></ng-include>'
}
}
function clientPreferencesController($scope, $resource, $rootScope, $http, $route, $location) {
this.model = #Html.Raw(JsonConvert.SerializeObject(Model));
$scope.location = $location.path();
$scope.template = function(){
if($scope.templateSrc) {
return '/AngularTemplates/ClientPreferences/'+ $scope.templateSrc + '.html';
}
}
}
Here share that templateSrc from viewController based on current route.
I have a simple angularjs controller which uses jquery that logs something to the console when mouse goes over an anchor element:
app.controller('MenuController', function() {
$("a").on('mouseover', function (e) {
console.log("mouser over a link");
});
});
I am using ui-router for organizing my app states:
app.config(["$urlRouterProvider", "$stateProvider", function($urlRouterProvider, $stateProvider) {
// For any unmatched url, redirect
$urlRouterProvider
.otherwise("/");
$stateProvider
.state('menu', {
controller: "MenuController",
controllerAs: "menuCtrl",
templateUrl: "partials/menu.html"
})
.state('menu.menu', {
url: '/',
templateUrl: "partials/menu.menu.html"
})
.state('menu.difficulty', {
url: '/difficulty',
templateUrl: "partials/menu.difficulty.html",
controller: "DifficultyController",
controllerAs: "difCtrl"
})
.state('menu.settings', {
url: "/settings",
templateUrl: "partials/menu.settings.html"
})
}]);
My basic html for the menu is in the menu.html file:
<!-- view - menu -->
<div ui-view>
<!-- nested views -->
</div>
Inside here a bunch of nested views get inserted through states. These views have a lot of anchor elements yet nothing happens when mouse goes over them. Why is that so? Shouldn't parent state controller expand on to child states? Thanks for the help!
The data which is bound to $scope in parent controller is accessible in the child states because the parent controller always runs if we access the child state.
In Menu Controller,If write write
$scope.name = 'XYZ'
This $scope.name is accessible in every child controller using $scope.name.
EDIT:
In your MenuController bind this anchor on document like this and It will work
app.controller('MenuController', function() {
$(document).on('mouseover','a', function (e) {
console.log("mouser over a link");
});
});
I have a fairly simple todo app using angular.js for which I am using the ui-router library. I looked through the ui-router example on github (https://github.com/angular-ui/ui-router/tree/master/sample) but was unable to figure out what I am doing wrong. In my app I have a sidebar navigation view (with the list of things todo) and a content view (which displays the todo item's details when clicked). The problem I have is that when I navigate to /todo/exampleItem the content view updates and the navigation panel is reloaded as well. This doesn't effect the functionality of the app but I would like to avoid the navigation panel flickering each time you click on an item.
Here is my code to handle the state changes:
app.config(function ($stateProvider) {
$stateProvider
.state('todo', {
url: "/todo",
views: {
"navPanel": {
templateUrl: "./navPanel.html",
controller: 'PanelController'
}
}
})
.state('todo/:item', {
url: "/todo/:item",
views: {
"PanelView": {
templateUrl: "./navPanel.html",
controller: 'PanelController'
},
"ContentView": {
templateUrl: "./content.html",
controller: 'ContentController'
}
}
})
});
In my index.html my views are set up as follows:
<div class="column" data-ui-view="PanelView"></div>
<div class="column" data-ui-view="ContentView"></div>
Is there some way I can stop the navPanel view from being reloaded each time a new item is clicked?
Based on the voted answer of that question angularjs ui-router - how to build master state which is global across app
app.config(['$stateProvider', function ($stateProvider) {
$stateProvider
.state('todo', {
abstract: true,
views: {
"navPanel": {
templateUrl: "./navPanel.html",
controller: 'PanelController'
}
}
})
.state('todo/:item', {
url: "/todo/:item",
views: {
"ContentView#": {
templateUrl: "./content.html",
controller: 'ContentController'
}
}
})
}]);
I have problem I can't figure out but I do have a hint. Before integrating TinyMCE the main navigation was working fine eg links Settings, Analytics, Setup; it isn't working now if you click them.
Here is my js file:
var app_htmleditor_module = angular.module('app_htmleditor', ['components']).
config(['$routeProvider', function($routeProvider) {
$routeProvider.
when('/', {templateUrl: getBaseURL()+'public/tpl/app/htmleditor.htm', controller: HtmlEditorCtrl, reloadOnSearch:false }).
otherwise( {redirectTo: '/'});
}
]);
angular.module('components', []).directive('imageUpload', function () {
return {
restrict: 'E',
scope: {
uploaderid:'#uploaderid'
},
templateUrl: '/public/tpl/imageupload.htm'
}
});
app_htmleditor_module.directive('uiTinymce', function() {
return {
require: 'ngModel',
link: function(scope, element, attrs, ngModel) {
element.tinymce({
// Location of TinyMCE script
script_url: 'http://resources.holycrap.ws/jscripts/tiny_mce/tiny_mce.js',
// General options
theme: "simple",
// Change from local directive scope -> "parent" scope
// Update Textarea and Trigger change event
// you can also use handle_event_callback which fires more often
onchange_callback: function(e) {
if (this.isDirty()) {
this.save();
// tinymce inserts the value back to the textarea element, so we get the val from element (work's only for textareas)
//ngModel.$setViewValue(e.getBody().innerHTML);
ngModel.$setViewValue(element.val());
scope.$apply();
return true;
}
}
});
}
}
});
And I added above tinymce directive into textarea using ui:tinymce like this:
<textarea ui:tinymce ng-model="data.html_tab" id="{{fileUploaderID}}_html_tab" name="{{fileUploaderID}}_html_tab" style="width:600px; height:300px"></textarea>
Notice ui:tinymce above. If I remove that, the navigation works fine again. So how do I make my navigation work with ui:tinymce added in textarea?
DEMO URL:
http://dev-socialapps.rkm-group.com/app/htmleditor/index#/
Any help will be greatly appreciated. Thanks
Update:
As suggested, I added ui js file to my template file first:
<script src="https://raw.github.com/angular-ui/angular-ui/master/build/angular-ui.js"></script>
Then In my js file, I added:
var app_htmleditor_module = angular.module('app_htmleditor', ['components', 'ui']).
config(['$routeProvider', function($routeProvider) {
$routeProvider.
when('/', {
templateUrl: getBaseURL()+'public/tpl/app/htmleditor.htm',
controller: HtmlEditorCtrl,
reloadOnSearch:false
}).
otherwise( {redirectTo: '/'});
}
]);
app_htmleditor_module.value('ui.config', {
tinymce: {
theme: 'simple'
}
});
And in textarea tag:
<textarea ui-tinymce ng-model="tinymce" id="{{fileUploaderID}}_html_tab" name="{{fileUploaderID}}_html_tab" style="width:600px; height:300px"></textarea>
But I am getting error:
ReferenceError: tinymce is not defined
Though ui js file is added fine, I confirmed by viewing source code and clicking on link
Have you tried the latest version of the tinymce directive in the angular-ui library?
Demo
JS file