I am creating an angular js Application. which has a side bar navigation sustem. when I click on the sidebar item, then it has to show contents under that item in the content section,I am using bootstrap
See the code I've written
HTML
<div class="sidebar">
<ul>
<li ng-repeat="item in supplyItem">
<a class="span" href="#{{item.header}}">{{item.header}}</a>
</li>
</ul>
</div>
<div class="content-part">
<div class="tab-content">
<div class="tab-pane" ng-repeat="item in supplyItem" id="{{item.header}}">
{{item.desc}}
</div>
</div>
JS
myApp.config(['$routeProvider',function($routeProvider){
$routeProvider.
when('/home',{
templateUrl : 'partials/home_page.aspx',
controller:'HomePageController',
}).
when('/supplies',{
templateUrl : 'partials/supplies.aspx',
controller:'MyController',
}).
otherwise({
redirectTo: '/home'
});
}]);
appController.controller('MyController', ['$scope', function ($scope) {
$scope.supplyItem = [
{
"header": "header1",
"desc": "Descipriotn 1"
},
{
"header": "header2",
"desc": "Descipriotn 2"
}
];
$('.sidebar a').click(function (e) {
e.preventDefault();
$(this).tab('show');
});
$(function () {
$('.sidebar a:last').tab('show');
});
} ]);
but when I click on sidebar nav item it goes to the home page as i mentioned in the routeProvider.otherwise()
what is the error and how do I solve this ? any one help me please
I think you should have the ids of your tap-pane divs different:
id="item.header" should be id="{{item.header}}"
Also I noticed that in you JS you have:
$scope.supplyItem = [
{
"header": "header1",
"desc": "Descipriotn 1"
},
{
"header": "header1",
"desc": "Descipriotn 2"
}
];
And I think that the "header" values should be different in order for the bootstrap plugin to discriminate between the different divs.
Related
I'm new to AngularJS and am trying to build a simple site with three tabs. I like the Bootstrap Tabs interface so I'm building off of that:
example.js
angular.module('base', ['ngAnimate', 'ngSanitize', 'ui.bootstrap']);
angular.module('base').controller('UiCtrl', function ($scope, $window) {
content1 = "Bunch of Figs";
array2 = ["Newton 1", "Newton 2"];
content2 = array2.join('<br><br>');
content3 = "Bunch of Widgets";
$scope.tabs = [
{ title:'Figs', content:content1 },
{ title:'Newtons', content:content2 }, //, disabled: true },
{ title:'Widgets', content:content3, select:'alertMe()' }
];
$scope.alertMe = function() {
setTimeout(function() {
$window.alert('You\'ve selected the widget tab!');
});
};
$scope.model = {
name: 'Tabs'
};
});
index.html
<!doctype html>
<html ng-app="base">
<head>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular-animate.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular-sanitize.js"></script>
<script src="http://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-2.5.0.js"></script>
<script src="example.js"></script>
<link href="http://netdna.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<style type="text/css">
form.tab-form-demo .tab-pane {
margin: 20px 20px;
}
</style>
<div ng-controller="UiCtrl">
<p>
<uib-tabset active="activeJustified" justified="true">
<uib-tab index="$index + 1" ng-repeat="tab in tabs" heading="{{tab.title}}" disable="tab.disabled", select="tab.select">
{{tab.content}}
</uib-tab>
</uib-tabset>
</div>
</body>
</html>
I have two problems:
1) The HTML tags in the join are not treated as HTML in the tabs.
2) The select callback is not set to the dynamic tab.
How can I display HTML inside the tabs?
How can I attach select callbacks to dynamic tabs?
1- You have to use ng-bind-html in your html, and $sce.trustAsHtml() in your controller
HTML:
<uib-tabset active="activeJustified" justified="true">
<uib-tab index="$index + 1" ng-repeat="tab in tabs" heading="{{tab.title}}" disable="tab.disabled", select="tab.select()">
<div ng-bind-html="tab.content"></div>
</uib-tab>
</uib-tabset>
CONTROLLER:
angular.module('base').controller('UiCtrl', function ($scope, $window, $sce) {
content1 = $sce.trustAsHtml("<h1>Html content<br/> example</h1>");
$scope.tabs = [
{ title:'Figs', content:content1 },
{ title:'Widgets', content:content3, select: $scope.alertMe }
];
....
});
2- You aren't calling the function.
HTML:
Change select="tab.select" to select="tab.select()".
CONTROLLER:
Change select: 'alertMe()' to select: $scope.alertMe
Check this post about ng-bind-html
Check ui.boostrap docs about tabs
1. How can I display HTML inside the tabs?
=> You can use ng-bind-html and $sce.trustAsHtml()
HTML
<uib-tab index="$index + 1" ng-repeat="tab in tabs" heading="{{tab.title}}" disable="tab.disabled", select="tab.select()">
<span ng-bind-html="tab.content"></span>
</uib-tab>
JS
$scope.tabs = [
{ title:'Figs', content: $sce.trustAsHtml(content1) },
{ title:'Newtons', content: $sce.trustAsHtml(content2) }, //, disabled: true },
{ title:'Widgets', content: $sce.trustAsHtml(content3), select: $scope.alertMe }
];
2. How can I attach select callbacks to dynamic tabs?
=> Change select="tab.select" to select="tab.select()" and { title:'Widgets', content:content3, select:'alertMe()' } to { title:'Widgets', content: $sce.trustAsHtml(content3), select: $scope.alertMe }
$scope.alertMe must be defined before $scope.tabs
==> You can refer to this demo: https://codeide.co/master/qVGVQyWG
I choose to skip the tab component. Mostly because it did not have back button support. Further it became tricky to navigate to ex: the 3:rd tab from another page. So I used simple routing instead. ex: if there are 3 tabs I have 3 pages with specific routing. To avoid duplicating tab menu I created a component that i put in all three pages.
<ul ng-controller="tabsCtrl as tabs" class="nav nav-tabs">
<li ng-class="{'active':tabs.generalTab.isActive}">
<a ng-href="{{tabs.generalTab.path}}" translate>general.GENERAL</a>
</li>
<li ng-class="{'active':tabs.settingsTab.isActive}">
<a ng-href="{{tabs.settingsTab.path}}" translate>settings.MENU_LABEL</a>
</li>
<li ng-class="{'active':tabs.extrasTab.isActive}">
<a ng-href="{{tabs.extrasTab.path}}" translate>extras.MENU_LABEL</a>
</li>
</ul>
I have top level menu, and then I have left menus, which will be refreshed based on the selected top level menu. I am able to create that link, but as soon as I select the left menu, it goes blank as can be seen when selecting HOME.
At this time only HOME is wired up Route1 & Route2 is not wired up.
Also here is the Plunker for it
http://plnkr.co/edit/Jwow4VtNsSfMMcpv6qaa?p=preview
How do I prevent resetting/reloading of left menu on selection? I also want to keep highlighted the clicked left menu.
<!DOCTYPE html>
<html ng-app="myapp">
<head>
<title>AngularJS: UI-Router Quick Start</title>
<!-- Bootstrap CSS -->
<link href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.3.1/css/bootstrap.min.css" rel="stylesheet">
</head>
<body class="container">
<div class="navbar">
<div class="navbar-inner">
<a class="brand" ui-sref="index">Quick Start</a>
<ul class="nav">
<li><a ui-sref="index">Home</a></li>
<li><a ui-sref="route1">Route 1</a></li>
<li><a ui-sref="route2">Route 2</a></li>
</ul>
</div>
</div>
<div class="row">
<div class="span6">
<div class="well" ui-view="LeftMenu"></div>
</div>
<div class="span6">
<div class="well" ui-view="Content"></div>
</div>
</div>
<!-- Angular -->
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.4/angular.min.js"></script>
<!-- UI-Router -->
<script src="//angular-ui.github.io/ui-router/release/angular-ui-router.js"></script>
<!-- App Script -->
<script>
var myapp = angular.module('myapp', ["ui.router"])
myapp.config(function($stateProvider){
$stateProvider
.state('index', {
url: "",
views: {
"LeftMenu": {
template: '<ul><li><a ui-sref="LeftMenuMenu1">Index-Left Menu1</a></li><li><a ui-sref="LeftMenuMenu2">Index-Left Menu2</a></li><li><a ui-sref="LeftMenuMenu3">Index-Left Menu3</a></li></ul>'
},
"Content": {
template: "LeftMenu index selected"
}
}
})
.state('LeftMenuMenu1', {
views:{
"Content": {
template: "LeftMenu.Menu1 selected"
}
}
})
.state('LeftMenuMenu2', {
views: {
"Content": {
template: "LeftMenu.Menu2 selected"
}
}
})
.state('LeftMenuMenu3', {
url: "",
views: {
"Content": {
template: "LeftMenu.Menu3 selected"
}
}
})
.state('route1', {
url: "/route1",
views: {
"LeftMenu": {
template: '<ul><li><a ui-sref="Route1.Menu1">Route1-Left Menu1</a></li><li><a ui-sref="Route1.Menu2">Route1-Left Menu2</a></li><li><a ui-sref="Route1.Menu3">Route1-Left Menu3</a></li></ul>'
},
"viewB": {
template: "route1.viewB"
}
}
})
.state('route2', {
url: "/route2",
views: {
"LeftMenu": {
template:'<ul><li>Route2-Left Menu1</li><li>Route2-Left Menu2</li><li>Route2-Left Menu3</li></ul>'
},
"viewB": {
template: "route2.viewB"
}
}
})
});
</script>
</body>
</html>
I think what you would want to do is to work with substates, rather than only root states. In each root state you are then able to set the left menu options.
Consider the below example where index is the root state where we set the left menu and set where we want the sub states to be rendered in the view. Each substate(index.LeftMenuMenu1, index.LeftMenuMenu2, index.LeftMenuMenu3), will then be rendered where ever we placed the <div ui-view=content></div> element.
$stateProvider
//Root state
.state('index', {
url: "",
views: {
//Set left side bar
"LeftMenu": {
template: '<ul><li><a ui-sref="index.LeftMenuMenu1">Index-Left Menu1</a></li><li><a ui-sref="index.LeftMenuMenu2">Index-Left Menu2</a></li><li><a ui-sref="index.LeftMenuMenu3">Index-Left Menu3</a></li></ul>'
},
//Each substate will live here
"Content": {
template: "<div ui-view></div>"
}
}
})
//substates
.state('index.LeftMenuMenu1', {
template: "LeftMenu.Menu1 selected"
})
.state('index.LeftMenuMenu2', {
template: "LeftMenu.Menu2 selected"
})
.state('index.LeftMenuMenu3', {
template: "LeftMenu.Menu3 selected"
})
Then you reuse this pattern for the other sections on your page.
$stateProvider
...
//Root state route 1
.state('route1', {
url: "/route1",
views: {
"LeftMenu": {
template: 'Route 1 menu options..'
},
"Content": {
template: "<div ui-view></div>"
}
}
})
.state('route1.LeftMenuMenu1', {
template: "LeftMenu.Menu1 selected"
})
.state('route1.LeftMenuMenu2', {
template: "LeftMenu.Menu2 selected"
})
//Root state route 2
.state('route2', {
url: "/route2",
views: {
"LeftMenu": {
template: 'Route 2 menu options..'
},
"Content": {
template: "<div ui-view></div>"
}
}
})
.state('route2.LeftMenuMenu1', {
template: "LeftMenu.Menu1 selected"
})
.state('route2.LeftMenuMenu2', {
template: "LeftMenu.Menu2 selected"
})
Updated plunker
However, is your case with the left menu is that you will only change the links and the view will be the same, I would recommend to user another pattern. Probably having a menu service that servers the menu options. And the for each root state you can use the onEnter property to trigger the menu options to update.
I want to provide the navigation menu dynamically by an angularjs controller:
index.html:
<body>
<div ng-controller="navi">
<ul>
<li ng-repeat="nav in navigations">
{{nav.name}}
</li>
<ul>
</div>
<script src="js/navi.js"></script>
</body>
navi.js:
angular.module('app').controller('navi') {
$scope.navigations = [
{"path": "www.google.de", "name": "Google"},
{"path": "www.bing.de", "name": "Bing"},
];
}
Result: blank page. Why?
Sorry, of course one has to use the function($scope) for this to work:
angular.module('app').controller('navi', function($scope) {
...
});
I'm using : https://github.com/angular-ui-tree/angular-ui-tree
I want to accept:
Categories to root scope of ui-tree
apps to the apps of same categories.
My controller is (partial):
//Accept Categories at root scope and accept apps only inside same category
$scope.options = {
accept: function(sourceNodeScope, destNodesScope, destIndex) {
//todo check nodes and return
alert('called');
$log.debug("sourceNodeScope");
$log.debug(sourceNodeScope);
$log.debug("destNodesScope");
$log.debug(destNodesScope);
return false;
},
dropped: function(event) {
},
beforeDrop: function(event) {
}
};
My HTML is:
<div ng-controller="CpoTreeViewCtrl">
<div>
<script type="text/ng-template" id="apps_renderer.html">
<div ui-tree-handle>
{{app.name}}
</div>
</script>
<script type="text/ng-template" id="category_renderer.html">
<div ui-tree-handle >
{{category.name}}
</div>
<ol ui-tree-nodes ng-model="category.apps">
<li ng-repeat="app in category.apps" ui-tree-node ng-include="'apps_renderer.html'">
</li>
</ol>
</script>
<div ui-tree="options">
<ol ui-tree-nodes ng-model="treeData" id="tree-root">
<li ng-repeat="category in treeData" ui-tree-node ng-include="'category_renderer.html'"></li>
</ol>
</div>
</div>
</div>
I want to accept:
Categories to root scope of ui-tree
apps to the apps of same categories.
The accept callback is not getting fired. What's not right here?
Thanks!
If anyone is wondering how to restrict by groups, here's how I got it working. The docs leave a bit to be desired on how to do this.
here is the html markup
<div ng-repeat="list in lists" >
<div ui-tree="treeOptions" class="col-xs-6" >
<ol ui-tree-nodes ng-model="list.categories" data-type="{{list.type}}">
<li ng-repeat="item in list.categories" ui-tree-node data-type="{{item.type}}">
<div ui-tree-handle class="tree-node">
<div class="tree-node-content">
{{item.name}}
</div>
</div>
</li>
</ol>
</div>
<div class="clearfix" ng-if="::$index===1"></div>
</div>
for a sample item array such as
$scope.lists = [{
"name": "Selected Charts",
"type": "charts",
"categories": [{
"name": "222 docs",
"type": "charts"
}]
}, {
"name": "sdf",
"type": "tables",
"categories": [{
"name": "2222 docs",
"type": "tables"
}]
}];
then in tree options, define
$scope.treeOptions = {
accept: function(sourceNodeScope, destNodesScope, destIndex) {
var srctype = sourceNodeScope.$element.attr('data-type');
var dsttype = destNodesScope.$element.attr('data-type');
if(srctype===dsttype){
return true;
}else{
return false;
}
}
};
That will prevent non-matching types from dropping.
The API of this awesome package is updated and same was not available in doc/demo.
Details : https://github.com/angular-ui-tree/angular-ui-tree/pull/281
Quick Fix :
<div ui-tree="options">
should be replaced with
<div ui-tree callbacks="options">
Update (with thanks to #zach-l)
After v2.8.0 you need to switch back to
<div ui-tree="options">
I would do this.
accept: function(sourceNodeScope, destNodesScope) {
return sourceNodeScope.$parent.$id === destNodesScope.$id;
}
I am new in angularjs.I wanted to implements tabs like tab1,tab2,tab3
when i click tab1 then it will be opend view1.html
when i click tab2 then it will be opend view2.html
when i click tab3 then it will be opend view3.html
three tabs is inside mainIndex.cshtml page.
my three view(html) and mainIndex.cshtml are inside one folder called admin
now i wanted to perform all action using angularjs .i don't want to inline code
i have tried below code but unable to achive my senario
my mainIndex.cshtml
<div id="tabs" ng-controller="AdminCtrl">
<ul id="ul1">
<li id="li1" ng-repeat="tab in tabs"
ng-class="{active:isActiveTab(tab.url)}"
ng-click="onClickTab(tab)">{{tab.title}}</li>
</ul>
<div id="mainView">
<div ng-include="currentTab"></div>
</div>
</div>
<script type="text/ng-template" src="view1.html">
</script>
<script type="text/ng-template" id="view2.html">
</script>
<script type="text/ng-template" id="view3.html">
</script>
my controller
app.controller('AdminCtrl', ['$scope', 'registerSvc', function ($scope, registerSvc) {
$scope.tabs = [{
title: 'tab1',
url: 'view1.html' // here it should be opened view1.html after clicking tab1
}, {
title: 'tab2',
url: 'view2.html'
}, {
title: 'tab3',
url: 'view3.html'
}];
$scope.currentTab = 'view1.html';
$scope.onClickTab = function (tab) {
$scope.currentTab = tab.url;
}
$scope.isActiveTab = function (tabUrl) {
return tabUrl == $scope.currentTab;
}
}]);
have you tried using ng-if directive?
like:
<div ng-if="currentTab=='tab1'">
//tab1 partial
</div>
<div ng-if="currentTab=='tab2'">
//tab2 partial
</div>
and so on... ?