AngularMaterial Tabs showing only 1st tab - angularjs

Why are md-tabs showing only the first tab? The rest of them appears after I click in the tabs area.
First tab looks like this:
After clicking in the tab area:
My code looks like this:
<md-tabs md-dynamic-height md-border-bottom>
<md-tab label="Home"></md-tab>
<md-tab label="Profile"></md-tab>
<md-tab label="Messages"></md-tab>
</md-tabs>
On purpose I left the content of tabs empty because I want to get rid of the transition animation as described here.
One of the problems could be that the tabs are in bootstrap dropdown menu.
Thank you for your ideas!
EDIT
I have just found out that the tabs has troubles even without bootstrap when using them in md-menu.

Have you solved it yet?
I'm having the same problem except that my angular tabs is in bootstrap's modal.
When I click on a button to toggle the modal it only show the first tab until I click on it.
After doing some testing it appears that I could work around by hiding the angular tabs with ng-show and show it after a small amount of delay.
<button ng-click="controller.showTabs()">Show Tab</button>
<md-tabs md-dynamic-height md-border-bottom ng-show="show_tab">
<md-tab label="Home"></md-tab>
<md-tab label="Profile"></md-tab>
<md-tab label="Messages"></md-tab>
</md-tabs>
Controller's function when user clicks on the drop down / button to toggle the modal:
this.showTabs =
function()
{
//250ms delay
$timeout(function()
{
$scope.show_tab = true;
},250);
}

Related

changing md-selected with md-tabs and using md-button (prev, next)

I am experiencing a strange behavior when switching tabs using different methods of changing the tab index. I can change md-selected using the $scope.changeQuestion function with ng-click. I can also use the built in clicking of the md-tab to change md-selected. The issue lies when I click the md-tab and then try to click my prev or next buttons that utilize the $scope.changeQuestion function. If I click the tabs and then try to use my buttons to change the index, the buttons don't change the tab index anymore. They do log the appropriate index I want to switch to, however.
controller
$scope.changeQuestion = function(index){
$scope.selectedQuestion = index;
};
html
<md-tabs md-selected='selectedQuestion' md-stretch-tabs md-dynamic-height md-border-bottom>
<md-tab ng-repeat='question in assessment.questions | toArrayKeepKeys | orderBy: "order"'>
<md-tab-label>
{{question.order}} <i class="fas fa-fire fire" ng-if='question.bonus'></i>
</md-tab-label>
<md-tab-body>
<div class='question-tab-content'>
<question class='margin-top-1em' details='question' answer='answers[question.key]'></question>
<div>
<md-button ng-click='changeQuestion($index - 1)' ng-hide='question.order === 1' class='md-primary md-raised no-left-margin'>Previous</md-button>
<md-button ng-click='changeQuestion($index + 1)' ng-hide='question.order === _.size(assessment.questions)' class='md-primary md-raised no-left-margin'>Next</md-button>
</div>
</div>
</md-tab-body>
</md-tab>
</md-tabs>
Here is the example of the behavior:
I was able to get a working example in codepen but can't seem to get it to work in my project.
Update
Tried putting a $watch on $scope.selectedQuestion and it doesn't fire if I click the tabs. It's like the md-selected='selectedQuestion' and $scope.selectedQuestion are different but only after I click a tab.
Found Solution: scope inheritance
Changing $scope.selectedQuestion = 0; to $scope.selectedQuestion = { selected: 0 }; and updating other references did the trick.
Unexplained: why the codepen example works without the modifications from the solution

md-tabs not showing scroll or pagination

I have recently upgraded my angularjs material version from 1.0.9 to 1.1.10. After the change my scroll bars have stopped showing up in the sides of my tab menu panels when there is an overflow. This used to work fine earlier.
Now I only see the following in the Devtools, for some reason the this flag is not becoming true for the pagination to work. Please let me know what could be the issue here.
<!-- ngIf: $mdTabsCtrl.shouldPaginate -->
This is the code that I have.
<div class="mainContentWrapper md-whiteframe-2dp" id="mainContentWrapper" style="overflow:auto;">
<div class="tab-panel">
<md-content class="md-padding">
<md-tabs md-selected="selectedIndex" md-border-bottom md-autoselect>
<md-tab>
<img class="dashboard" width="20" src="../../images/dashboard-icon1.png" />
<md-tooltip md-direction="right" ng-click="backToDashboard()">
Dashboard
</md-tooltip>
</md-tab>
<md-tab ng-repeat="tab in tabs"
ng-disabled="tab.disabled"
title="{{tab.desc}}" ng-if="$index>0">
{{tab.title}}
<md-tooltip>
{{tab.desc}}
</md-tooltip>
</md-tab>
</md-tabs>
</md-content>
</div>
There has been a change in implementation from 1.0.9 to 1.1.10. in the new version its using MutationObserver to detect any change to decide if it needs to show pagination.
var mutationCallback = function() {
ctrl.updatePagination();
ctrl.updateInkBarStyles();
};
if('MutationObserver' in $window) {
var config = {
childList: true,
subtree: true,
// Per https://bugzilla.mozilla.org/show_bug.cgi?id=1138368, browsers will not fire
// the childList mutation, once a <span> element's innerText changes.
// The characterData of the <span> element will change.
characterData: true
};
observer = new MutationObserver(mutationCallback);
observer.observe(element[0], config);
disconnect = observer.disconnect.bind(observer);
} else {
var debounced = $mdUtil.debounce(mutationCallback, 15, null, false);
element.on('DOMSubtreeModified', debounced);
disconnect = element.off.bind(element, 'DOMSubtreeModified', debounced);
}
Previously it was using only $mdUtil.debounce(mutationCallback, 100) which means it was updating the flags every 100ms. for some reason when I resize my window the mutation is not triggered. So I had to manually mutate the contents of the tab on resizing the tabs. I dont like this fix. Am I missing something?

"Previous" / "Next" tab navigation system (AngularJS / AngularJS Material)

I am developing some content display in various tabs, using Angular.js 1.5.x and AngularJS Material 1.1.0.
I first used the Angular Material md-tabs system like this : https://material.angularjs.org/latest/demo/tabs.
Unfortunately, our users do not use them as they do not seem to understand they are tabs. I am now working on a new, more obvious, tabs system :
I haven't found any Angular material way to create this "previous/next"-based tab navigation system.
Do you know where I could look ? It does not need to be Angular Material, any help or lead is welcome :) I want to avoid complexity or custom code if possible, so I want to capitalize on existing frameworks.
You can still use mdTabs. You can create a custom button and make them to command the tab by changing the selected tab with: md-selected
Then hide the tab navigation by md-no-pagination , or by adding display:none to .md-tab css.
eg, for 3 tabs:
<div>
<md-tabs md-selected="tabIndex">
<md-tab label="tab1">
tab1 content
</md-tab>
<md-tab label="tab2">
tab 2 content
</md-tab>
<md-tab label="tab3">
tab 3 content
</md-tab>
</md-tabs>
<md-button ng-click="back()" class="md-raised">
Previous
</md-button>
<md-button ng-click="next()" class="md-raised">
Next
</md-button>
</div>
and controller:
$scope.back = function() {
if ($scope.tabIndex > 0) {
$scope.tabIndex--;
}
};
$scope.next = function() {
if ($scope.tabIndex < 2) {
$scope.tabIndex++;
}
}
plunkr: http://plnkr.co/edit/NWSRBb?p=preview

Load and call content of md-tab when it's clicked or selected from md-tabs (angular 1.5)

I'm using following HTML structure in parent.html page (and have corresponding Controller for this parent HTML Page)
<md-tabs md-dynamic-height class="report-tabs" layout-align="center stretch" md-no-pagination="true">
<md-tab>
<md-tab-label>
<span class="tab-label">Tab 1</span>
</md-tab-label>
<md-tab-body>
<div ng-include="tab1-page-URL"></div>
</md-tab-body>
</md-tab>
<md-tab>
<md-tab-label>
<span class="tab-label">Tab 2</span>
</md-tab-label>
<md-tab-body>
<div ng-include="tab2-page-URL"></div>
</md-tab-body>
</md-tab>
Currently when I load this parent.html page, All contents of all tabs are getting loaded at beginning.
Don't we have lazy loading where contents of tab are loaded when it's active (when selected/clicked upon) ?
If we don't have such provision, How can I call function of child tab's controller, when particular tab is selected ? Currently all functions of all child tab's controllers are getting called - which is time consuming and not needed where user will see first tab only when page completes compiling and rendering ?
I've tried calling Child-tab controller functions on parent.html page, but unless all md-tab contents are not loaded, nothing from child-controller is accessible. Only accessible part in this page will be parent.html's own controller functions.
Let me know if any other way I can proceed, Or am I missing completely something here ? Thank you.
From the official doc, for using md-tab , there are no lazy loading contents.
If we don't have such provision, How can I call function of child
tab's controller, when particular tab is selected ? Currently all
functions of all child tab's controllers are getting called - which is
time consuming and not needed where user will see first tab only when
page completes compiling and rendering ?
My method is by using the button only tabs, then using dynamic ng-include, and setting the reladed view during selecting the tab, by md-on-select
something like:
<md-tabs>
<md-tab label="Tab #1" md-on-select="onTabSelected(1)"></md-tab>
<md-tab label="Tab #2" md-on-select="onTabSelected(2)"></md-tab>
<md-tab label="Tab #3" md-on-select="onTabSelected(3)"></md-tab>
</md-tabs>
<md-content class="md-padding">
<ng-include src="'templates/tabs/'+ tabId +'.html'"></ng-include>
</md-content>
controller :
$scope.tabId = 1; //default template loaded
$scope.onTabSelected = function(tabId) {
//you can add some loading before rendering
$scope.tabId = tabId;
};
templates directory:
templates/
tabs/
1.html
2.html
3.html
You could try something like:
<md-tabs md-dynamic-height class="report-tabs" layout-align="center stretch" md-no-pagination="true">
<md-tab md-on-select="onSelect(tab)" ng-repeat="tab in tabs">
<md-tab-label>
<span class="{{tab.class}}">{{tab.label}}</span>
</md-tab-label>
<md-tab-body>
<div ng-if="selectedTab === tab.id" ng-include="{{tab.url}}"></div>
</md-tab-body>
</md-tab>
and in controller:
$scope.tabs = [
{id: 1, label: "label for tab 1", url: "url-tab-1.html"},
{id: 2, label: "label for tab 2", url: "url-tab-2.html"}
];
$scope.onSelect = function(tab) {
$scope.selectedTab = tab.id;
};
$scope.onSelect(1);

titles not showing correctly in angular material tabs

I'm using angular material tabs but there is something wrong with my implementation and it gives me this result (on Chrome and Firefox):
As you can see the tab titles are truncated.
Here is my implementation:
HTML:
<md-tabs>
<md-tab ng-repeat="tab in tabs">
<md-tab-label>{{tab.titre}}</md-tab-label>
<div class="md-tabs-content">
content tab
</div>
</md-tab>
</md-tabs>
JS:
var tabs = [];
for(i=0;i<3; i++){
tabs.push({
titre: 'title'
});
}
$scope.tabs = tabs;
$scope.selectedTab = 0;
Added the plnkr:
http://plnkr.co/edit/nFMFmaGpLUwJPxRd1TpT?p=preview
Quoting from Angularmaterial docs for md-tab
Please note that if you use <md-tab-label>, your content MUST be wrapped in the <md-tab-body> tag. This is to define a clear separation between the tab content and the tab label.
So can you trying changing your code to:
<md-tabs>
<md-tab ng-repeat="tab in tabs">
<md-tab-label>{{tab.titre}}</md-tab-label>
<md-tab-body class="md-padding">
content tab
</md-tab-body>
</md-tab>
</md-tabs>

Resources