How can I open a page, which contains an ons-tabbar inside, and tell it to show a specific tab, using ons-navigator? I have a menu with some buttons, and depending which one is pushed, it has to be displayed the tabbar page, with a specific tab active.
This is what I have tried so far:
index.html (Main page)
<body>
<ons-navigator animation="slide" var="app.navi">
<ons-page>
<ons-toolbar>
<div class="center">Inicio</div>
</ons-toolbar>
<div>
<p style="text-align: center">
<ons-button modifier="large" ng-click="app.navi.pushPage('tabs.html', {params: { tab: 0 }});">OPEN TAB 0</ons-button>
</p>
<p style="text-align: center">
<ons-button modifier="large" ng-click="app.navi.pushPage('tabs.html', {params: {tab: 1}});">OPEN TAB 1</ons-button>
</p>
</div>
</ons-page>
</ons-navigator>
</body>
tabs.html
<div ng-controller="TabsCtrl">
<ons-tabbar var="tabbar" position="top">
<ons-tabbar-item
icon="home"
label="Home"
page="page0.html"></ons-tabbar-item>
<ons-tabbar-item
icon="comment"
label="Comments"
page="page1.html"></ons-tabbar-item>
</ons-tabbar>
</div>
AngularJS controller:
angular.module('myControllers', [])
.controller('TabsCtrl', ['$scope', function ($scope) {
// Trying to set active tab on the controller
$scope.tabbar.setActiveTab($scope.ons.navigator.getCurrentPage().options.params.tab);
}]);
However, when I push a buton in the main page, the debugger says that cannot call method setActiveTab on undefined. I know that this may be because the tabbar hasn't been created when the controller is executed, but I can't figure out how to show a specific tab when the page is displayed, based on some navigator parameter.
Yeah it's true that when the controller is executed there won't be any tabbar object, but it will be created immediately after.
So you could use setImmediate(fn) in the controller to call setActiveIndex(idx).
Example:
angular.module('app', ['onsen'])
.controller('TabsController', function() {
setImmediate(function() {
var tabIndex = app.navi.getCurrentPage().options.params.tab;
app.tabbar.setActiveTab(tabIndex);
});
});
Pen:
http://codepen.io/argelius/pen/XJryPM
Actually, in 1.2.0 there is an 'ons-tabbar:init' DOM event that you could listen to which is probably better to use. The event object will attach the tabbar object so you could do something like:
someElement.addEventListener('ons-tabbar:init', function(event) {
var tabBar = event.component;
tabBar.setActiveTab(someIndex);
});
Related
I'm building an Single Page App where the paypal button is generated on ng-click from a button (Add products).
The problem I'm facing, is that if the user clicks this button several times, the app will generate several buttons one after the other.
This can very well happen as the user might click the button, but then go back and add an extra product, before finish the purchase.
How could I manage to remove all existing buttons before adding the new one?
The function looks like this:
$scope.formulari = function(){
paypal.Button.render({
env: 'production', // Or 'sandbox'
locale: 'es_ES',
style: {
label: 'paypal',
...
And after a few clicks, my initial HTML button <a id="paypal-button"></a> looks like this:
<a id="paypal-button">
<div id="xcomponent-paypal-button-6d3dcbc0c4" class="paypal-button paypal-button-context-iframe paypal-button-label-paypal paypal-button-size-large paypal-button-layout-horizontal" style=""></div>
<div id="xcomponent-paypal-button-46823018c3" class="paypal-button paypal-button-context-iframe paypal-button-label-paypal paypal-button-size-large paypal-button-layout-horizontal" style=""></div>
<div id="xcomponent-paypal-button-41aad29e14" class="paypal-button paypal-button-context-iframe paypal-button-label-paypal paypal-button-size-large paypal-button-layout-horizontal" style=""></div>
<div id="xcomponent-paypal-button-48d3247535" class="paypal-button paypal-button-context-iframe paypal-button-label-paypal paypal-button-size-large paypal-button-layout-horizontal" style=""></div>
</a>
Generating a button on click might not be the way you want to go with an AngularJs structure. Editing your DOM structure is more a jQuery thing and in general you don't want to mix the two (Some explanations of why: 1, 2).
An Angular way to pick this up would be the following (Explanation beneath snippet):
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.articles = ['PC', 'Playstation', 'Xbox'];
$scope.cart = [];
$scope.addArticleToCart = function(article) {
$scope.cart.push(article);
}
$scope.clearCart = function() {
$scope.cart = [];
}
$scope.doPaypalThings = function() {
//REST API stuff
}
});
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
</head>
<body>
<div ng-app="myApp" ng-controller="myCtrl">
<div ng-repeat="article in articles">
<button ng-click="addArticleToCart(article)">
{{article}}
</button>
</div>
<br>
<div ng-show="cart.length > 0">
<button id="paypal-button" ng-click="doPaypalThings()">
Paypal
</button>
</div>
<br>
<div>
In cart:
</div>
<div ng-repeat="item in cart">
{{item}}
</div>
<br>
<div>
<button ng-click="clearCart()">
Clear cart
</button>
</div>
</div>
</body>
</html>
With this method the button always exists, it just isn't visible until the requirements within the ng-show are met. In the example, the requirement is that there are items in the cart. You will notice that once the requirements are no longer met the button will disappear again.
An opposite of ng-show is ng-hide which can be used in the same way:
ng-hide="cart.length == 0" or ng-hide="cart.length < 1
If you're dead set on using your current method, you can check out this answer here, although it is not Angular.
I am building an app for a scheduler using Appgyver Steroids, and on the navbar, I have a button to switch days, but I can't figure out how to switch de label:
index.html
<script src="/scripts/application.js"></script>
<super-navbar-button ng-bind="dayTitle" side="right" onclick="supersonic.ui.drawers.open('right')">Day</super-navbar-button>
drawerMenu.html
<script src="/scripts/application.js"></script>
<li class="item" onclick="supersonic.ui.drawers.close('right')" ng-model="day" ng-click="newDay()">Monday</li>
<div style="clear: both;"></div>
<li class="item" onclick="supersonic.ui.drawers.close('right')" ng-model="day" ng-click="newDay()">Tuesday</li>
<div style="clear: both;"></div>
application.js
angular.module('SteroidsApplication', [
'supersonic'
])
.controller('IndexController', function($scope, supersonic) {
$scope.newDay= function(){
supersonic.logger.log("Got here");
$scope.dayTitle= $scope.day;
}
});
Right now I'm not even logging the "Got here" text, probably I have a minor error or something I'm missing. This is my first steroids/supersonic/angular/hybrid application. Thanks in advance.
two things dont do onclick with angular, instead do ng-click
did you tried doing
{{ day }}
instead of writing the day?
I'm trying to figure out why I can't seem to wrangle a simple angular dropdown reset.
When the view loads, you hit the button "Reset", and it changes whatever value is selected to a different one, based on what the functionality in the controller dictates. This works fine on page load, but if you change the value in the dropdown THEN click "Reset", it does nothing. It doesn't reset the dropdown as specified in the function and I can't figure it out.
Steps to reproduce:
Page loads
Click "Reset" button
Dropdown value changes to "Japanese"
Change the value back to "English"
Click "Reset" button
Nothing. It should change the value back to English, but doesn't.
I've boiled everything down to the most basic example using an extremely basic ionic example in my Codepen:
http://codepen.io/starshock/pen/EPdXpz
Basically, here is my controller code:
.controller('DropdownController', [ '$scope', '$state', function($scope, $state) {
$scope.navTitle = 'Dropdown Reset';
$scope.reset = function() {
$scope.selectedOption = $scope.languages[0];
}
$scope.languages = [
{ name: "English"},
{ name: "Japanese"}
];
$scope.selectedOption = $scope.languages[1];
}]);
And here is my template:
<script id="entry.html" type="text/ng-template">
<ion-nav-bar animation="nav-title-slide-ios7"
type="bar-positive"
back-button-type="button-icon"
back-button-icon="ion-ios7-arrow-back">
</ion-nav-bar>
<ion-view title="{{navTitle}}" class="bubble-background">
<ion-content has-header="true" padding="true">
<div class="item item-input item-select" href="#">
<label>
<div class="input-label">
Select language
</div>
<select
data-ng-options="language.name for language in languages"
data-ng-model="selectedOption">
</select>
</label>
</div>
<button class="button button-positive" ng-click="reset()">Reset</button>
</ion-content>
</ion-view>
</script>
I've been struggling with this problem for months and I have a number of instances that utilize similar code. Any Angular masters have any thoughts? :D
You need to change your controller slightly to reference the same object each time (see https://stackoverflow.com/a/17607794/360067 and the answer referenced i.e. https://stackoverflow.com/a/14049482/360067 for the basics).
Assuming the default value you want is English (if it's Japanese, just change the index to 1 in both places)
$scope.reset = function() {
$scope.filter.selectedOption = $scope.languages[0];
}
...
$scope.filter = {
selectedOption: $scope.languages[0]
};
and in your HTML
<select
data-ng-options="language.name for language in languages"
data-ng-model="filter.selectedOption">
</select>
CodePen - http://codepen.io/anon/pen/KVGqOG
So I followed this guide so I could have a nav bar on every page: http://tomaszdziurko.pl/2013/02/twitter-bootstrap-navbar-angularjs-component/
And it was working, until I created a separate controller to populate my bootstrap carousel. The thing is, my ng-repeat works fine, but when it does I can't see my navbar on that page. I can see it just fine on other pages. I believe this is a scoping issue, but I am not sure where.
This is what I have in the main body of this page:
<body>
<reusable-navbar></reusable-navbar>
<!-- Carousel Start -->
<div id="main-carousel" class="carousel slide container" data-ride="carousel">
<!-- Wrapper for slides -->
<div class="carousel-inner">
<!--Must set this by hand-->
<div class="item active">
<img alt="" src="../Revamp/Images/carousel/1.jpg">
</div>
<!--Repeat through the rest-->
<div ng-controller="carouselPhotoController">
<div class="item" ng-repeat="source in source">
<img alt="" ng-src="{{source.source}}">
</div>
</div>
</div>
</div>
And my controller looks like this:
var carouselPhotoController=angular.module("revampApp", []);
carouselPhotoController.controller("carouselPhotoController", function($scope, $http){
$http.get('../Revamp/Images/carousel/photos.json').success(function(photos){
//Carousel photos
$scope.source = photos;
})
});
And the directive is identical to the one in that walk through, just with a different template. So how to I get it so my nav bar will show up AND I can use ng-repeat?
Make sure you are not recreating the app.
This creates a new app:
var carouselPhotoController=angular.module("revampApp", []);
But this only accesses an app already created (note the absence of the second parameter):
var carouselPhotoController=angular.module("revampApp");
Change the above line and it should work.
Question:
How can I add a "Login" view/route to my angular app that hides an element that is outside the ng-view DOM?
Situation:
In my Angular page, I have a navigation tree view on the left and the main view in the center:
<div ng-app="myApp">
<div class="col-sm-3" ng-controller="TreeController">
<div treeviewdirective-here>
</div>
</div>
<div class="col-sm-9 content" ng-view="">
</div>
</div>
Each node in the treeview changes the location using something like window.location.hash = '#/' + routeForTheClickedItem;.
Using the standard routing, this works great, i.e. the tree is not reloaded each time, but only the main "window".
Problem:
I want to add a login functionality with a login view. For this view, the treeview should not be visible - only after the login. To achieve this with the normal routing, I know I could move the ng-view one level up, i.e. embed the treeview into each view - but this would result in the treeview being reloaded with every route change.
Is there an easy alternative that allows me to check what page is displayed in the ng-view? Or check some other variable set during the routing? Then I could use something like:
<div class="col-sm-3" ng-controller="TreeController" ng-show="IsUserLoggedIn">
You could listen for a routeChangeSuccess outside ng-view
$scope.$on('$routeChangeSuccess', function (event, currentRoute, previousRoute) {
//do something here
});
hope that helps, you can catch me on angularjs IRC - maurycyg
You could define a controller at the top div level.
Something like:
<div ng-app="myApp" ng-controller="MainController">
and in MainController inject a Session. Something like Session is enough to decide whether to show the tree.
Here's an example of MainController:
_app.controller('MainController', function ($scope, SessionService) {
$scope.user = SessionService.getUser();
});
Here's an example of SessionService:
_app.factory('SessionService', function() {
var user = null;
return {
getUser : function() {
return user;
},
setUser : function(newUser) {
user= newUser;
}
};
});
Of course, when you login you must set the user to the SessionService. Therefore, a SessionService has to be injected into your LoginController, too.
And finally, your html:
<div ng-app="myApp" ng-controller="MainController">
<div class="col-sm-3" ng-controller="TreeController">
<div ng-hide="user == null" treeviewdirective-here>
</div>
</div>
<div class="col-sm-9 content" ng-view="">
</div>
</div>