Build a menu which changes based on url path and params - angularjs

Is there a good tutorial on how to create a menu in angularjs, the menu should only appear on few pages, for example:
localhost/web (is the page which shows all my projects)
because I don't have any project selected I don't get a sidemenu
localhost/web/1 (is the main page of a project)
because I've selected project 1 I can see a sidemenu.
My links in the sidemenu will have the projectID
Project Settings(url) -> localhost/web/1/settings
web.settings({projectID: projectID})
And many others, the sidemenu will show in all that pages where a project id is selected.

Keep your menu data in JSON like
// here key in json object is your current url.
$scope.menus = {
"syllabus":[{name:"Chapters",url:"",class:"fa fa-folder-open"},{name:"Q&A",url:"url",class:"fa fa-folder-open"},{name:"syllabus 3",url:"url 1",class:"fa fa-folder-open"}],
};
$scope.sub_menus = [];
$scope.setSubMenu =function(menu){
$scope.sub_menus = $scope.menus[menu];
}
Call setSubMenu function whenever you change the route. pass your current route as an argument that will set the current page menu data in to sub_menus array. angular will render this automatically for you.
app.directive('subMenu', ['$compile', function($compile) {
return {
restrict: 'EA',
template: '<div ng-if="sub_menus.length" class="subtabs"> <ul class="nav"><li ng-repeat = "sb in sub_menus"><i class=\"{{sb.class}}\""></i> {{sb.name}}</li>' +
'</ul></div>',
compile: function() {
return {
post: function($scope) {
}
}
}
}
}]);

Related

Asigning the href (i.e., route name and route param name) in template based on the value from scope

I'm new to AngularJs and still learning the things, I'm creating a menu with items that are clickable. When someone clicks on the item it will redirect to a view using the route name provided in the href, the catch here is that my menu will be generates out of the scope from the controller using the ng-repeat. I want to change my href value based on the item value, so that the corresponding view will be loaded based on route, here is my mark up and the controller that populates the scope. Can someone help me what is the best way to do this.
<a data-ng-repeat="c in vm.List | orderBy: 'order'" href="#Categories/{{c.category}}/{{c.name}}" data-ng-show="{{c.count}} >0">
function getHomeConfigsCtrl($http, iService, $routeParams) {
var vm = this;
vm.List = [];
var promise =
iService.getConfig(ID);
promise.then(
function (result) {
angular.forEach(result.data.menu, function (value, key) {
vm.List.push(value);
});
},
function (errorPayload) {
$log.error('failure loading home page config', errorPayload);
});
};

Bootstrap modal to play videos and image slider with angular js

I want to show list of videos in Bootstrap modal. and when user clicks on any video from the list that video should play in modal only. similarly I want to show albums in modal and on click of specific album I want to show slideshow in the same modal, for this I am using angular js and Codeigniter with bootstrap. Please help me.
Not a very descriptive question, but I recommend you check out Angular UI's Bootstrap directives.
I use their modal directive a lot and being able to specify a template and controller for a modal is priceless when it comes to working with things like you're describing.
Update to address your comment:
I have no idea where $scope.hall_videos is coming from, but you need to use the resolve property to return the correct videos. For instance, if $scope.hall_videos was an object where the key was the id and the value was an array of videos like so:
$scope.hall_videos = {
'1': ['video1', 'video2'],
...
'7': ['video14', 'video15']
};
You could populate with the correct videos like this:
$scope.open = function (size, id) {
var modalInstance = $modal.open({
templateUrl: 'video_gallery.html',
controller: 'HomeCtrl',
size: size,
resolve: {
hall_videos: function () {
var videos = [];
angular.forEach($scope.hall_videos, function(video) {
if (video.hall_info_id === id) {
videos.push(video);
}
});
return videos;
}
}
});
};

Angular navigate to a specific tab on a page

I would like to navigate to a page of my single page application using a link like /#/invoices/1?tab=2. This page contains tabs, so I would also like to send the user directly to the tab I wish through the url.
Could you provide some pointers on how to implement this in the cleanest way?
Use $anchorScroll method, passing a class name on it you can go directly to that element.
Just an update to above answer.
Few examples with custom directives
http://nadeemkhedr.com/angularjs-scroll-to-element-using-directives/
angular.module('MyApp').directive('scrollToBookmark', function() {
return {
link: function(scope, element, attrs) {
var value = attrs.scrollToBookmark;
element.click(function() {
scope.$apply(function() {
var selector = "[scroll-bookmark='"+ value +"']";
var element = $(selector);
if(element.length) {
window.scrollTo(0, element[0].offsetTop – 100);
// Don’t want the top to be the exact element, -100 will go to the top for a little bit more
}
});
});
}
};
});

Creating a new html page from controller

I have an input form page, that when the user submits, it updates that page with some tables of data. If the user likes what they see, they should be able to print a cleaned up (no header nav, footer nav, etc) version of those tables with formatting intact.
I'm creating the tables using bootstrap and angularjs. What I'm trying to do is that when the uset clicks 'print', my angular controller grabs the desired content from the generated page (in a div called 'template') and inserts it into a new html page that I can then open in a new window for printing.
I created a directive that I was hoping would allow me to use $compile to transclude my data:
app.directive('printTemplate', function () {
return {
templateUrl: 'app/partials/printtemplate.html',
replace: true,
transclude: true,
restrict: 'A'
};
});
And in my controller:
$scope.printTemplate = function () {
var page = angular.element(template).contents();
var newpage = $compile("<html><body><div print-template>" + page + "</div></body></html>")($scope);
var win = window.open();
win.document.write(newpage);
//win.print();
};
But this doesn't seem to do what I expect. And it feels like I'm doing it wrong. The idea was that because my data tables require bootstrap script and css references I need to include those in my printtemplate.html file.
Is there an easier/better way to do this, or what am I missing?
Instead of trying to create a whole new page, why not simply use specific css for print media.
As always the w3 is the best place to start http://www.w3.org/TR/CSS2/media.html

AngularJS modal window directive

I'm trying to make a directive angularJS directive for Twitter Bootstrap Modal.
var demoApp = angular.module('demoApp', []);
demoApp.controller('DialogDemoCtrl', function AutocompleteDemoCtrl($scope) {
$scope.Langs = [
{Id:"1", Name:"ActionScript"},
{Id:"2", Name:"AppleScript"},
{Id:"3", Name:"Asp"},
{Id:"4", Name:"BASIC"},
{Id:"5", Name:"C"},
{Id:"6", Name:"C++"}
];
$scope.confirm = function (id) {
console.log(id);
var item = $scope.Langs.filter(function (item) { return item.Id == id })[0];
var index = $scope.Langs.indexOf(item);
$scope.Langs.splice(index, 1);
};
});
demoApp.directive('modal', function ($compile, $timeout) {
var modalTemplate = angular.element("<div id='{{modalId}}' class='modal' style='display:none' tabindex='-1' role='dialog' aria-labelledby='myModalLabel' aria-hidden='true'><div class='modal-header'><h3 id='myModalLabel'>{{modalHeaderText}}</h3></div><div class='modal-body'><p>{{modalBodyText}}</p></div><div class='modal-footer'><a class='{{cancelButtonClass}}' data-dismiss='modal' aria-hidden='true'>{{cancelButtonText}}</a><a ng-click='handler()' class='{{confirmButtonClas}}'>{{confirmButtonText}}</a></div></div>");
var linkTemplate = "<a href='#{{modalId}}' id= role='button' data-toggle='modal' class='btn small_link_button'>{{linkTitle}}</a>"
var linker = function (scope, element, attrs) {
scope.confirmButtonText = attrs.confirmButtonText;
scope.cancelButtonText = attrs.cancelButtonText;
scope.modalHeaderText = attrs.modalHeaderText;
scope.modalBodyText = attrs.modalBodyText;
scope.confirmButtonClass = attrs.confirmButtonClass;
scope.cancelButtonClass = attrs.cancelButtonClass;
scope.modalId = attrs.modalId;
scope.linkTitle = attrs.linkTitle;
$compile(element.contents())(scope);
var newTemplate = $compile(modalTemplate)(scope);
$(newTemplate).appendTo('body');
$("#" + scope.modalId).modal({
backdrop: false,
show: false
});
}
var controller = function ($scope) {
$scope.handler = function () {
$timeout(function () {
$("#"+ $scope.modalId).modal('hide');
$scope.confirm();
});
}
}
return {
restrict: "E",
rep1ace: true,
link: linker,
controller: controller,
template: linkTemplate
scope: {
confirm: '&'
}
};
});​
Here is JsFiddle example http://jsfiddle.net/okolobaxa/unyh4/15/
But handler() function runs as many times as directives on page. Why? What is the right way?
I've found that just using twitter bootstrap modals the way the twitter bootstrap docs say to is enough to get them working.
I am using a modal to house a user edit form on my admin page. The button I use to launch it has an ng-click attribute that passes the user ID to a function of that scope, which in turn passes that off to a service. The contents of the modal is tied to its own controller that listens for changes from the service and updates values to display on the form.
So.. the ng-click attribute is actually only passing data off, the modal is still triggered with the data-toggle and href tags. As for the content of the modal itself, that's a partial. So, I have multiple buttons on the page that all trigger the single instance of the modal that's in the markup, and depending on the button clicked, the values on the form in that modal are different.
I'll take a look at my code and see if I can pull any of it out to build a plnkr demo.
EDIT:
I've thrown together a quick plunker demo illustrating essentially what I'm using in my app: http://embed.plnkr.co/iqVl0Wb57rmKymza7AlI/preview
Bonus, it's got some tests to ensure two password fields match (or highlights them as errored), and disables the submit button if the passwords don't match, or for new users username and password fields are empty. Of course, save doesn't do anything, since it's just a demo.
Enjoy.
There is a working native implementation in AngularStrap for Bootstrap3 that leverages ngAnimate from AngularJS v1.2+
Demo : http://mgcrea.github.io/angular-strap/##modals
You may also want to checkout:
Source : https://github.com/mgcrea/angular-strap/blob/master/src/modal/modal.js
Plunkr : http://plnkr.co/edit/vFslNmBAoKPVXtdmBXgv?p=preview
Well, unless you want to reinvent this, otherwise I think there is already a solution.
Check out this from AngularUI. It runs without twitter bootstrap.
I know it might be late but i started trying to figure out why the handler got called several times as an exercise and I couldn't stop until done :P
The reason was simply that each div you created for each modal had no unique id, once I fixed that everything started working. Don't ask me as to what the exact reason for this is though, probably has something to do with the $('#' + scope.modalId).modal() call.
Just though I should post my finding if someone else is trying to figure this out :)

Resources