href not working as expected - javascript

I'm using this snippet from HERE. It looks ok, but when I click on a tab, instead of changing the content of the body (<a href="#tab2success" data-toggle="tab">), it redirects to localhost:9000/#tab2success, which does not exist. How is it possible to achieve this? I just want that when clicking on the tab, it goes to the specific content in the body. Looks like that href is not the solution here...
<div class="col-md-9">
<div class="panel with-nav-tabs panel-success">
<div class="panel-heading">
<ul class="nav nav-tabs">
<li class="active">Success 1</li>
<li>Success 2</li>
<li>Success 3</li>
</ul>
</div>
<div class="panel-body">
<div class="tab-content">
<div class="tab-pane fade in active" id="tab1success">Success 1</div>
<div class="tab-pane fade" id="tab2success">Success 2</div>
<div class="tab-pane fade" id="tab3success">Success 3</div>
</div>
</div>
PD: I'm using angularJS, so if there is any directive or something that could help, it may be also a valid option.
EDIT: Part of my router implementation. It's just o part of the code, because it's too longo to post it all..
angular
.module('Test', [ //setting a module
'oc.lazyLoad',
'ui.router',
'ui.bootstrap',
'angular-loading-bar'
])
.config(['$stateProvider', '$urlRouterProvider', '$ocLazyLoadProvider', function ($stateProvider, $urlRouterProvider, $ocLazyLoadProvider) {
$ocLazyLoadProvider.config({
//$ocLazyLoad returns a promise that will be rejected when there is an error but if you set debug to true, //$ocLazyLoad will also log all errors to the console.
debug: false,
events: true,
});
// For any unmatched url, redirect to '/dashboard/home'
$urlRouterProvider.otherwise('/dashboard/rank');
// Now we set up the states
$stateProvider
.state('dashboard', { //parent view
url: '/dashboard',
templateUrl: 'views/dashboard/main.html',

This is the normal behavior for href's.
To solve your issue please refer to this article :
Nav tabs in Angular
Basically, there is a flag that controls the visibility of tabs and a ng-click event that will update the value for the flag.
Once the value of the model (flag) was updated, it will automatically update the view.

This is exactly the expected behaviour of href - if you don't supply a full URL, it'll append it onto your current URL (I'm assuming you are using localhost:9000 while developing). Have a look at this link which explains how to use it right, utilising ng-href directive.
To sum it up, you need to use the "handlebars" format inside the ng-href directive:
<a ng-href="{{/#tab2success}}" data-toggle="tab">

There is no need for any Angular code or overcomplications. You are just missing the bootstrap.js file that operates the tabs.
Make sure you are using the correct classes of the tab markup, import the JS file at the end of the body of your document, and that's it.
You can read more about the Bootstrap tabs, the markup, and the way they work in the official Bootstrap documentation.

Related

Problem with ng-if in ng-include html template from root controller

I come from Angular9 and am really used to it, and I have been asked to work a bit on an AngularJS project, which I have never experienced. So I am really struggling with the whole app structure.
My issue is simple: I have a sub-navbar.html template directly injected in my root.html template using ng-include, and I would like to condition the display of one section of this sub-navbar with 'ng-if' (not just hide the section, I don't want it there at all).
I have a backend call which sends me a boolean according to whether the connected user can see the section or not.
The problem I have is that my section is actually never active even when the boolean is 'true'.
Things I tried:
Change the priority of the ng-if and 'ng-controller' directives ---> Broke the app
Add a new 'subnavbar-controller' and declare it as a .state in the app.js ---> Didn't work
Create a custom directive ---> Can't figure out hw the work apparently, didn't work
I unfortunately can't copy all my code, but here are the main pieces I'm working on:
app.js: (I wrote nothing concerning this '$rootScope.adminSection' in the '.run()' function and also tried the same approach directly calling the service without the '$onInit')
$urlRouterProvider.otherwise("/orders");
$stateProvider
.state('root', {
abstract: true,
url: '',
views: {
'': {
templateUrl: "view/root.html",
controller: ['$rootScope', 'AdministratorService', function ($rootScope, AdministratorService) {
const vm = this;
vm.$onInit = function() {
AdministratorService.getAdminSection().then(function (result) {
$rootScope.adminSection = result;
}
)
};
}]
}
}])
root.html:
<div ui-view="root_header"></div>
<div class="row" style="min-height: 600px">
<div class="col-md-2">
<br/>
<div ng-include="'view/subnavbar.html'"></div>
</div>
<div class="col-md-10">
<div ui-view></div>
</div>
</div>
<div ng-include="'view/footer.html'"></div>
subnavbar.html:
<ul class="nav nav-pills nav-stacked" role="tablist">
<li></li>
<li ui-sref-active="active"><a ui-sref="root.contracts"></a><div class='arrow' aria-hidden='true'></div>
</li>
<li ng-if="$rootScope.adminSection" ui-sref-active="active"><a ui-sref="root.administrator">
</a><div class='arrow' aria-hidden='true'></div></li>
<li ui-sref-active="active"><a ui-sref="root.users"></a><div class='arrow' aria-hidden='true'>
</div></li>
</ul>
Any help welcome, thanks in advance !
There are several ways this can work. The reason it is not working now is that $rootScope in the template is not defined. Try, in your template, to replace $rootScope.adminSection with just adminSection.
ngInclude directive creates a new scope which inherits from $rootScope. Therefore, variables in $rootScope should be directly accessible from the template.

Angular directive crashing browser

I have the following directive in my project:
app.directive('eventSessionsList', function() {
return {
restrict: 'AEC',
scope: {
input: '=data'
},
templateUrl: 'directives/event-sessions-list.html'
};
});
The template looks like this:
<ul class="event-sessions-list">
<li ng-repeat="session in input.eventSessions">
<span class="date">{{ session.date }}</span>
<p class="info">
{{ session.length }} hr session # {{ session.venue }}</p>
</li>
</ul>
When I try to load the page it crashes with no errors (tested in both Safari and Chrome).
The mistake was a simple one, but to help you avoid it here's what I did wrong: The name of my CSS class on the UL element is the same as the name of my directive (angular equates hyphenated words and camel case). This means that angular interpreted the CSS class as a call to instance the directive. This created an infinite nesting loop.
To fix this problem I changed the name of the class from "event-sessions-list" to "sessions-list".
I hope this saves you tearing your hair out!
I had a very similar problem but instead of a clash with CSS classes (OP's case), I had it with HTML tags.
Just posting in case someone runs into this slightly different variation of the same root problem.
HTML
<div id="header">
<div id="header_main">
<nav></nav>
</div>
</div>
Nav Template
<div class="dark-blue-section main-color">
<div class="container">
<nav class="navbar" role="navigation">
Nav Component
angular
.module('common')
.component('nav', {
templateUrl: './nav.html',
});
Like OP said, simply renaming it will solve it.
NOTE: I did first try renaming from nav to navbar which is ALSO an HTML class if you look at the Nav Template HTML, but this did not seem to confuse AngularJS.
Not sure why CSS classes cause confusion, but HTML classes don't so maybe someone else can chime in there.

angularjs vs twitter bootstrap tabs javascript

I'm making my first steps with angularJS. In the "code school" video (http://campus.codeschool.com/courses/shaping-up-with-angular-js/level/2/section/2/video/1) there is a sample code that makes tabs in angular:
HTML
<section class="tab" ng-controller="TabController as tab">
<ul class="nav nav-pills">
<li ng-class="{active:tab.isSet(1)}">
<a href ng-click="tab.setTab(1)">Description</a></li>
<li ng-class="{active:tab.isSet(2)}">
<a href ng-click="tab.setTab(2)">Specs</a></li>
<li ng-class="{active:tab.isSet(3)}">
<a href ng-click="tab.setTab(3)">Reviews</a></li>
</ul>
<div ng-show="tab.isSet(1)">
<h4>Description</h4>
<blockquote>{{product.description}}</blockquote>
</div>
<div ng-show="tab.isSet(2)">
<h4>Specs</h4>
<blockquote>Shine: {{product.shine}}</blockquote>
</div>
<div ng-show="tab.isSet(3)">
<h4>Reviews</h4>
<blockquote></blockquote>
</div>
</section>
JavaScript:
app.controller('TabController', function(){
this.tab = 1;
this.setTab = function(newValue){
this.tab = newValue;
};
this.isSet = function(tabName){
return this.tab === tabName;
};
});
I know that twitter bootstrap has its own JavaScript for managing dynamic tabs (http://getbootstrap.com/javascript/#tabs).
My question is: is angularjs using bootstrap javascript here? I guess not. And if not (while this means angular is using only bootstrap's CSS), then why is angular reinventing the wheel = implementing new code that does the same thing as bootstrap's javascript code? I mean, why writing different code that does the same stuff, why not to use existing code?
Maybe it's just a matter of this tutorial - but is there a way to make angular use native bootstrap's javascript?
bootstrap provides one-way binding data. Howerver, angularJS supplies two-way binding. I suggest you should take a look at angular-ui. If you want use bootstrap with angularjs, you shoud search keyword "custom directive angularjs".
Reinventing the wheel? They are only using ng-show, which just changes the display style in your element to none.
Angular has no problem to use anyone scripts, you only have to do it the angular way. In this case it is called directives (most cases when you are going to manipulate DOM this is the way).
So for angular directives you can use template or templateUrl, template you give a string, templateUrl you give a file path. In your case I recommend you to place a new html file and write there your tabs content.
so in you tabs.html file
<div class="tab-content">
<div class="tab-pane active" class="home">...</div>
<div class="tab-pane" class="profile">...</div>
<div class="tab-pane" class="messages">...</div>
<div class="tab-pane" class="settings">...</div>
</div>
your directive should look something like this, according to bootstrap docs
myapp.directive('theNameOfMyDirective', function () {
return {
restrict: 'E',
replace: true,
templateUrl: 'the path to my html file', you can use only template too and writte your html as string, but in your case I think it is more clean if you do it in a diferent file
link: function (scope,element){
// angular.element() this is similar to $() in Jquery or Jquery()
angular.element(element).find('.profile').on('click', function (e){
e.preventDefault()
$(this).tab('show');
});
angular.element(element).find('.home').on('click', function (e){
e.preventDefault()
$(this).tab('show');
});
//some other tabs
}
}
});
since we restrict our directive to be E (Element), we have to add this html to render our tabs wherever we need them
<theNameOfMyDirective></theNameOfMyDirective>
for more info of custom directives http://tutorials.jenkov.com/angularjs/custom-directives.html

AngularJS ui router - not showing nested partials views

I have an AngularJs app with start up page as index.html, by default the projects view will be displayed and on top of the page I am showing a icon to show the todo items (for the logged-in user) which I am using bootstrap's data-toggle dropdown. The issue is whenever I click the todo link the partial view (todo.html) is not showing. BTW, I am new to the angular world so please forgive me if there is anything silly. Please see the code below:
Index.html
<!DOCTYPE html>
<html lang="en" ng-app="myApp">
<head></head>
<body>
<a data-toggle="dropdown" class="dropdown-toggle" ui-sref=".todo">
<i class="icon-tasks"></i>
<span class="badge badge-grey">4</span>
</a>
<div ng-view></div>
</body>
app.js
// For any unmatched url, redirect to /projects
$urlRouterProvider.otherwise("/projects");
//
// Now set up the states
$stateProvider
.state('projects', {
url: "/projects",
templateUrl: "/app/views/projects/projects.html",
controller: "projectController"
})
.state('projects.todo', {
url: "/todo",
templateUrl: "/app/views/todo/todo.html"
});
First of all replace ng-view with ui-view in the root template, cause it seems you want to use ui-router instead of ng-router.
Wrap the content of your template files with div of ui-view as a parent element.
/app/views/projects/projects.html
/app/views/todo/todo.html
<div ui-view>
... previously defined content ...
</div>
Let's say your view was
<div class="container">
<div class="page-header">
<h1>Title: {{title}}</h1>
</div>
</div
you need to add ui-view to the div
<div class="container" ui-view>
<div class="page-header">
<h1>Title: {{title}}</h1>
</div>
</div
or wrap your view with div containing ui-view descriptor in case your vie contains several tags.
I cannot show you an example since you did not provide content of view files.
/app/views/projects/projects.html
/app/views/todo/todo.html
The issue is that after fist template applying angular does not see the place to put new template anymore.
ui-router isn't really supposed to be used in this way. To integrate bootstrap with angular you want to look at UI Bootstrap - http://angular-ui.github.io/bootstrap/
Then to achieve your drop down, look at their basic examples. If you want to use separate view files to define your drop down content, you can use <div ng-include="'mycontent.html'"></div>.
ui-router is useful if you have a complex view hierarchy, where you are for example, looking for dynamic loading of children, while keeping parent states static.
In ui-router you defined all of this in the $stateProvider, so there you should define that you have a view that has another view belonging to it, example:
<!-- In index.html the main view that will have all the page views-->
<div id="main" ui-view="main"></div>
<!-- In todo.html with a partial with the dropdown code in dropdown.html -->
<h1> This is a nice todo drop down </h1>
<div id="todoDropDown" ui-view="todoDropDown"></div>
//In your app file
.state('projects.todo', {
url: '/todo',
views: {
'main#': {
templateUrl: '/app/views/todo/todo.html',
controller: 'TodoCtrl'
},
'todoDropDown#projects.todo': {
templateUrl: '/app/views/partials/dropdown.html'
}
}
})
"todoDropDown#projects.todo" This does the magic, it tells that this view has another view inside. And you can add controller to it and all other options you have in ui-router. In this way you can break up as much as possible reusable parts.

UI Router not working with Angular not matter what

(angularJS 1.2.5 & ui-router 0.2.7)
Please help its 4 in the morning and its been 2-3hrs since i'm stuck with this, flipped the code multiple times but cudn't make it run.
In my index.html, I have the following code:
<div class="well sidebar-nav sidebar-slide">
<ul class="nav nav-list" style="font-size:17px">
<li class="nav-header">Demand Type</li>
<li><a ui-sref="add14" data-toggle="tab">ADD-14</a></li>
<li><a ui-sref="cash_purchase" data-toggle="tab">Cash Purchase</a></li>
<li><a ui-sref="local_purchase" data-toggle="tab">Local Purchase</a></li>
</ul>
</div>
<div class="hero-unit" ui-view></div>
In my app.js, I have the following code:
var ODS = angular.module('ODS', ['ui.router','ngAnimate']);
//Define Routing for app
ODS.config(['$stateProvider', '$urlRouterProvider',
function($stateProvider, $urlRouterProvider) {
// For any unmatched url, redirect to /state1
$urlRouterProvider
.when('/add14', '/add14/create_order')
.when('/cp', '/cp/create_order')
.when('/lp', '/lp/create_order')
.otherwise("/intro");
$stateProvider
.state('intro', {
url: "/intro",
templateUrl: "templates/core/intro.html"
})
.state("add14", {
url: '/add14',
templateUrl: 'templates/core/add14.html'
})
.state("add14.create_order", {
url: "/create_order",
templateUrl: "templates/ADD14/add14.create_order.html"
})
.state("add14.own_demand", {
url: "/own_demand",
templateUrl: "templates/ADD14/add14.own_demand.html"
})
}]);
In my add14.html, I have following code:
<a ui-sref=".create_order">Create</a></button>
<a ui-sref=".own_demand">Own Demand</a>
<div ui-view></div>
In my add14.create_order.html & add14.own_demand.jsp i have sample code to print.
Thank You for your patience!
Did you ever get this figured out? I'm running into a similar problem - I find that using <a href='#/url'> seems to work, but I can't access my states via ui-sref either. I've also noticed that the rendered html doesn't auto-generate an href corresponding to the state as the documentation said it would. Fairly confused why it's not working myself.
Heads up: try to make sure you add the "ng-app" directive to your body tag (in your main template), otherwise, it seems angular-ui-router stuff, such as the ui-sref directive, will not be called.
Example:
<html ng-app="myApp">...</html><!-- Nope. Don't do this -->
<html>...<body ng-app="myApp"></body></html><!-- Do this instead -->
You are using both $stateProvider and $urlRouterProvider. try just using $stateProvider instead of both as that could be where your error is. And you don't have controllers for each of your states. Hope this helps you.

Categories