I'm working with an application in angular where I have items in an array, and when I click on each item, details should be displayed in details page,I want to achieve this by displaying details of all items in the same details page dynamically, how do I do this?
Here is my code
<body ng-app="myApp" ng-controller="mobileController">
search:<p><inpu type="text" ng-model="test"></p>
<ul>
<li ng-repeat="x in names | filter :test" >
<a href=#/> {{ x }}</a>
</li>
</ul>
<div ng-view></div>
var app = angular.module("myApp",[]);
app.controller('mobileController', function($scope) {
$scope.names = ['iphone', 'Moto', 'Oneplus'];
});
</body>
I want to display the details of iPhone ,moto,oneplus in same details page,when user clicks on iPhone iPhone details should be displayed and same for others.
Here's a plunkr on how to do what you want using UI-Router
You can use two states to do what you want by having two states: one for the list view and one for the details view.
$stateProvider
.state('items', {
url: '/',
controller: 'ItemsListCtrl',
templateUrl: 'items-list.html',
resolve: {
Items: function (ItemsService) {
return ItemsService.getAll();
}
}
})
.state('items.details', {
url: ':itemId/',
controller: 'ItemDetailsCtrl',
templateUrl: 'item-details.html',
resolve: {
Item: function (ItemsService, $stateParams) {
return ItemsService.getById($stateParams.itemId);
}
}
})
When someone clicks on an item you send them to a url with the itemId as a stateParam and resolve that item as you load the view within the view you have currently rendered (these are called nested/child views in ui-router).
Then in the controllers you just inject the items/item you resolved at the state level, and can manipulate them or assign them to your scope.
.controller('ItemsListCtrl', function ($scope, Items, $state) {
$scope.Items = Items;
$scope.viewItemDetails = function (item) {
$state.go('items.details', {itemId: item.id});
};
})
.controller('ItemDetailsCtrl', function ($scope, Item, $state) {
console.log(Item);
$scope.Item = Item;
$scope.closeDetails = function () {
$state.go('items');
};
})
I'd recommend checking out UI-Router's docs https://github.com/angular-ui/ui-router/wiki
Related
I am making an online food ordering site using AngularJS. What I want to do is change the filter by clicking on category tabs. This is my code:
shoppingCart.prototype.changeFilter = function (cat) {
var ref = document.getElementById("refresh");
category = cat;
}
My HTML looks like this:
<ul class="menu-filter-list list-inline margin-b-40 text-center">
<li>
<a ng-click="cart.changeFilter(null)" id="refresh">All</a>
</li>
<li data-filter=".{{product.category}}" ng-repeat="product in store.products | unique:'category'" >
<a ng-click="cart.changeFilter(product.category)">
{{product.category}}
<span></span>
</a>
</li>
</ul>
The filter is applied on ng-click="cart.changeFilter(product.category)"
UPDATE: controller.js
'use strict';
// the storeController contains two objects:
// - store: contains the product list
// - cart: the shopping cart object
function storeController($scope, $routeParams, DataService) {
// get store and cart from service
$scope.store = DataService.store;
$scope.cart = DataService.cart;
// use routing to pick the selected product
if ($routeParams.productSku != null) {
$scope.product = $scope.store.getProduct($routeParams.productSku);
}
}
app.js
'use strict';
// App Module: the name OnlineOrders matches the ng-app attribute in the main <html> tag
// the route provides parses the URL and injects the appropriate partial page
var storeApp = angular.module('OnlineOrders', ['ui']).
config(['$routeProvider', function($routeProvider) {
$routeProvider.
when('/store', {
templateUrl: 'partials/store.htm',
controller: storeController,
}).
when('/products/:productSku', {
templateUrl: 'partials/product.htm',
controller: storeController
}).
when('/cart', {
templateUrl: 'partials/shoppingCart.htm',
controller: storeController
}).
when('/processing', {
templateUrl: 'partials/processingOrder.htm',
controller: storeController
}).
otherwise({
redirectTo: '/store'
});
}]);
// create a data service that provides a store and a shopping cart that
// will be shared by all views (instead of creating fresh ones for each view).
storeApp.factory("DataService", function () {
// create store
var myStore = new store();
// create shopping cart
var myCart = new shoppingCart("OnlineOrders");
myCart.addCheckoutParameters("Stripe", "pk_test_9iwiq8RA0aacvfi350h76350");
// return data object with store and cart
return {
store: myStore,
cart: myCart
};
});
I have added my controller.js and app.js.
Can anyone please help me figuring out why the UI is not changing?
Actually i was new to angular js i am trying to call my factory operation into controller i dont know where i am going wrong
and my js goes here
app.factory("myFactory",function(){
var something = {};
something.getsum = function() {
$scope.service = " heloo people"
}
return something;
});
app.controller("helloController", function($scope,myFactory) {
$scope.clickme = function() {
$scope.service=myFactory.getsum();
}
});
and my html goes here
<div ng-controller="hello controller">
<button ng-click="clickme"></button>
<h2>{{service}}</h2>
</div>
and my config goes here:
$urlRouterProvider.otherwise("/index/utilise");
$stateProvider
.state('index', {
abstract: true,
url: "/index",
templateUrl: "display.html",
controller:'mainController',
controllerAs: "parentCtrl",
})
.state('index.sample', {
url: "/home",
templateUrl: "content/sample.html",
})
.state('index.utilise', {
url: "/utilise",
templateUrl: "content/utilise.html",
})
})
First issue is that to use the myFactory factory in your controller you would need to inject it into the controller via dependency injection:
app.controller("helloController", function($scope, myFactory) {
$scope.clickme = function() {
$scope.service = myFactory.getsum();
}
});
Second issue you would not use $scope in the myFactory factory method getsum(), you would simply return the value you need:
app.factory("myFactory",function(){
var something = {};
something.getsum = function() {
return " heloo people";
}
return something;
});
Third issue is ng-click was not actually execute controller function clickme as there was parenthesis () as you would with any JavaScript function. It should be ng-click="clickme()" to actually call the function on the controller:
<div ng-controller="helloController">
<button ng-click="clickme()"></button>
<h2>{{service}}</h2>
</div>
Finally, it's unclear what the structure of your application based on the ui-router configuration your provided. With ui-router you wouldn't really have the need to use ng-controller as you can specify what controller any given view should be using. I've created multiple Plunkers, one and two, demonstrating the factory functionality with and without controllers specified for child routes. This should be more than enough to demonstrating calling a controller function in different situations.
Hopefully that helps!
I have had a look at all the examples around and tried to integrate with my Ionic project and failed. Here is what I have so far.
I am using a project created using creator.ionic.com
I have an html page that im loading a JSON file into
(agentSchedule.html)
<ion-view style="" title="Agent Schedule">
<ion-content class="has-header" overflow-scroll="true" padding="true">
<ion-refresher on-refresh="doRefresh()">
</ion-refresher>
<div ng-controller="agentScheduleCtrl">
<ion-list style="">
<ion-item class="item-icon-right item item-text-wrap item-thumbnail-left" ng-repeat="user in users">
<img ng-src="{{ user.image }}">
<h2>{{ user.fname }} {{ user.lname }}</h2>
<h4>Role : {{ user.jobtitle }}</h4>
<h4>Username : {{ user.username }}</h4><i class="button-icon icon ion-ios-arrow-forward"></i>
</ion-item>
</ion-list>
</div>
</ion-content>
Here is the controller and routes for that page
.controller('agentScheduleCtrl', function($scope, $http, $timeout) {
var url = "http://www.otago.ac.nz/itssd-schedule/mobileappdevice/services/getUsers.php";
var url = "users.json";
$http.get(url).success( function(response) {
$scope.users = response;
});
.state('menu.agentSchedule', {
url: '/page4',
views: {
'side-menu21': {
templateUrl: 'templates/agentSchedule.html',
controller: 'agentScheduleCtrl'
}
}
})
I am another page that I want to pass the username to, and then use on any page that I go from there
(specificAgentDetails.html)
<ion-view style="" view-title="Agent Specific Schedule">
<ion-content class="has-header" overflow-scroll="true" padding="true">
</ion-content>
</ion-view>
Here is the controller and routes for that page
.controller('specificAgentDetailsCtrl', function($scope) {
})
.state('menu.specificAgentDetailsCtrl', {
url: '/page9',
views: {
'side-menu21': {
templateUrl: 'templates/specificAgentDetailsCtrl.html',
controller: 'specificAgentDetailsCtrl'
}
}
})
How to Pass the user.username JSON variable to the next page as a global variable ??
Any help would be awesome - im going around in circles
So what #shershen said is true most ionic apps are set up as SPA's, what you're going to do isn't a "ionic" thing it's more of a AngularJS thing. You're going to want to setup a Service to hold your User info and then share it with your other controllers.
Create a Factory to share the data.
Inject the factory into the first controller and set it.
Inject the factory into the second controller and retrieve it.
Share data between AngularJS controllers
If you're familiar with get/set in OOP you should have no problem.
.factory('Data', function () {
var user = {};
return {
getUser: function () {
return user;
},
setUser: function (userparameter) {
user = userparameter;
}
};
})
.controller('agentScheduleCtrl', function($scope, $http, $timeout, Data) {
var url = "http://www.otago.ac.nz/itssdschedule/mobileappdevice/services/getUsers.php";
var url = "users.json";
$http.get(url).success( function(response) {
Data.setUser(response);
$scope.users = response;
});
Then in your second controller:
.controller('specificAgentDetailsCtrl', function($scope, Data) {
$scope.user = Data.getUser();
})
Make sure the syntax between the view and controllers are correct. I'm using user you're using users, setup breakpoints in your controllers to see what's going on there.
I use a little generic factory to do the job.
.factory('LocalRepo', function () {
var data = {}
return {
Get: function (key) {
return data.key;
},
Set: function (key, val) {
return data.key = val;
}
}
})
.controller('One', function($scope, LocalRepo) {
//Set in first controller
//TODO: $scope.users = .... from your call
LocalRepo.Set('users', $scope.users);
})
.controller('Two', function($scope, LocalRepo) {
//Get in second controller
$scope.users = LocalRepo.Get('users');
})
Use it to set whatever you want between controllers
Here is a quite simple solution. use $window and it will hold the data globally available for all controllers, services or anything etc.
.controller('agentScheduleCtrl', function($scope, $http, $timeout,$windows) {
$window.users = [];
var url = "http://www.otago.ac.nz/itssd-schedule/mobileappdevice/services/getUsers.php";
var url = "users.json";
$http.get(url).success( function(response) {
$window.users = response;
});
})
Inject $window as dependency in other controller and you can access it like $window.users.
Hope it helps someone.
I have a Angular SPA in which things are working fine except that the business wants me to move the code from this link-group.html (which has its own controller, module etc..)
The URL with the code to put into a template or place the code underneath the other html code supervisors.html
URL for News that is in link-group.html that I need to move:
http://localhost:1337/doc-home/#/tips/2?paginatePage=1
File:
link-group.html
Location:
Then the location of where I needs to display (move to)
URL:
http://localhost:1337/doc-home/#/supervisors
File:
supervisors.html
Location:
Template? controller reference?
UPDATE
I want to take all the code from the link.group.html and move it to the supervisor.html page
However, there is specific code that is referring to the controller/module/database that is based on the URL
<div class="links-group" ng-repeat="group in groups" ng-show="!group.hidden">
<div ng-show="!edit" style="margin: 5px 0;">
<h3>{{ group.title }}</h3>
<div ng-show="edit === true">
<input style="margin: 5px 0" placeholder="title..." class="input" ng-model="group.title" />
UPDATE 2 per suggestion from OP
Current controller.js for supervisor.html
angular.module('supervisors')
.controller('SupervisorsCtrl',
function ($scope, UserService) {
UserService.get(function (err, user) {
$scope.user = user;
});
});
So in order to modify can I add another module underneath it?
angular.module('supervisors')
.controller('SupervisorsCtrl',
function ($scope, UserService) {
UserService.get(function (err, user) {
$scope.user = user;
});
});
angular.module('linkgroup', ['ng'])
.directive('linkgroup', function({{ dependencies of your controller here }}) {
return {
templateUrl: {{ url of the template, likely link-group.html }},
link: function($scope, $element, $attributes) {
// think of this as the controller of a directive
{{ code of your controller,
replace `this` with `$scope` if you used ControllerAs }}
}
};
});
Seems that there is NO module.js in the common folder, there is a directives.js and controller.js
However I see that with links folder there is this code
angular.module('links')
.controller('LinksCtrl', function ($scope, LinksService, SearchService, UserService, notify, $window, $location) {
$scope.message = "";
UserService.get(function (err, user) {
if (err) {
notify.error('Error getting current user.');
} else {
if (user.groups.WEB_ESO !== true) {
$location.path('/');
}
}
});
Sounds like you could get away with a directive that contains your link-group. Transformation is pretty straightforward (if you used $scope in your controller it's almost direct copy+paste):
angular.module('linkgroup', ['ng'])
.directive('linkgroup', function({{ dependencies of your controller here }}) {
return {
templateUrl: {{ url of the template, likely link-group.html }},
link: function($scope, $element, $attributes) {
// think of this as the controller of a directive
{{ code of your controller,
replace `this` with `$scope` if you used ControllerAs }}
}
};
});
Then in supervisors.html add <linkgroup></linkgroup> at the bottom.
I have a table in a template which is retrieving json data something like this
`
id type date
755 video 21/09/12
`.
here is my controller of retrieving data for table
.controller('list', function($scope, $http) {
$http.get(baseUrl + '/page/1', _auth)
.success(function(data) {
$scope.value = data.data;
}, function(err) {
console.error(err);
});
$scope.detail = function(index) {
$http.get(baseUrl + '/page')
}
})
for routing i am using ui-router and doing something like this
$stateProvider
.state('/get' , {
url: '/data',
templateUrl: 'app/list/data/data.html'
})
This page also has button which redirects you to a different template on clicking any row from table. All I want is by clicking any row it redirects you to a different template and will show data only related to the id clicked. How can i achieve this? Any Help ?
Thankx
You'll need a route to display this particular element :
$stateProvider
.state('/get' , {
url: '/data',
templateUrl: 'app/list/data/data.html'
})
.state('/getone' , {
url: '/data/:id',
templateUrl: 'app/list/data/detail.html',
controller:"MyController"
})
You will have a param ":id" that will give you the element to show.
You can get it in your controller like this :
app.controller('MyController', function($scope, $stateParams) {
$scope.myDataId = $stateParams.id
});
You can navigate to this using this ui-sref syntax :
ui-sref="/getone({id:myelementid})"
Currently working on an exemple in plunker.
Hope it helped.
EDIT : Here is a clean "How to do"
See it in this plunker
My states definition
app.config(function($stateProvider, $urlRouterProvider){
$urlRouterProvider.otherwise('/datalist');
$stateProvider
.state('datalist', {
url: '/datalist',
templateUrl: 'data.html',
controller: 'DataCtrl',
})
.state('datadetail', {
url: '/datadetail/:id',
templateUrl: 'detail.html',
controller: 'DetailCtrl',
})
});
My controllers :
app.controller('DataCtrl', function($scope, $http){
$http.get("all.json").success(function(datas){
$scope.datas = datas;
})
});
app.controller('DetailCtrl', function($scope, $http, $stateParams){
$http.get($stateParams.id+".json").success(function(data){
$scope.data = data;
})
});
And finally the data template :
<div>Welcome to my awesome data list</div><br/>
<div ng-repeat="data in datas">
<div>
Data Id : {{data.id}}
</div>
<div>
Data name : {{data.name}}
</div>
<button ui-sref="datadetail({id:data.id})">See details of {{data.name}}</button>
</div>
I prefer a lot to not use a "/" in the state name till the state name is a technical name and will no be displayed.
If you have some trouble try to recreate your states, steps by steps.
EDIT 2 : How to match the question behavior
See it on this plunker
Here is how it would work with your "select" a row on a click.
Since you can refer to your "current" object of a "ng-repeat= data in datas" as "data". You are able to pass it to a function like this :
ng-repeat="data in datas" ng-click="select(data)"
The function simply affect this object to a var that represent the currently selected object :
$scope.select = function(data){
$scope.selectedData = data;
};
Now you button will take the information about "selectedData"
<button ui-sref="datadetail({id:selectedData.id})" ng-disabled="!selectedData">
See details of {{selectedData.name}}
</button>
And ... that's pretty much all. If you have the two states defined on my first exemple you will exactly have what you want.