Angular.js / Ionic make Tab-Button only clickable if var is set - javascript

how is it possible to not let the user click on the tab-bar, before a scope variable is set. The first view in my app is a view, where you can choose your city. The other Tabs (which uses the value of "city") should only be clickable after the user selects that city. The city is stored in $rootScope.selectedCity and this is the state where the city is needed:
.state('tab.friends', {
url: '/friends/:selectedCity',
views: {
'tab-friends': {
templateUrl: 'templates/tab-friends.html',
controller: 'FriendsCtrl'
}
}
})
Any suggestions for only making the tabs clickable after the user selects the city? Ty

You can handle ion-tab click by using on-select attribute, see : DOCS
on-select
(optional) |
expression
Called when this tab is selected.
In addition ion-tab supports ng-click as well: See $ionicTabsDelegate usage

Related

How to update the selected item after being re-directed into another page

Im creating an app where I have used ionic item-divider. When I click on the list header it will re-direct to the new view where the user can update and delete the currently selected item.The problem I face is in the updation because Im unable to push the information from the first page to the second page i.e I want to push both the selected item and its sub-item so that both are edited and saved. Im using key in my controller to know what is being selected, after which I'm struggling to push the option selected and its related information to the next page for update and save it. I have attached a plunker how my first page looks.
plnkr link
Main View:
<ion-list>
<ion-item ng-model="carBrand" ng-repeat="name in carSelect">
<button ng-click="selectItem(name)">{{name.name}}</button>
<div class="item" ng-repeat="type in name.types">{{type}}</div>
</ion-item>
</ion-list>
Things you are doing wrong
you cant use
$state.go('second.html',{key});
It needs proper routing,You cant use explicit .html file to go to. You should add config part in your js like this
carService.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('first', {
url: '/first',
templateUrl: 'templates/first.html',
controller: 'carBrand'
})
.state('second', {
url: '/second',
templateUrl: 'templates/second.html',
controller: 'secondCTRL',
params: {
object: null
}
});
$urlRouterProvider.otherwise('/first');
})
after that you can only goto secong page . And for passing parameters
you should pass it through like this
$state.go('second', {object:key});
but you are using $rootScope so you dont need to pass parameters , You can use that $rootScope.selectItem in your secondController.
Hope This helps You .. Thanks

How can I set a predetermined offset for Angular Material's "md-menu"?

I am working with Angular Material's "md-menu" as covered in these demos: https://material.angularjs.org/latest/demo/menu
What I want to do is keep the bottom option of the menu always above the button you click to show the menu no matter how many entries I have set. I measured a difference of maybe 50px added to the bottom of the menu for each extra entry.
Is there a way to determine the offset depending on the number of entries in the menu and set that as the offset?
So let's say that 1 entry is "0, -50", 2 entries is "0, -100", etc.
This value just needs to be determined by some method and won't dynamically change after the page is loaded.
It's probably not the answer you're looking for, but depending how soon you need this feature you could wait for the mdPanel feature. It's been merged into master in the last couple of days, so it shouldn't be that long imo.
What's good about mdPanel is that you can position it easily just as you would want. You can see the basics here: https://github.com/angular/material/blob/master/src/components/panel/panel.js#L465-L497
I haven't checked whether mdMenu has been rebased on mdPanel yet (probably not yet), but you could just create your menu with mdPanel anyways. Here is a basic example:
vm.menu = function () {
var position = $mdPanel.newPanelPosition()
.relativeTo(document.querySelector('#menu'))
.addPanelPosition($mdPanel.xPosition.ALIGN_START, $mdPanel.yPosition.ALIGN_BOTTOMS);
var config = {
templateUrl: 'widgets/menu.html',
hasBackdrop: false,
position: position,
clickOutsideToClose: true,
escapeToClose: true,
focusOnOpen: true,
controller: MenuController,
controllerAs: 'vm'
};
$mdPanel.open(config);
}
You could call this function on a simple mdButton element, or anything you would like really.

AngularJS Changing the particular view by $stateProvider from ui.router

I'm writing full stack e-commerce store with AngularJS and express.js, and I'm searching help of somebody more experienced with $stateProvider and ngAnimate.
Currently I'm having a trouble with $stateProvider and two columns layout.
I've got root view abstract state which is named 'pages'. This state includes base app template with view named 'main'. On state change event the 'main' view is transitioning to the next one with CSS transition by the ngAnimate module and it's all OK with regular one column page.
The trouble I'm experiencing is within the two-column layout included in the 'main' view. With the partial template of two columns view, ngAnimate was transitioning whole content, so column was unnecessary transitioned with the products view.
What I've done, I've created a sub-state and divided its template into two views. Right now the 'sidebar' view is including partial with categories of products, and the second one, the 'content' is a products list.
The products list view contents is depending on sub-state of products state, based on abstract state descibed above.
Right now the products list is changing correctly with transition attached to the 'content' view but the column 'sidebar' is unnecessary reloaded.
Is it possible to change state with changing only the content of particular view or are you having other ideas?
Live demo: http://rtbm.space:3000/#/products
Code: https://github.com/rtbm/angular-express-store/tree/master/public/assets/src/web/modules
The modules described above are pages and products.
You could use a more hierarchical route-structure:
.state('pages.products.category', {
abstract: true,
url: '/category',
templateUrl: 'assets/dist/web/modules/products/partials/products.category.html',
controller: 'ProductsCategoryController',
controllerAs: 'productsCategoryCtrl',
resolve: {
CategoriesData: function(CategoriesService) {
return CategoriesService.query();
}
}
})
.state('pages.products.category.content', {
url: '/:categoryId',
templateUrl: 'assets/dist/web/modules/products/partials/products.list.html',
controller: 'ProductsListController',
controllerAs: 'productsListCtrl',
resolve: {
ProductsData: function($stateParams, ProductsService) {
return ProductsService.query({
categoryId: $stateParams.categoryId
});
}
}
})
Now the products.category.html should contain only one <ui-view>. The result is that the abstract parent state pages.products.category (and therefore the category's side nav) isn't reloaded every time you click on a category link in the side nav.
I hope this helps!

Pass information to bootstrap modal from Angular.js controller

Simplified problem
I have a store. For a product to be included in the store there needs to be a shelf for it. So, to add a new product to the store the workflow is:
Add a shelf
Add product to that shelf
(The workflow can not be changed)
Realization
The shelf is realized by a row in a table, which in turn is controlled by an Angular.js controller (each shelf is an object in an array). To add an product the user selects "create product" in a drop-down menu that is present on each row. This will show an bootstrap modal where I have from a controller added a tab for each product that is possible to add (since each product needs configuration :) ) , then when the user presses a "create" button in the modal a JavaScript method is called interfacing a REST interface to add the product (the UI is updated by a Socket.io event send from the server when the product has been added successfully.
Problem
The JavaScript method (CreateProduct) needs to now what row (R) was affected as well as what tab (T) was selected so that the "onclick" method for the button is CreateProduct(R, T);
My current solution is pretty ugly imho, I have two global variables for R and T, then I use jQuery to capture show event and tab event from the modal, the link in the dropdown has a field "data-row-id" that is identifying the row
HTML (Jade) snippet from dropdown menu:
a(data-toggle="modal", href="#createProduct", data-row-id="{{row.RowID}}") Create Product
JavaScript:
var R = null;
$('#productModal').on('show.bs.modal', function(e) {
R = $(e.relatedTarget).data('row-id');
});
var T = null;
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
T = e.target.text;
});
I hope there is a better solution to this, I probably am just thinking a bit upsidedown due to inexperience with Angular.js , perhaps there is a way to pass these through the model? Perhaps add these to the modal controller, but then, how to pass the row? My dream would be something like this on the button code
button(type="button", class="btn btn-default", data-dismiss="modal", ng-click="storeCtrl.CreateProduct({{modalCtrl.shelf, modalCtrl.Product)") Create Product
I found a better way (at least I don't need to use jQuery) using ModalService
I created a CreateProductModalController having a variable selectedProduct, this is set on a ng-click event in the tab
ul(class="nav nav-pills", id="tabContent")
li(ng-repeat="prod in products", ng-class="{active: $index == 0}", ng-click="activateTab(prod.name)")
a(href="#{{prod.name}}", data-toggle="tab") {{prod.name}}
The ModalService is called with the rowID that was clicked.
The only problem I have now is that all must be in $scope, I want it to be more encapsulated

Evaluating an expression in AngularJS ng-show directive

Background: As part of a project I'm working on, Users (referred to as "artists" in the case below) can optionally select one or more from a series of Roles: Manager, Producer, Agent, and so forth. Consequently, I need to show or hide certain parts of page depending on which Role(s) the User has selected.
The example: I've tried using the following to conditionally show a div when the User has selected "Manager" as one of his/her Roles (and have it hidden when "Manager" isn't selected), but with no luck. What should I be using in the ng-show directive instead?
<div class="manager_section" ng-show="data.artist.roles.name == 'Manager'">Sample Text Here</div>
Please note: the div appears just fine with no ng-show/ng-hide directive applied, so I'm not looking for a CSS answer or anything; I'm simply looking for the conditional aspect provided by ng-show/ng-hide. And I know the data for the Roles is being pulled to the page, because when I ran the following on the page to test it, the names of each of the Roles the User had selected were accurately displayed:
<div ng-repeat="role in data.artist.roles">{{ role.name }}</div>
You can use controller method if you need to run arbitrary JavaScript code.
For example:
<div class="manager_section" ng-show="isAuthorized('Manager')">Sample Text Here</div>
angular.module('myApp', [])
.controller('AppCtrl',function(){
$scope.isAuthorized = function(role){
for(var i=0;i<$scope.data.artist.roles.length;i++){
if($scope.data.artist.roles[i].name === role) return true;
}
return false;
}
};

Categories

Resources