Display different template on selecting an option in menu - html

I'm trying to display different templates on selecting the menu options. I'm able to display it, but I want the menu to be displayed along with respective template selected in menu list (i.e., I want both menu and the respective option selected on same page). When I change the menu option, only the option template has to change and load different template keeping still displaying the menu.
Hope you got the idea. Can someone please suggest a way? Thank you.
Below are my codes:
UI Routing
"use strict";
angular.module('fleetOperate').config(function ($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise("main");
$stateProvider
.state('main', {
url: '/main',
templateUrl: 'app/landingPage/main.html'
})
.state('settings', {
url: '/settings',
views: {
'': {
controller: 'settingsController',
templateUrl:'app/landingPage/features/settings/settingsTemplate.html'
},
'settingsControlPanel#settings': {
controller: 'settingsControlPanelController',
templateUrl:'app/landingPage/features/settings/settingsControlPanel/settingsControlPanelTemplate.html'
},
'truckSettings#settings': {
controller: 'truckSettingsController',
templateUrl: 'app/landingPage/features/settings/settingsControlPanel/truckSettings/truckSettingsTemplate.html'
},
'trailerSettings#settings': {
controller: 'trailerSettingsController',
templateUrl: 'app/landingPage/features/settings/settingsControlPanel/trailerSettings/trailerSettingsTemplate.html'
}
}
})
});
main HTML
<div class="icon-bar" ui-view="main">
<a ui-sref="settings" class="item">
<i class="fa fa-cog" style="font-size:48px;"></i>
<label>Settings</label>
Settings HTML
<div ui-view="settingsControlPanel"></div>
Menu HTML
<div class="panel settings-panel panel-primary">
<div class="panel-heading" align="center">Settings</div>
<ul>
<li><a ui-sref="truckSettings"><i class="fa fa-truck settings-truck-icon"></i>Truck Settings</a></li>
<li><a ui-sref="trailerSettings"><i class="fa fa-train settings-truck-icon"></i>Trailer Settings</a></li>
</ul>
</div>
<div ui-view="truckSettings"></div>
<div ui-view="trailerSettings"></div>
Truck Settings HTML
<div class="panel truck-settings-panel panel-primary">
<div class="panel-heading">Truck Settings</div>
<table class="table truck-settings-table table-bordered table-condensed table-striped">
<tr>
<th>Model: </th>
<td class="list-truck-settings-data"></td>
</tr>
<tr>
<th>
Make Month & Year:
</th>
<td class="list-truck-settings-data"></td>
</tr>
</table>
</div>
Trailer Settings HTML
<div class="panel trailer-settings-panel panel-primary">
<div class="panel-heading">Trailer Settings</div>
<table class="table trailer-settings-table table-bordered table-condensed table-striped">
<tr>
<th>Model: </th>
<td class="list-trailer-settings-data"></td>
</tr>
<tr>
<th>
Make Month & Year:
</th>
<td class="list-trailer-settings-data"></td>
</tr>
</table>
</div>

If you don't need to route to individual pages, but are satisfied with just toggling on and off different sections of HTML from the same controller view, you could use ng-includes. Clicking the menu would set the variable for a particular include on or off, making it visible or invisible.
Example:
Menu HTML
<div class="panel settings-panel panel-primary">
<div class="panel-heading" align="center">Settings</div>
<ul>
<li ng-click="showTruck = true; showTrailer = false;"><i class="fa fa-truck settings-truck-icon"></i>Truck Settings</li>
<li ng-click="showTruck = false; showTrailer = true;"><i class="fa fa-train settings-truck-icon"></i>Trailer Settings</li>
</ul>
</div>
<div ng-if="showTrailer" ng-include="path/to/trailerSettingsTemplate.html"></div>
<div ng-if="showTruck" ng-include="path/to/truckSettingsTemplate.html"></div>
Ideally, the menu click logic should be a method in the controller that sets all values false, and only the one to show as true.
This pattern does not use routing, so if you want users to be able to navigate with history, this will not work. But if you have no need for individual controllers for each of these subviews, includes will do the job.
Angular docs for ngInclude

I found this as one option to the above posted question. We can simply use ng-show to trigger the views, while the controllers are still binded to each views in router.
Menu HTML
<div class="panel settings-panel panel-primary">
<div class="panel-heading" align="center">Settings</div>
<ul>
<li><a ng-click="truck=true; trailer=false"><i class="fa fa-truck settings-truck-icon"></i>Truck Settings</a></li>
<li><a ng-click="truck=false; trailer=true"><i class="fa fa-train settings-truck-icon"></i>Trailer Settings</a></li>
</ul>
</div>
<div ui-view="truckSettings" ng-show="truck"></div>
<div ui-view="trailerSettings" ng-show="trailer"></div>

Related

Spring Boot+Thymeleaf: load data from DB into iframe

on the home page of my dummy webapplication I want to display the top 5 sellers and the newest product. For this I am using a slide show. The slide show is already implemented. For the slides I want to use embedded HTML files with help of iframe tags. These embedded HTML files should display data loaded from mysql database.
The problem: how can I add a java entity to an iframe instead of adding it as an object to the ModelAndView? Is this even possible? Code snippet of the Spring controller (for loading the home page):
#RequestMapping(value={"","/"}, method = RequestMethod.GET)
public ModelAndView showHomePage() {
ModelAndView mv = new ModelAndView();
mv.setViewName("home");
List<ProductCategoryModel> productList = this.productRepository.getAllProductsByProductCategoryModel();
mv.addObject("productList",productList);
return mv;
}
Here I was adding all products as a list object to the home page view. Now inside the home.html, I would like to pass that list object to the iframe, but how? Here is the code snipped of the iframe (which is inside the div with id=slides__1):
<section>
<div class="slider-container">
<div class="slider">
<div class="slides">
<div id="slides__1" class="slide">
<iframe src="iframes/test.html" title="Top 5 Sellers"></iframe>
<a class="slide__prev" href="#slides__4" title="Next"></a>
<a class="slide__next" href="#slides__2" title="Next"></a>
</div>
<div id="slides__2" class="slide">
<span class="slide__text">2</span>
<a class="slide__prev" href="#slides__1" title="Prev"></a>
<a class="slide__next" href="#slides__3" title="Next"></a>
</div>
<div id="slides__3" class="slide">
<span class="slide__text">3</span>
<a class="slide__prev" href="#slides__2" title="Prev"></a>
<a class="slide__next" href="#slides__4" title="Next"></a>
</div>
<div id="slides__4" class="slide">
<span class="slide__text">4</span>
<a class="slide__prev" href="#slides__3" title="Prev"></a>
<a class="slide__next" href="#slides__1" title="Prev"></a>
</div>
</div>
<div class="slider__nav">
<a class="slider__navlink" href="#slides__1"></a>
<a class="slider__navlink" href="#slides__2"></a>
<a class="slider__navlink" href="#slides__3"></a>
<a class="slider__navlink" href="#slides__4"></a>
</div>
</div>
</div>
</section>
And now the HTML page (code snippet of the section) I want to embedd as iframe and that should load all products into a table. In this view I will access the list object with all products:
<section>
<div class="container">
<br><br><br>
<table class="table table-bordered table-striped" id="product-table">
<thead>
<tr>
<th>Image</th>
<th>Product Id</th>
<th>Category</th>
<th>Product Description</th>
<th>Price in $</th>
<th>Image Source</th>
<th>Enabled</th>
</tr>
</thead>
<tbody>
<tr th:each="product: ${productList}">
<td><img th:src="${product.productImgSource}" alt="productImg" width="50" height="50"></td>
<td th:text="${product.productId}"></td>
<td th:text="${product.categoryText}"></td>
<td th:text="${product.productDescription}"></td>
<td th:text="${product.productPrice}"></td>
<td th:text="${product.productImgSource}"></td>
<td th:text="${product.enabled}"></td>
</tr>
</tbody>
</table>
</div>
</section>
Note: finding the top 5 sellers is not implemented yet, I just wanted to test it first with all products. Thanks in advance for any advice.

Angular ExpressionChangedAfterItHasBeenCheckedError while using random numbers in progress bar

I get this ExpressionChangedAfterItHasBeenCheckedError when i am using random numbers progress bar in my html grid table.It says "ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: some value. Current value: some value.". Someone please help me with the issue.
<nav class="navbar navbar-expand-sm bg-primary navbar-dark">
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link" routerLinkActive="active">
<button class="btn btn-primary" (click)="goToAddUser()">Add User</button>
</a>
</li>
</ul>
</nav>
<div class="panel panel-primary">
<div class="panel-heading">
<h2>User List</h2>
</div>
<div class="panel-body">
<table class="table table-striped">
<thead>
<tr>
<th>Firstname</th>
<th>Lastname</th>
<th>Email</th>
<th>Actions</th>
<th>Progress</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let user of users | async">
<td>{{user.firstname}}</td>
<td>{{user.lastname}}</td>
<td>{{user.email}}</td>
<td>
<button (click)="goToEditUser(user.id)" class="btn btn-info">Update</button>
<button (click)="deleteUser(user.id)" class="btn btn-danger" style="margin-left: 10px">Delete</button>
<button (click)="goToViewUser(user.id)" class="btn btn-info" style="margin-left: 10px">Details</button>
</td>
<td>
<mat-progress-bar [value]="number" style="margin-right: 300px"></mat-progress-bar>
{{ number }}%
</td>
</tr>
</tbody>
</table>
</div>
</div>
The getRandomNumber() return value changes after angular change detection already checked its value. To understand the error better, read this article:
https://hackernoon.com/everything-you-need-to-know-about-the-expressionchangedafterithasbeencheckederror-error-e3fd9ce7dbb4
Here's one solution, make a class field called randomNumber and assign it to the value of getRandomNubmer().
class YourComponentClass { randomNumber : number = this.getRandomNumber(); ... }
In Html
<td> <mat-progress-bar [value]="randomNumber" style="margin-right: 300px">
</mat-progress-bar> {{ randomNumber }} </td>
if you want to change your randomNumber just create a click event handler to reassign randomNumber to getRandomNumber() method
You need to manually check for changes.
// Import
import { Component, OnInit, ChangeDetectorRef } from '#angular/core';
// Inject
constructor(private cd: ChangeDetectorRef)
// Call after making changes in component
someMethod() {
this.cd.detectChanges();
}

Angular CLI won't show CSS

I use angular cli 1.4.3, node 6.11.3, npm 5.4.2, I want to read the records by using angular2. The output at localhost should be like this:
but the output that I get is like this:
here the html code:
<div class="row m-b-18px">
<div class="col-md-12">
<!-- button to create new product -->
<a (click)="createProduct()" class='btn btn-primary pull-right'>
<span class='glyphicon glyphicon-plus'></span> Create Product
</a>
</div>
</div>
<div class="row">
<div class="col-md-12">
<!-- HTML table for our list of product records -->
<table class='table table-hover table-responsive table-bordered'>
<tr>
<th>Product</th>
<th>Price</th>
<th>Description</th>
<th>Category</th>
<th>Actions</th>
</tr>
<!-- Use *ngFor directive to loop throught our list of products. -->
<tr *ngFor="let product of products">
<td>{{product.name}}</td>
<td>{{product.price}}</td>
<td>{{product.description}}</td>
<td>{{product.category_name}}</td>
<td>
<!-- read one product button -->
<a (click)="readOneProduct(product.id)" class='btn btn-
primary m-r-5px'>
<span class='glyphicon glyphicon-eye-open'></span> Read
</a>
<!-- edit product button -->
<a (click)="updateProduct(product.id)" class='btn btn-info
m-r-5px'>
<span class='glyphicon glyphicon-edit'></span> Edit
</a>
<!-- delete product button -->
<a (click)="deleteProduct(product.id)" class='btn btn-danger
m-r-5px'>
<span class='glyphicon glyphicon-remove'></span> Delete
</a>
</td>
</tr>
</table>
</div>
</div>
Here the css code:
.m-b-18px{ margin-bottom: 18px; }
.m-r-5px{ margin-right: 5px; }
.w-40-pct{ width: 40%; }
.text-align-center{ text-align: center; }
Thank you
Looks like you do not include Bootstrap in your project. First, install it:
npm install --save bootstrap
Then go to angular-cli.json file, find styles properties and add "../node_modules/bootstrap/dist/css/bootstrap.min.css" so it looks like this:
"styles": [
"styles.css",
"../node_modules/bootstrap/dist/css/bootstrap.min.css"
],
Are you use the View encapsulation in the component?

Semantic-ui menu and Angularjs ngRoute

I am using the Semantic-UI with AngularJS and I have a problem with semantic-ui menu.
In the index.html file I define the main menu:
<div class="ui inverted tiered menu">
<a class="active item" href="#/login">
<i class="sign in icon"></i> Login
</a>
<div class="ui dropdown item">
<i class="users icon"></i> TEST <i class="icon dropdown"></i>
<div class="menu">
<a class="item" href="#/test/test1"><i class="add icon"></i>Dodaj</a>
</div>
</div>
</div>
...
<div ng-view></div>
In app.js I have:
hrmApp.config(['$routeProvider', function($routeProvider) {
$routeProvider.
when('/login', {
templateUrl: '/login.html',
controller: 'LoginController'
}).
when('/comment', {
templateUrl: '/test.html',
controller: 'TestController'
}).
otherwise({
redirectTo:'/login'
});
}]);
When I navigate to the site using /test/test1 then the dropdown menu works however when I navigate to the site using /login and then reload page (ctrl+r) then the dropdown menu doesnt work. What may be the cause of this problem?
I solved the problem. I have multiple controllers and ui.dropdown was initalized only in one of them using code presented below:
$('.ui.dropdown').dropdown();
Adding this code in other controllers solved it.

Multiple transclusions of separate html

I'd like to transclude multiple pieces into one directive. Here is my idea of how I'd set it up.
<div id="content" class="mainDirective">
<div class="sub">
<ul>
<li>Everyone</li>
<li>Development (3)</li>
<li>Marketing</li>
</ul>
</div>
<div class="subButtons">
<span class="csStIcon add" data-ng-click="addTeam()"></span>
<span class="csStIcon edit" data-ng-click="editTeam()"></span>
<span class="csStIcon delete" data-ng-click="deleteTeam()"></span>
</div>
<div class="main">
<table>
<thead>
<tr><td>Name</td><td>Last name</td><td>Department</td></tr>
</thead>
<tbody>
<tr><td>Lorem</td><td>Ipsum</td><td>Development</td></tr>
<tr><td>Lorem</td><td>Ipsum</td><td>Development</td></tr>
<tr><td>Lorem</td><td>Ipsum</td><td>Development</td></tr>
</tbody>
</table>
</div>
</div>
My directive template:
<div>
<div class="left">
<div data-ng-multi-transclude="sub"></div>
<div class="bottomOptions">
<span class="csStIcon collapse"></span>
<div data-ng-multi-transclude="subButtons"></div>
</div>
</div>
<div class="right">
<div data-ng-multi-transclude="main"></div>
</div>
</div>
And the final output:
<div>
<div class="left">
<div class="sub">
<ul>
<li>Everyone</li>
<li data-ng-click="loadDepartment()">Development (3)</li>
<li data-ng-click="loadDepartment()">Marketing</li>
</ul>
</div>
<div class="bottomOptions">
<span class="csStIcon collapse"></span>
<div class="subButtons">
<div class="subButtons">
<span class="csStIcon add" data-ng-click="addTeam()"></span>
<span class="csStIcon edit" data-ng-click="editTeam()"></span>
<span class="csStIcon delete" data-ng-click="deleteTeam()"></span>
</div>
</div>
</div>
</div>
<div class="right">
<div class="main">
<table>
<thead>
<tr><td>Name</td><td>Last name</td><td>Department</td></tr>
</thead>
<tbody>
<tr><td>Lorem</td><td>Ipsum</td><td>Development</td></tr>
<tr><td>Lorem</td><td>Ipsum</td><td>Development</td></tr>
<tr><td>Lorem</td><td>Ipsum</td><td>Development</td></tr>
</tbody>
</table>
</div>
</div>
</div>
Is this possible within angular?
I ended up needing this functionality as well, so I wrote ng-multi-transclude -- funnily enough, I hadn't seen this question at the time, just lucked into the same name.
Usage is almost exactly as your question sketches; the only difference is that you use the name attribute to pick the "hole" to fill instead of the class attribute.
This has been added in angular 1.5
http://angularjs.blogspot.ca/2016/02/angular-150-ennoblement-facilitation.html
I came up with this directive using transclude function:
app.directive('mainDirective', function($compile) {
var template = ['<div>',
' <div class="left">',
' <div data-ng-multi-transclude="sub"></div>',
' <div class="bottomOptions">',
' <span class="csStIcon collapse"></span>',
' <div data-ng-multi-transclude="subButtons"></div>',
' </div>',
' </div>',
' <div class="right">',
' <div data-ng-multi-transclude="main"></div>',
' </div>',
'</div>'].join('\n');
return {
restrict: 'C',
transclude: true,
template: template,
link: function(scope, element, attr, model, transclude) {
var places = element.find('[data-ng-multi-transclude]');
console.log(element);
places.each(function() {
var self = $(this);
var class_ = self.data('ng-multi-transclude');
transclude(scope.$new(), function(clone, scope) {
var item = clone.closest('.' + class_);
$compile(item)(scope).appendTo(self);
});
});
}
};
});
I've used compile so you can use angular inside your transcluded code.
If you use this:
self.replaceWith($compile(item)(scope));
you'll don't get those original wrappers divs with data-ng-multi-transclude attributes.
Also you need to have jQuery included (always before Angular, because otherwise you get jQLite instead).
I have used multiple 'transclusions' in the component I am writing. In practice, it's just nested directives but they get the job done: https://github.com/AlexCppns/ac-fancy-input
More specifically, have a look at the following file:
https://github.com/AlexCppns/ac-fancy-input/blob/master/src/ac-fancy-input/directives/fancy-input.js