I am trying to implement Single Page Application in AngularJs. However, when I select the link ({{item.Name}} in Tree.Html). Corresponding view is not displayed in ng-View.
Any help will be appreciated
Main.html
<body ng-app="InfoModule" ng-controller="MainController" style="max-width:1000px; margin:auto">
<nav class="navbar navbar-inverse">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="#">Information</a>
</div>
<span class="pull-right navbar-text">{{UserName}}</span>
</div>
</nav>
<div class="row">
<div class="col-lg-6 col-md-6 col-sm-6 col-xs-6">
Info Page
<div ui-tree data-drag-enabled="false">
<ol ui-tree-nodes ng-model="itemList" class="font-weight-normal">
<li ng-repeat="item in itemList track by $index" ui-tree-node ng-include="'Tree.html'">
</li>
</ol>
</div>
</div>
<div class="col-lg-6 col-md-6 col-sm-6 col-xs-6">
<div ng-include="Details"></div>
<div data-ng-view>
</div>
</div>
</div>
<div class="panel-footer">
(C) My Solutions
</div>
Tree.html
<div ui-tree-handle class="tree-node tree-node-content">
<a class="btn btn-success btn-xs" ng-if="item.nodes && item.nodes.length > 0" ng-click="toggle(this)">
<span class="glyphicon" ng-class="{'glyphicon-chevron-right': collapsed,'glyphicon-chevron-down': !collapsed}"></span>
</a>
<a href="#Details" >
{{item.Name}}
</a>
Master.js
var app = angular.module('InfoModule', ['ui.tree', 'ngRoute', 'ngStorage']);
app.config(['$routeProvider', '$locationProvider', function ($routeProvider, $locationProvider) {
$routeProvider
.when('/login', {
templateURL: 'Login.html',
controller: '/mYscriptS/LoginController.js'
})
.when('Details', {
templateURL: 'pages/Details.html',
controller: '../mYscriptS/DetailsController.js'
})
.when('/Main', {
templateURL: 'main.html',
controller: '/mYscriptS/MainController.js'
});
//.otherwise({
// redirectTo: 'pages/Main.html'
// //templateURL: '/Main.html',
// //controller: '/mYscriptS/MainController.js'
//});
$locationProvider.html5Mode({
enabled: true,
requireBase: false
});
$locationProvider.html5Mode(true);
}]);
Details.html
<div ng-controller="DetailsController" >
<div class="row">
<div class="col-md-6">
User Id
{{UserName}}
</div>
<div class="col-md-6">
<input type="text" name="txtUserId" />
</div>
</div>
<div class="row">
<div class="col-md-6">
Password
</div>
<div class="col-md-6">
<input type="text" name="txtPassword" />
</div>
</div>
Once I had gotten a problem that was same as yours.
I've tried to figure it out, and many people recommended using 'ui.router' instead of 'ngRoute'.
Maybe there are more differences between them specifically.
But even just this explain, could help you deciding side.
ngRoute is a angular core module which is good for basic scenarios. I believe that they will add more powerful features in upcoming releases.
Ui-router is a contributed module which is overcome the problems of ngRoute. Mainly Nested/Complex views.
URL: https://github.com/angular-ui/ui-router
Related
I'm switching from vue to vuex and I'm having trouble implementing an onclick event. I'm using bootstrap collapse to create 3 div. Each div has a button to show the collapsible elements inside. With vue I'm taking the data from an api request. I want every single button to open its parent div. Currently every button open all the three divs. When using vue I simply wrote this:
methods:{
//set expand to true foreach player card,
//set open to true foreach plus button
playerCardCollapse(index) {
this.teams = this.teams.map((item, i) => {
item.expanded = !item.expanded
item.open = !item.open
if (i !== index) {
item.expanded = false
item.open = false
}
return item
})
},
},
This is my template:
<!-- Container Card -->
<div v-for="(team, i) in teams" :key="i" class="col-6">
<div class="row mb-2 team-default align-items-center" style="height:106px;">
<div class="col-2 section">
<img class="rounded-circle" :src="team.team_img" style="border:2px solid #fff;box-shadow: 0 2px 31px 0 rgba(0, 0, 0, 0.23);">
</div>
<div class="col section team end">
<p class="intestazione">Team Name:</p>
<p class="result">{{team.team_name}}</p>
</div>
<div class="col-2 section end">
<button type="button" class="btnProfile" data-bs-toggle="collapse" data-bs-target="#profile-row" :aria-expanded="team.expanded" aria-controls="profile-row" #click.prevent="playerCardCollapse(i)">
<div class="plus-icon" :class="{open: team.open}"></div>
</button>
</div>
</div>
<!-- Collapsed -->
<div v-if="team.player.length>0">
<div class="collapse show" :class="{show: team.expanded}">
<div v-for="(p, j) in team.player" :key="j" class="row team-default mt-2 mb-3" id="profile-row">
<div class="col-2 section">
<div class="player-img-container">
<img class="rounded-circle player-img" :src="p.profilePic">
<img class="rounded-circle flag-img" src="https://picsum.photos/31/31">
</div>
</div>
<div class="col section team end">
<p class="intestazione">Team {{p.role}}</p>
<p class="result">{{p.name}}</p>
</div>
<div class="col-4 section end">
<button class="btnProfile-cta">Visualizza Profilo</button>
</div>
</div>
</div>
</div>
</div>
But with vuex I don't know how to implement this playerCardCollapse().
Hope someone could help (I don't know if you need more code snippets)
I'm making an app that needs to be accessible for users without an account but as soon as someone makes an account they need to be able to see additional functionality and it needs to be responsive as well.
For responsiveness I'm using material design for bootstrap and angular materialmdbootstrap. In the example bellow I'd want to change the mdb-col-size from 9 to 12 depending on if the user is logged in or not and thus not display save,... option(s).
<div>
<div class="row ">
<div class="col-lg-9 col-md-8 col-sm-6 ">
<div class="row ">
<div class="col-md-12 mb-12">
<div class="card testimonial-card ">
<div class="card-up lighten-1 ">
<div class="card-body">
<h4 class="card-title">{{ dare.title }}</h4>
<hr />
<p>{{ dare.description }}</p>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="col-lg-3 col-md-4 col-sm-6"><!--this shouldn't be displayed when someone is not logged in-->
<div class="row">
<div class="col-12">
<button mat-raised-button class="btn btn-block">
Save
</button>
</div>
</div>
<br />
<div class="row">
<div class="col-12">
<button mat-raised-button class="btn btn-block">
Challenge someone else
</button>
</div>
</div>
<br />
<div class="row">
<div class="col-12">
<button mat-raised-button class="btn btn-block">
Create new ...
</button>
</div>
</div>
</div>
</div>
<br />
</div>
I expect to see the options only when someone is logged in and the responsiveness changing accordingly.
Thanks you in advance!
You should rather use Guards in your project, example in documentation: https://angular.io/api/router/CanActivate
To achieve it you should implement two components (one for authenticated user, another for non-authenticated user). Define routing, for example:
{
path: '',
component: AuthenticatedUserComponent,
canActivate: [AuthenticatedUserGuard]
},
{
path: '',
component: UnauthenticatedUserComponent
}
And then define guard:
#Injectable()
class AuthenticatedUserGuard implements CanActivate {
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean|UrlTree>|Promise<boolean|UrlTree>|boolean|UrlTree {
return true; // here you should call a method from service, that
// that holds whether user is authenticated or not
}
}
How can I pass the data in my ng-repeat to a data-attribute?
Please see below what I'm aiming for.
Sorry for the poor format this is my first time posting to StackOverflow.
<div class="row">
<div class="col-md-3" ng-repeat="p in controller.prod | filter:{state:'California'}">
<div class="card">
<div class="card-block">
<h3 class="card-title">{{p.productName}}</h3>
<h6 class="card-subtitle text-muted">${{p.price}}</h6>
<img ng-src="{{p.productImage}}" class="img-fluid">
</div>
<div class="card-block">
<div class="card-text">Product information<a
href="#"
class="card-link productItem btn btn-primary"
<!--Below is what i'm trying to accomplish -->
data-name="{{p.productName}}"
data-s="black"
data-price="{{p.price}}"
data-id="1">Add to Cart</a>
</div>
<br />
</div>
</div>
</div>
</div>
you have to assign one array in $scope in your controller and after that bind it with ng-reapeat in your html template like this:
app.controller("myCtrl", function($scope) {
$scope.records = [
"Alfreds Futterkiste",
"Berglunds snabbköp",
"Centro comercial Moctezuma",
"Ernst Handel",
]
});
your template:
<h1 ng-repeat="x in records">{{x}}</h1>
I am using a text box in which user can enter any text.
based on that the items in the list shown below are filtered as soon as text is typed/erased...
select all(send everyone there) removes the items from mainlist and adds those elements to selected list...
works fine for all. i want that only the filtered ones should be moved from one list to another...(on select all, all items are transferred!)
can i pass the same text(entered by user) and use that as a filter on my list inside the angular controller??
if yes, then guide me how.
below is the code segment :
$scope.transferList = function ( x ) {
if ( x === "selectAllServers" ) {
for ( i = 0; i < $scope.lists.serversList.servers.length; i++ ) {
$scope.lists.selectedServersList.servers.push( $scope.lists.serversList.servers[ i ] );
}
$scope.lists.serversList.servers = [];
}
};
<div class="text-center">
<h3>Select Servers</h3>
</div>
<div class="container col-md-4 col-md-offset-1">
<form>
<div class="form-group">
<div class="input-group style='width: 100%'">
<div class="input-group-addon"><i class="glyphicon glyphicon-filter"></i></div>
<input type="text" class="form-control" placeholder="Enter text to filter servers..." ng-model="searchTerm">
</div>
</div>
</form>
</div>
<div class="row">
<div class="box col-md-4 col-md-offset-1">
<ul dnd-list="lists.serversList.servers"
dnd-allowed-types="lists.serversList.allowedTypes">
<li class="text-center">Servers Available</li>
<li ng-repeat="server in lists.serversList.servers|filter:searchTerm"
dnd-draggable="server" dnd-type="server.type"
dnd-disable-if="server.type == 'unknown'"
dnd-moved="lists.serversList.servers.splice($index, 1)"
dnd-effect-allowed="move" class="background-unselected"
class="searchable">
<div class="handle">
<i class="glyphicon glyphicon-chevron-right"
ng-click="selectItem('server',$index)"></i>
</div>
<div class="name">{{server.name}}</div>
</li>
<li class="dndPlaceholder">Drop <strong>server</strong> here
</li>
</ul>
</div>
<div class="box col-md-4 col-md-offset-2">
<ul dnd-list="lists.selectedServersList.servers"
dnd-allowed-types="lists.selectedServersList.allowedTypes">
<li class="text-center">Servers Selected</li>
<li ng-repeat="server in lists.selectedServersList.servers"
dnd-draggable="server" dnd-type="server.type"
dnd-disable-if="server.type == 'unknown'"
dnd-moved="lists.selectedServersList.servers.splice($index, 1)"
dnd-effect-allowed="move" class="background-selected">
<div class="handle">
<i class="glyphicon glyphicon-chevron-left"
ng-click="removeItem('server',$index)"></i>
</div>
<div class="name">{{server.name}}</div>
</li>
<li class="dndPlaceholder">Drop <strong>server</strong> here
</li>
</ul>
</div>
</div>
<br />
<div class="row">
<div class="col-md-4 col-md-offset-1">
<button class="btn btn-default btn-block"
ng-click="transferList('selectAllServers')">
Send Everyone there <i class="glyphicon glyphicon-arrow-right"></i>
</button>
</div>
<div class="col-md-4 col-md-offset-2">
<button class="btn btn-default btn-block"
ng-click="transferList('unSelectAllServers')">
<i class="glyphicon glyphicon-arrow-left"></i> Send Everyone there
</button>
</div>
</div>
hope the code is readable enough.
1.You can launch same filter:
$scope.add = function() {
var filtered = $filter('filter')($scope.lists.serversList.servers, $scope.searchTerm);
// actual add here
}
2.As you see there is some code duplication here - you use same filter twice, so you can rewrite a bit:
<input type="text" class="form-control" placeholder="Enter text to filter servers..." ng-model="searchTerm" ng-change="recalculateFiltered()">
<li ng-repeat="server in filteredList" ...
And in controller:
$scope.recalculateFiltered = function() {
$scope.filteredList = $filter('filter')($scope.lists.serversList.servers, $scope.searchTerm);
}
I'm working on an application that needs to be able to change views on a click.
I have a table of values that are clickable leading to the main page for that object. I'm having an issue with my routes because no matter what my route goes back to the default ('/').
Here is my main javascript file.
angular.module('myApp',['ui.router', 'templates', 'angular-loading-bar'])
.config([
'$stateProvider',
'$urlRouterProvider',
function($stateProvider, $urlRouterProvider) {
// Default route
$urlRouterProvider.otherwise('/');
$stateProvider
.state('home', {
url: '/',
controller: 'MainCtrl',
templateUrl: 'home/_home.html',
resolve: {
product: ['products', function(products) {
return products.get();
}]
}
})
.state('schedules', {
url:'/schedules',
controller: 'SchedulesCtrl',
templateUrl:'schedules/_schedules.html',
resolve: {
schedules: ['schedules', function(schedules) {
return schedules.get();
}]
}
});
}]);
I've tried two different ways to change the page, a regular link on the navbar <li>Click Me</li> and by adding a function an ng-click $location.path('/schedules'); on the table. I can see the link change quickly, but it re-routes to the default.
Here's my main application.html.erb
<!DOCTYPE html>
<html>
<head>
<title>Features</title>
<%= stylesheet_link_tag 'application', media: 'all' %>
<%= javascript_include_tag 'application' %>
<%= csrf_meta_tags %>
</head>
<body ng-app="myApp">
<!-- Navbar -->
<div ng-include="'nav/_nav.html'"></div>
<div class="row" >
<div class="col-md-8 col-md-offset-2">
<div ui-view></div>
</div>
</div>
</body>
</html>
HTML for Navbar partial
<nav class="navbar navbar-default"role="navigation">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#nav-toggle">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand">My App</a>
</div>
<div class="collapse navbar-collapse" id="nav-toggle">
<ul class="nav navbar-nav">
<li class="active">Main</li>
<li>Schedule</li>
</ul>
<form class="navbar-form navbar-right" role="search">
<label for="date">Label</label>
<input type="text" class="form-control" ng-model="datePicker" datepicker id="date"/>
</form>
</div>
</nav>
Home Partial
<div class="panel panel-default ">
<div class="panel-heading flex">
<span class="sg-box inline">
<h2>Home
<div class="flex inline flex-right pull-right">
<form class="form-inline">
<a ng-attr-class="btn btn-default btn-small {{allFilterOn && 'btn-secondary'}}" ng-click="turnOnAllFilter()">All</a>
<a ng-attr-class="btn btn-default btn-small {{missingFilterOn && 'btn-secondary'}}" ng-click="turnOnMissingFilter()">Missing</a>
<a ng-attr-class="btn btn-default btn-small {{readyFilterOn && 'btn-secondary'}}" ng-click="turnOnReadyFilter()">Ready</a>
<input type="text" class=" form-control input-md" placeholder="Filter" ng-model="name">
</form>
</div>
</h2>
</span>
</div>
<div class="panel-body">
<table class="table table-align-middle table-hover">
<thead>
<tr>
<th class="name">Name <a ng-click="sortFields('name')"><i class="glyphicon glyphicon-sort"></i></a></th>
<th class="delivery">Delivery</th>
<th class="features">Features</th>
<th class="warnings">Warnings</th>
</tr>
</thead>
<tbody>
<tr ng-click="go(p)"ng-repeat="p in filteredProducts = (product.products | filter: productName | productFilter:allFilterOn:missingFilterOn:readyFilterOn | orderBy:sortType:sortReverse)">
<td>{{p.name}}</td>
<td>Daily</td>
<td>
<div class="progress">
<div class="progress-bar" role="progressbar" aria-valuenow="{{p.listing_count}}" aria-valuemin="0" aria-valuemax="{{p.required_features}}" style="min-width: 2em; width: {{(100*p.listing_count/p.required_features)| number:0}}%;">
{{p.listing_count}}
</div>
</div>
</td>
<td>
<span class="glyphicon glyphicon-warning-sign"> 0 </span>
</td>
</tr>
</tbody>
</table>
</div
</div>
Go Function in MainCtrl
$scope.go = function(product) {
console.log($location);
console.log(product.id);
$location.path('#/schedules');
}
When using the angular ui.router package, you should always stick to the state change functions provided.
So you can either use the html tag that replaces the href-tag:
<a ui-sref="state.name.here">Link</a>
Or you go with the function that can be used in the controller:
function Controller($scope, $state) {
$scope.goSchedules = function() {
$state.go('state.name.here');
}
}
And use the function in an ng-click tag on an element.
When manually changing the URL via href-tag or the location-service, you will not only have trouble when you change the URL of a state, but also when switching between normal- and HTML5-mode (no hashtag # sign in the URL bar). Changing the URL for a state could be an issue in future when two names conflict or you want to optimize for SEO. And switching off the HTML5-mode is sometimes helpful during development, but it simply looks better in production.