Accessing controller inside overridden template-url of uib-tab - angularjs

angular-bootstrap version used : 1.2.0
angular-version : 1.5.7
I am trying to override header html of uib-tab like below,
<li ng-class="{active: active, disabled: disabled}" class="uib-tab">
<a ui-sref="MyController.overviewStateUrl" ng-click="select()" uib-tab-heading-transclude>{{heading}}</a>
</li>
When the page is rendered, the value for ui-sref is taken as MyController.overviewStateUrl instead of the real value which is stored in overviewStateUrl attribute of MyController. Is there any way to do it?
I tried to put it inside interpolation, but it returns empty string. Here's the plunker.

Have you tried as like below code?
<a ui-sref="{{MyController.overviewStateUrl}}" ng-click="select()" uib-tab-heading-transclude>{{heading}}</a>

Related

Pagination repeater has an active class that i must move when pagination button clicked

Take the following pagination html and repeater:
<ul id="ProductListPagination" class="pagination">
<li class="disabled"><span aria-hidden="true">«</span><span class="sr-only">Previous</span></li>
<li ng-repeat="n in PageCount" ng-class="{active: n==1}"><a ng-click="Paginate( n )" href="#"><% n %> <span class="sr-only">(current)</span></a></li>
</ul>
How do I go about moving the active class on the repeater when one of the pagination buttons are pressed... Is there a built in angular way?...
context:
If there is no built in way in angular, how do I pass the dom element through to the Paginate( n ) function?
I have the receiving function:
$scope.Paginate = function( obj, page ){
// Remove currently active button's active class
$( "#ProductListPagination li.active" ).each( function() {
$( this ).removeClass( "active" );
} );
// Add to element just clicked on
$( obj ).parent().addClass( "active" );
...
}
And the html to go with that, you'll see I tried passing in this.
<li style="cursor:pointer" ng-repeat="n in PageCount" ng-class="{active: n==1}"><a ng-click="Paginate( this, n )" href="#"><% n %> <span class="sr-only">(current)</span></a></li>
But that doesn't work as this, is not a dom element.
Directives
This could be done with Directives, these allow you to define custom markup ie. an element, an attribute name, it even can hook onto class names. Then from that you can attach all sorts of stuff.
https://egghead.io/lessons/angularjs-first-directive
So you could make a "Pagination" directive.
and that would then be used something like:
<my-pagination pages="arrayInScope">
You can then provide an external template or even a string of markup (eww) for what needs to be either IN this element or to replace this element.
Another Solution
But this is a quick way and I guess it doesn't really need any more over complicating anyway.
Example on CodePen
From the markup I am calling the paginate function parsing ng-repeat's provided $index. In the paginate function in the js i then set it.
As angular digests this: ng-class="{ active : page == current }" will then re-evaluate.
But if you need access to the element for some reason then use directives. jQuery is best avoided when using Angular, if it is just a class change or a visibility toggle etc. then its best to let Angular do it for ya'
Hope that helps.

ngRoute RouteController getting called only once

I've a fiddler to show my setup.
http://jsfiddle.net/smartdev101/dt6kkyy3
The problem is the routeController function is getting called only once on the page load, but then on hash change (as a result of link click), the function routeController is not getting called again.
I've my links generated in another ng module, not sure if the links have to be with in the same module as the router.
<div id="router">
<div ng-view></div>
</div>
<div id="navigation" data-ng-cloak>
<ul id="folios" data-ng-controller="FoliosController" class="nav nav-pills nav-stacked">
<li data-ng-repeat="folio in folios" ng-class="{active: isActive('/search/{{folio.productId}}')}">
{{folio.title}}
</li>
</ul>
<div ui-view></div>
</div>
Edit:
Problem has been further diagnosed. Any list/anchor that was generated by an ng controller, is not responding to hash changes outside the scope, while the static links are. from the plunkr link, "foo" and "bar" clicks trigger the controller but "abc" and "def" are not. please review. Question is how to make "abc" and "def" (dynamic links) respond to changes as well.
http://plnkr.co/edit/ea1OHa?p=preview
The code is behaving as intended with the way you have it coded. You are calling routeController in the constructor of the controller, but its not being invoked anywhere else (the router isn't going to do that either).
If you need the routeController function to be invoked on every route change consider binding to route changing events:
https://docs.angularjs.org/api/ngRoute/service/$route
Take a look at this plunk. Note I am binding to stateChangeSuccess instead since you are using the ui-router instead of ngRoute.
http://plnkr.co/edit/CiYLqnqAzrXoouMSXkuk

How to use angular.bootstrap twice?

I have a page where there are few tabs and I use angular+bootstrap.
I use angular.bootstrap initially.
Then I have another controller for showing different set of data in one of the tabs. when I try to use angular.bootstrap again, I get the error it cannot be bootstrapped twice. To make it simple, consider the following code.
<div id="mainpage" ng-controller="mainPageController">
<ul>
<li id="test1"> <a href="gototest1"> GoToTest1 </li>
<li id="test2"> <a href="gototest2"> GoToTest2 </li>
</ul>
</div>
<div id="gototest1">
this is some sample. I have another html page here which will be loaded as a tab
</div
The page for gototest1 looks like this
<div ng-controller="gototestcontroller>
Here comes the another widget from another controller and
I try to use angular.boostrap here again. And I get the error because it is already bootstrapped in mainPage
</div>
What is the best way to use angular.bootstrap here?
Angular bootstrap is used to manually initialize an Angular the document or an element.
https://docs.angularjs.org/guide/bootstrap
Angular cannot be initialized more than once on an element. Is there a reason you don't use automatic initialization, using ng-app?
It sounds like you could benefit from using the module ngRoute and applying the attirbute ng-view instead of trying to bootstrap twice.
https://docs.angularjs.org/api/ngRoute

Why angularjs ignore ng-if?

i try use ng-if, but angular no compile him. Look in test code:
<ul class="tmmenu-admin-tabs-builder-panel-answer">
<li class="tmmenu-admin-tabs-builder-panel-portlet" ng-repeat="answer in answers">
<div>
<span ng-repeat="question in questions">
<label ng-repeat="answer in question.answers">
<input type="checkbox">{{question.id}}.{{answer.id+1}}
<span ng-if="test()">ddd</span>
</label>
</span>
</div>
<textarea>{{answer.text}}</textarea>
</li>
</ul>
and function test:
$scope.test = function(){
console.log('d');
return false;
}
if run this page, we can see "ddd" in "Li" despite to test return false.
Next step, i replaced at "ng-if" "ng-show" :
<ul class="tmmenu-admin-tabs-builder-panel-answer">
...
<span ng-show="test()">ddd</span>
...
</ul>
And its working, "ddd" hide. Why ng-if not working where working ng-show?
The ngIf directive removes or recreates a portion of the DOM tree based on an {expression}. If the expression assigned to ngIf evaluates to a false value then the element is removed from the DOM, otherwise a clone of the element is reinserted into the DOM.
The ngShow directive shows or hides the given HTML element based on the expression provided to the ngShow attribute. The element is shown or hidden by removing or adding the ng-hide CSS class onto the element. The .ng-hide CSS class is predefined in AngularJS and sets the display style to none (using an !important flag). For CSP mode please add angular-csp.css to your html file (see ngCsp).
Could be a scope problem, is there something in a child scope that might override the value for test? ng-if works fine for me (plunker). I assume that everything else is working fine, are you seeing 'd' in the console to show that your function is getting executed?
Try changing your tag to this to help debug and you should see that it is a function:
<span ng-if="test()">test is: {{test.toString()}}</span>

Passing parameter to ng-click directive, within custom directive

I'm using ng-repeat in the template for a custom directive as follows:
<li ng-repeat="image in images">
<img ng-src="{{image.url}}" ng-click="togglePhoto({{$index}})">
</li>
When rendered on the page the source looks like
<li ng-repeat="image in images" class="ng-scope">
<img ng-src="http://example.com/example.jpg" ng-click="togglePhoto(1)" src="http://example.com/example.jpg">
</li>
I have the function togglePhoto defined in my directive. Without the {{index}} parameter being passed in it works and the function is called. With the index, it doesn't fire.
How do I get the index of the photo clicked into the togglePhoto function?
Figured this out. Hope it helps anyone else stuck on it.
Firstly this
ng-click="togglePhoto({{$index}})"
Should be
ng-click="togglePhoto($index)"
Braces not needed!
Secondly I found that you can pass the event object into the click function eg
ng-click="togglePhoto($event)"
Then catch that event and find out what element trigged it in your click function
$scope.togglePhoto = function(e)
{
console.log(e.currentTarget)
}
I think that the issue is that you are using the double curly braces inside of the ng-click, and angular doesn't like that.
Try changing your repeater to this (note there are no curly braces around $index):
<li ng-repeat="image in images">
<img ng-src="{{image.url}}" ng-click="togglePhoto($index)">
</li>
I also put together a working jsfiddle to show that this works.
http://jsfiddle.net/n02ms8s0/4/

Resources