How to create links for array elements in AngularJS - javascript

I am new to AngularJS. I want to create links for elements in the array. Suggest me some code or descriptives.
app.js
app.controller('ItemsController', function($scope) {
$scope.message = 'Items are displayed';
$scope.items=['Appliances','Books','Cosmetics','Home & Furniture','Mens','women','kids'];
});
items.html
<div ng-controller="ItemsController">
<p><h1>Type a letter in the input field:</h1></p>
<p><input type="text" ng-model="test"></p>
{{message}}
<ul><h2>
<li ng-repeat="x in items| filter:test">
{{ x }}
</li>
</h2></ul>
</div>
Here is the sample output for the above code. Items displayed in the output should be links.

If you are using routing then just create an anchor tag in the li.
<ul>
<h2>
<li ng-repeat="x in items| filter:test">
{{x}}
</li>
</h2>
</ul>
In the route configuration, just handle the specific route pertaining to the item. Like if you want to display the details for the item.
myApp.config(['$routeProvider',function($routeProvider){
$routeProvider.
when('/details/:item',{
templateUrl:'partials/details.html',
controller: 'DetailsController'
}).
otherwise({
redirectTo : 'yourdefaultpath'
})
Item shall be available in your controller as a routeParam and then you can display your data accordingly.
Hope this helps.

You can use ui-sref and declare your items as states using ngRoute in your app, this is how would be your code:
<ul>
<li ng-repeat="x in items| filter:test">
<a ui-sref="{{x}}"><h2>{{ x }}</h2></a>
</li>
</ul>
Update your JS to add the states, like this:
app.config(function($stateProvider) {
$stateProvider.state('Appliances', {
url: 'Appliances',
templateUrl: 'app/views/appliances.html'
});
});

Related

ng-repeat gets refreshed when an item clicked

This is html:
<div class="main" ng-controller="companies">
<ul style="list-style: none;">
<li ng-repeat="company in companies | orderBy:'name' | filter:companies_filter">
<a href="#!/companies/{{company.id}}" ng-click="companySelected(company)">
{{company.name}}
</a>
</li>
</ul>
</div>
This is router.js:
...
.when('/companies', {
templateUrl: '../html/companies.html',
controller: 'companies'
})
.when('/companies/:companyId', {
templateUrl: '../html/companies.html'
});
....
This is working:
$scope.companySelected = function(company) {
console.log(company);
}
The list is pretty huge. If I scroll down to bottom and click on a company, the list gets back to the top. Same happens when I enter company name to filter and click, again, it gets back to its initial view. How can I fix it so that it stays where it is?
you are looking for $anchorScroll.
Here is the documentation: anchorScroll
When you return from company page to the list, you might need to add hash Id of the element that you clicked earlier. To that, you first need to add ID to li element like below.
<li id={{company.id}} ng-repeat="company in companies | orderBy:'name' | filter:companies_filter">
<a href="#!/companies/{{company.id}}" ng-click="companySelected(company)">
{{company.name}}
</a>
</li>
while coming back to list page, call $anchorScroll(); You can send hash as a parameter in the anchorscroll or update the location hash like below before calling $anchorScroll();
$location.hash('id_value');

How to redirect to new state in Angularjs?

Hi I am developing SPA application in Angularjs. This is my first application in Angularjs. I have two master pages. In first master page there is one tab when i click on that tab i want to redirect to another master page. I am using UI routing in Angularjs. I completed Login and registration modules but these modules should come in second master page but i have it in first master page now.
Below is my index.html first master page file.
<ul id="nav">
<li><a ui-sref="Registration.mainRegistration">{{ 'Registration' | translate }}</a></li>
<li><a ui-sref="Registration.Login">Login</a></li>
<li>{{ 'Careers' | translate }} </li>
<li>{{ 'Offers & Deals' | translate }} </li>
<li>{{ 'Financial' | translate }} </li>
This is the first page loads. There is one Financial tab in the above file. When i click on that tab all my above master page disappears and in that place new master page should come.
Below is my App.js
var app = angular.module('RoslpApp', ['pascalprecht.translate', 'ui.router', 'toastr']);
app.config(function ($stateProvider,
$urlRouterProvider,
$translateProvider,
$translatePartialLoaderProvider) {
$stateProvider
.state('Registration', {
abstract: true,
url: '/Registration',
templateUrl: 'Registration/placeholder.html',
controller: 'MainRegistration'
});
//there are other states also.
I am in the initial stage of development. So May I know this can be achieved? Any help would be appreciated. Thank you.
Your state should not contain abstract: true. Abstract states are usually created when you want a parent view and create nested views.
var app = angular.module('RoslpApp', ['pascalprecht.translate', 'ui.router', 'toastr']);
app.config(function ($stateProvider, $urlRouterProvider, $translateProvider, $translatePartialLoaderProvider) {
$stateProvider
.state('registration', {
url: '/registration',
templateUrl: 'Registration/registration.html',
controller: 'RegistrationController'
})
.state('login', {
url: '/login',
templateUrl: 'Registration/login.html',
controller: 'LoginController'
});
Refer the states in ui-sref as below:
/All css,js and angular references.
<script src="ForgotPassword/ForgotPasswordController.js"></script>
<script src="ForgotPassword/ResetPasswordController.js"></script>
<script src="ForgotPassword/OTPVerificationController.js"></script>
<script src="ForgotPassword/ChangePasswordController.js"></script>
//header
<ul id="nav">
<li><a ui-sref="registration">{{ 'Registration' | translate }}</a></li>
<li><a ui-sref="login">Login</a></li>
<li>{{ 'Careers' | translate }} </li>
<li>{{ 'Offers & Deals' | translate }} </li>
<li>{{ 'Financial' | translate }} </li>
</ul>
<div ui-view></div>
//Footer
Create the registration.html and login.html under Registration folder. Create the controller files RegistrationController and LoginController

Make newest item on top in To Do List using Angular

I have a problem with my todo list. I want when I input a new item, it appears on top of list items, not below the list items. I have put track by -$index but it doesn't work
index.html snippet
<ul class="unstyled">
<li ng-repeat="todo in todos track by -$index">
<input type="checkbox" ng-model="todo.done">
<span class="done-{{todo.done}}">{{todo.text}}</span>
</li>
</ul>
controller.js snippet
app.controller('TodoListController', ['$scope', function($scope) {
$scope.todos = [];
$scope.addTodo = function() {
$scope.todos.push({text:$scope.todoText, done:false});
$scope.todoText = '';
};
Are there any solution for this ?
Use unshift() to prepend the items to your array instead of push() and remove your track by -$index
Javascript
app.controller('TodoListController', ['$scope', function($scope) {
$scope.todos = [];
$scope.addTodo = function() {
$scope.todos.unshift({text:$scope.todoText, done:false});
$scope.todoText = '';
};
HTML
<ul class="unstyled">
<li ng-repeat="todo in todos">
<input type="checkbox" ng-model="todo.done">
<span class="done-{{todo.done}}">{{todo.text}}</span>
</li>
</ul>
The solution from #nipeco works fine but it changes the logic for presentation purposes which personally I wouldn't recommend.
I think it's best to push and use the filter orderBy+reverse to have the desired output.
<li ng-repeat="todo in todos | orderBy:'-$index':reverse">
Hope it helps!

Filter matched elements by class name in Angular js.

Problem:
I have an unordered list of items which are returned from a json call and are output using ng-repeat. Each one of these items has a class name (there are about 9 categories).
I have a second unordered list which is simply a list of available categories.
Aim:
I want to be able to select one of the categories in the right hand list, which will apply a filter to the actual list of returned elements. This should be activated via a toggle (so click once: filtered, click again: filter removed). So it is simply looking to match the classname in the clicked element, to the elements that share the same classname in the list of json data.
I cannot use ng-model (as this is reserved for certain form elements).
For my jsfiddle I am simply using static html.
Here is my angular code:
/* angular custom filter on returned ajax api data */
var app = angular.module('app', []);
app.controller('main', function($scope) {
$scope.chFilters = {};
$scope.links = [
{name: 'atm'},
{name: 'internet'},
{name: 'mobile'},
{name: 'sms'},
{name: 'postal'}
];
$scope.channels = ["ATM", "INTERNET", "SMS", "POSTAL","MOBILE"];
});
(this is based on another question I found on SO). Unfortunately the fiddle is a bit messy and has some extraneous code in it.
HTML:
<div ng-app="app">
<div ng-controller="main">
<ul>
<li class="atm">Some stuff ATM</li>
<li class="internet">Some stuff INTERNET</li>
<li class="sms">Some stuff ATM</li>
<li class="atm">Some stuff ATM</li>
<li class="postal">Some stuff POSTAL</li>
<li class="atm">Some stuff ATM</li>
<li class="internet">Some stuff INTERNET</li>
<li class="postal">Some stuff POSTAL</li>
<li class="postal">Some stuff POSTAL</li>
<li class="atm">Some stuff ATM</li>
<li class="sms">Some stuff SMS</li>
<li class="mobile">Some stuff MOBILE</li>
<li class="internet">Some stuff INTERNET</li>
<li class="mobile">Some stuff MOBILE</li>
</ul>
<ul class="channel-filters">
<li ng-repeat="link in links | filter:chFilters" class="{{link.name | lowercase}}"><a ng-click="chFilters.name = link.name">{{link.name | uppercase}}</a></li>
<li class="last" ng-click="chFilters.name = ''">CLEAR FILTER</li>
</ul>
<ul>
<li ng-repeat="channel in channels | filter:chFilters">
<strong>{{channel}}</strong>
<a ng-click="chFilters = channel">{{channel}}</a>
</li>
</ul>
<!-- original -->
<ul>
<li ng-repeat="link in links | filter:chFilters">
<strong>{{link.name}}</strong>
<a ng-click="chFilters.name = link.name">{{link.name}}</a>
</li>
</ul>
</div>
</div>
This is the actual HTML from the application (with the call to the api).
<ul class="accordion">
<li class="search-text-channel">
<input type="textarea" ng-model="searchTextChannel.$" placeholder="Search"/>
</li>
<li ng-repeat="day in interactions.model.byDay | filter:searchTextChannel" ng-click="hidden = !hidden" ng-init="hidden = false" class="{{day.channel | removeSpace | lowercase}}" ng-class="{'closed': !hidden, 'open': hidden}">
<span class="date">{{day.date}}</span>
<span class="subheading">{{day.channel}}</span>
<ul ng-show="hidden">
<li ng-repeat="interaction in day.interactions">
{{interaction.time}} {{interaction.description | removeUnderscore}}
</li>
</ul>
</li>
<li class="load-more">
<i class="fa fa-plus"></i>LOAD MORE
</li>
</ul>
I have managed to recreate this functionality in jquery, but I think it would be better to implement an angular solution in an angular application.
I've tried researching and also attempted to implement show/hide as well as a custom filter, but so far no joy.
Here is my (messy) jsfiddle
<ul>
<li ng-repeat="channel in channels | filter:chFilters.name">
<strong>{{channel}}</strong>
<a ng-click="chFilters = channel">{{channel}}</a>
</li>
</ul>
<!-- original -->
<ul>
<li ng-repeat="link in links | filter:chFilters.name">
<strong>{{link.name}}</strong>
<a ng-click="chFilters.name = link.name">{{link.name}}</a>
</li>
</ul>
Update Plunker
Let me know if you have any question on this.
Here is part of the solution:
Suppose your items look like this:
$scope.items = [
{ class: "atm", label: "Some stuff ATM" },
{ class: "internet", label: "Some stuff INTERNET" },
{ class: "sms", label: "Some stuff SMS" },
{ class: "postal", label: "Some stuff POSTAL" },
...
];
To show a filtered list (only filtering by a single channel for now): create a separate list in the scope, with the filters applied:
$scope.click = function(name) {
$scope.chFilters.name = name;
$scope.filteredItems = $scope.items.filter(function(item) {
return item.class === $scope.chFilters.name;
});
};
Call this click handler from the bottom list:
...<a ng-click="click(link.name)">{{link.name | uppercase}}</a>....
And show filteredItems in the top list:
<ul>
<li ng-repeat="item in filteredItems" ng-class="item.class">{{item.label}}</li>
</ul>
So this is really just a starting point, it should be extended to handle multiple filters, etc...

Angularjs optional navigation

I have an angular app with 11 pages. Some of them have a nav which is using this code:
<div class="well sidebar-nav" ng-app="navList">
<ul class="nav nav-list" ng-controller="navCtrl">
<li ng-class="navClass('home')"><a href='#/home'>Home</a></li>
<li ng-class="navClass('about')"><a href='#/about'>About Us</a></li>
<li ng-class="navClass('contact')"><a href='#/contact'>Contact Us</a></li>
</ul>
</div>
var navList = angular.module('navList', []);
navList.controller('navCtrl', ['$scope', '$location', function ($scope, $location) {
$scope.navClass = function (page) {
var currentRoute = $location.path().substring(1) || 'home';
return page === currentRoute ? 'active' : '';
};
}]);
I don't want this nav on all the pages. What is best solution to handle this situation? Should I show hide DOM element or do I need to remove it when not required?
It's entirely up to you. As #Chandermani said, there's not problem hiding it if your DOM is small. This is how most web-apps that have a fluid layout work. And given the size of your navigation, that's really not going to pose much of a problem.
If you did want to remove it entirely though (which is also fine) you could get angular to do this with the ng-switch directive. On your outer element that contains the code you posted, you add the switch, then on the well class element above, you add your condition, so for example, you may have
<div class="wrapper" ng-switch="smallScreen" ng-app="navList">
<div class="well sidebar-nav" ng-switch-when="true">
<ul class="nav nav-list" ng-controller="navCtrl">
<li ng-class="navClass('home')"><a href='#/home'>Home</a></li>
<li ng-class="navClass('about')"><a href='#/about'>About Us</a></li>
<li ng-class="navClass('contact')"><a href='#/contact'>Contact Us</a></li>
</ul>
</div>
</div>
Then in your controller you'll need a scope variable called smallScreen which you set to true or false depending on whether you want to see it.
On another note, it's unusual to have the ng-app directive attached to a menu or was this just for demonstration?

Categories